From 37f10877836df47b1becbb61bac181142f0e0cb9 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 6 May 2019 00:04:47 +0200 Subject: [PATCH] [dxvk] Add API for specialization constants --- src/dxvk/dxvk_context.cpp | 10 ++++++++++ src/dxvk/dxvk_context.h | 13 +++++++++++++ src/dxvk/dxvk_graphics.cpp | 3 +++ src/dxvk/dxvk_graphics.h | 2 ++ src/dxvk/dxvk_limits.h | 1 + src/dxvk/dxvk_shader.h | 3 ++- src/dxvk/dxvk_spec_const.h | 37 +++++++++++++++++++++++++++++++++++++ 7 files changed, 68 insertions(+), 1 deletion(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index ebf192fbb..87ce23cb9 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -2142,6 +2142,16 @@ namespace dxvk { m_flags.set(DxvkContextFlag::GpDirtyPipelineState); } + + + void DxvkContext::setSpecConstant( + uint32_t index, + uint32_t value) { + if (m_state.gp.state.scSpecConstants[index] != value) { + m_state.gp.state.scSpecConstants[index] = value; + m_flags.set(DxvkContextFlag::GpDirtyPipelineState); + } + } void DxvkContext::setPredicate( diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index 043007afb..b5636f7b3 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -856,6 +856,19 @@ namespace dxvk { uint32_t attachment, const DxvkBlendMode& blendMode); + /** + * \brief Sets specialization constants + * + * Replaces current specialization constants with + * the given list of constant entries. The specId + * in the shader can be computed with \c getSpecId. + * \param [in] index Constant index + * \param [in] value Constant value + */ + void setSpecConstant( + uint32_t index, + uint32_t value); + /** * \brief Sets predicate * diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index d5086385a..1bb4e46bf 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -205,6 +205,9 @@ namespace dxvk { specData.set(specId + 3, util::getComponentIndex(state.omComponentMapping[i].a, 3), 3u); } } + + for (uint32_t i = 0; i < MaxNumSpecConstants; i++) + specData.set(getSpecId(i), state.scSpecConstants[i], 0u); VkSpecializationInfo specInfo = specData.getSpecInfo(); diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 5ee841c03..e56869505 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -109,6 +109,8 @@ namespace dxvk { VkLogicOp omLogicOp; VkPipelineColorBlendAttachmentState omBlendAttachments[MaxNumRenderTargets]; VkComponentMapping omComponentMapping[MaxNumRenderTargets]; + + uint32_t scSpecConstants[MaxNumSpecConstants]; }; diff --git a/src/dxvk/dxvk_limits.h b/src/dxvk/dxvk_limits.h index 183b4492b..f983c97e6 100644 --- a/src/dxvk/dxvk_limits.h +++ b/src/dxvk/dxvk_limits.h @@ -15,6 +15,7 @@ namespace dxvk { MaxNumActiveBindings = 128, MaxNumQueuedCommandBuffers = 8, MaxNumQueryCountPerPool = 128, + MaxNumSpecConstants = 8, MaxUniformBufferSize = 65536, MaxVertexBindingStride = 2048, MaxPushConstantSize = 128, diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index 640d12793..fb38e2ba4 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -30,7 +30,8 @@ namespace dxvk { // Specialization constants for pipeline state SpecConstantRangeStart = ColorComponentMappings + MaxNumRenderTargets * 4, - RasterizerSampleCount = SpecConstantRangeStart, + RasterizerSampleCount = SpecConstantRangeStart + 0, + FirstPipelineConstant }; diff --git a/src/dxvk/dxvk_spec_const.h b/src/dxvk/dxvk_spec_const.h index 8c0f42f44..df4f041cb 100644 --- a/src/dxvk/dxvk_spec_const.h +++ b/src/dxvk/dxvk_spec_const.h @@ -4,6 +4,18 @@ #include "dxvk_shader.h" namespace dxvk { + + /** + * \briefS Specialization constant entry + * + * Used to pass a list of user-defined + * specialization constants to shaders. + */ + struct DxvkSpecConstant { + uint32_t specId; + uint32_t value; + }; + /** * \brief Specialization constant info @@ -36,6 +48,18 @@ namespace dxvk { setAsUint32(specId, uint32_t(value)); } + /** + * \brief Sets specialization constant value + * + * Always passes the constant value to the driver. + * \param [in] specId Specialization constant ID + * \param [in] value Specialization constant value + */ + template + void set(uint32_t specId, T value) { + setAsUint32(specId, uint32_t(value)); + } + /** * \brief Generates specialization info structure * \returns Specialization info for shader module @@ -50,5 +74,18 @@ namespace dxvk { void setAsUint32(uint32_t specId, uint32_t value); }; + + + /** + * \brief Computes specialization constant ID + * + * Computest the specId to use within shaders + * for a given pipeline specialization constant. + * \param [in] index Spec constant index + * \returns Specialization constant ID + */ + inline uint32_t getSpecId(uint32_t index) { + return uint32_t(DxvkSpecConstantId::FirstPipelineConstant) + index; + } } \ No newline at end of file