From 9b70e1034a476db0c8fe74391b8d917b5b8c1bd9 Mon Sep 17 00:00:00 2001 From: Skyth <19259897+blueskythlikesclouds@users.noreply.github.com> Date: Thu, 24 Oct 2024 14:57:23 +0300 Subject: [PATCH] Implement alpha to coverage. --- UnleashedRecomp/config.h | 2 +- UnleashedRecomp/gpu/rhi/rt64_d3d12.cpp | 1 + .../gpu/rhi/rt64_render_interface_types.h | 1 + UnleashedRecomp/gpu/rhi/rt64_vulkan.cpp | 1 + UnleashedRecomp/gpu/video.cpp | 32 +++++++++++++++++-- thirdparty/ShaderRecomp | 2 +- 6 files changed, 35 insertions(+), 4 deletions(-) diff --git a/UnleashedRecomp/config.h b/UnleashedRecomp/config.h index 7bc0c68..44970d1 100644 --- a/UnleashedRecomp/config.h +++ b/UnleashedRecomp/config.h @@ -45,7 +45,7 @@ public: CONFIG_DEFINE("Video", size_t, AnisotropicFiltering, 16); CONFIG_DEFINE_ENUM("Video", EShadowResolution, ShadowResolution, EShadowResolution::x4096); CONFIG_DEFINE_ENUM("Video", EGITextureFiltering, GITextureFiltering, EGITextureFiltering::Bicubic); - CONFIG_DEFINE("Video", bool, AlphaToCoverage, false); + CONFIG_DEFINE("Video", bool, AlphaToCoverage, true); CONFIG_DEFINE("Video", bool, Xbox360ColourCorrection, false); CONFIG_DEFINE_ENUM("Video", EMovieScaleMode, MovieScaleMode, EMovieScaleMode::Fit); CONFIG_DEFINE_ENUM("Video", EUIScaleMode, UIScaleMode, EUIScaleMode::Centre); diff --git a/UnleashedRecomp/gpu/rhi/rt64_d3d12.cpp b/UnleashedRecomp/gpu/rhi/rt64_d3d12.cpp index c9aae25..ff22332 100644 --- a/UnleashedRecomp/gpu/rhi/rt64_d3d12.cpp +++ b/UnleashedRecomp/gpu/rhi/rt64_d3d12.cpp @@ -2718,6 +2718,7 @@ namespace RT64 { psoDesc.DepthStencilState.DepthWriteMask = desc.depthWriteEnabled ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO; psoDesc.DepthStencilState.DepthFunc = toD3D12(desc.depthFunction); psoDesc.NumRenderTargets = desc.renderTargetCount; + psoDesc.BlendState.AlphaToCoverageEnable = desc.alphaToCoverageEnabled; for (uint32_t i = 0; i < desc.renderTargetCount; i++) { psoDesc.RTVFormats[i] = toDXGI(desc.renderTargetFormat[i]); diff --git a/UnleashedRecomp/gpu/rhi/rt64_render_interface_types.h b/UnleashedRecomp/gpu/rhi/rt64_render_interface_types.h index 7bdfbaf..ffed923 100644 --- a/UnleashedRecomp/gpu/rhi/rt64_render_interface_types.h +++ b/UnleashedRecomp/gpu/rhi/rt64_render_interface_types.h @@ -1165,6 +1165,7 @@ namespace RT64 { bool depthEnabled = false; bool depthWriteEnabled = false; RenderMultisampling multisampling; + bool alphaToCoverageEnabled = false; RenderPrimitiveTopology primitiveTopology = RenderPrimitiveTopology::TRIANGLE_LIST; RenderCullMode cullMode = RenderCullMode::NONE; RenderFormat renderTargetFormat[MaxRenderTargets] = {}; diff --git a/UnleashedRecomp/gpu/rhi/rt64_vulkan.cpp b/UnleashedRecomp/gpu/rhi/rt64_vulkan.cpp index cce596e..38c5efd 100644 --- a/UnleashedRecomp/gpu/rhi/rt64_vulkan.cpp +++ b/UnleashedRecomp/gpu/rhi/rt64_vulkan.cpp @@ -1462,6 +1462,7 @@ namespace RT64 { multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; multisampling.pNext = multisamplingNext; multisampling.rasterizationSamples = VkSampleCountFlagBits(desc.multisampling.sampleCount); + multisampling.alphaToCoverageEnable = desc.alphaToCoverageEnabled; thread_local std::vector colorBlendAttachments; colorBlendAttachments.clear(); diff --git a/UnleashedRecomp/gpu/video.cpp b/UnleashedRecomp/gpu/video.cpp index 50e9546..4d6fe49 100644 --- a/UnleashedRecomp/gpu/video.cpp +++ b/UnleashedRecomp/gpu/video.cpp @@ -62,13 +62,21 @@ struct PipelineState RenderFormat renderTargetFormat{}; RenderFormat depthStencilFormat{}; RenderSampleCounts sampleCount = RenderSampleCount::COUNT_1; + bool enableAlphaToCoverage = false; +}; + +enum class AlphaTestMode : uint32_t +{ + Disabled, + AlphaThreshold, + AlphaToCoverage }; struct SharedConstants { uint32_t textureIndices[16]{}; uint32_t samplerIndices[16]{}; - uint32_t alphaTestMode{}; + AlphaTestMode alphaTestMode{}; float alphaThreshold{}; uint32_t booleans{}; uint32_t swappedTexcoords{}; @@ -348,9 +356,25 @@ static void SetRenderStateZWriteEnable(GuestDevice* device, uint32_t value) SetDirtyValue(g_dirtyStates.pipelineState, g_pipelineState.zWriteEnable, value != 0); } +static void SetAlphaTestMode(bool enable) +{ + AlphaTestMode alphaTestMode = AlphaTestMode::Disabled; + + if (enable) + { + if (Config::AlphaToCoverage && g_renderTarget != nullptr && g_renderTarget->sampleCount != RenderSampleCount::COUNT_1) + alphaTestMode = AlphaTestMode::AlphaToCoverage; + else + alphaTestMode = AlphaTestMode::AlphaThreshold; + } + + SetDirtyValue(g_dirtyStates.sharedConstants, g_sharedConstants.alphaTestMode, alphaTestMode); + SetDirtyValue(g_dirtyStates.pipelineState, g_pipelineState.enableAlphaToCoverage, alphaTestMode == AlphaTestMode::AlphaToCoverage); +} + static void SetRenderStateAlphaTestEnable(GuestDevice* device, uint32_t value) { - SetDirtyValue(g_dirtyStates.sharedConstants, g_sharedConstants.alphaTestMode, value ? 1u : 0); + SetAlphaTestMode(value != 0); } static RenderBlend ConvertBlendMode(uint32_t blendMode) @@ -1357,6 +1381,9 @@ static void SetRenderTarget(GuestDevice* device, uint32_t index, GuestSurface* r SetDirtyValue(g_dirtyStates.renderTargetAndDepthStencil, g_renderTarget, renderTarget); SetDirtyValue(g_dirtyStates.pipelineState, g_pipelineState.renderTargetFormat, renderTarget != nullptr ? renderTarget->format : RenderFormat::UNKNOWN); SetDirtyValue(g_dirtyStates.pipelineState, g_pipelineState.sampleCount, renderTarget != nullptr ? renderTarget->sampleCount : RenderSampleCount::COUNT_1); + + // When alpha to coverage is enabled, update the alpha test mode as it's dependent on sample count. + SetAlphaTestMode(g_sharedConstants.alphaTestMode != AlphaTestMode::Disabled); } static GuestSurface* GetDepthStencilSurface(GuestDevice* device) @@ -1508,6 +1535,7 @@ static RenderPipeline* CreateGraphicsPipeline(const PipelineState& pipelineState desc.renderTargetCount = pipelineState.renderTargetFormat != RenderFormat::UNKNOWN ? 1 : 0; desc.depthTargetFormat = pipelineState.depthStencilFormat; desc.multisampling.sampleCount = pipelineState.sampleCount; + desc.alphaToCoverageEnabled = pipelineState.enableAlphaToCoverage; desc.inputElements = pipelineState.vertexDeclaration->inputElements.get(); desc.inputElementsCount = pipelineState.vertexDeclaration->inputElementCount; diff --git a/thirdparty/ShaderRecomp b/thirdparty/ShaderRecomp index f315ae4..2489145 160000 --- a/thirdparty/ShaderRecomp +++ b/thirdparty/ShaderRecomp @@ -1 +1 @@ -Subproject commit f315ae49baeebdcbd817d8a8928e23ce07df7596 +Subproject commit 2489145820713afe12231e2c1d4526c14cf64085