From 223cf6b1b95c7fb1dcc6c8384c0febfe025c4eeb Mon Sep 17 00:00:00 2001 From: FakeMichau <49685661+FakeMichau@users.noreply.github.com> Date: Wed, 21 Oct 2026 11:52:39 +0200 Subject: [PATCH] Fix MVs in Enshrouded By dmitsuki on discord --- OptiScaler/OptiScaler.vcxproj | 3 + OptiScaler/OptiScaler.vcxproj.filters | 9 ++ OptiScaler/shaders/velocity_convert/VC_Vk.cpp | 98 ++++++++++++++++++ OptiScaler/shaders/velocity_convert/VC_Vk.h | 17 +++ .../velocity_convert/precompile/vc.hlsl | 21 ++++ .../precompile/vc_Shader_Vk.h | 78 ++++++++++++++ .../precompile/vc_Shader_Vk.spv | Bin 0 -> 1400 bytes OptiScaler/spoofing/Vulkan_Spoofing.cpp | 5 + OptiScaler/upscalers/ffx/FFXFeature_Vk.cpp | 22 +++- OptiScaler/upscalers/ffx/FFXFeature_Vk.h | 3 + 10 files changed, 253 insertions(+), 3 deletions(-) create mode 100644 OptiScaler/shaders/velocity_convert/VC_Vk.cpp create mode 100644 OptiScaler/shaders/velocity_convert/VC_Vk.h create mode 100644 OptiScaler/shaders/velocity_convert/precompile/vc.hlsl create mode 100644 OptiScaler/shaders/velocity_convert/precompile/vc_Shader_Vk.h create mode 100644 OptiScaler/shaders/velocity_convert/precompile/vc_Shader_Vk.spv diff --git a/OptiScaler/OptiScaler.vcxproj b/OptiScaler/OptiScaler.vcxproj index e6c8c056..ddb2c9d8 100644 --- a/OptiScaler/OptiScaler.vcxproj +++ b/OptiScaler/OptiScaler.vcxproj @@ -366,6 +366,8 @@ copy NUL "$(SolutionDir)x64\Release\a\!! EXTRACT ALL FILES TO GAME FOLDER !!" /Y + + @@ -660,6 +662,7 @@ copy NUL "$(SolutionDir)x64\Release\a\!! EXTRACT ALL FILES TO GAME FOLDER !!" /Y + diff --git a/OptiScaler/OptiScaler.vcxproj.filters b/OptiScaler/OptiScaler.vcxproj.filters index 9509101c..c880f91f 100644 --- a/OptiScaler/OptiScaler.vcxproj.filters +++ b/OptiScaler/OptiScaler.vcxproj.filters @@ -704,6 +704,12 @@ Header Files + + Header Files + + + Header Files + Header Files @@ -1580,6 +1586,9 @@ Source Files + + Source Files + Source Files diff --git a/OptiScaler/shaders/velocity_convert/VC_Vk.cpp b/OptiScaler/shaders/velocity_convert/VC_Vk.cpp new file mode 100644 index 00000000..f52164f6 --- /dev/null +++ b/OptiScaler/shaders/velocity_convert/VC_Vk.cpp @@ -0,0 +1,98 @@ +#include +#include "VC_Vk.h" +#include "precompile/vc_Shader_Vk.h" + +VelocityConvert_Vk::VelocityConvert_Vk(std::string InName, VkDevice InDevice, VkPhysicalDevice InPhysicalDevice) + : Shader_Vk(InName, InDevice, InPhysicalDevice) +{ + if (InDevice == VK_NULL_HANDLE) + { + LOG_ERROR("InDevice is nullptr!"); + return; + } + + LOG_DEBUG("{0} start!", _name); + + // Setup descriptor layouts + std::vector bindings = { CreateBinding(0, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE), + CreateBinding(1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) }; + CreateLayouts(bindings); + + // Setup descriptor pool sizes and allocate sets + std::vector poolSizes = { { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, _maxFramesInFlight }, + { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, _maxFramesInFlight } }; + CreateDescriptorPool(poolSizes, _maxFramesInFlight); + CreateDescriptorSets(_descriptorSetLayout, _descriptorPool, _descriptorSets); + + // Load precompiled shader and create compute pipeline + std::vector shaderCode(vc_spv, vc_spv + sizeof(vc_spv)); + if (!CreateComputePipeline(_device, _pipelineLayout, &_pipeline, shaderCode)) + { + LOG_ERROR("[{0}] Failed to create pipeline!", _name); + _init = false; + return; + } + + _init = true; +} + +bool VelocityConvert_Vk::Dispatch(VkCommandBuffer InCmdList, VkImageView InResourceView, VkExtent2D InExtent) +{ + if (!_init || InCmdList == VK_NULL_HANDLE || InResourceView == VK_NULL_HANDLE) + return false; + + if (!CreateImageResource(InExtent.width, InExtent.height, VK_FORMAT_R16G16_SFLOAT, + VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_SAMPLED_BIT)) + { + LOG_ERROR("[{0}] Failed to create intermediate image!", _name); + return false; + } + + VkImageMemoryBarrier barrier { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER }; + barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.image = _intermediateImage; + barrier.subresourceRange = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }; + + // Whole image gets overwritten, previous contents can be discarded. + // Only an execution dependency is needed against the previous frame's reads + barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; + barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL; + barrier.srcAccessMask = 0; + barrier.dstAccessMask = VK_ACCESS_SHADER_WRITE_BIT; + vkCmdPipelineBarrier(InCmdList, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, + nullptr, 0, nullptr, 1, &barrier); + + _currentSetIndex = (_currentSetIndex + 1) % _maxFramesInFlight; + + VkDescriptorSet descriptorSet = _descriptorSets[_currentSetIndex]; + VkDescriptorImageInfo sourceInfo { VK_NULL_HANDLE, InResourceView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }; + VkDescriptorImageInfo destInfo { VK_NULL_HANDLE, _intermediateImageView, VK_IMAGE_LAYOUT_GENERAL }; + + std::vector descriptorWritesBuffer = { + { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, nullptr, descriptorSet, 0, 0, 1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + &sourceInfo, nullptr, nullptr }, + { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, nullptr, descriptorSet, 1, 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + &destInfo, nullptr, nullptr } + }; + + vkUpdateDescriptorSets(_device, static_cast(descriptorWritesBuffer.size()), descriptorWritesBuffer.data(), + 0, nullptr); + + vkCmdBindPipeline(InCmdList, VK_PIPELINE_BIND_POINT_COMPUTE, _pipeline); + vkCmdBindDescriptorSets(InCmdList, VK_PIPELINE_BIND_POINT_COMPUTE, _pipelineLayout, 0, 1, &descriptorSet, 0, + nullptr); + + uint32_t dispatchWidth = (InExtent.width + InNumThreadsX - 1) / InNumThreadsX; + uint32_t dispatchHeight = (InExtent.height + InNumThreadsY - 1) / InNumThreadsY; + vkCmdDispatch(InCmdList, dispatchWidth, dispatchHeight, 1); + + barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL; + barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; + barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + vkCmdPipelineBarrier(InCmdList, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0, + nullptr, 0, nullptr, 1, &barrier); + + return true; +} diff --git a/OptiScaler/shaders/velocity_convert/VC_Vk.h b/OptiScaler/shaders/velocity_convert/VC_Vk.h new file mode 100644 index 00000000..af5b13e7 --- /dev/null +++ b/OptiScaler/shaders/velocity_convert/VC_Vk.h @@ -0,0 +1,17 @@ +#pragma once +#include +#include + +class VelocityConvert_Vk : public Shader_Vk +{ + uint32_t InNumThreadsX = 16; + uint32_t InNumThreadsY = 16; + + public: + VelocityConvert_Vk(std::string InName, VkDevice InDevice, VkPhysicalDevice InPhysicalDevice); + ~VelocityConvert_Vk() = default; + + // Copies InResourceView into the R16G16_SFLOAT intermediate image (GetImage()), + // left in VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL + bool Dispatch(VkCommandBuffer InCmdList, VkImageView InResourceView, VkExtent2D InExtent); +}; diff --git a/OptiScaler/shaders/velocity_convert/precompile/vc.hlsl b/OptiScaler/shaders/velocity_convert/precompile/vc.hlsl new file mode 100644 index 00000000..328342ce --- /dev/null +++ b/OptiScaler/shaders/velocity_convert/precompile/vc.hlsl @@ -0,0 +1,21 @@ +#ifdef VK_MODE +[[vk::binding(0, 0)]] +#endif +Texture2D SourceTexture : register(t0); + +#ifdef VK_MODE +[[vk::binding(1, 0)]] +[[vk::image_format("rg16f")]] +#endif +RWTexture2D DestinationTexture : register(u0); + +[numthreads(16, 16, 1)] +void CSMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + uint width, height; + DestinationTexture.GetDimensions(width, height); + if (dispatchThreadID.x >= width || dispatchThreadID.y >= height) + return; + + DestinationTexture[dispatchThreadID.xy] = SourceTexture.Load(int3(dispatchThreadID.xy, 0)); +} diff --git a/OptiScaler/shaders/velocity_convert/precompile/vc_Shader_Vk.h b/OptiScaler/shaders/velocity_convert/precompile/vc_Shader_Vk.h new file mode 100644 index 00000000..daca769d --- /dev/null +++ b/OptiScaler/shaders/velocity_convert/precompile/vc_Shader_Vk.h @@ -0,0 +1,78 @@ +#pragma once + +inline static const unsigned char vc_spv[] = { + 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x31, 0x00, 0x00, 0x00, 0x11, 0x00, + 0x02, 0x00, 0x32, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x06, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x43, 0x53, 0x4d, 0x61, 0x69, 0x6e, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x05, 0x00, 0x00, 0x00, 0x58, 0x02, + 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x32, 0x64, 0x2e, 0x69, + 0x6d, 0x61, 0x67, 0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x04, 0x00, 0x00, 0x00, 0x53, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x32, 0x64, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x00, 0x00, 0x00, 0x05, 0x00, + 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x65, + 0x78, 0x74, 0x75, 0x72, 0x65, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x43, 0x53, 0x4d, 0x61, + 0x69, 0x6e, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, + 0x00, 0x47, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, + 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x02, 0x00, 0x09, 0x00, 0x00, 0x00, 0x29, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, + 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x16, 0x00, 0x03, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x07, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, + 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x12, 0x00, 0x00, + 0x00, 0x21, 0x00, 0x03, 0x00, 0x13, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x14, 0x00, + 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x07, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x16, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x17, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x17, 0x00, 0x04, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3b, 0x00, + 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, + 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, + 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfb, 0x00, 0x03, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x1e, 0x00, + 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x05, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x68, + 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, + 0x00, 0x0f, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x41, 0x00, + 0x05, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x04, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x05, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, + 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x25, 0x00, 0x00, 0x00, 0x27, 0x00, + 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x27, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0xae, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, + 0x00, 0x2a, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x26, 0x00, + 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x26, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x07, 0x00, 0x09, 0x00, 0x00, 0x00, 0x2b, + 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, + 0xf7, 0x00, 0x03, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x2b, 0x00, 0x00, + 0x00, 0x2d, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x2d, 0x00, 0x00, 0x00, 0xf9, 0x00, + 0x02, 0x00, 0x1d, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x04, + 0x00, 0x07, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x04, 0x00, 0x07, 0x00, + 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x50, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00, 0x00, 0x32, + 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07, 0x00, + 0x16, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x5f, 0x00, 0x07, 0x00, 0x17, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x33, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x4f, 0x00, 0x07, 0x00, 0x14, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x05, 0x00, 0x00, 0x00, 0x38, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x63, 0x00, 0x05, 0x00, 0x38, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x1d, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, + 0x00, 0x1d, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00 +}; diff --git a/OptiScaler/shaders/velocity_convert/precompile/vc_Shader_Vk.spv b/OptiScaler/shaders/velocity_convert/precompile/vc_Shader_Vk.spv new file mode 100644 index 0000000000000000000000000000000000000000..2c54c772db336b08f7811fd61304ca73ffa465d7 GIT binary patch literal 1400 zcmZvcTT4`76o!|MqaB^hQ+C{=WtldWl^M}R6m%68df{CRw#m6@3>%@K-z5FH=tR)- z?EQTq)Pgl@z3cp~y_m-E!dS#mM2yD+ex->Rt}M#i39ll@qoKR=Ry%TGjdl}aL zg&1$;O0rqg`4*AVPvZ4mg|#`Odaiv9-P+z)uDyh={UFu8j;_tweh{7OD8KRr?Y|6r zufE@SdpO4mQgRMsZot}{L*07rQmj4ip@Z(erEI&2uFc(irk=NR3pO@m|9gyk$>zN; z|AUOt?*3ko<(=Ju^~sVoeZRMO7xu1R6YCA$OEz=zcd(B4xR(6JNY>Hk_r4E1Z+=Ja a;ccwLqwqF6RyWpK(&3%Bo8MGjhyMVe`ArZ2 literal 0 HcmV?d00001 diff --git a/OptiScaler/spoofing/Vulkan_Spoofing.cpp b/OptiScaler/spoofing/Vulkan_Spoofing.cpp index f3d1e1da..83021cb2 100644 --- a/OptiScaler/spoofing/Vulkan_Spoofing.cpp +++ b/OptiScaler/spoofing/Vulkan_Spoofing.cpp @@ -612,6 +612,8 @@ struct VulkanDeviceFeatureState::Impl features != &features2); EnableFeatureValue(modifiedFeatures, features->features.shaderStorageImageWriteWithoutFormat, supported.features.shaderStorageImageWriteWithoutFormat, features != &features2); + EnableFeatureValue(modifiedFeatures, features->features.shaderStorageImageExtendedFormats, + supported.features.shaderStorageImageExtendedFormats, features != &features2); return; } @@ -624,6 +626,9 @@ struct VulkanDeviceFeatureState::Impl if (supported.features.shaderStorageImageWriteWithoutFormat == VK_TRUE) coreFeatures.shaderStorageImageWriteWithoutFormat = VK_TRUE; + if (supported.features.shaderStorageImageExtendedFormats == VK_TRUE) + coreFeatures.shaderStorageImageExtendedFormats = VK_TRUE; + pCreateInfo->pEnabledFeatures = &coreFeatures; } diff --git a/OptiScaler/upscalers/ffx/FFXFeature_Vk.cpp b/OptiScaler/upscalers/ffx/FFXFeature_Vk.cpp index e189747b..a20a3bb2 100644 --- a/OptiScaler/upscalers/ffx/FFXFeature_Vk.cpp +++ b/OptiScaler/upscalers/ffx/FFXFeature_Vk.cpp @@ -305,9 +305,25 @@ bool FFXFeatureVk::EvaluateInternal(VkCommandBuffer InCmdBuffer, NVSDK_NGX_Param { LOG_DEBUG("MotionVectors exist.."); - params.motionVectors = ffxApiGetResourceVK(paramVelocity->Resource.ImageViewInfo.Image, - ffxApiGetImageResourceDescriptionVKLocal(paramVelocity), - FFX_API_RESOURCE_STATE_COMPUTE_READ); + auto& mvInfo = paramVelocity->Resource.ImageViewInfo; + auto mvDesc = ffxApiGetImageResourceDescriptionVKLocal(paramVelocity); + VkImage mvImage = mvInfo.Image; + + // Normalized 16-bit MV formats get copied into an R16G16_SFLOAT image + if (mvInfo.Format == VK_FORMAT_R16G16_SNORM || mvInfo.Format == VK_FORMAT_R16G16_UNORM) + { + if (!_velocityConvert) + _velocityConvert = std::make_unique("VelocityConvert", Device, PhysicalDevice); + + if (_velocityConvert->CanRender() && + _velocityConvert->Dispatch(InCmdBuffer, mvInfo.ImageView, { mvInfo.Width, mvInfo.Height })) + { + mvImage = _velocityConvert->GetImage(); + mvDesc.format = FFX_API_SURFACE_FORMAT_R16G16_FLOAT; + } + } + + params.motionVectors = ffxApiGetResourceVK(mvImage, mvDesc, FFX_API_RESOURCE_STATE_COMPUTE_READ); } else { diff --git a/OptiScaler/upscalers/ffx/FFXFeature_Vk.h b/OptiScaler/upscalers/ffx/FFXFeature_Vk.h index 0ad23eea..818782d9 100644 --- a/OptiScaler/upscalers/ffx/FFXFeature_Vk.h +++ b/OptiScaler/upscalers/ffx/FFXFeature_Vk.h @@ -4,6 +4,7 @@ #include "vk/ffx_api_vk.h" #include +#include class FFXFeatureVk : public FFXFeature, public IFeature_Vk { @@ -11,6 +12,8 @@ class FFXFeatureVk : public FFXFeature, public IFeature_Vk // amd_fidelityfx_vk.dll or the driver provided upscaler FfxModule* _ffx = nullptr; + std::unique_ptr _velocityConvert = nullptr; + // Last logged inputs of the driver provided FSR 4 std::string _lastFsr4Inputs;