1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-02 01:24:11 +01:00

[dxvk] Store shader capability information in separate set of flags

This commit is contained in:
Philip Rebohle 2019-11-12 18:05:03 +01:00
parent 1ca235d186
commit 420d95e396
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
4 changed files with 40 additions and 27 deletions

View File

@ -1987,11 +1987,11 @@ namespace dxvk {
auto shader = commonShader.GetShader();
if (shader->hasCapability(spv::CapabilityStencilExportEXT)
if (shader->flags().test(DxvkShaderFlag::ExportsStencilRef)
&& !m_dxvkDevice->extensions().extShaderStencilExport)
return E_INVALIDARG;
if (shader->hasCapability(spv::CapabilityShaderViewportIndexLayerEXT)
if (shader->flags().test(DxvkShaderFlag::ExportsViewportIndexLayerFromVertexStage)
&& !m_dxvkDevice->extensions().extShaderViewportIndexLayer)
return E_INVALIDARG;

View File

@ -29,13 +29,13 @@ namespace dxvk {
m_vsIn = m_shaders.vs != nullptr ? m_shaders.vs->interfaceSlots().inputSlots : 0;
m_fsOut = m_shaders.fs != nullptr ? m_shaders.fs->interfaceSlots().outputSlots : 0;
if (m_shaders.gs != nullptr && m_shaders.gs->hasCapability(spv::CapabilityTransformFeedback))
if (m_shaders.gs != nullptr && m_shaders.gs->flags().test(DxvkShaderFlag::HasTransformFeedback))
m_flags.set(DxvkGraphicsPipelineFlag::HasTransformFeedback);
if (m_layout->getStorageDescriptorStages())
m_flags.set(DxvkGraphicsPipelineFlag::HasStorageDescriptors);
m_common.msSampleShadingEnable = m_shaders.fs != nullptr && m_shaders.fs->hasCapability(spv::CapabilitySampleRateShading);
m_common.msSampleShadingEnable = m_shaders.fs != nullptr && m_shaders.fs->flags().test(DxvkShaderFlag::HasSampleRateShading);
m_common.msSampleShadingFactor = 1.0f;
}

View File

@ -127,8 +127,21 @@ namespace dxvk {
m_o1IdxOffset = ins.offset() + 3;
}
if (ins.opCode() == spv::OpCapability)
m_capabilities.push_back(spv::Capability(ins.arg(1)));
if (ins.opCode() == spv::OpExecutionMode) {
if (ins.arg(2) == spv::ExecutionModeStencilRefReplacingEXT)
m_flags.set(DxvkShaderFlag::ExportsStencilRef);
if (ins.arg(2) == spv::ExecutionModeXfb)
m_flags.set(DxvkShaderFlag::HasTransformFeedback);
}
if (ins.opCode() == spv::OpCapability) {
if (ins.arg(1) == spv::CapabilitySampleRateShading)
m_flags.set(DxvkShaderFlag::HasSampleRateShading);
if (ins.arg(1) == spv::CapabilityShaderViewportIndexLayerEXT)
m_flags.set(DxvkShaderFlag::ExportsViewportIndexLayerFromVertexStage);
}
}
}
@ -138,15 +151,6 @@ namespace dxvk {
}
bool DxvkShader::hasCapability(spv::Capability cap) {
auto entry = std::find(
m_capabilities.begin(),
m_capabilities.end(), cap);
return entry != m_capabilities.end();
}
void DxvkShader::defineResourceSlots(
DxvkDescriptorSlotMapping& mapping) const {
for (const auto& slot : m_slots)

View File

@ -34,6 +34,20 @@ namespace dxvk {
FirstPipelineConstant
};
/**
* \brief Shader flags
*
* Provides extra information about the features
* used by a shader.
*/
enum DxvkShaderFlag : uint64_t {
HasSampleRateShading,
HasTransformFeedback,
ExportsStencilRef,
ExportsViewportIndexLayerFromVertexStage,
};
using DxvkShaderFlags = Flags<DxvkShaderFlag>;
/**
* \brief Shader interface slots
@ -143,16 +157,12 @@ namespace dxvk {
}
/**
* \brief Checks whether a capability is enabled
*
* If the shader contains an \c OpCapability
* instruction with the given capability, it
* is considered enabled. This may be required
* to correctly set up certain pipeline states.
* \param [in] cap The capability to check
* \returns \c true if \c cap is enabled
* \brief Retrieves shader flags
* \returns Shader flags
*/
bool hasCapability(spv::Capability cap);
DxvkShaderFlags flags() const {
return m_flags;
}
/**
* \brief Adds resource slots definitions to a mapping
@ -274,13 +284,12 @@ namespace dxvk {
std::vector<DxvkResourceSlot> m_slots;
std::vector<size_t> m_idOffsets;
DxvkInterfaceSlots m_interface;
DxvkShaderFlags m_flags;
DxvkShaderOptions m_options;
DxvkShaderConstData m_constData;
DxvkShaderKey m_key;
size_t m_hash = 0;
std::vector<spv::Capability> m_capabilities;
size_t m_o1IdxOffset = 0;
size_t m_o1LocOffset = 0;