mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-15 07:29:17 +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);
|
emitValueStore(ptr, value, mask);
|
||||||
} break;
|
} 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:
|
default:
|
||||||
Logger::warn(str::format(
|
Logger::warn(str::format(
|
||||||
"DxbcCompiler: Unhandled VS SV output: ", sv));
|
"DxbcCompiler: Unhandled VS SV output: ", sv));
|
||||||
@ -5394,47 +5438,11 @@ namespace dxvk {
|
|||||||
case DxbcSystemValue::Position:
|
case DxbcSystemValue::Position:
|
||||||
case DxbcSystemValue::CullDistance:
|
case DxbcSystemValue::CullDistance:
|
||||||
case DxbcSystemValue::ClipDistance:
|
case DxbcSystemValue::ClipDistance:
|
||||||
|
case DxbcSystemValue::RenderTargetId:
|
||||||
|
case DxbcSystemValue::ViewportId:
|
||||||
emitVsSystemValueStore(sv, mask, value);
|
emitVsSystemValueStore(sv, mask, value);
|
||||||
break;
|
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: {
|
case DxbcSystemValue::PrimitiveId: {
|
||||||
if (m_primitiveIdOut == 0) {
|
if (m_primitiveIdOut == 0) {
|
||||||
m_primitiveIdOut = emitNewBuiltinVariable({
|
m_primitiveIdOut = emitNewBuiltinVariable({
|
||||||
@ -5477,6 +5485,8 @@ namespace dxvk {
|
|||||||
case DxbcSystemValue::Position:
|
case DxbcSystemValue::Position:
|
||||||
case DxbcSystemValue::CullDistance:
|
case DxbcSystemValue::CullDistance:
|
||||||
case DxbcSystemValue::ClipDistance:
|
case DxbcSystemValue::ClipDistance:
|
||||||
|
case DxbcSystemValue::RenderTargetId:
|
||||||
|
case DxbcSystemValue::ViewportId:
|
||||||
emitVsSystemValueStore(sv, mask, value);
|
emitVsSystemValueStore(sv, mask, value);
|
||||||
break;
|
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(
|
DxbcCfgBlock* DxbcCompiler::cfgFindBlock(
|
||||||
const std::initializer_list<DxbcCfgBlockType>& types) {
|
const std::initializer_list<DxbcCfgBlockType>& types) {
|
||||||
for (auto cur = m_controlFlowBlocks.rbegin();
|
for (auto cur = m_controlFlowBlocks.rbegin();
|
||||||
|
@ -329,6 +329,18 @@ namespace dxvk {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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
|
* \brief DXBC to SPIR-V shader compiler
|
||||||
*
|
*
|
||||||
@ -473,6 +485,10 @@ namespace dxvk {
|
|||||||
DxbcCompilerPsPart m_ps;
|
DxbcCompilerPsPart m_ps;
|
||||||
DxbcCompilerCsPart m_cs;
|
DxbcCompilerCsPart m_cs;
|
||||||
|
|
||||||
|
/////////////////////////////
|
||||||
|
// Enabled SPIR-V extensions
|
||||||
|
DxbcSpirvExtensions m_extensions;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////
|
||||||
// Shader interface and metadata declaration methods
|
// Shader interface and metadata declaration methods
|
||||||
void emitDcl(
|
void emitDcl(
|
||||||
@ -1051,6 +1067,10 @@ namespace dxvk {
|
|||||||
uint32_t emitBuiltinTessLevelInner(
|
uint32_t emitBuiltinTessLevelInner(
|
||||||
spv::StorageClass storageClass);
|
spv::StorageClass storageClass);
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
// Extension enablement methods
|
||||||
|
void enableShaderViewportIndexLayer();
|
||||||
|
|
||||||
////////////////
|
////////////////
|
||||||
// Misc methods
|
// Misc methods
|
||||||
DxbcCfgBlock* cfgFindBlock(
|
DxbcCfgBlock* cfgFindBlock(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user