summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineVulkan
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2018-04-13 06:12:34 +0000
committerEgor Yusov <egor.yusov@gmail.com>2018-04-13 06:12:34 +0000
commitc628d43a0bed402b79e85a41a7a7ea70086f8064 (patch)
tree123ca65cea1f8f0a568c51010cd6674e93cba923 /Graphics/GraphicsEngineVulkan
parentFixed validation errors; updated pipeline state vk implementaiton (diff)
downloadDiligentCore-c628d43a0bed402b79e85a41a7a7ea70086f8064.tar.gz
DiligentCore-c628d43a0bed402b79e85a41a7a7ea70086f8064.zip
Updated vulkan structure initialization
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
-rw-r--r--Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.h1
-rw-r--r--Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp65
-rw-r--r--Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp57
3 files changed, 88 insertions, 35 deletions
diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.h b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.h
index 15f9c8da..10a35c9a 100644
--- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.h
+++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.h
@@ -41,6 +41,7 @@ namespace VulkanUtilities
static constexpr uint32_t InvalidMemoryTypeIndex = static_cast<uint32_t>(-1);
uint32_t GetMemoryTypeIndex(uint32_t typeBits, VkMemoryPropertyFlags properties)const;
+ const VkPhysicalDeviceProperties& GetProperties()const{return m_Properties;}
private:
VulkanPhysicalDevice(VkPhysicalDevice vkDevice);
diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
index 62272b67..65bc8b6c 100644
--- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
@@ -173,7 +173,6 @@ PipelineStateVkImpl :: PipelineStateVkImpl(IReferenceCounters *pRefCounters, Ren
*/
{
const auto &LogicalDevice = pDeviceVk->GetLogicalDevice();
-
if (PipelineDesc.IsComputePipeline)
{
auto &ComputePipeline = PipelineDesc.ComputePipeline;
@@ -236,10 +235,11 @@ PipelineStateVkImpl :: PipelineStateVkImpl(IReferenceCounters *pRefCounters, Ren
}
else
{
+ const auto &PhysicalDevice = pDeviceVk->GetPhysicalDevice();
+
auto &GraphicsPipeline = PipelineDesc.GraphicsPipeline;
CreateRenderPass(LogicalDevice);
-
VkGraphicsPipelineCreateInfo PipelineCI = {};
PipelineCI.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
@@ -255,7 +255,14 @@ PipelineStateVkImpl :: PipelineStateVkImpl(IReferenceCounters *pRefCounters, Ren
std::vector<VkPipelineShaderStageCreateInfo> Stages(PipelineCI.stageCount);
PipelineCI.pStages = Stages.data();
PipelineCI.pVertexInputState;
- PipelineCI.pInputAssemblyState;
+
+ VkPipelineInputAssemblyStateCreateInfo InputAssemblyCI = {};
+ InputAssemblyCI.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
+ InputAssemblyCI.pNext = nullptr;
+ InputAssemblyCI.flags;
+ InputAssemblyCI.topology;
+ InputAssemblyCI.primitiveRestartEnable = VK_FALSE;
+ PipelineCI.pInputAssemblyState = &InputAssemblyCI;
VkPipelineTessellationStateCreateInfo TessStateCI = {};
if(GraphicsPipeline.pHS != nullptr && GraphicsPipeline.pDS)
@@ -274,12 +281,28 @@ PipelineStateVkImpl :: PipelineStateVkImpl(IReferenceCounters *pRefCounters, Ren
VkPipelineViewportStateCreateInfo ViewPortStateCI = {};
ViewPortStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
ViewPortStateCI.pNext = nullptr;
- ViewPortStateCI.flags;
- ViewPortStateCI.viewportCount = 1; // Even though we use dynamic viewports, the number of viewports used
- // by the pipeline is still specified by the viewportCount member
+ ViewPortStateCI.flags = 0; // reserved for future use
+ ViewPortStateCI.viewportCount =
+ GraphicsPipeline.NumViewports; // Even though we use dynamic viewports, the number of viewports used
+ // by the pipeline is still specified by the viewportCount member (23.5)
ViewPortStateCI.pViewports = nullptr; // We will be using dynamic viewport & scissor states
- ViewPortStateCI.scissorCount = 1;
- ViewPortStateCI.pScissors = nullptr;
+ ViewPortStateCI.scissorCount = ViewPortStateCI.viewportCount; // the number of scissors must match the number of viewports (23.5)
+ // (why the hell it is in the struct then?)
+ VkRect2D ScissorRect = {};
+ if (GraphicsPipeline.RasterizerDesc.ScissorEnable)
+ {
+ ViewPortStateCI.pScissors = nullptr; // Ignored if the scissor state is dynamic
+ }
+ else
+ {
+ const auto &Props = PhysicalDevice.GetProperties();
+ // There are limitiations on the viewport width and height (23.5), but
+ // it is not clear if there are limitations on the scissor rect width and
+ // height
+ ScissorRect.extent.width = Props.limits.maxViewportDimensions[0];
+ ScissorRect.extent.height = Props.limits.maxViewportDimensions[1];
+ ViewPortStateCI.pScissors = &ScissorRect;
+ }
PipelineCI.pViewportState = &ViewPortStateCI;
VkPipelineRasterizationStateCreateInfo RasterizerStateCI =
@@ -296,9 +319,9 @@ PipelineStateVkImpl :: PipelineStateVkImpl(IReferenceCounters *pRefCounters, Ren
MSStateCI.rasterizationSamples = static_cast<VkSampleCountFlagBits>(1 << (GraphicsPipeline.SmplDesc.Count-1));
MSStateCI.sampleShadingEnable = VK_FALSE;
MSStateCI.minSampleShading = 0; // a minimum fraction of sample shading if sampleShadingEnable is set to VK_TRUE.
- uint32_t SampleMask = GraphicsPipeline.SampleMask;
- MSStateCI.pSampleMask = &SampleMask; // a bitmask of static coverage information that is ANDed with the coverage
- // information generated during rasterization
+ uint32_t SampleMask[] = {GraphicsPipeline.SampleMask, 0}; // Vulkan spec allows up to 64 samples
+ MSStateCI.pSampleMask = SampleMask; // an array of static coverage information that is ANDed with
+ // the coverage information generated during rasterization (25.3)
MSStateCI.alphaToCoverageEnable = VK_FALSE; // whether a temporary coverage value is generated based on
// the alpha component of the fragment’s first color output
MSStateCI.alphaToOneEnable = VK_FALSE; // whether the alpha component of the fragment’s first color output is replaced with one
@@ -321,18 +344,13 @@ PipelineStateVkImpl :: PipelineStateVkImpl(IReferenceCounters *pRefCounters, Ren
DynamicStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
DynamicStateCI.pNext = nullptr;
DynamicStateCI.flags = 0; // reserved for future use
- VkDynamicState DynamicStates[] =
+ std::vector<VkDynamicState> DynamicStates =
{
VK_DYNAMIC_STATE_VIEWPORT,// pViewports state in VkPipelineViewportStateCreateInfo will be ignored and must be
// set dynamically with vkCmdSetViewport before any draw commands. The number of viewports
// used by a pipeline is still specified by the viewportCount member of
// VkPipelineViewportStateCreateInfo.
- VK_DYNAMIC_STATE_SCISSOR, // pScissors state in VkPipelineViewportStateCreateInfo will be ignored and must be set
- // dynamically with vkCmdSetScissor before any draw commands. The number of scissor rectangles
- // used by a pipeline is still specified by the scissorCount member of
- // VkPipelineViewportStateCreateInfo.
-
VK_DYNAMIC_STATE_BLEND_CONSTANTS, // blendConstants state in VkPipelineColorBlendStateCreateInfo will be ignored
// and must be set dynamically with vkCmdSetBlendConstants
@@ -340,8 +358,17 @@ PipelineStateVkImpl :: PipelineStateVkImpl(IReferenceCounters *pRefCounters, Ren
// for both front and back will be ignored and must be set dynamically
// with vkCmdSetStencilReference
};
- DynamicStateCI.dynamicStateCount = _countof(DynamicStates);
- DynamicStateCI.pDynamicStates = DynamicStates;
+
+ if(GraphicsPipeline.RasterizerDesc.ScissorEnable)
+ {
+ // pScissors state in VkPipelineViewportStateCreateInfo will be ignored and must be set
+ // dynamically with vkCmdSetScissor before any draw commands. The number of scissor rectangles
+ // used by a pipeline is still specified by the scissorCount member of
+ // VkPipelineViewportStateCreateInfo.
+ DynamicStates.push_back(VK_DYNAMIC_STATE_SCISSOR);
+ }
+ DynamicStateCI.dynamicStateCount = static_cast<uint32_t>(DynamicStates.size());
+ DynamicStateCI.pDynamicStates = DynamicStates.data();
PipelineCI.pDynamicState = &DynamicStateCI;
PipelineCI.layout;
diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp
index ad28c1c4..24f7300b 100644
--- a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp
@@ -655,17 +655,25 @@ VkPipelineRasterizationStateCreateInfo RasterizerStateDesc_To_VkRasterizationSta
RSStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
RSStateCI.pNext = nullptr;
RSStateCI.flags = 0; // Reserved for future use.
- RSStateCI.depthClampEnable = RasterizerDesc.DepthClipEnable ? VK_FALSE : VK_TRUE; // whether to clamp the fragment’s depth
- // values instead of clipping primitives to the z planes of the frustum.
- // This value is the opposite of clip enable
+
+ // If depth clamping is enabled, before the incoming fragment’s zf is compared to za, zf is clamped to
+ // [min(n,f), max(n,f)], where n and f are the minDepth and maxDepth depth range values of the viewport
+ // used by this fragment, respectively (25.10)
+ // This value is the opposite of clip enable
+ RSStateCI.depthClampEnable = RasterizerDesc.DepthClipEnable ? VK_FALSE : VK_TRUE;
+
RSStateCI.rasterizerDiscardEnable = VK_FALSE; // Whether primitives are discarded immediately before the rasterization stage.
- RSStateCI.polygonMode = FillModeToVkPolygonMode(RasterizerDesc.FillMode);
- RSStateCI.cullMode = CullModeToVkCullMode(RasterizerDesc.CullMode);
- RSStateCI.frontFace = RasterizerDesc.FrontCounterClockwise ? VK_FRONT_FACE_COUNTER_CLOCKWISE : VK_FRONT_FACE_CLOCKWISE;
+ RSStateCI.polygonMode = FillModeToVkPolygonMode(RasterizerDesc.FillMode); // 24.7.2
+ RSStateCI.cullMode = CullModeToVkCullMode(RasterizerDesc.CullMode); // 24.7.1
+ RSStateCI.frontFace = RasterizerDesc.FrontCounterClockwise ? VK_FRONT_FACE_COUNTER_CLOCKWISE : VK_FRONT_FACE_CLOCKWISE; // 24.7.1
+ // Depth bias (24.7.3)
RSStateCI.depthBiasEnable = (RasterizerDesc.DepthBias != 0 || RasterizerDesc.SlopeScaledDepthBias != 0.f) ? VK_TRUE : VK_FALSE;
- RSStateCI.depthBiasConstantFactor = static_cast<float>(RasterizerDesc.DepthBias); // a scalar factor controlling the constant depth value added to each fragment.
+ RSStateCI.depthBiasConstantFactor =
+ static_cast<float>(RasterizerDesc.DepthBias); // a scalar factor applied to an implementation-dependent constant
+ // that relates to the usable resolution of the depth buffer
RSStateCI.depthBiasClamp = RasterizerDesc.DepthBiasClamp; // maximum (or minimum) depth bias of a fragment.
- RSStateCI.depthBiasSlopeFactor = RasterizerDesc.SlopeScaledDepthBias; // a scalar factor applied to a fragment’s slope in depth bias calculations.
+ RSStateCI.depthBiasSlopeFactor =
+ RasterizerDesc.SlopeScaledDepthBias; // a scalar factor applied to a fragment’s slope in depth bias calculations.
RSStateCI.lineWidth = 1.f; // If the wide lines feature is not enabled, and no element of the pDynamicStates member of
// pDynamicState is VK_DYNAMIC_STATE_LINE_WIDTH, the lineWidth member of
// pRasterizationState must be 1.0 (9.2)
@@ -721,14 +729,24 @@ VkStencilOp StencilOpToVkStencilOp(STENCIL_OP StencilOp)
VkStencilOpState StencilOpDescToVkStencilOpState(const StencilOpDesc& desc, Uint8 StencilReadMask, Uint8 StencilWriteMask)
{
+ // Stencil state (25.9)
VkStencilOpState StencilState = {};
StencilState.failOp = StencilOpToVkStencilOp(desc.StencilFailOp);
StencilState.passOp = StencilOpToVkStencilOp(desc.StencilPassOp);
StencilState.depthFailOp = StencilOpToVkStencilOp(desc.StencilDepthFailOp);
StencilState.compareOp = ComparisonFuncToVkCompareOp(desc.StencilFunc);
+
+ // The s least significant bits of compareMask, where s is the number of bits in the stencil framebuffer attachment,
+ // are bitwise ANDed with both the reference and the stored stencil value, and the resulting masked values are those
+ // that participate in the comparison controlled by compareOp (25.9)
StencilState.compareMask = StencilReadMask;
+
+ // The least significant s bits of writeMask, where s is the number of bits in the stencil framebuffer
+ // attachment, specify an integer mask. Where a 1 appears in this mask, the corresponding bit in the stencil
+ // value in the depth / stencil attachment is written; where a 0 appears, the bit is not written (25.9)
StencilState.writeMask = StencilWriteMask;
- StencilState.reference = 0;
+
+ StencilState.reference = 0; // Set dynamically
return StencilState;
}
@@ -736,19 +754,21 @@ VkStencilOpState StencilOpDescToVkStencilOpState(const StencilOpDesc& desc, Uint
VkPipelineDepthStencilStateCreateInfo DepthStencilStateDesc_To_VkDepthStencilStateCI(const DepthStencilStateDesc &DepthStencilDesc)
{
+ // Depth-stencil state (25.7)
VkPipelineDepthStencilStateCreateInfo DSStateCI = {};
DSStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
DSStateCI.pNext = nullptr;
DSStateCI.flags = 0; // reserved for future use
DSStateCI.depthTestEnable = DepthStencilDesc.DepthEnable ? VK_TRUE : VK_FALSE;
DSStateCI.depthWriteEnable = DepthStencilDesc.DepthWriteEnable ? VK_TRUE : VK_FALSE;
- DSStateCI.depthCompareOp = ComparisonFuncToVkCompareOp(DepthStencilDesc.DepthFunc);
- DSStateCI.depthBoundsTestEnable = VK_FALSE;
- DSStateCI.stencilTestEnable = DepthStencilDesc.StencilEnable;
+ DSStateCI.depthCompareOp = ComparisonFuncToVkCompareOp(DepthStencilDesc.DepthFunc); // 25.10
+ DSStateCI.depthBoundsTestEnable = VK_FALSE; // 25.8
+ DSStateCI.stencilTestEnable = DepthStencilDesc.StencilEnable ? VK_TRUE : VK_FALSE; // 25.9
DSStateCI.front = StencilOpDescToVkStencilOpState(DepthStencilDesc.FrontFace, DepthStencilDesc.StencilReadMask, DepthStencilDesc.StencilWriteMask);
DSStateCI.back = StencilOpDescToVkStencilOpState(DepthStencilDesc.BackFace, DepthStencilDesc.StencilReadMask, DepthStencilDesc.StencilWriteMask);
- DSStateCI.minDepthBounds = 0;
- DSStateCI.maxDepthBounds = 1;
+ // Depth Bounds Test (25.8)
+ DSStateCI.minDepthBounds = 0; // must be between 0.0 and 1.0, inclusive
+ DSStateCI.maxDepthBounds = 1; // must be between 0.0 and 1.0, inclusive
return DSStateCI;
}
@@ -758,6 +778,7 @@ class BlendFactorToVkBlendFactorMapper
public:
BlendFactorToVkBlendFactorMapper()
{
+ // 26.1.1
m_Map[BLEND_FACTOR_ZERO] = VK_BLEND_FACTOR_ZERO;
m_Map[BLEND_FACTOR_ONE] = VK_BLEND_FACTOR_ONE;
m_Map[BLEND_FACTOR_SRC_COLOR] = VK_BLEND_FACTOR_SRC_COLOR;
@@ -793,6 +814,7 @@ class LogicOperationToVkLogicOp
public:
LogicOperationToVkLogicOp()
{
+ // 26.2
m_Map[ LOGIC_OP_CLEAR ] = VK_LOGIC_OP_CLEAR;
m_Map[ LOGIC_OP_SET ] = VK_LOGIC_OP_SET;
m_Map[ LOGIC_OP_COPY ] = VK_LOGIC_OP_COPY;
@@ -826,6 +848,7 @@ class BlendOperationToVkBlendOp
public:
BlendOperationToVkBlendOp()
{
+ // 26.1.3
m_Map[ BLEND_OPERATION_ADD ] = VK_BLEND_OP_ADD;
m_Map[ BLEND_OPERATION_SUBTRACT ] = VK_BLEND_OP_SUBTRACT;
m_Map[ BLEND_OPERATION_REV_SUBTRACT ] = VK_BLEND_OP_REVERSE_SUBTRACT;
@@ -868,16 +891,18 @@ void BlendStateDesc_To_VkBlendStateCI(const BlendStateDesc &BSDesc,
VkPipelineColorBlendStateCreateInfo &ColorBlendStateCI,
std::vector<VkPipelineColorBlendAttachmentState> &ColorBlendAttachments)
{
+ // Color blend state (26.1)
static const LogicOperationToVkLogicOp LogicOpToVkLogicOp;
ColorBlendStateCI.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
ColorBlendStateCI.pNext = nullptr;
ColorBlendStateCI.flags = 0; // reserved for future use
- ColorBlendStateCI.logicOpEnable = BSDesc.RenderTargets[0].LogicOperationEnable;
+ ColorBlendStateCI.logicOpEnable = BSDesc.RenderTargets[0].LogicOperationEnable; // 26.2
ColorBlendStateCI.logicOp = LogicOpToVkLogicOp[BSDesc.RenderTargets[0].LogicOp];
- ColorBlendStateCI.blendConstants[0] = 0.f;
+ ColorBlendStateCI.blendConstants[0] = 0.f; // We use dynamic blend constants
ColorBlendStateCI.blendConstants[1] = 0.f;
ColorBlendStateCI.blendConstants[2] = 0.f;
ColorBlendStateCI.blendConstants[3] = 0.f;
+ // attachmentCount must equal the colorAttachmentCount for the subpass in which this pipeline is used.
for(uint32_t attachment = 0; attachment < ColorBlendStateCI.attachmentCount; ++attachment)
{
const auto& RTBlendState = BSDesc.IndependentBlendEnable ? BSDesc.RenderTargets[attachment] : BSDesc.RenderTargets[0];