From 17a6c4168ea67011f13efb9c831e7636f7830538 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 15 Sep 2019 14:56:23 +0200 Subject: [PATCH] [dxbc] Implement stencil ref export from fragment shaders This is an optional feature in D3D11.3, but easy enough to support. --- src/d3d11/d3d11_device.cpp | 3 ++- src/dxbc/dxbc_compiler.cpp | 17 +++++++++++++++++ src/dxbc/dxbc_compiler.h | 1 + src/dxbc/dxbc_enums.h | 1 + 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 4a6f4145..6679ac7d 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1367,10 +1367,11 @@ namespace dxvk { if (FeatureSupportDataSize != sizeof(D3D11_FEATURE_DATA_D3D11_OPTIONS2)) return E_INVALIDARG; + const auto& extensions = m_dxvkDevice->extensions(); const auto& features = m_dxvkDevice->features(); auto info = static_cast(pFeatureSupportData); - info->PSSpecifiedStencilRefSupported = FALSE; // TODO + info->PSSpecifiedStencilRefSupported = extensions.extShaderStencilExport; info->TypedUAVLoadAdditionalFormats = features.core.features.shaderStorageImageReadWithoutFormat; info->ROVsSupported = FALSE; info->ConservativeRasterizationTier = D3D11_CONSERVATIVE_RASTERIZATION_NOT_SUPPORTED; diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index ffd0c0ad..911f2527 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -554,6 +554,18 @@ namespace dxvk { "oDepth"); } break; + case DxbcOperandType::OutputStencilRef: { + m_module.enableExtension("SPV_EXT_shader_stencil_export"); + m_module.enableCapability(spv::CapabilityStencilExportEXT); + m_module.setExecutionMode(m_entryPointId, + spv::ExecutionModeStencilRefReplacingEXT); + m_ps.builtinStencilRef = emitNewBuiltinVariable({ + { DxbcScalarType::Sint32, 1, 0 }, + spv::StorageClassOutput }, + spv::BuiltInFragStencilRefEXT, + "oStencilRef"); + } break; + case DxbcOperandType::OutputDepthGe: { m_module.setExecutionMode(m_entryPointId, spv::ExecutionModeDepthReplacing); m_module.setExecutionMode(m_entryPointId, spv::ExecutionModeDepthGreater); @@ -4860,6 +4872,11 @@ namespace dxvk { { DxbcScalarType::Float32, 1 }, m_ps.builtinDepth }; + case DxbcOperandType::OutputStencilRef: + return DxbcRegisterPointer { + { DxbcScalarType::Sint32, 1 }, + m_ps.builtinStencilRef }; + case DxbcOperandType::InputPrimitiveId: return DxbcRegisterPointer { { DxbcScalarType::Uint32, 1 }, diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index e7a6eaeb..39e9743f 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -171,6 +171,7 @@ namespace dxvk { uint32_t builtinFragCoord = 0; uint32_t builtinDepth = 0; + uint32_t builtinStencilRef = 0; uint32_t builtinIsFrontFace = 0; uint32_t builtinSampleId = 0; uint32_t builtinSampleMaskIn = 0; diff --git a/src/dxbc/dxbc_enums.h b/src/dxbc/dxbc_enums.h index 27610e46..5ecd10bd 100644 --- a/src/dxbc/dxbc_enums.h +++ b/src/dxbc/dxbc_enums.h @@ -288,6 +288,7 @@ namespace dxvk { OutputDepthGe = 38, OutputDepthLe = 39, CycleCounter = 40, + OutputStencilRef = 41, };