mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-13 19:29:14 +01:00
[dxbc] Support RenderTargetId and ViewportId in Vertex/Domain shaders
Fixes shader compilation errors in Pillars of Eternity II (#408) and Lost Sphear (#406). Currently unsupported by RADV.
This commit is contained in:
parent
3a520dfe4a
commit
9ff17b03f2
@ -5322,6 +5322,50 @@ namespace dxvk {
|
||||
emitValueStore(ptr, value, mask);
|
||||
} break;
|
||||
|
||||
case DxbcSystemValue::RenderTargetId: {
|
||||
if (m_version.type() != DxbcProgramType::GeometryShader)
|
||||
enableShaderViewportIndexLayer();
|
||||
|
||||
if (m_gs.builtinLayer == 0) {
|
||||
m_gs.builtinLayer = emitNewBuiltinVariable({
|
||||
{ DxbcScalarType::Uint32, 1, 0 },
|
||||
spv::StorageClassOutput },
|
||||
spv::BuiltInLayer,
|
||||
"o_layer");
|
||||
}
|
||||
|
||||
DxbcRegisterPointer ptr;
|
||||
ptr.type = { DxbcScalarType::Uint32, 1 };
|
||||
ptr.id = m_gs.builtinLayer;
|
||||
|
||||
emitValueStore(
|
||||
ptr, emitRegisterExtract(value, mask),
|
||||
DxbcRegMask(true, false, false, false));
|
||||
} break;
|
||||
|
||||
case DxbcSystemValue::ViewportId: {
|
||||
if (m_version.type() != DxbcProgramType::GeometryShader)
|
||||
enableShaderViewportIndexLayer();
|
||||
|
||||
if (m_gs.builtinViewportId == 0) {
|
||||
m_module.enableCapability(spv::CapabilityMultiViewport);
|
||||
|
||||
m_gs.builtinViewportId = emitNewBuiltinVariable({
|
||||
{ DxbcScalarType::Uint32, 1, 0 },
|
||||
spv::StorageClassOutput },
|
||||
spv::BuiltInViewportIndex,
|
||||
"o_viewport");
|
||||
}
|
||||
|
||||
DxbcRegisterPointer ptr;
|
||||
ptr.type = { DxbcScalarType::Uint32, 1};
|
||||
ptr.id = m_gs.builtinViewportId;
|
||||
|
||||
emitValueStore(
|
||||
ptr, emitRegisterExtract(value, mask),
|
||||
DxbcRegMask(true, false, false, false));
|
||||
} break;
|
||||
|
||||
default:
|
||||
Logger::warn(str::format(
|
||||
"DxbcCompiler: Unhandled VS SV output: ", sv));
|
||||
@ -5394,47 +5438,11 @@ namespace dxvk {
|
||||
case DxbcSystemValue::Position:
|
||||
case DxbcSystemValue::CullDistance:
|
||||
case DxbcSystemValue::ClipDistance:
|
||||
case DxbcSystemValue::RenderTargetId:
|
||||
case DxbcSystemValue::ViewportId:
|
||||
emitVsSystemValueStore(sv, mask, value);
|
||||
break;
|
||||
|
||||
case DxbcSystemValue::RenderTargetId: {
|
||||
if (m_gs.builtinLayer == 0) {
|
||||
m_gs.builtinLayer = emitNewBuiltinVariable({
|
||||
{ DxbcScalarType::Uint32, 1, 0 },
|
||||
spv::StorageClassOutput },
|
||||
spv::BuiltInLayer,
|
||||
"gs_layer");
|
||||
}
|
||||
|
||||
DxbcRegisterPointer ptr;
|
||||
ptr.type = { DxbcScalarType::Uint32, 1 };
|
||||
ptr.id = m_gs.builtinLayer;
|
||||
|
||||
emitValueStore(
|
||||
ptr, emitRegisterExtract(value, mask),
|
||||
DxbcRegMask(true, false, false, false));
|
||||
} break;
|
||||
|
||||
case DxbcSystemValue::ViewportId: {
|
||||
if (m_gs.builtinViewportId == 0) {
|
||||
m_module.enableCapability(spv::CapabilityMultiViewport);
|
||||
|
||||
m_gs.builtinViewportId = emitNewBuiltinVariable({
|
||||
{ DxbcScalarType::Uint32, 1, 0 },
|
||||
spv::StorageClassOutput },
|
||||
spv::BuiltInViewportIndex,
|
||||
"gs_viewport_id");
|
||||
}
|
||||
|
||||
DxbcRegisterPointer ptr;
|
||||
ptr.type = { DxbcScalarType::Uint32, 1};
|
||||
ptr.id = m_gs.builtinViewportId;
|
||||
|
||||
emitValueStore(
|
||||
ptr, emitRegisterExtract(value, mask),
|
||||
DxbcRegMask(true, false, false, false));
|
||||
} break;
|
||||
|
||||
case DxbcSystemValue::PrimitiveId: {
|
||||
if (m_primitiveIdOut == 0) {
|
||||
m_primitiveIdOut = emitNewBuiltinVariable({
|
||||
@ -5477,6 +5485,8 @@ namespace dxvk {
|
||||
case DxbcSystemValue::Position:
|
||||
case DxbcSystemValue::CullDistance:
|
||||
case DxbcSystemValue::ClipDistance:
|
||||
case DxbcSystemValue::RenderTargetId:
|
||||
case DxbcSystemValue::ViewportId:
|
||||
emitVsSystemValueStore(sv, mask, value);
|
||||
break;
|
||||
|
||||
@ -6318,6 +6328,16 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void DxbcCompiler::enableShaderViewportIndexLayer() {
|
||||
if (!m_extensions.shaderViewportIndexLayer) {
|
||||
m_extensions.shaderViewportIndexLayer = true;
|
||||
|
||||
m_module.enableExtension("SPV_EXT_shader_viewport_index_layer");
|
||||
m_module.enableCapability(spv::CapabilityShaderViewportIndexLayerEXT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DxbcCfgBlock* DxbcCompiler::cfgFindBlock(
|
||||
const std::initializer_list<DxbcCfgBlockType>& types) {
|
||||
for (auto cur = m_controlFlowBlocks.rbegin();
|
||||
|
@ -328,6 +328,18 @@ namespace dxvk {
|
||||
uint32_t stride;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief SPIR-V extension set
|
||||
*
|
||||
* Keeps track of which optional SPIR-V extensions
|
||||
* are enabled so that any required setup code is
|
||||
* only run once.
|
||||
*/
|
||||
struct DxbcSpirvExtensions {
|
||||
bool shaderViewportIndexLayer = false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief DXBC to SPIR-V shader compiler
|
||||
@ -472,6 +484,10 @@ namespace dxvk {
|
||||
DxbcCompilerGsPart m_gs;
|
||||
DxbcCompilerPsPart m_ps;
|
||||
DxbcCompilerCsPart m_cs;
|
||||
|
||||
/////////////////////////////
|
||||
// Enabled SPIR-V extensions
|
||||
DxbcSpirvExtensions m_extensions;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// Shader interface and metadata declaration methods
|
||||
@ -1050,6 +1066,10 @@ namespace dxvk {
|
||||
|
||||
uint32_t emitBuiltinTessLevelInner(
|
||||
spv::StorageClass storageClass);
|
||||
|
||||
////////////////////////////////
|
||||
// Extension enablement methods
|
||||
void enableShaderViewportIndexLayer();
|
||||
|
||||
////////////////
|
||||
// Misc methods
|
||||
|
Loading…
x
Reference in New Issue
Block a user