summaryrefslogtreecommitdiffstats
path: root/Graphics
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2018-04-12 04:06:57 +0000
committerEgor Yusov <egor.yusov@gmail.com>2018-04-12 04:06:57 +0000
commit4a27b8a45fd535fa28496bb79c675bf8fd90a6cb (patch)
treea5453bfeb26f50e3b7f18ae7f590200df8a9c358 /Graphics
parentAdded rasterizer and depth-stencil state desc conversions to Vulkan types (diff)
downloadDiligentCore-4a27b8a45fd535fa28496bb79c675bf8fd90a6cb.tar.gz
DiligentCore-4a27b8a45fd535fa28496bb79c675bf8fd90a6cb.zip
Vulkan: added blend state desc conversion
Diffstat (limited to 'Graphics')
-rw-r--r--Graphics/GraphicsEngineD3DBase/include/D3DTypeConversionImpl.h14
-rw-r--r--Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.h4
-rw-r--r--Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp13
-rw-r--r--Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp163
4 files changed, 158 insertions, 36 deletions
diff --git a/Graphics/GraphicsEngineD3DBase/include/D3DTypeConversionImpl.h b/Graphics/GraphicsEngineD3DBase/include/D3DTypeConversionImpl.h
index e5d328e3..047bf37c 100644
--- a/Graphics/GraphicsEngineD3DBase/include/D3DTypeConversionImpl.h
+++ b/Graphics/GraphicsEngineD3DBase/include/D3DTypeConversionImpl.h
@@ -23,6 +23,8 @@
#pragma once
+#include <array>
+
/// \file
/// Implementation of D3D type conversions
@@ -70,7 +72,7 @@ namespace Diligent
D3D_PRIM_TOPOLOGY TopologyToD3DTopology(PRIMITIVE_TOPOLOGY Topology)
{
static bool bIsInit = false;
- static D3D_PRIM_TOPOLOGY d3dPrimTopology[PRIMITIVE_TOPOLOGY_NUM_TOPOLOGIES] = {};
+ static std::array<D3D_PRIM_TOPOLOGY, PRIMITIVE_TOPOLOGY_NUM_TOPOLOGIES> d3dPrimTopology = {};
if( !bIsInit )
{
d3dPrimTopology[PRIMITIVE_TOPOLOGY_UNDEFINED] = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
@@ -126,7 +128,7 @@ namespace Diligent
{
// D3D12_FILL_MODE is identical tp D3D11_FILL_MODE
static bool bIsInit = false;
- static D3D_FILL_MODE d3dFillModes[FILL_MODE_NUM_MODES] = {};
+ static std::array<D3D_FILL_MODE, FILL_MODE_NUM_MODES> d3dFillModes = {};
if( !bIsInit )
{
d3dFillModes[ FILL_MODE_WIREFRAME ] = D3D_FILL_MODE_WIREFRAME;
@@ -152,7 +154,7 @@ namespace Diligent
{
// D3D_CULL_MODE is identical to D3D11_CULL_MODE
static bool bIsInit = false;
- static D3D_CULL_MODE d3dCullModes[CULL_MODE_NUM_MODES] = {};
+ static std::array<D3D_CULL_MODE, CULL_MODE_NUM_MODES> d3dCullModes = {};
if( !bIsInit )
{
d3dCullModes[ CULL_MODE_NONE ] = D3D_CULL_MODE_NONE;
@@ -204,7 +206,7 @@ namespace Diligent
// Note that this code is safe for multithreaded environments since
// bIsInit is set to true only AFTER the entire map is initialized.
static bool bIsInit = false;
- static D3D_BLEND D3DBlend[BLEND_FACTOR_NUM_FACTORS] = {};
+ static std::array<D3D_BLEND, BLEND_FACTOR_NUM_FACTORS> D3DBlend = {};
if( !bIsInit )
{
// In a multithreaded environment, several threads can potentially enter
@@ -249,7 +251,7 @@ namespace Diligent
// D3D12_BLEND_OP and D3D11_BLEND_OP are identical
static bool bIsInit = false;
- static D3D_BLEND_OP D3DBlendOp[BLEND_OPERATION_NUM_OPERATIONS] = {};
+ static std::array<D3D_BLEND_OP, BLEND_OPERATION_NUM_OPERATIONS> D3DBlendOp = {};
if( !bIsInit )
{
D3DBlendOp[ BLEND_OPERATION_ADD ] = D3D_BLEND_OP_ADD;
@@ -311,7 +313,7 @@ namespace Diligent
D3D_STENCIL_OP StencilOpToD3DStencilOp( STENCIL_OP StencilOp )
{
static bool bIsInit = false;
- static D3D_STENCIL_OP StOpToD3DStOpMap[STENCIL_OP_NUM_OPS] = {};
+ static std::array<D3D_STENCIL_OP, STENCIL_OP_NUM_OPS> StOpToD3DStOpMap = {};
if( !bIsInit )
{
StOpToD3DStOpMap[ STENCIL_OP_KEEP ] = D3D_STENCIL_OP_KEEP;
diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.h b/Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.h
index 8c1a46ce..bdb0c792 100644
--- a/Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.h
+++ b/Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.h
@@ -38,7 +38,9 @@ VkFormat TypeToVkFormat(VALUE_TYPE ValType, Uint32 NumComponents, Bool bIsNormal
VkPipelineRasterizationStateCreateInfo RasterizerStateDesc_To_VkRasterizationStateCI(const RasterizerStateDesc &RasterizerDesc);
VkPipelineDepthStencilStateCreateInfo DepthStencilStateDesc_To_VkDepthStencilStateCI(const DepthStencilStateDesc &DepthStencilDesc);
-VkPipelineColorBlendStateCreateInfo BlendStateDesc_To_VkBlendStateCI(const BlendStateDesc &BSDesc);
+void BlendStateDesc_To_VkBlendStateCI(const BlendStateDesc &BSDesc,
+ VkPipelineColorBlendStateCreateInfo &ColorBlendStateCI,
+ std::vector<VkPipelineColorBlendAttachmentState> &ColorBlendAttachments);
#if 0
diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
index c2ca23fa..332986f2 100644
--- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp
@@ -226,16 +226,23 @@ PipelineStateVkImpl :: PipelineStateVkImpl(IReferenceCounters *pRefCounters, Ren
PipelineCI.pInputAssemblyState;
PipelineCI.pTessellationState;
PipelineCI.pViewportState;
+
VkPipelineRasterizationStateCreateInfo RasterizerStateCI =
RasterizerStateDesc_To_VkRasterizationStateCI(GraphicsPipeline.RasterizerDesc);
PipelineCI.pRasterizationState = &RasterizerStateCI;
PipelineCI.pMultisampleState;
+
VkPipelineDepthStencilStateCreateInfo DepthStencilStateCI =
DepthStencilStateDesc_To_VkDepthStencilStateCI(GraphicsPipeline.DepthStencilDesc);
PipelineCI.pDepthStencilState = &DepthStencilStateCI;
- VkPipelineColorBlendStateCreateInfo BlendStateCI =
- BlendStateDesc_To_VkBlendStateCI(GraphicsPipeline.BlendDesc);
- PipelineCI.pColorBlendState;
+
+ std::vector<VkPipelineColorBlendAttachmentState> ColorBlendAttachmentStates(m_Desc.GraphicsPipeline.NumRenderTargets);
+ VkPipelineColorBlendStateCreateInfo BlendStateCI = {};
+ BlendStateCI.pAttachments = !ColorBlendAttachmentStates.empty() ? ColorBlendAttachmentStates.data() : nullptr;
+ BlendStateCI.attachmentCount = m_Desc.GraphicsPipeline.NumRenderTargets; // must equal the colorAttachmentCount for the subpass in which this pipeline is used.
+ BlendStateDesc_To_VkBlendStateCI(GraphicsPipeline.BlendDesc, BlendStateCI, ColorBlendAttachmentStates);
+ PipelineCI.pColorBlendState = &BlendStateCI;
+
PipelineCI.pDynamicState;
PipelineCI.layout;
PipelineCI.renderPass = m_RenderPass;
diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp
index 71abf131..0454cfb4 100644
--- a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp
@@ -23,6 +23,7 @@
#include "pch.h"
#include <unordered_map>
+#include <array>
#include "VulkanTypeConversions.h"
#include "VulkanTypeDefinitions.h"
@@ -679,13 +680,13 @@ VkCompareOp ComparisonFuncToVkCompareOp(COMPARISON_FUNCTION CmpFunc)
return VK_COMPARE_OP_ALWAYS;
case COMPARISON_FUNC_NEVER: return VK_COMPARE_OP_NEVER;
- case COMPARISON_FUNC_LESS: return VK_COMPARE_OP_LESS;
- case COMPARISON_FUNC_EQUAL: return VK_COMPARE_OP_EQUAL;
- case COMPARISON_FUNC_LESS_EQUAL: return VK_COMPARE_OP_LESS_OR_EQUAL;
- case COMPARISON_FUNC_GREATER: return VK_COMPARE_OP_GREATER;
- case COMPARISON_FUNC_NOT_EQUAL: return VK_COMPARE_OP_NOT_EQUAL;
- case COMPARISON_FUNC_GREATER_EQUAL: return VK_COMPARE_OP_GREATER_OR_EQUAL;
- case COMPARISON_FUNC_ALWAYS: return VK_COMPARE_OP_ALWAYS;
+ case COMPARISON_FUNC_LESS: return VK_COMPARE_OP_LESS;
+ case COMPARISON_FUNC_EQUAL: return VK_COMPARE_OP_EQUAL;
+ case COMPARISON_FUNC_LESS_EQUAL: return VK_COMPARE_OP_LESS_OR_EQUAL;
+ case COMPARISON_FUNC_GREATER: return VK_COMPARE_OP_GREATER;
+ case COMPARISON_FUNC_NOT_EQUAL: return VK_COMPARE_OP_NOT_EQUAL;
+ case COMPARISON_FUNC_GREATER_EQUAL: return VK_COMPARE_OP_GREATER_OR_EQUAL;
+ case COMPARISON_FUNC_ALWAYS: return VK_COMPARE_OP_ALWAYS;
default:
UNEXPECTED("Unknown comparison function" );
@@ -750,10 +751,136 @@ VkPipelineDepthStencilStateCreateInfo DepthStencilStateDesc_To_VkDepthStencilSt
return DSStateCI;
}
-VkPipelineColorBlendStateCreateInfo BlendStateDesc_To_VkBlendStateCI(const BlendStateDesc &BSDesc)
+class BlendFactorToVkBlendFactorMapper
{
- VkPipelineColorBlendStateCreateInfo BlendStateCI = {};
- return BlendStateCI;
+public:
+ BlendFactorToVkBlendFactorMapper()
+ {
+ 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;
+ m_Map[BLEND_FACTOR_INV_SRC_COLOR] = VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
+ m_Map[BLEND_FACTOR_SRC_ALPHA] = VK_BLEND_FACTOR_SRC_ALPHA;
+ m_Map[BLEND_FACTOR_INV_SRC_ALPHA] = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
+ m_Map[BLEND_FACTOR_DEST_ALPHA] = VK_BLEND_FACTOR_DST_ALPHA;
+ m_Map[BLEND_FACTOR_INV_DEST_ALPHA] = VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
+ m_Map[BLEND_FACTOR_DEST_COLOR] = VK_BLEND_FACTOR_DST_COLOR;
+ m_Map[BLEND_FACTOR_INV_DEST_COLOR] = VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
+ m_Map[BLEND_FACTOR_SRC_ALPHA_SAT] = VK_BLEND_FACTOR_SRC_ALPHA_SATURATE;
+ m_Map[BLEND_FACTOR_BLEND_FACTOR] = VK_BLEND_FACTOR_CONSTANT_COLOR;
+ m_Map[BLEND_FACTOR_INV_BLEND_FACTOR] = VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR;
+ m_Map[BLEND_FACTOR_SRC1_COLOR] = VK_BLEND_FACTOR_SRC1_COLOR;
+ m_Map[BLEND_FACTOR_INV_SRC1_COLOR] = VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR;
+ m_Map[BLEND_FACTOR_SRC1_ALPHA] = VK_BLEND_FACTOR_SRC1_ALPHA;
+ m_Map[BLEND_FACTOR_INV_SRC1_ALPHA] = VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA;
+ }
+
+ VkBlendFactor operator[](BLEND_FACTOR bf)const
+ {
+ VERIFY_EXPR(bf > BLEND_FACTOR_UNDEFINED && bf < BLEND_FACTOR_NUM_FACTORS);
+ return m_Map[static_cast<int>(bf)];
+ }
+
+private:
+ std::array<VkBlendFactor, BLEND_FACTOR_NUM_FACTORS> m_Map = {};
+};
+
+
+class LogicOperationToVkLogicOp
+{
+public:
+ LogicOperationToVkLogicOp()
+ {
+ 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;
+ m_Map[ LOGIC_OP_COPY_INVERTED ] = VK_LOGIC_OP_COPY_INVERTED;
+ m_Map[ LOGIC_OP_NOOP ] = VK_LOGIC_OP_NO_OP;
+ m_Map[ LOGIC_OP_INVERT ] = VK_LOGIC_OP_INVERT;
+ m_Map[ LOGIC_OP_AND ] = VK_LOGIC_OP_AND;
+ m_Map[ LOGIC_OP_NAND ] = VK_LOGIC_OP_NAND;
+ m_Map[ LOGIC_OP_OR ] = VK_LOGIC_OP_OR;
+ m_Map[ LOGIC_OP_NOR ] = VK_LOGIC_OP_NOR;
+ m_Map[ LOGIC_OP_XOR ] = VK_LOGIC_OP_XOR;
+ m_Map[ LOGIC_OP_EQUIV ] = VK_LOGIC_OP_EQUIVALENT;
+ m_Map[ LOGIC_OP_AND_REVERSE ] = VK_LOGIC_OP_AND_REVERSE;
+ m_Map[ LOGIC_OP_AND_INVERTED ] = VK_LOGIC_OP_AND_INVERTED;
+ m_Map[ LOGIC_OP_OR_REVERSE ] = VK_LOGIC_OP_OR_REVERSE;
+ m_Map[ LOGIC_OP_OR_INVERTED ] = VK_LOGIC_OP_OR_INVERTED;
+ }
+
+ VkLogicOp operator[](LOGIC_OPERATION op)const
+ {
+ VERIFY_EXPR(op >= LOGIC_OP_CLEAR && op < LOGIC_OP_NUM_OPERATIONS);
+ return m_Map[static_cast<int>(op)];
+ }
+
+private:
+ std::array<VkLogicOp, LOGIC_OP_NUM_OPERATIONS> m_Map = {};
+};
+
+class BlendOperationToVkBlendOp
+{
+public:
+ BlendOperationToVkBlendOp()
+ {
+ 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;
+ m_Map[ BLEND_OPERATION_MIN ] = VK_BLEND_OP_MIN;
+ m_Map[ BLEND_OPERATION_MAX ] = VK_BLEND_OP_MAX;
+ }
+
+ VkBlendOp operator[](BLEND_OPERATION op)const
+ {
+ VERIFY_EXPR(op > BLEND_OPERATION_UNDEFINED && op < BLEND_OPERATION_NUM_OPERATIONS);
+ return m_Map[static_cast<int>(op)];
+ }
+
+private:
+ std::array<VkBlendOp, BLEND_OPERATION_NUM_OPERATIONS> m_Map = {};
+};
+
+VkPipelineColorBlendAttachmentState RenderTargetBlendDescToVkColorBlendAttachmentState(const RenderTargetBlendDesc &RTBlendDesc)
+{
+ static const BlendFactorToVkBlendFactorMapper BFtoVKBF;
+ static const BlendOperationToVkBlendOp BOtoVKBO;
+ VkPipelineColorBlendAttachmentState AttachmentBlendState = {};
+ AttachmentBlendState.blendEnable = RTBlendDesc.BlendEnable;
+ AttachmentBlendState.srcColorBlendFactor = BFtoVKBF[RTBlendDesc.SrcBlend];
+ AttachmentBlendState.dstColorBlendFactor = BFtoVKBF[RTBlendDesc.DestBlend];
+ AttachmentBlendState.colorBlendOp = BOtoVKBO[RTBlendDesc.BlendOp];
+ AttachmentBlendState.srcAlphaBlendFactor = BFtoVKBF[RTBlendDesc.SrcBlendAlpha];
+ AttachmentBlendState.dstAlphaBlendFactor = BFtoVKBF[RTBlendDesc.DestBlendAlpha];
+ AttachmentBlendState.alphaBlendOp = BOtoVKBO[RTBlendDesc.BlendOpAlpha];
+ AttachmentBlendState.colorWriteMask =
+ ((RTBlendDesc.RenderTargetWriteMask & COLOR_MASK_RED) ? VK_COLOR_COMPONENT_R_BIT : 0) |
+ ((RTBlendDesc.RenderTargetWriteMask & COLOR_MASK_GREEN) ? VK_COLOR_COMPONENT_G_BIT : 0) |
+ ((RTBlendDesc.RenderTargetWriteMask & COLOR_MASK_BLUE) ? VK_COLOR_COMPONENT_B_BIT : 0) |
+ ((RTBlendDesc.RenderTargetWriteMask & COLOR_MASK_ALPHA) ? VK_COLOR_COMPONENT_A_BIT : 0);
+
+ return AttachmentBlendState;
+}
+
+void BlendStateDesc_To_VkBlendStateCI(const BlendStateDesc &BSDesc,
+ VkPipelineColorBlendStateCreateInfo &ColorBlendStateCI,
+ std::vector<VkPipelineColorBlendAttachmentState> &ColorBlendAttachments)
+{
+ 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.logicOp = LogicOpToVkLogicOp[BSDesc.RenderTargets[0].LogicOp];
+ ColorBlendStateCI.blendConstants[0] = 0.f;
+ ColorBlendStateCI.blendConstants[1] = 0.f;
+ ColorBlendStateCI.blendConstants[2] = 0.f;
+ ColorBlendStateCI.blendConstants[3] = 0.f;
+ for(uint32_t attachment = 0; attachment < ColorBlendStateCI.attachmentCount; ++attachment)
+ {
+ const auto& RTBlendState = BSDesc.IndependentBlendEnable ? BSDesc.RenderTargets[attachment] : BSDesc.RenderTargets[0];
+ ColorBlendAttachments[attachment] = RenderTargetBlendDescToVkColorBlendAttachmentState(RTBlendState);
+ }
}
@@ -803,22 +930,6 @@ D3D12_LOGIC_OP LogicOperationToD3D12LogicOp( LOGIC_OPERATION lo )
// In a multithreaded environment, several threads can potentially enter
// this block. This is not a problem since they will just initialize the
// memory with the same values more than once
- D3D12LogicOp[ D3D12_LOGIC_OP_CLEAR ] = D3D12_LOGIC_OP_CLEAR;
- D3D12LogicOp[ D3D12_LOGIC_OP_SET ] = D3D12_LOGIC_OP_SET;
- D3D12LogicOp[ D3D12_LOGIC_OP_COPY ] = D3D12_LOGIC_OP_COPY;
- D3D12LogicOp[ D3D12_LOGIC_OP_COPY_INVERTED ] = D3D12_LOGIC_OP_COPY_INVERTED;
- D3D12LogicOp[ D3D12_LOGIC_OP_NOOP ] = D3D12_LOGIC_OP_NOOP;
- D3D12LogicOp[ D3D12_LOGIC_OP_INVERT ] = D3D12_LOGIC_OP_INVERT;
- D3D12LogicOp[ D3D12_LOGIC_OP_AND ] = D3D12_LOGIC_OP_AND;
- D3D12LogicOp[ D3D12_LOGIC_OP_NAND ] = D3D12_LOGIC_OP_NAND;
- D3D12LogicOp[ D3D12_LOGIC_OP_OR ] = D3D12_LOGIC_OP_OR;
- D3D12LogicOp[ D3D12_LOGIC_OP_NOR ] = D3D12_LOGIC_OP_NOR;
- D3D12LogicOp[ D3D12_LOGIC_OP_XOR ] = D3D12_LOGIC_OP_XOR;
- D3D12LogicOp[ D3D12_LOGIC_OP_EQUIV ] = D3D12_LOGIC_OP_EQUIV;
- D3D12LogicOp[ D3D12_LOGIC_OP_AND_REVERSE ] = D3D12_LOGIC_OP_AND_REVERSE;
- D3D12LogicOp[ D3D12_LOGIC_OP_AND_INVERTED ] = D3D12_LOGIC_OP_AND_INVERTED;
- D3D12LogicOp[ D3D12_LOGIC_OP_OR_REVERSE ] = D3D12_LOGIC_OP_OR_REVERSE;
- D3D12LogicOp[ D3D12_LOGIC_OP_OR_INVERTED ] = D3D12_LOGIC_OP_OR_INVERTED;
bIsInit = true;
}