[dxvk] Generate bit mask of used spec constants in DxvkShader

This way we can more accurately track which constants are used, and not
pass any unnecessary data at compile time. We can extend this in the
future to also skip unused constants for pipeline lookups.

Also, any spec constant with the ID of MaxNumSpecConstants will be treated
as a spec constant selector. If the shader uses this constant, it is assumed
that it does not access any other spec constants if the value of this constant
is 0. This will allow shaders with spec constants to be used with pipeline
libraries.
This commit is contained in:
Philip Rebohle 2022-07-30 15:39:22 +02:00
parent 753aede1fc
commit 80a58f000a
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 16 additions and 4 deletions

View File

@ -64,8 +64,10 @@ namespace dxvk {
bindingOffsets[varId].setOffset = ins.offset() + 3;
}
if (ins.arg(2) == spv::DecorationSpecId && ins.arg(3) < MaxNumSpecConstants)
m_flags.set(DxvkShaderFlag::HasSpecConstants);
if (ins.arg(2) == spv::DecorationSpecId) {
if (ins.arg(3) <= MaxNumSpecConstants)
m_specConstantMask |= 1u << ins.arg(3);
}
if (ins.arg(2) == spv::DecorationLocation && ins.arg(3) == 1) {
m_o1LocOffset = ins.offset() + 3;
@ -158,7 +160,8 @@ namespace dxvk {
return false;
// Ignore shaders that have user-defined spec constants
return !m_flags.test(DxvkShaderFlag::HasSpecConstants);
// and no selector to read their contents from elsewhere
return !m_specConstantMask || (m_specConstantMask & (1u << MaxNumSpecConstants));
}

View File

@ -27,7 +27,6 @@ namespace dxvk {
enum DxvkShaderFlag : uint64_t {
HasSampleRateShading,
HasTransformFeedback,
HasSpecConstants,
ExportsStencilRef,
ExportsViewportIndexLayerFromVertexStage,
};
@ -112,6 +111,14 @@ namespace dxvk {
return m_bindings;
}
/**
* \brief Retrieves spec constant mask
* \returns Bit mask of used spec constants
*/
uint32_t getSpecConstantMask() const {
return m_specConstantMask;
}
/**
* \brief Patches code using given info
*
@ -209,6 +216,8 @@ namespace dxvk {
size_t m_o1IdxOffset = 0;
size_t m_o1LocOffset = 0;
uint32_t m_specConstantMask = 0;
std::vector<char> m_uniformData;
std::vector<BindingOffsets> m_bindingOffsets;