Implement alpha to coverage.

This commit is contained in:
Skyth 2024-10-24 14:57:23 +03:00
parent 98554eaffa
commit 9b70e1034a
6 changed files with 35 additions and 4 deletions

View file

@ -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);

View file

@ -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]);

View file

@ -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] = {};

View file

@ -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<VkPipelineColorBlendAttachmentState> colorBlendAttachments;
colorBlendAttachments.clear();

View file

@ -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;

@ -1 +1 @@
Subproject commit f315ae49baeebdcbd817d8a8928e23ce07df7596
Subproject commit 2489145820713afe12231e2c1d4526c14cf64085