From 08b3cbf5bfdab0b8baaa0066a408180abe85b22e Mon Sep 17 00:00:00 2001 From: Corentin Wallez Date: Mon, 5 Feb 2018 14:04:46 -0500 Subject: [PATCH] Vulkan: Implement DepthStencilState --- src/backend/CMakeLists.txt | 2 + src/backend/vulkan/DepthStencilStateVk.cpp | 112 +++++++++++++++++++++ src/backend/vulkan/DepthStencilStateVk.h | 39 +++++++ src/backend/vulkan/GeneratedCodeIncludes.h | 1 + src/backend/vulkan/RenderPipelineVk.cpp | 29 +----- src/backend/vulkan/VulkanBackend.cpp | 1 + src/backend/vulkan/VulkanBackend.h | 3 +- 7 files changed, 158 insertions(+), 29 deletions(-) create mode 100644 src/backend/vulkan/DepthStencilStateVk.cpp create mode 100644 src/backend/vulkan/DepthStencilStateVk.h diff --git a/src/backend/CMakeLists.txt b/src/backend/CMakeLists.txt index 19a3147d44..f05f88061b 100644 --- a/src/backend/CMakeLists.txt +++ b/src/backend/CMakeLists.txt @@ -300,6 +300,8 @@ if (NXT_ENABLE_VULKAN) ${VULKAN_DIR}/BufferVk.h ${VULKAN_DIR}/CommandBufferVk.cpp ${VULKAN_DIR}/CommandBufferVk.h + ${VULKAN_DIR}/DepthStencilStateVk.cpp + ${VULKAN_DIR}/DepthStencilStateVk.h ${VULKAN_DIR}/FencedDeleter.cpp ${VULKAN_DIR}/FencedDeleter.h ${VULKAN_DIR}/FramebufferVk.cpp diff --git a/src/backend/vulkan/DepthStencilStateVk.cpp b/src/backend/vulkan/DepthStencilStateVk.cpp new file mode 100644 index 0000000000..bbdb9d4842 --- /dev/null +++ b/src/backend/vulkan/DepthStencilStateVk.cpp @@ -0,0 +1,112 @@ +// Copyright 2018 The NXT Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "backend/vulkan/DepthStencilStateVk.h" + +#include "common/Assert.h" + +namespace backend { namespace vulkan { + + namespace { + VkCompareOp VulkanCompareOp(nxt::CompareFunction op) { + switch (op) { + case nxt::CompareFunction::Always: + return VK_COMPARE_OP_ALWAYS; + case nxt::CompareFunction::Equal: + return VK_COMPARE_OP_EQUAL; + case nxt::CompareFunction::Greater: + return VK_COMPARE_OP_GREATER; + case nxt::CompareFunction::GreaterEqual: + return VK_COMPARE_OP_GREATER_OR_EQUAL; + case nxt::CompareFunction::Less: + return VK_COMPARE_OP_LESS; + case nxt::CompareFunction::LessEqual: + return VK_COMPARE_OP_LESS_OR_EQUAL; + case nxt::CompareFunction::Never: + return VK_COMPARE_OP_NEVER; + case nxt::CompareFunction::NotEqual: + return VK_COMPARE_OP_NOT_EQUAL; + default: + UNREACHABLE(); + } + } + + VkStencilOp VulkanStencilOp(nxt::StencilOperation op) { + switch (op) { + case nxt::StencilOperation::Keep: + return VK_STENCIL_OP_KEEP; + case nxt::StencilOperation::Zero: + return VK_STENCIL_OP_ZERO; + case nxt::StencilOperation::Replace: + return VK_STENCIL_OP_REPLACE; + case nxt::StencilOperation::IncrementClamp: + return VK_STENCIL_OP_INCREMENT_AND_CLAMP; + case nxt::StencilOperation::DecrementClamp: + return VK_STENCIL_OP_DECREMENT_AND_CLAMP; + case nxt::StencilOperation::Invert: + return VK_STENCIL_OP_INVERT; + case nxt::StencilOperation::IncrementWrap: + return VK_STENCIL_OP_INCREMENT_AND_WRAP; + case nxt::StencilOperation::DecrementWrap: + return VK_STENCIL_OP_DECREMENT_AND_WRAP; + default: + UNREACHABLE(); + } + } + + } // anonymous namespace + + DepthStencilState::DepthStencilState(DepthStencilStateBuilder* builder) + : DepthStencilStateBase(builder) { + mCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; + mCreateInfo.pNext = nullptr; + mCreateInfo.flags = 0; + + const auto& depth = GetDepth(); + mCreateInfo.depthTestEnable = VK_TRUE; + mCreateInfo.depthWriteEnable = depth.depthWriteEnabled ? VK_TRUE : VK_FALSE; + mCreateInfo.depthCompareOp = VulkanCompareOp(depth.compareFunction); + mCreateInfo.depthBoundsTestEnable = false; + mCreateInfo.minDepthBounds = 0.0f; + mCreateInfo.maxDepthBounds = 0.0f; + + const auto& stencil = GetStencil(); + mCreateInfo.stencilTestEnable = StencilTestEnabled() ? VK_TRUE : VK_FALSE; + + mCreateInfo.front.failOp = VulkanStencilOp(stencil.front.stencilFail); + mCreateInfo.front.passOp = VulkanStencilOp(stencil.front.depthStencilPass); + mCreateInfo.front.depthFailOp = VulkanStencilOp(stencil.front.depthFail); + mCreateInfo.front.compareOp = VulkanCompareOp(stencil.front.compareFunction); + + mCreateInfo.back.failOp = VulkanStencilOp(stencil.back.stencilFail); + mCreateInfo.back.passOp = VulkanStencilOp(stencil.back.depthStencilPass); + mCreateInfo.back.depthFailOp = VulkanStencilOp(stencil.back.depthFail); + mCreateInfo.back.compareOp = VulkanCompareOp(stencil.back.compareFunction); + + // NXT doesn't have separate front and back stencil masks. + mCreateInfo.front.compareMask = stencil.readMask; + mCreateInfo.back.compareMask = stencil.readMask; + mCreateInfo.front.writeMask = stencil.writeMask; + mCreateInfo.back.writeMask = stencil.writeMask; + + // The stencil reference is always dynamic + mCreateInfo.front.reference = 0; + mCreateInfo.back.reference = 0; + } + + const VkPipelineDepthStencilStateCreateInfo* DepthStencilState::GetCreateInfo() const { + return &mCreateInfo; + } + +}} // namespace backend::vulkan diff --git a/src/backend/vulkan/DepthStencilStateVk.h b/src/backend/vulkan/DepthStencilStateVk.h new file mode 100644 index 0000000000..b2714fbf8a --- /dev/null +++ b/src/backend/vulkan/DepthStencilStateVk.h @@ -0,0 +1,39 @@ +// Copyright 2018 The NXT Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef BACKEND_VULKAN_DEPTHSTENCILSTATEVK_H_ +#define BACKEND_VULKAN_DEPTHSTENCILSTATEVK_H_ + +#include "backend/DepthStencilState.h" + +#include "common/vulkan_platform.h" + +namespace backend { namespace vulkan { + + class Device; + + // Pre-computes the depth-stencil configuration to give to a graphics pipeline create info. + class DepthStencilState : public DepthStencilStateBase { + public: + DepthStencilState(DepthStencilStateBuilder* builder); + + const VkPipelineDepthStencilStateCreateInfo* GetCreateInfo() const; + + private: + VkPipelineDepthStencilStateCreateInfo mCreateInfo; + }; + +}} // namespace backend::vulkan + +#endif // BACKEND_VULKAN_DEPTHSTENCILSTATEVK_H_ diff --git a/src/backend/vulkan/GeneratedCodeIncludes.h b/src/backend/vulkan/GeneratedCodeIncludes.h index c3b89182ee..cbefa5b78c 100644 --- a/src/backend/vulkan/GeneratedCodeIncludes.h +++ b/src/backend/vulkan/GeneratedCodeIncludes.h @@ -17,6 +17,7 @@ #include "backend/vulkan/BlendStateVk.h" #include "backend/vulkan/BufferVk.h" #include "backend/vulkan/CommandBufferVk.h" +#include "backend/vulkan/DepthStencilStateVk.h" #include "backend/vulkan/FramebufferVk.h" #include "backend/vulkan/InputStateVk.h" #include "backend/vulkan/PipelineLayoutVk.h" diff --git a/src/backend/vulkan/RenderPipelineVk.cpp b/src/backend/vulkan/RenderPipelineVk.cpp index 8227993acc..7fba8e84e5 100644 --- a/src/backend/vulkan/RenderPipelineVk.cpp +++ b/src/backend/vulkan/RenderPipelineVk.cpp @@ -15,6 +15,7 @@ #include "backend/vulkan/RenderPipelineVk.h" #include "backend/vulkan/BlendStateVk.h" +#include "backend/vulkan/DepthStencilStateVk.h" #include "backend/vulkan/FencedDeleter.h" #include "backend/vulkan/InputStateVk.h" #include "backend/vulkan/PipelineLayoutVk.h" @@ -130,32 +131,6 @@ namespace backend { namespace vulkan { multisample.alphaToCoverageEnable = VK_FALSE; multisample.alphaToOneEnable = VK_FALSE; - VkPipelineDepthStencilStateCreateInfo depthStencil; - depthStencil.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; - depthStencil.pNext = nullptr; - depthStencil.flags = 0; - depthStencil.depthTestEnable = VK_TRUE; - depthStencil.depthWriteEnable = VK_TRUE; - depthStencil.depthCompareOp = VK_COMPARE_OP_LESS; - depthStencil.depthBoundsTestEnable = VK_FALSE; - depthStencil.stencilTestEnable = VK_FALSE; - depthStencil.front.failOp = VK_STENCIL_OP_KEEP; - depthStencil.front.passOp = VK_STENCIL_OP_KEEP; - depthStencil.front.depthFailOp = VK_STENCIL_OP_KEEP; - depthStencil.front.compareOp = VK_COMPARE_OP_NEVER; - depthStencil.front.compareMask = 0; - depthStencil.front.writeMask = 0; - depthStencil.front.reference = 0; - depthStencil.back.failOp = VK_STENCIL_OP_KEEP; - depthStencil.back.passOp = VK_STENCIL_OP_KEEP; - depthStencil.back.depthFailOp = VK_STENCIL_OP_KEEP; - depthStencil.back.compareOp = VK_COMPARE_OP_NEVER; - depthStencil.back.compareMask = 0; - depthStencil.back.writeMask = 0; - depthStencil.back.reference = 0; - depthStencil.minDepthBounds = 0.0f; - depthStencil.maxDepthBounds = 0.0f; - // Initialize the "blend state info" that will be chained in the "create info" from the data // pre-computed in the BlendState const auto& subpassInfo = GetRenderPass()->GetSubpassInfo(GetSubPass()); @@ -211,7 +186,7 @@ namespace backend { namespace vulkan { createInfo.pViewportState = &viewport; createInfo.pRasterizationState = &rasterization; createInfo.pMultisampleState = &multisample; - createInfo.pDepthStencilState = &depthStencil; + createInfo.pDepthStencilState = ToBackend(GetDepthStencilState())->GetCreateInfo(); createInfo.pColorBlendState = &colorBlend; createInfo.pDynamicState = &dynamic; createInfo.layout = ToBackend(GetLayout())->GetHandle(); diff --git a/src/backend/vulkan/VulkanBackend.cpp b/src/backend/vulkan/VulkanBackend.cpp index 2736aa46a1..cc597a4138 100644 --- a/src/backend/vulkan/VulkanBackend.cpp +++ b/src/backend/vulkan/VulkanBackend.cpp @@ -21,6 +21,7 @@ #include "backend/vulkan/BufferUploader.h" #include "backend/vulkan/BufferVk.h" #include "backend/vulkan/CommandBufferVk.h" +#include "backend/vulkan/DepthStencilStateVk.h" #include "backend/vulkan/FencedDeleter.h" #include "backend/vulkan/FramebufferVk.h" #include "backend/vulkan/InputStateVk.h" diff --git a/src/backend/vulkan/VulkanBackend.h b/src/backend/vulkan/VulkanBackend.h index d73381f50e..f71a9b0158 100644 --- a/src/backend/vulkan/VulkanBackend.h +++ b/src/backend/vulkan/VulkanBackend.h @@ -18,7 +18,6 @@ #include "nxt/nxtcpp.h" #include "backend/ComputePipeline.h" -#include "backend/DepthStencilState.h" #include "backend/Device.h" #include "backend/Queue.h" #include "backend/Sampler.h" @@ -40,7 +39,7 @@ namespace backend { namespace vulkan { using BufferView = BufferViewBase; class CommandBuffer; using ComputePipeline = ComputePipelineBase; - using DepthStencilState = DepthStencilStateBase; + class DepthStencilState; class Device; class Framebuffer; class InputState;