Commit 73832434 by Alexis Hetu Committed by Alexis Hétu

Dynamic state implementation

Implemented all dynamic state commands and applied the proper state within the draw command. Bug b/118619338 Change-Id: Ifeca42be1698f642e137e807aa59958447921fcc Tests: dEQP-VK.dynamic_state.* Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/28890Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Presubmit-Ready: Alexis Hétu <sugoi@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarChris Forbes <chrisforbes@google.com>
parent 17ecf2a6
......@@ -133,6 +133,7 @@ namespace sw
rasterizerDiscard = false;
depthCompareMode = VK_COMPARE_OP_LESS;
depthBoundsTestEnable = false;
depthBufferEnable = false;
depthWriteEnable = false;
......
......@@ -179,6 +179,7 @@ namespace sw
// Pixel processor states
bool rasterizerDiscard;
bool depthBoundsTestEnable;
bool depthBufferEnable;
VkCompareOp depthCompareMode;
bool depthWriteEnable;
......
......@@ -250,6 +250,157 @@ struct IndexBufferBind : public CommandBuffer::Command
const VkIndexType indexType;
};
struct SetViewport : public CommandBuffer::Command
{
SetViewport(const VkViewport& viewport, uint32_t viewportID) :
viewport(viewport), viewportID(viewportID)
{
}
void play(CommandBuffer::ExecutionState& executionState) override
{
executionState.dynamicState.viewport = viewport;
}
const VkViewport viewport;
uint32_t viewportID;
};
struct SetScissor : public CommandBuffer::Command
{
SetScissor(const VkRect2D& scissor, uint32_t scissorID) :
scissor(scissor), scissorID(scissorID)
{
}
void play(CommandBuffer::ExecutionState& executionState) override
{
executionState.dynamicState.scissor = scissor;
}
const VkRect2D scissor;
uint32_t scissorID;
};
struct SetDepthBias : public CommandBuffer::Command
{
SetDepthBias(float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor) :
depthBiasConstantFactor(depthBiasConstantFactor), depthBiasClamp(depthBiasClamp), depthBiasSlopeFactor(depthBiasSlopeFactor)
{
}
void play(CommandBuffer::ExecutionState& executionState) override
{
executionState.dynamicState.depthBiasConstantFactor = depthBiasConstantFactor;
executionState.dynamicState.depthBiasClamp = depthBiasClamp;
executionState.dynamicState.depthBiasSlopeFactor = depthBiasSlopeFactor;
}
float depthBiasConstantFactor;
float depthBiasClamp;
float depthBiasSlopeFactor;
};
struct SetBlendConstants : public CommandBuffer::Command
{
SetBlendConstants(const float blendConstants[4])
{
memcpy(this->blendConstants, blendConstants, sizeof(this->blendConstants));
}
void play(CommandBuffer::ExecutionState& executionState) override
{
memcpy(&(executionState.dynamicState.blendConstants[0]), blendConstants, sizeof(blendConstants));
}
float blendConstants[4];
};
struct SetDepthBounds : public CommandBuffer::Command
{
SetDepthBounds(float minDepthBounds, float maxDepthBounds) :
minDepthBounds(minDepthBounds), maxDepthBounds(maxDepthBounds)
{
}
void play(CommandBuffer::ExecutionState& executionState) override
{
executionState.dynamicState.minDepthBounds = minDepthBounds;
executionState.dynamicState.maxDepthBounds = maxDepthBounds;
}
float minDepthBounds;
float maxDepthBounds;
};
struct SetStencilCompareMask : public CommandBuffer::Command
{
SetStencilCompareMask(VkStencilFaceFlags faceMask, uint32_t compareMask) :
faceMask(faceMask), compareMask(compareMask)
{
}
void play(CommandBuffer::ExecutionState& executionState) override
{
if(faceMask & VK_STENCIL_FACE_FRONT_BIT)
{
executionState.dynamicState.compareMask[0] = compareMask;
}
if(faceMask & VK_STENCIL_FACE_BACK_BIT)
{
executionState.dynamicState.compareMask[1] = compareMask;
}
}
VkStencilFaceFlags faceMask;
uint32_t compareMask;
};
struct SetStencilWriteMask : public CommandBuffer::Command
{
SetStencilWriteMask(VkStencilFaceFlags faceMask, uint32_t writeMask) :
faceMask(faceMask), writeMask(writeMask)
{
}
void play(CommandBuffer::ExecutionState& executionState) override
{
if(faceMask & VK_STENCIL_FACE_FRONT_BIT)
{
executionState.dynamicState.writeMask[0] = writeMask;
}
if(faceMask & VK_STENCIL_FACE_BACK_BIT)
{
executionState.dynamicState.writeMask[1] = writeMask;
}
}
VkStencilFaceFlags faceMask;
uint32_t writeMask;
};
struct SetStencilReference : public CommandBuffer::Command
{
SetStencilReference(VkStencilFaceFlags faceMask, uint32_t reference) :
faceMask(faceMask), reference(reference)
{
}
void play(CommandBuffer::ExecutionState& executionState) override
{
if(faceMask & VK_STENCIL_FACE_FRONT_BIT)
{
executionState.dynamicState.reference[0] = reference;
}
if(faceMask & VK_STENCIL_FACE_BACK_BIT)
{
executionState.dynamicState.reference[1] = reference;
}
}
VkStencilFaceFlags faceMask;
uint32_t reference;
};
void CommandBuffer::ExecutionState::bindVertexInputs(sw::Context& context, int firstVertex, int firstInstance)
{
for(uint32_t i = 0; i < MAX_VERTEX_INPUT_BINDINGS; i++)
......@@ -319,16 +470,52 @@ struct DrawBase : public CommandBuffer::Command
context.descriptorDynamicOffsets = pipelineState.descriptorDynamicOffsets;
context.pushConstants = executionState.pushConstants;
if (indexed)
if(indexed)
{
context.indexBuffer = Cast(executionState.indexBufferBinding.buffer)->getOffsetPointer(
executionState.indexBufferBinding.offset + first * bytesPerIndex(executionState));
}
// Apply either pipeline state or dynamic state
executionState.renderer->setScissor(pipeline->hasDynamicState(VK_DYNAMIC_STATE_SCISSOR) ?
executionState.dynamicState.scissor : pipeline->getScissor());
executionState.renderer->setViewport(pipeline->hasDynamicState(VK_DYNAMIC_STATE_VIEWPORT) ?
executionState.dynamicState.viewport : pipeline->getViewport());
executionState.renderer->setBlendConstant(pipeline->hasDynamicState(VK_DYNAMIC_STATE_BLEND_CONSTANTS) ?
executionState.dynamicState.blendConstants : pipeline->getBlendConstants());
if(pipeline->hasDynamicState(VK_DYNAMIC_STATE_DEPTH_BIAS))
{
// If the depth bias clamping feature is not enabled, depthBiasClamp must be 0.0
ASSERT(executionState.dynamicState.depthBiasClamp == 0.0f);
context.depthBias = executionState.dynamicState.depthBiasConstantFactor;
context.slopeDepthBias = executionState.dynamicState.depthBiasSlopeFactor;
}
if(pipeline->hasDynamicState(VK_DYNAMIC_STATE_DEPTH_BOUNDS) && context.depthBoundsTestEnable)
{
// Unless the VK_EXT_depth_range_unrestricted extension is enabled minDepthBounds and maxDepthBounds must be between 0.0 and 1.0, inclusive
ASSERT(executionState.dynamicState.minDepthBounds >= 0.0f && executionState.dynamicState.minDepthBounds <= 1.0f);
ASSERT(executionState.dynamicState.maxDepthBounds >= 0.0f && executionState.dynamicState.maxDepthBounds <= 1.0f);
UNIMPLEMENTED("depthBoundsTestEnable");
}
if(pipeline->hasDynamicState(VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK) && context.stencilEnable)
{
context.frontStencil.compareMask = executionState.dynamicState.compareMask[0];
context.backStencil.compareMask = executionState.dynamicState.compareMask[1];
}
if(pipeline->hasDynamicState(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK) && context.stencilEnable)
{
context.frontStencil.writeMask = executionState.dynamicState.writeMask[0];
context.backStencil.writeMask = executionState.dynamicState.writeMask[1];
}
if(pipeline->hasDynamicState(VK_DYNAMIC_STATE_STENCIL_REFERENCE) && context.stencilEnable)
{
context.frontStencil.reference = executionState.dynamicState.reference[0];
context.backStencil.reference = executionState.dynamicState.reference[1];
}
executionState.renderer->setContext(context);
executionState.renderer->setScissor(pipeline->getScissor());
executionState.renderer->setViewport(pipeline->getViewport());
executionState.renderer->setBlendConstant(pipeline->getBlendConstants());
executionState.bindAttachments();
......@@ -1008,85 +1195,73 @@ void CommandBuffer::pushConstants(VkPipelineLayout layout, VkShaderStageFlags st
void CommandBuffer::setViewport(uint32_t firstViewport, uint32_t viewportCount, const VkViewport* pViewports)
{
// Note: The bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_VIEWPORT dynamic state enabled
UNIMPLEMENTED("setViewport");
if(firstViewport != 0 || viewportCount > 1)
{
UNIMPLEMENTED("viewport");
}
for(uint32_t i = 0; i < viewportCount; i++)
{
addCommand<SetViewport>(pViewports[i], i + firstViewport);
}
}
void CommandBuffer::setScissor(uint32_t firstScissor, uint32_t scissorCount, const VkRect2D* pScissors)
{
// Note: The bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_SCISSOR dynamic state enabled
UNIMPLEMENTED("setScissor");
if(firstScissor != 0 || scissorCount > 1)
{
UNIMPLEMENTED("scissor");
}
for(uint32_t i = 0; i < scissorCount; i++)
{
addCommand<SetScissor>(pScissors[i], i + firstScissor);
}
}
void CommandBuffer::setLineWidth(float lineWidth)
{
// Note: The bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_LINE_WIDTH dynamic state enabled
// If the wide lines feature is not enabled, lineWidth must be 1.0
ASSERT(lineWidth == 1.0f);
UNIMPLEMENTED("setLineWidth");
}
void CommandBuffer::setDepthBias(float depthBiasConstantFactor, float depthBiasClamp, float depthBiasSlopeFactor)
{
// Note: The bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_DEPTH_BIAS dynamic state enabled
// If the depth bias clamping feature is not enabled, depthBiasClamp must be 0.0
ASSERT(depthBiasClamp == 0.0f);
UNIMPLEMENTED("setDepthBias");
addCommand<SetDepthBias>(depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
}
void CommandBuffer::setBlendConstants(const float blendConstants[4])
{
// Note: The bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_BLEND_CONSTANTS dynamic state enabled
// blendConstants is an array of four values specifying the R, G, B, and A components
// of the blend constant color used in blending, depending on the blend factor.
UNIMPLEMENTED("setBlendConstants");
addCommand<SetBlendConstants>(blendConstants);
}
void CommandBuffer::setDepthBounds(float minDepthBounds, float maxDepthBounds)
{
// Note: The bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_DEPTH_BOUNDS dynamic state enabled
// Unless the VK_EXT_depth_range_unrestricted extension is enabled minDepthBounds and maxDepthBounds must be between 0.0 and 1.0, inclusive
ASSERT(minDepthBounds >= 0.0f && minDepthBounds <= 1.0f);
ASSERT(maxDepthBounds >= 0.0f && maxDepthBounds <= 1.0f);
UNIMPLEMENTED("setDepthBounds");
addCommand<SetDepthBounds>(minDepthBounds, maxDepthBounds);
}
void CommandBuffer::setStencilCompareMask(VkStencilFaceFlags faceMask, uint32_t compareMask)
{
// Note: The bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK dynamic state enabled
// faceMask must not be 0
ASSERT(faceMask != 0);
UNIMPLEMENTED("setStencilCompareMask");
addCommand<SetStencilCompareMask>(faceMask, compareMask);
}
void CommandBuffer::setStencilWriteMask(VkStencilFaceFlags faceMask, uint32_t writeMask)
{
// Note: The bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_STENCIL_WRITE_MASK dynamic state enabled
// faceMask must not be 0
ASSERT(faceMask != 0);
UNIMPLEMENTED("setStencilWriteMask");
addCommand<SetStencilWriteMask>(faceMask, writeMask);
}
void CommandBuffer::setStencilReference(VkStencilFaceFlags faceMask, uint32_t reference)
{
// Note: The bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_STENCIL_REFERENCE dynamic state enabled
// faceMask must not be 0
ASSERT(faceMask != 0);
UNIMPLEMENTED("setStencilReference");
addCommand<SetStencilReference>(faceMask, reference);
}
void CommandBuffer::bindDescriptorSets(VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout vkLayout,
......
......@@ -135,6 +135,24 @@ public:
RenderPass* renderPass = nullptr;
Framebuffer* renderPassFramebuffer = nullptr;
std::array<PipelineState, VK_PIPELINE_BIND_POINT_RANGE_SIZE> pipelineState;
struct DynamicState
{
VkViewport viewport;
VkRect2D scissor;
sw::Color<float> blendConstants;
float depthBiasConstantFactor = 0.0f;
float depthBiasClamp = 0.0f;
float depthBiasSlopeFactor = 0.0f;
float minDepthBounds = 0.0f;
float maxDepthBounds = 0.0f;
uint32_t compareMask[2] = { 0 };
uint32_t writeMask[2] = { 0 };
uint32_t reference[2] = { 0 };
};
DynamicState dynamicState;
sw::PushConstantStorage pushConstants;
struct VertexInputBinding
......
......@@ -231,12 +231,36 @@ GraphicsPipeline::GraphicsPipeline(const VkGraphicsPipelineCreateInfo* pCreateIn
{
if(((pCreateInfo->flags & ~(VK_PIPELINE_CREATE_DERIVATIVE_BIT | VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT)) != 0) ||
(pCreateInfo->stageCount != 2) ||
(pCreateInfo->pTessellationState != nullptr) ||
(pCreateInfo->pDynamicState != nullptr))
(pCreateInfo->pTessellationState != nullptr))
{
UNIMPLEMENTED("pCreateInfo settings");
}
if(pCreateInfo->pDynamicState)
{
for(uint32_t i = 0; i < pCreateInfo->pDynamicState->dynamicStateCount; i++)
{
VkDynamicState dynamicState = pCreateInfo->pDynamicState->pDynamicStates[i];
switch(dynamicState)
{
case VK_DYNAMIC_STATE_VIEWPORT:
case VK_DYNAMIC_STATE_SCISSOR:
case VK_DYNAMIC_STATE_LINE_WIDTH:
case VK_DYNAMIC_STATE_DEPTH_BIAS:
case VK_DYNAMIC_STATE_BLEND_CONSTANTS:
case VK_DYNAMIC_STATE_DEPTH_BOUNDS:
case VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK:
case VK_DYNAMIC_STATE_STENCIL_WRITE_MASK:
case VK_DYNAMIC_STATE_STENCIL_REFERENCE:
ASSERT(dynamicState < (sizeof(dynamicStateFlags) * 8));
dynamicStateFlags |= (1 << dynamicState);
break;
default:
UNIMPLEMENTED("dynamic state");
}
}
}
const VkPipelineVertexInputStateCreateInfo* vertexInputState = pCreateInfo->pVertexInputState;
if(vertexInputState->flags != 0)
{
......@@ -346,6 +370,7 @@ GraphicsPipeline::GraphicsPipeline(const VkGraphicsPipelineCreateInfo* pCreateIn
UNIMPLEMENTED("depthStencilState");
}
context.depthBoundsTestEnable = depthStencilState->depthBoundsTestEnable;
context.depthBufferEnable = depthStencilState->depthTestEnable;
context.depthWriteEnable = depthStencilState->depthWriteEnable;
context.depthCompareMode = depthStencilState->depthCompareOp;
......@@ -480,6 +505,11 @@ const sw::Color<float>& GraphicsPipeline::getBlendConstants() const
return blendConstants;
}
bool GraphicsPipeline::hasDynamicState(VkDynamicState dynamicState) const
{
return (dynamicStateFlags & (1 << dynamicState)) != 0;
}
ComputePipeline::ComputePipeline(const VkComputePipelineCreateInfo* pCreateInfo, void* mem)
: Pipeline(Cast(pCreateInfo->layout))
{
......
......@@ -75,11 +75,13 @@ public:
const VkRect2D& getScissor() const;
const VkViewport& getViewport() const;
const sw::Color<float>& getBlendConstants() const;
bool hasDynamicState(VkDynamicState dynamicState) const;
private:
sw::SpirvShader *vertexShader = nullptr;
sw::SpirvShader *fragmentShader = nullptr;
uint32_t dynamicStateFlags = 0;
sw::Context context;
VkRect2D scissor;
VkViewport viewport;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment