[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:
Philip Rebohle 2018-06-01 13:57:26 +02:00
parent 3a520dfe4a
commit 9ff17b03f2
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 78 additions and 38 deletions

View File

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

View File

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