mirror of
https://github.com/optiscaler/OptiScaler.git
synced 2026-10-10 05:51:37 +00:00
Add Hudless fixup to No Man's Sky
Seems like the same issue as with Cyberprank's DLSSG inputs Also enables hud cutoff on Vulkan NvngxFG
This commit is contained in:
1 parent
d394e4b000
commit
ebc2d31dec
14 files changed
+455
-100
No files matched your search
@@ -333,6 +333,7 @@ copy NUL "$(SolutionDir)x64\Release\a\!! EXTRACT ALL FILES TO GAME FOLDER !!" /Y
|
||||
<ClInclude Include="hooks\LibraryLoad_Hooks.h" />
|
||||
<ClInclude Include="hooks\CommandBuffer_StateTracker.h" />
|
||||
<ClInclude Include="framegen\nvngx\IFGNvngx.h" />
|
||||
<ClInclude Include="shaders\hud_copy\HudCopy_Vk.h" />
|
||||
<ClInclude Include="inputs\FG\Streamline_Inputs_Sl1_Dx12.h" />
|
||||
<ClInclude Include="include\device_info\device_info.hpp" />
|
||||
<ClInclude Include="inputs\FG\Upscaler_Inputs_Dx11wDx12.h" />
|
||||
@@ -340,6 +341,7 @@ copy NUL "$(SolutionDir)x64\Release\a\!! EXTRACT ALL FILES TO GAME FOLDER !!" /Y
|
||||
<ClInclude Include="low_latency\input\input_reflex.h" />
|
||||
<ClInclude Include="low_latency\input\input_xell.h" />
|
||||
<ClInclude Include="low_latency\input\input_antilag2.h" />
|
||||
<ClInclude Include="shaders\hud_copy\precompile\HudCopy_Shader_Vk.h" />
|
||||
<ClInclude Include="shaders\magnifier\Magnifier_Dx11.h" />
|
||||
<ClInclude Include="menu\input\input_system.h" />
|
||||
<ClInclude Include="menu\input\input_system_internal.h" />
|
||||
@@ -621,6 +623,7 @@ copy NUL "$(SolutionDir)x64\Release\a\!! EXTRACT ALL FILES TO GAME FOLDER !!" /Y
|
||||
<ClCompile Include="hooks\LibraryLoad_Hooks.cpp" />
|
||||
<ClCompile Include="hooks\VulkanwDx12_Hooks.cpp" />
|
||||
<ClCompile Include="hooks\Xell_Hooks.cpp" />
|
||||
<ClCompile Include="shaders\hud_copy\HudCopy_Vk.cpp" />
|
||||
<ClCompile Include="inputs\FG\Streamline_Inputs_Sl1_Dx12.cpp" />
|
||||
<ClCompile Include="include\device_info\device_info.cpp" />
|
||||
<ClCompile Include="inputs\FG\Upscaler_Inputs_Dx11wDx12.cpp" />
|
||||
|
||||
@@ -956,6 +956,12 @@
|
||||
<ClInclude Include="shaders\magnifier\precompile\Magnifier_Shader_Vk.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="shaders\hud_copy\HudCopy_Vk.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="shaders\hud_copy\precompile\HudCopy_Shader_Vk.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Config.cpp">
|
||||
@@ -1544,6 +1550,9 @@
|
||||
<ClCompile Include="shaders\magnifier\Magnifier_Vk.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="shaders\hud_copy\HudCopy_Vk.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="OptiScaler.rc" />
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "Nvngx_FFX.h"
|
||||
#include "Nvngx_Combo.h"
|
||||
#include <imgui/ImGuiNotify.hpp>
|
||||
#include <nvsdk_ngx_vk.h>
|
||||
|
||||
IFGNvngx* Nvngx_FG::getProvider()
|
||||
{
|
||||
@@ -363,10 +364,10 @@ NVSDK_NGX_Result Nvngx_FG::D3D12_EvaluateFeature(ID3D12GraphicsCommandList* InCm
|
||||
|
||||
if (presentWithHud && hudlessResource && device)
|
||||
{
|
||||
if (_hudCopy.get() == nullptr)
|
||||
_hudCopy = std::make_unique<HudCopy_Dx12>("HudCopy", device);
|
||||
if (_hudCopyDx12.get() == nullptr)
|
||||
_hudCopyDx12 = std::make_unique<HudCopy_Dx12>("HudCopy", device);
|
||||
|
||||
if (auto hudCopy = _hudCopy.get(); hudCopy && hudCopy->IsInit())
|
||||
if (auto hudCopy = _hudCopyDx12.get(); hudCopy && hudCopy->IsInit())
|
||||
{
|
||||
// In Cyberprank - DLSSG has noise issues, FSR FG has noise + vignetting
|
||||
// In Death Stranding 2 - DLSSG has wrong colormapping it seems, FSR FG is fine
|
||||
@@ -418,6 +419,9 @@ NVSDK_NGX_Result Nvngx_FG::VULKAN_Init(unsigned long long InApplicationId, const
|
||||
if (!provider)
|
||||
return NVSDK_NGX_Result_Fail;
|
||||
|
||||
if (!_hudCopyVk)
|
||||
_hudCopyVk = std::make_unique<HudCopy_Vk>("HudCopy", InDevice, InPD);
|
||||
|
||||
return provider->VULKAN_Init(InApplicationId, InApplicationDataPath, InInstance, InPD, InDevice, InGIPA, InGDPA,
|
||||
InFeatureInfo, InSDKVersion);
|
||||
}
|
||||
@@ -432,6 +436,9 @@ NVSDK_NGX_Result Nvngx_FG::VULKAN_Init_Ext(unsigned long long InApplicationId, c
|
||||
if (!provider)
|
||||
return NVSDK_NGX_Result_Fail;
|
||||
|
||||
if (!_hudCopyVk)
|
||||
_hudCopyVk = std::make_unique<HudCopy_Vk>("HudCopy", InDevice, InPD);
|
||||
|
||||
return provider->VULKAN_Init_Ext(InApplicationId, InApplicationDataPath, InInstance, InPD, InDevice, InSDKVersion,
|
||||
InFeatureInfo);
|
||||
}
|
||||
@@ -447,6 +454,9 @@ NVSDK_NGX_Result Nvngx_FG::VULKAN_Init_Ext2(unsigned long long InApplicationId,
|
||||
if (!provider)
|
||||
return NVSDK_NGX_Result_Fail;
|
||||
|
||||
if (!_hudCopyVk)
|
||||
_hudCopyVk = std::make_unique<HudCopy_Vk>("HudCopy", InDevice, InPD);
|
||||
|
||||
return provider->VULKAN_Init_Ext2(InApplicationId, InApplicationDataPath, InInstance, InPD, InDevice, InGIPA,
|
||||
InGDPA, InSDKVersion, InFeatureInfo);
|
||||
}
|
||||
@@ -583,6 +593,44 @@ NVSDK_NGX_Result Nvngx_FG::VULKAN_EvaluateFeature(VkCommandBuffer InCmdList, con
|
||||
Nvngx_FG_Handle* ourHandle = (Nvngx_FG_Handle*) InFeatureHandle;
|
||||
std::shared_lock lock(ourHandle->handleMutex);
|
||||
|
||||
bool applyHudCutoff = Config::Instance()->FGHudCutoff.value_or_default() > 0.0f ||
|
||||
State::Instance().gameQuirks & GameQuirk::FSRFGHudlessMismatchFixup;
|
||||
|
||||
uint32_t frameIndex = 1;
|
||||
InParameters->Get("DLSSG.MultiFrameIndex", &frameIndex);
|
||||
|
||||
if (applyHudCutoff && frameIndex == 1)
|
||||
{
|
||||
NVSDK_NGX_Resource_VK* presentWithHud = nullptr;
|
||||
InParameters->Get("DLSSG.Backbuffer", (void**) &presentWithHud);
|
||||
VkImageLayout presentWithHudLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
|
||||
NVSDK_NGX_Resource_VK* hudlessResource = nullptr;
|
||||
InParameters->Get("DLSSG.HUDLess", (void**) &hudlessResource);
|
||||
VkImageLayout hudlessLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
|
||||
if (presentWithHud && hudlessResource)
|
||||
{
|
||||
if (auto hudCopy = _hudCopyVk.get(); hudCopy && hudCopy->IsInit())
|
||||
{
|
||||
float hudDetectionThreshold = 0.03f;
|
||||
|
||||
if (Config::Instance()->FGHudCutoff.value_or_default() > 0.0f)
|
||||
hudDetectionThreshold = Config::Instance()->FGHudCutoff.value_or_default() / 10.0f;
|
||||
|
||||
VkImageInfo presentWithHudInfo = *(VkImageInfo*) &presentWithHud->Resource.ImageViewInfo;
|
||||
VkImageInfo hudlessResourceInfo = *(VkImageInfo*) &hudlessResource->Resource.ImageViewInfo;
|
||||
|
||||
hudCopy->Dispatch(InCmdList, hudlessResourceInfo, hudlessLayout, presentWithHudInfo,
|
||||
presentWithHudLayout, hudDetectionThreshold);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_WARN("Couldn't run hudless fixup");
|
||||
}
|
||||
}
|
||||
|
||||
if (Config::Instance()->NvngxFGDisableHudless.value_or_default())
|
||||
InParameters->Set("DLSSG.HUDLess", (void*) nullptr);
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "proxies/NVNGX_Proxy.h"
|
||||
#include "proxies/Ntdll_Proxy.h"
|
||||
#include <shaders/hud_copy/HudCopy_Dx12.h>
|
||||
#include <shaders/hud_copy/HudCopy_Vk.h>
|
||||
#include "IFGNvngx.h"
|
||||
|
||||
class Nvngx_FG
|
||||
@@ -21,7 +22,8 @@ class Nvngx_FG
|
||||
|
||||
static inline std::atomic_uint32_t lastIdCreated = 0;
|
||||
static inline std::unique_ptr<IFGNvngx> _provider;
|
||||
static inline std::unique_ptr<HudCopy_Dx12> _hudCopy;
|
||||
static inline std::unique_ptr<HudCopy_Dx12> _hudCopyDx12;
|
||||
static inline std::unique_ptr<HudCopy_Vk> _hudCopyVk;
|
||||
|
||||
static IFGNvngx* getProvider();
|
||||
|
||||
|
||||
@@ -569,7 +569,7 @@ static const QuirkEntry quirkTable[] = {
|
||||
|
||||
// No Man's Sky
|
||||
QUIRK_ENTRY("nms.exe", GameQuirk::KernelBaseHooks, GameQuirk::VulkanDLSSBarrierFixup,
|
||||
GameQuirk::EnableVulkanSpoofing),
|
||||
GameQuirk::EnableVulkanSpoofing, GameQuirk::FSRFGHudlessMismatchFixup),
|
||||
|
||||
// RTX Remix
|
||||
QUIRK_ENTRY("nvremixbridge.exe", GameQuirk::DisableDxgiSpoofing, GameQuirk::LoadVulkanManually,
|
||||
|
||||
@@ -2,32 +2,55 @@
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
static std::string shaderCode = R"(
|
||||
cbuffer Params : register(b0)
|
||||
class HudCopy_Common
|
||||
{
|
||||
float DiffThreshold;
|
||||
};
|
||||
protected:
|
||||
struct alignas(256) InternalHudCopyParams
|
||||
{
|
||||
float DiffThreshold = 0.02f;
|
||||
};
|
||||
|
||||
Texture2D<float3> Hudless : register(t0);
|
||||
Texture2D<float3> PresentCopy : register(t1);
|
||||
const std::string shaderCode = R"(
|
||||
#ifdef VK_MODE
|
||||
cbuffer Params : register(b0, space0)
|
||||
#else
|
||||
cbuffer Params : register(b0)
|
||||
#endif
|
||||
{
|
||||
float DiffThreshold;
|
||||
};
|
||||
|
||||
RWTexture2D<float3> Present : register(u0);
|
||||
#ifdef VK_MODE
|
||||
[[vk::binding(1, 0)]]
|
||||
#endif
|
||||
Texture2D<float3> Hudless : register(t0);
|
||||
|
||||
[numthreads(16, 16, 1)]
|
||||
void CSMain(uint3 dispatchThreadID : SV_DispatchThreadID)
|
||||
{
|
||||
uint2 pixelCoord = dispatchThreadID.xy;
|
||||
#ifdef VK_MODE
|
||||
[[vk::binding(2, 0)]]
|
||||
#endif
|
||||
Texture2D<float3> PresentCopy : register(t1);
|
||||
|
||||
float3 hudless = Hudless.Load(int3(pixelCoord, 0));
|
||||
float3 present = PresentCopy.Load(int3(pixelCoord, 0));
|
||||
#ifdef VK_MODE
|
||||
[[vk::binding(3, 0)]]
|
||||
#endif
|
||||
RWTexture2D<float3> Present : register(u0);
|
||||
|
||||
[numthreads(16, 16, 1)]
|
||||
void CSMain(uint3 dispatchThreadID : SV_DispatchThreadID)
|
||||
{
|
||||
uint2 pixelCoord = dispatchThreadID.xy;
|
||||
|
||||
float3 hudless = Hudless.Load(int3(pixelCoord, 0));
|
||||
float3 present = PresentCopy.Load(int3(pixelCoord, 0));
|
||||
|
||||
float3 diff = abs(hudless - present);
|
||||
float delta = max(max(diff.r, diff.g), diff.b);
|
||||
float3 diff = abs(hudless - present);
|
||||
float delta = max(max(diff.r, diff.g), diff.b);
|
||||
|
||||
float uiMask = smoothstep(DiffThreshold, DiffThreshold * 2.0f, delta);
|
||||
float uiMask = smoothstep(DiffThreshold, DiffThreshold * 2.0f, delta);
|
||||
|
||||
float3 ui = (present - hudless) * uiMask;
|
||||
float3 ui = (present - hudless) * uiMask;
|
||||
|
||||
Present[pixelCoord] = hudless + ui;
|
||||
}
|
||||
)";
|
||||
Present[pixelCoord] = hudless + ui;
|
||||
}
|
||||
)";
|
||||
};
|
||||
@@ -65,7 +65,7 @@ bool HudCopy_Dx12::Dispatch(ID3D12GraphicsCommandList* cmdList, ID3D12Resource*
|
||||
CreateShaderResourceView(_device, present, currentHeap.GetSrvCPU(1));
|
||||
CreateUnorderedAccessView(_device, _buffer, currentHeap.GetUavCPU(0), 0);
|
||||
|
||||
InternalCompareParams constants {};
|
||||
InternalHudCopyParams constants {};
|
||||
constants.DiffThreshold = hudDetectionThreshold;
|
||||
|
||||
if (!CreateConstantsBuffer(_device, _constantBuffer, constants, currentHeap.GetCbvCPU(0)))
|
||||
@@ -117,7 +117,7 @@ HudCopy_Dx12::HudCopy_Dx12(std::string InName, ID3D12Device* InDevice) : Shader_
|
||||
return;
|
||||
}
|
||||
|
||||
D3D12_RESOURCE_DESC desc = CD3DX12_RESOURCE_DESC::Buffer(sizeof(InternalCompareParams));
|
||||
D3D12_RESOURCE_DESC desc = CD3DX12_RESOURCE_DESC::Buffer(sizeof(InternalHudCopyParams));
|
||||
auto heapProps = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD);
|
||||
|
||||
auto result =
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include "HudCopy_Common.h"
|
||||
|
||||
#include "SysUtils.h"
|
||||
|
||||
@@ -10,14 +11,9 @@
|
||||
|
||||
#define HudCopy_NUM_OF_HEAPS 2
|
||||
|
||||
class HudCopy_Dx12 : public Shader_Dx12
|
||||
class HudCopy_Dx12 : public Shader_Dx12, public HudCopy_Common
|
||||
{
|
||||
private:
|
||||
struct alignas(256) InternalCompareParams
|
||||
{
|
||||
float DiffThreshold = 0.02f;
|
||||
};
|
||||
|
||||
FrameDescriptorHeap _frameHeaps[HudCopy_NUM_OF_HEAPS];
|
||||
|
||||
ID3D12Resource* _buffer = nullptr;
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
#include "pch.h"
|
||||
#include "HudCopy_Vk.h"
|
||||
#include <Config.h>
|
||||
#include <State.h>
|
||||
#include "precompile/HudCopy_Shader_Vk.h"
|
||||
|
||||
HudCopy_Vk::HudCopy_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 (0: Params, 1: Hudless, 2: PresentCopy, 3: PresentOut)
|
||||
CreateSampler(VK_FILTER_NEAREST, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
|
||||
CreateConstantBuffer(sizeof(InternalHudCopyParams));
|
||||
|
||||
std::vector<VkDescriptorSetLayoutBinding> bindings = { CreateBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER),
|
||||
CreateBinding(1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER),
|
||||
CreateBinding(2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER),
|
||||
CreateBinding(3, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) };
|
||||
CreateLayouts(bindings);
|
||||
|
||||
std::vector<VkDescriptorPoolSize> poolSizes = { { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, _maxFramesInFlight },
|
||||
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||
_maxFramesInFlight * 2 },
|
||||
{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, _maxFramesInFlight } };
|
||||
CreateDescriptorPool(poolSizes, _maxFramesInFlight);
|
||||
CreateDescriptorSets(_descriptorSetLayout, _descriptorPool, _descriptorSets);
|
||||
|
||||
std::vector<char> shaderCode(HudCopy_spv, HudCopy_spv + sizeof(HudCopy_spv));
|
||||
if (!CreateComputePipeline(_device, _pipelineLayout, &_pipeline, shaderCode))
|
||||
{
|
||||
LOG_ERROR("[{0}] Failed to create pipeline!", _name);
|
||||
_init = false;
|
||||
return;
|
||||
}
|
||||
|
||||
_init = true;
|
||||
}
|
||||
|
||||
bool HudCopy_Vk::Dispatch(VkCommandBuffer InCmdList, const VkImageInfo& InHudlessInfo, VkImageLayout HudlessState,
|
||||
const VkImageInfo& InPresentInfo, VkImageLayout PresentState, float HudDetectionThreshold)
|
||||
{
|
||||
if (!_init || InCmdList == VK_NULL_HANDLE || InHudlessInfo.Image == VK_NULL_HANDLE ||
|
||||
InPresentInfo.Image == VK_NULL_HANDLE)
|
||||
return false;
|
||||
|
||||
if (!CreateImageResource(InPresentInfo.Width, InPresentInfo.Height, InPresentInfo.Format,
|
||||
VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT))
|
||||
{
|
||||
LOG_ERROR("[{0}] Failed to create or resize intermediate buffer", _name);
|
||||
return false;
|
||||
}
|
||||
|
||||
_currentSetIndex = (_currentSetIndex + 1) % _maxFramesInFlight;
|
||||
|
||||
VkImageSubresourceRange copySubresourceRange = InPresentInfo.SubresourceRange;
|
||||
copySubresourceRange.baseMipLevel = 0;
|
||||
copySubresourceRange.levelCount = 1;
|
||||
copySubresourceRange.baseArrayLayer = 0;
|
||||
copySubresourceRange.layerCount = 1;
|
||||
|
||||
SetImageLayout(InCmdList, InPresentInfo.Image, PresentState, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
copySubresourceRange);
|
||||
SetImageLayout(InCmdList, _intermediateImage, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
copySubresourceRange);
|
||||
|
||||
VkImageCopy copyRegion {};
|
||||
copyRegion.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
|
||||
copyRegion.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
|
||||
copyRegion.extent = { InPresentInfo.Width, InPresentInfo.Height, 1 };
|
||||
|
||||
vkCmdCopyImage(InCmdList, InPresentInfo.Image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, _intermediateImage,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©Region);
|
||||
|
||||
SetImageLayout(InCmdList, InPresentInfo.Image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, copySubresourceRange);
|
||||
SetImageLayout(InCmdList, _intermediateImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
|
||||
copySubresourceRange);
|
||||
SetImageLayout(InCmdList, InHudlessInfo.Image, HudlessState, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
InHudlessInfo.SubresourceRange);
|
||||
|
||||
InternalHudCopyParams constants {};
|
||||
constants.DiffThreshold = HudDetectionThreshold;
|
||||
|
||||
if (_mappedConstantBuffer)
|
||||
memcpy(_mappedConstantBuffer, &constants, sizeof(InternalHudCopyParams));
|
||||
|
||||
VkDescriptorSet descriptorSet = _descriptorSets[_currentSetIndex];
|
||||
|
||||
VkDescriptorBufferInfo bufferInfo { _constantBuffer, 0, sizeof(InternalHudCopyParams) };
|
||||
VkDescriptorImageInfo hudlessInfo { _textureSampler, InHudlessInfo.ImageView,
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL };
|
||||
VkDescriptorImageInfo presentInfo { _textureSampler, InPresentInfo.ImageView,
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL };
|
||||
VkDescriptorImageInfo destUAVInfo { VK_NULL_HANDLE, _intermediateImageView, VK_IMAGE_LAYOUT_GENERAL };
|
||||
|
||||
std::vector<VkWriteDescriptorSet> descriptorWritesBuffer = {
|
||||
{ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, nullptr, descriptorSet, 0, 0, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
nullptr, &bufferInfo, nullptr },
|
||||
{ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, nullptr, descriptorSet, 1, 0, 1,
|
||||
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &hudlessInfo, nullptr, nullptr },
|
||||
{ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, nullptr, descriptorSet, 2, 0, 1,
|
||||
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &presentInfo, nullptr, nullptr },
|
||||
{ VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, nullptr, descriptorSet, 3, 0, 1, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||
&destUAVInfo, nullptr, nullptr }
|
||||
};
|
||||
|
||||
vkUpdateDescriptorSets(_device, static_cast<uint32_t>(descriptorWritesBuffer.size()), descriptorWritesBuffer.data(),
|
||||
0, nullptr);
|
||||
|
||||
// Bind & Dispatch
|
||||
vkCmdBindPipeline(InCmdList, VK_PIPELINE_BIND_POINT_COMPUTE, _pipeline);
|
||||
vkCmdBindDescriptorSets(InCmdList, VK_PIPELINE_BIND_POINT_COMPUTE, _pipelineLayout, 0, 1, &descriptorSet, 0,
|
||||
nullptr);
|
||||
|
||||
uint32_t dispatchWidth = (InPresentInfo.Width + InNumThreadsX - 1) / InNumThreadsX;
|
||||
uint32_t dispatchHeight = (InPresentInfo.Height + InNumThreadsY - 1) / InNumThreadsY;
|
||||
vkCmdDispatch(InCmdList, dispatchWidth, dispatchHeight, 1);
|
||||
|
||||
// 3. Transition and copy the internal computed target back to 'present'
|
||||
SetImageLayout(InCmdList, _intermediateImage, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
copySubresourceRange);
|
||||
SetImageLayout(InCmdList, InPresentInfo.Image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, copySubresourceRange);
|
||||
|
||||
vkCmdCopyImage(InCmdList, _intermediateImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, InPresentInfo.Image,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©Region);
|
||||
|
||||
// 4. Restore original resource states
|
||||
SetImageLayout(InCmdList, InPresentInfo.Image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, PresentState,
|
||||
copySubresourceRange);
|
||||
SetImageLayout(InCmdList, InHudlessInfo.Image, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, HudlessState,
|
||||
InHudlessInfo.SubresourceRange);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
#include "HudCopy_Common.h"
|
||||
|
||||
#include <shaders/Shader_Vk.h>
|
||||
|
||||
class HudCopy_Vk : public Shader_Vk, public HudCopy_Common
|
||||
{
|
||||
uint32_t InNumThreadsX = 16;
|
||||
uint32_t InNumThreadsY = 16;
|
||||
|
||||
public:
|
||||
HudCopy_Vk(std::string InName, VkDevice InDevice, VkPhysicalDevice InPhysicalDevice);
|
||||
virtual ~HudCopy_Vk() = default;
|
||||
|
||||
bool Dispatch(VkCommandBuffer InCmdList, const VkImageInfo& InHudlessInfo, VkImageLayout HudlessState,
|
||||
const VkImageInfo& InPresentInfo, VkImageLayout PresentState, float HudDetectionThreshold);
|
||||
};
|
||||
@@ -1,11 +1,25 @@
|
||||
#ifdef VK_MODE
|
||||
cbuffer Params : register(b0, space0)
|
||||
#else
|
||||
cbuffer Params : register(b0)
|
||||
#endif
|
||||
{
|
||||
float DiffThreshold;
|
||||
};
|
||||
|
||||
#ifdef VK_MODE
|
||||
[[vk::binding(1, 0)]]
|
||||
#endif
|
||||
Texture2D<float3> Hudless : register(t0);
|
||||
|
||||
#ifdef VK_MODE
|
||||
[[vk::binding(2, 0)]]
|
||||
#endif
|
||||
Texture2D<float3> PresentCopy : register(t1);
|
||||
|
||||
#ifdef VK_MODE
|
||||
[[vk::binding(3, 0)]]
|
||||
#endif
|
||||
RWTexture2D<float3> Present : register(u0);
|
||||
|
||||
[numthreads(16, 16, 1)]
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
#pragma once
|
||||
|
||||
inline static const unsigned char HudCopy_spv[] = {
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x11, 0x00, 0x02, 0x00, 0x38, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00,
|
||||
0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30, 0x00,
|
||||
0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x06, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x43, 0x53, 0x4d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x03, 0x00, 0x00,
|
||||
0x00, 0x10, 0x00, 0x06, 0x00, 0x02, 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, 0x05, 0x00, 0x04, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x00,
|
||||
0x06, 0x00, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x69, 0x66, 0x66, 0x54, 0x68, 0x72,
|
||||
0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x00, 0x00, 0x50, 0x61,
|
||||
0x72, 0x61, 0x6d, 0x73, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x74, 0x79, 0x70, 0x65, 0x2e,
|
||||
0x32, 0x64, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
|
||||
0x48, 0x75, 0x64, 0x6c, 0x65, 0x73, 0x73, 0x00, 0x05, 0x00, 0x05, 0x00, 0x08, 0x00, 0x00, 0x00, 0x50, 0x72, 0x65,
|
||||
0x73, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x70, 0x79, 0x00, 0x05, 0x00, 0x06, 0x00, 0x09, 0x00, 0x00, 0x00, 0x74, 0x79,
|
||||
0x70, 0x65, 0x2e, 0x32, 0x64, 0x2e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x0a,
|
||||
0x00, 0x00, 0x00, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x00, 0x05, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0x43, 0x53, 0x4d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00,
|
||||
0x00, 0x1c, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47,
|
||||
0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
|
||||
0x08, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00,
|
||||
0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x21, 0x00,
|
||||
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x05, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x05, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x48, 0x00, 0x05, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x47, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x0b, 0x00,
|
||||
0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
|
||||
0x2b, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1e, 0x00, 0x03,
|
||||
0x00, 0x04, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0d, 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, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
|
||||
0x00, 0x19, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
|
||||
0x00, 0x04, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00,
|
||||
0x12, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x13, 0x00, 0x00,
|
||||
0x00, 0x12, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x15, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x16,
|
||||
0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x17, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x18, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
|
||||
0x00, 0x17, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x17, 0x00,
|
||||
0x04, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x1b,
|
||||
0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x1c, 0x00, 0x00, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00,
|
||||
0x00, 0x02, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b,
|
||||
0x00, 0x04, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
|
||||
0x14, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00,
|
||||
0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x1d, 0x00,
|
||||
0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x13, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x4f,
|
||||
0x00, 0x07, 0x00, 0x17, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x12, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
|
||||
0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x12, 0x00, 0x00, 0x00, 0x21, 0x00,
|
||||
0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x22,
|
||||
0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
|
||||
0x21, 0x00, 0x00, 0x00, 0x50, 0x00, 0x06, 0x00, 0x19, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00,
|
||||
0x00, 0x23, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x07, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x25, 0x00,
|
||||
0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3d,
|
||||
0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x07, 0x00,
|
||||
0x1b, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
|
||||
0x00, 0x0c, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x08, 0x00, 0x18, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x27, 0x00,
|
||||
0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3d,
|
||||
0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x07, 0x00,
|
||||
0x1b, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
|
||||
0x00, 0x0c, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x08, 0x00, 0x18, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x2a, 0x00,
|
||||
0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x83,
|
||||
0x00, 0x05, 0x00, 0x18, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00,
|
||||
0x0c, 0x00, 0x06, 0x00, 0x18, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
|
||||
0x00, 0x2c, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x2d, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x2d,
|
||||
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05,
|
||||
0x00, 0x0d, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00,
|
||||
0x07, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x30,
|
||||
0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00,
|
||||
0x00, 0x33, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x34, 0x00,
|
||||
0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00,
|
||||
0x83, 0x00, 0x05, 0x00, 0x18, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00,
|
||||
0x00, 0x8e, 0x00, 0x05, 0x00, 0x18, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x36, 0x00,
|
||||
0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x18, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x38,
|
||||
0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
|
||||
0x63, 0x00, 0x05, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00
|
||||
};
|
||||
Binary file not shown.
@@ -21,75 +21,86 @@ class Magnifier_Common
|
||||
float Padding[3]; // Padding to maintain 16-byte alignment
|
||||
};
|
||||
|
||||
const std::string shaderCode = R"(
|
||||
#ifdef VK_MODE
|
||||
cbuffer Params : register(b0, space0)
|
||||
#else
|
||||
cbuffer MagnifierCB : register(b0)
|
||||
#endif
|
||||
{
|
||||
float2 Resolution; // Screen or texture resolution in pixels
|
||||
float2 CursorPos; // Cursor position in pixel coordinates
|
||||
float2 Offset; // Offset of the lens relative to the cursor (in pixels)
|
||||
float Radius; // Radius of the magnifying glass (in pixels)
|
||||
int ZoomFactor; // Integer scaling multiplier (e.g., 2, 3, 4)
|
||||
float BorderThickness; // Thickness of the black border (in pixels)
|
||||
float3 Padding; // Padding to maintain 16-byte alignment
|
||||
};
|
||||
|
||||
#ifdef VK_MODE
|
||||
[[vk::binding(1, 0)]]
|
||||
#endif
|
||||
Texture2D<float4> InTexture : register(t0);
|
||||
|
||||
#ifdef VK_MODE
|
||||
[[vk::binding(2, 0)]]
|
||||
#endif
|
||||
RWTexture2D<float4> OutTexture : register(u0);
|
||||
|
||||
[numthreads(16, 16, 1)]
|
||||
void CSMain(uint3 dispatchThreadId : SV_DispatchThreadID)
|
||||
{
|
||||
// 1. Boundary Guard: Ensure threads outside the texture dimensions do not execute
|
||||
if (dispatchThreadId.x >= (uint) Resolution.x || dispatchThreadId.y >= (uint) Resolution.y)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Determine the current pixel coordinate
|
||||
int2 currentPixelInt = dispatchThreadId.xy;
|
||||
float2 currentPixel = float2(currentPixelInt);
|
||||
|
||||
// 3. Calculate the center of the magnifying lens
|
||||
float2 lensCenter = CursorPos + Offset;
|
||||
|
||||
// 4. Find the distance from the current pixel to the lens center
|
||||
float2 vecToCenter = currentPixel - lensCenter;
|
||||
float dist = length(vecToCenter);
|
||||
|
||||
float4 finalColor;
|
||||
|
||||
// 5. Outside the magnifier: Render the normal, unscaled image
|
||||
if (dist > Radius)
|
||||
{
|
||||
finalColor = InTexture.Load(int3(currentPixelInt, 0));
|
||||
}
|
||||
// 6. Border: Render a black outline
|
||||
else if (dist > Radius - BorderThickness)
|
||||
{
|
||||
finalColor = float4(0.0f, 0.0f, 0.0f, 1.0f); // Black border
|
||||
}
|
||||
// 7. Inside the magnifier: Apply integer scaling
|
||||
else
|
||||
{
|
||||
int maxZoom = max(1, ZoomFactor); // Prevent division by zero
|
||||
float2 scaledOffset = floor(vecToCenter / (float) maxZoom);
|
||||
|
||||
// Calculate the source pixel coordinate around the actual cursor position
|
||||
int2 srcPixel = int2(CursorPos + scaledOffset);
|
||||
|
||||
// Clamp coordinates to ensure we don't sample outside the texture bounds
|
||||
srcPixel = clamp(srcPixel, int2(0, 0), int2(Resolution) - int2(1, 1));
|
||||
|
||||
finalColor = InTexture.Load(int3(srcPixel, 0));
|
||||
}
|
||||
|
||||
// 8. Write the final calculated pixel back to the UAV
|
||||
OutTexture[currentPixelInt] = finalColor;
|
||||
}
|
||||
)";
|
||||
|
||||
void FilloutStruct(float Width, float Height, InternalMagnifierParams& InternalStruct);
|
||||
|
||||
public:
|
||||
bool ShouldRun();
|
||||
};
|
||||
|
||||
static std::string shaderCode = R"(
|
||||
cbuffer MagnifierCB : register(b0)
|
||||
{
|
||||
float2 Resolution; // Screen or texture resolution in pixels
|
||||
float2 CursorPos; // Cursor position in pixel coordinates
|
||||
float2 Offset; // Offset of the lens relative to the cursor (in pixels)
|
||||
float Radius; // Radius of the magnifying glass (in pixels)
|
||||
int ZoomFactor; // Integer scaling multiplier (e.g., 2, 3, 4)
|
||||
float BorderThickness; // Thickness of the black border (in pixels)
|
||||
float3 Padding; // Padding to maintain 16-byte alignment
|
||||
};
|
||||
|
||||
Texture2D<float4> InTexture : register(t0);
|
||||
RWTexture2D<float4> OutTexture : register(u0);
|
||||
|
||||
[numthreads(16, 16, 1)]
|
||||
void CSMain(uint3 dispatchThreadId : SV_DispatchThreadID)
|
||||
{
|
||||
// 1. Boundary Guard: Ensure threads outside the texture dimensions do not execute
|
||||
if (dispatchThreadId.x >= (uint) Resolution.x || dispatchThreadId.y >= (uint) Resolution.y)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Determine the current pixel coordinate
|
||||
int2 currentPixelInt = dispatchThreadId.xy;
|
||||
float2 currentPixel = float2(currentPixelInt);
|
||||
|
||||
// 3. Calculate the center of the magnifying lens
|
||||
float2 lensCenter = CursorPos + Offset;
|
||||
|
||||
// 4. Find the distance from the current pixel to the lens center
|
||||
float2 vecToCenter = currentPixel - lensCenter;
|
||||
float dist = length(vecToCenter);
|
||||
|
||||
float4 finalColor;
|
||||
|
||||
// 5. Outside the magnifier: Render the normal, unscaled image
|
||||
if (dist > Radius)
|
||||
{
|
||||
finalColor = InTexture.Load(int3(currentPixelInt, 0));
|
||||
}
|
||||
// 6. Border: Render a black outline
|
||||
else if (dist > Radius - BorderThickness)
|
||||
{
|
||||
finalColor = float4(0.0f, 0.0f, 0.0f, 1.0f); // Black border
|
||||
}
|
||||
// 7. Inside the magnifier: Apply integer scaling
|
||||
else
|
||||
{
|
||||
int maxZoom = max(1, ZoomFactor); // Prevent division by zero
|
||||
float2 scaledOffset = floor(vecToCenter / (float) maxZoom);
|
||||
|
||||
// Calculate the source pixel coordinate around the actual cursor position
|
||||
int2 srcPixel = int2(CursorPos + scaledOffset);
|
||||
|
||||
// Clamp coordinates to ensure we don't sample outside the texture bounds
|
||||
srcPixel = clamp(srcPixel, int2(0, 0), int2(Resolution) - int2(1, 1));
|
||||
|
||||
finalColor = InTexture.Load(int3(srcPixel, 0));
|
||||
}
|
||||
|
||||
// 8. Write the final calculated pixel back to the UAV
|
||||
OutTexture[currentPixelInt] = finalColor;
|
||||
}
|
||||
)";
|
||||
Reference in new issue
Block a user