diff options
| author | Stenzek <stenzek@gmail.com> | 2017-04-17 23:14:17 +1000 |
|---|---|---|
| committer | Stenzek <stenzek@gmail.com> | 2017-04-18 21:55:22 +1000 |
| commit | 9dc7358395c167925cac18af3c900fe7847da847 (patch) | |
| tree | 0f7705287f1f7c6c25e3deb1feaa98431c15fca1 /Source/Core/VideoBackends/Vulkan/ObjectCache.cpp | |
| parent | 34ad5b457dacf175d30b5521f863b45176374dff (diff) | |
Vulkan: Use BlendingState from VideoCommon
Remove the internal BlendState union. Also fixes Kirby's Return to
Dreamland shadows.
Diffstat (limited to 'Source/Core/VideoBackends/Vulkan/ObjectCache.cpp')
| -rw-r--r-- | Source/Core/VideoBackends/Vulkan/ObjectCache.cpp | 90 |
1 files changed, 76 insertions, 14 deletions
diff --git a/Source/Core/VideoBackends/Vulkan/ObjectCache.cpp b/Source/Core/VideoBackends/Vulkan/ObjectCache.cpp index 1fb083be0f..431728f39e 100644 --- a/Source/Core/VideoBackends/Vulkan/ObjectCache.cpp +++ b/Source/Core/VideoBackends/Vulkan/ObjectCache.cpp @@ -135,33 +135,95 @@ GetVulkanDepthStencilState(const DepthStencilState& state) }; } -static VkPipelineColorBlendAttachmentState GetVulkanAttachmentBlendState(const BlendState& state) +static VkPipelineColorBlendAttachmentState GetVulkanAttachmentBlendState(const BlendingState& state) { - VkPipelineColorBlendAttachmentState vk_state = { - state.blend_enable, // VkBool32 blendEnable - state.src_blend, // VkBlendFactor srcColorBlendFactor - state.dst_blend, // VkBlendFactor dstColorBlendFactor - state.blend_op, // VkBlendOp colorBlendOp - state.src_alpha_blend, // VkBlendFactor srcAlphaBlendFactor - state.dst_alpha_blend, // VkBlendFactor dstAlphaBlendFactor - state.alpha_blend_op, // VkBlendOp alphaBlendOp - state.write_mask // VkColorComponentFlags colorWriteMask - }; + VkPipelineColorBlendAttachmentState vk_state = {}; + vk_state.blendEnable = static_cast<VkBool32>(state.blendenable); + vk_state.colorBlendOp = state.subtract ? VK_BLEND_OP_REVERSE_SUBTRACT : VK_BLEND_OP_ADD; + vk_state.alphaBlendOp = state.subtractAlpha ? VK_BLEND_OP_REVERSE_SUBTRACT : VK_BLEND_OP_ADD; + + if (state.usedualsrc && g_vulkan_context->SupportsDualSourceBlend()) + { + static constexpr std::array<VkBlendFactor, 8> src_factors = { + {VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_DST_COLOR, + VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA, + VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, VK_BLEND_FACTOR_DST_ALPHA, + VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA}}; + static constexpr std::array<VkBlendFactor, 8> dst_factors = { + {VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_SRC_COLOR, + VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA, + VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, VK_BLEND_FACTOR_DST_ALPHA, + VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA}}; + + vk_state.srcColorBlendFactor = src_factors[state.srcfactor]; + vk_state.srcAlphaBlendFactor = src_factors[state.srcfactoralpha]; + vk_state.dstColorBlendFactor = dst_factors[state.dstfactor]; + vk_state.dstAlphaBlendFactor = dst_factors[state.dstfactoralpha]; + } + else + { + static constexpr std::array<VkBlendFactor, 8> src_factors = { + {VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_DST_COLOR, + VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, VK_BLEND_FACTOR_SRC_ALPHA, + VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, VK_BLEND_FACTOR_DST_ALPHA, + VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA}}; + + static constexpr std::array<VkBlendFactor, 8> dst_factors = { + {VK_BLEND_FACTOR_ZERO, VK_BLEND_FACTOR_ONE, VK_BLEND_FACTOR_SRC_COLOR, + VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, VK_BLEND_FACTOR_SRC_ALPHA, + VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, VK_BLEND_FACTOR_DST_ALPHA, + VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA}}; + + vk_state.srcColorBlendFactor = src_factors[state.srcfactor]; + vk_state.srcAlphaBlendFactor = src_factors[state.srcfactoralpha]; + vk_state.dstColorBlendFactor = dst_factors[state.dstfactor]; + vk_state.dstAlphaBlendFactor = dst_factors[state.dstfactoralpha]; + } + + if (state.colorupdate) + { + vk_state.colorWriteMask = + VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT; + } + else + { + vk_state.colorWriteMask = 0; + } + + if (state.alphaupdate) + vk_state.colorWriteMask |= VK_COLOR_COMPONENT_A_BIT; return vk_state; } static VkPipelineColorBlendStateCreateInfo -GetVulkanColorBlendState(const BlendState& state, +GetVulkanColorBlendState(const BlendingState& state, const VkPipelineColorBlendAttachmentState* attachments, uint32_t num_attachments) { + static constexpr std::array<VkLogicOp, 16> vk_logic_ops = { + {VK_LOGIC_OP_CLEAR, VK_LOGIC_OP_AND, VK_LOGIC_OP_AND_REVERSE, VK_LOGIC_OP_COPY, + VK_LOGIC_OP_AND_INVERTED, VK_LOGIC_OP_NO_OP, VK_LOGIC_OP_XOR, VK_LOGIC_OP_OR, + VK_LOGIC_OP_NOR, VK_LOGIC_OP_EQUIVALENT, VK_LOGIC_OP_INVERT, VK_LOGIC_OP_OR_REVERSE, + VK_LOGIC_OP_COPY_INVERTED, VK_LOGIC_OP_OR_INVERTED, VK_LOGIC_OP_NAND, VK_LOGIC_OP_SET}}; + + VkBool32 vk_logic_op_enable = static_cast<VkBool32>(state.logicopenable); + if (vk_logic_op_enable && !g_vulkan_context->SupportsLogicOps()) + { + // At the time of writing, Adreno and Mali drivers didn't support logic ops. + // The "emulation" through blending path has been removed, so just disable it completely. + // These drivers don't support dual-source blend either, so issues are to be expected. + vk_logic_op_enable = VK_FALSE; + } + + VkLogicOp vk_logic_op = vk_logic_op_enable ? vk_logic_ops[state.logicmode] : VK_LOGIC_OP_CLEAR; + VkPipelineColorBlendStateCreateInfo vk_state = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType nullptr, // const void* pNext 0, // VkPipelineColorBlendStateCreateFlags flags - state.logic_op_enable, // VkBool32 logicOpEnable - state.logic_op, // VkLogicOp logicOp + vk_logic_op_enable, // VkBool32 logicOpEnable + vk_logic_op, // VkLogicOp logicOp num_attachments, // uint32_t attachmentCount attachments, // const VkPipelineColorBlendAttachmentState* pAttachments {1.0f, 1.0f, 1.0f, 1.0f} // float blendConstants[4] |
