diff --git a/src/backend/CMakeLists.txt b/src/backend/CMakeLists.txt index 593fe0d363..d362acc113 100644 --- a/src/backend/CMakeLists.txt +++ b/src/backend/CMakeLists.txt @@ -226,6 +226,8 @@ if (NXT_ENABLE_D3D12) ${D3D12_DIR}/CommandBufferD3D12.h ${D3D12_DIR}/ComputePipelineD3D12.cpp ${D3D12_DIR}/ComputePipelineD3D12.h + ${D3D12_DIR}/DepthStencilStateD3D12.cpp + ${D3D12_DIR}/DepthStencilStateD3D12.h ${D3D12_DIR}/DescriptorHeapAllocator.cpp ${D3D12_DIR}/DescriptorHeapAllocator.h ${D3D12_DIR}/D3D12Backend.cpp diff --git a/src/backend/d3d12/D3D12Backend.cpp b/src/backend/d3d12/D3D12Backend.cpp index 04b45fa85b..9186746f31 100644 --- a/src/backend/d3d12/D3D12Backend.cpp +++ b/src/backend/d3d12/D3D12Backend.cpp @@ -23,6 +23,7 @@ #include "backend/d3d12/DescriptorHeapAllocator.h" #include "backend/d3d12/FramebufferD3D12.h" #include "backend/d3d12/InputStateD3D12.h" +#include "backend/d3d12/DepthStencilStateD3D12.h" #include "backend/d3d12/PipelineLayoutD3D12.h" #include "backend/d3d12/QueueD3D12.h" #include "backend/d3d12/RenderPipelineD3D12.h" @@ -257,12 +258,6 @@ namespace d3d12 { return new TextureView(builder); } - // DepthStencilState - - DepthStencilState::DepthStencilState(Device* device, DepthStencilStateBuilder* builder) - : DepthStencilStateBase(builder), device(device) { - } - // RenderPass RenderPass::RenderPass(Device* device, RenderPassBuilder* builder) diff --git a/src/backend/d3d12/D3D12Backend.h b/src/backend/d3d12/D3D12Backend.h index fab0af7153..a4e4eee6d2 100644 --- a/src/backend/d3d12/D3D12Backend.h +++ b/src/backend/d3d12/D3D12Backend.h @@ -146,14 +146,6 @@ namespace d3d12 { } pendingCommands; }; - class DepthStencilState : public DepthStencilStateBase { - public: - DepthStencilState(Device* device, DepthStencilStateBuilder* builder); - - private: - Device* device; - }; - class RenderPass : public RenderPassBase { public: RenderPass(Device* device, RenderPassBuilder* builder); diff --git a/src/backend/d3d12/DepthStencilStateD3D12.cpp b/src/backend/d3d12/DepthStencilStateD3D12.cpp new file mode 100644 index 0000000000..1e414b3a2e --- /dev/null +++ b/src/backend/d3d12/DepthStencilStateD3D12.cpp @@ -0,0 +1,101 @@ +// Copyright 2017 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/d3d12/DepthStencilStateD3D12.h" + +#include "common/BitSetIterator.h" + +namespace backend { +namespace d3d12 { + + static D3D12_STENCIL_OP StencilOp(nxt::StencilOperation op) { + switch (op) { + case nxt::StencilOperation::Keep: + return D3D12_STENCIL_OP_KEEP; + case nxt::StencilOperation::Zero: + return D3D12_STENCIL_OP_ZERO; + case nxt::StencilOperation::Replace: + return D3D12_STENCIL_OP_REPLACE; + case nxt::StencilOperation::IncrementClamp: + return D3D12_STENCIL_OP_INCR_SAT; + case nxt::StencilOperation::DecrementClamp: + return D3D12_STENCIL_OP_DECR_SAT; + case nxt::StencilOperation::Invert: + return D3D12_STENCIL_OP_INVERT; + case nxt::StencilOperation::IncrementWrap: + return D3D12_STENCIL_OP_INCR; + case nxt::StencilOperation::DecrementWrap: + return D3D12_STENCIL_OP_DECR; + default: + UNREACHABLE(); + } + } + + static D3D12_COMPARISON_FUNC ComparisonFunc(nxt::CompareFunction func) { + switch (func) + { + case nxt::CompareFunction::Always: + return D3D12_COMPARISON_FUNC_ALWAYS; + case nxt::CompareFunction::Equal: + return D3D12_COMPARISON_FUNC_EQUAL; + case nxt::CompareFunction::Greater: + return D3D12_COMPARISON_FUNC_GREATER; + case nxt::CompareFunction::GreaterEqual: + return D3D12_COMPARISON_FUNC_GREATER_EQUAL; + case nxt::CompareFunction::Less: + return D3D12_COMPARISON_FUNC_LESS; + case nxt::CompareFunction::LessEqual: + return D3D12_COMPARISON_FUNC_LESS_EQUAL; + case nxt::CompareFunction::Never: + return D3D12_COMPARISON_FUNC_NEVER; + case nxt::CompareFunction::NotEqual: + return D3D12_COMPARISON_FUNC_NOT_EQUAL; + default: + UNREACHABLE(); + } + } + + static D3D12_DEPTH_STENCILOP_DESC StencilOpDesc(backend::DepthStencilStateBase::StencilFaceInfo faceInfo) { + D3D12_DEPTH_STENCILOP_DESC desc; + + desc.StencilFailOp = StencilOp(faceInfo.stencilFail); + desc.StencilDepthFailOp = StencilOp(faceInfo.depthFail); + desc.StencilPassOp = StencilOp(faceInfo.depthStencilPass); + desc.StencilFunc = ComparisonFunc(faceInfo.compareFunction); + + return desc; + } + + DepthStencilState::DepthStencilState(Device* device, DepthStencilStateBuilder* builder) + : DepthStencilStateBase(builder), device(device) { + + // If you have anything other than Never, then enable depth testing + depthStencilDescriptor.DepthEnable = TRUE; // (GetDepth().compareFunction == nxt::CompareFunction::Never) ? FALSE : TRUE; + depthStencilDescriptor.DepthWriteMask = GetDepth().depthWriteEnabled ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO; + depthStencilDescriptor.DepthFunc = ComparisonFunc(GetDepth().compareFunction); + + depthStencilDescriptor.StencilEnable = StencilTestEnabled() ? TRUE : FALSE; + depthStencilDescriptor.StencilReadMask = (UINT8)GetStencil().readMask; + depthStencilDescriptor.StencilWriteMask = (UINT8)GetStencil().writeMask; + + depthStencilDescriptor.FrontFace = StencilOpDesc(GetStencil().front); + depthStencilDescriptor.BackFace = StencilOpDesc(GetStencil().back); + } + + const D3D12_DEPTH_STENCIL_DESC& DepthStencilState::GetD3D12DepthStencilDescriptor() const { + return depthStencilDescriptor; + } + +} +} diff --git a/src/backend/d3d12/DepthStencilStateD3D12.h b/src/backend/d3d12/DepthStencilStateD3D12.h new file mode 100644 index 0000000000..76c6c5afd2 --- /dev/null +++ b/src/backend/d3d12/DepthStencilStateD3D12.h @@ -0,0 +1,41 @@ +// Copyright 2017 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_D3D12_DEPTHSTENCILSTATED3D12_H_ +#define BACKEND_D3D12_DEPTHSTENCILSTATED3D12_H_ + +#include "backend/DepthStencilState.h" + +#include "backend/d3d12/d3d12_platform.h" + +namespace backend { +namespace d3d12 { + + class Device; + + class DepthStencilState : public DepthStencilStateBase { + public: + DepthStencilState(Device* device, DepthStencilStateBuilder* builder); + + const D3D12_DEPTH_STENCIL_DESC& GetD3D12DepthStencilDescriptor() const; + + private: + Device* device; + D3D12_DEPTH_STENCIL_DESC depthStencilDescriptor; + }; + +} +} + +#endif // BACKEND_D3D12_DEPTHSTENCILSTATED3D12_H_ diff --git a/src/backend/d3d12/GeneratedCodeIncludes.h b/src/backend/d3d12/GeneratedCodeIncludes.h index 2f547ef89b..ed72d6831e 100644 --- a/src/backend/d3d12/GeneratedCodeIncludes.h +++ b/src/backend/d3d12/GeneratedCodeIncludes.h @@ -20,6 +20,7 @@ #include "backend/d3d12/ComputePipelineD3D12.h" #include "backend/d3d12/FramebufferD3D12.h" #include "backend/d3d12/InputStateD3D12.h" +#include "backend/d3d12/DepthStencilStateD3D12.h" #include "backend/d3d12/PipelineLayoutD3D12.h" #include "backend/d3d12/QueueD3D12.h" #include "backend/d3d12/RenderPipelineD3D12.h" diff --git a/src/backend/d3d12/RenderPipelineD3D12.cpp b/src/backend/d3d12/RenderPipelineD3D12.cpp index 245b5076e0..c7d2052a38 100644 --- a/src/backend/d3d12/RenderPipelineD3D12.cpp +++ b/src/backend/d3d12/RenderPipelineD3D12.cpp @@ -16,6 +16,7 @@ #include "backend/d3d12/D3D12Backend.h" #include "backend/d3d12/InputStateD3D12.h" +#include "backend/d3d12/DepthStencilStateD3D12.h" #include "backend/d3d12/ShaderModuleD3D12.h" #include "backend/d3d12/PipelineLayoutD3D12.h" #include "common/Assert.h" @@ -154,8 +155,9 @@ namespace d3d12 { descriptor.BlendState.RenderTarget[0].LogicOp = D3D12_LOGIC_OP_NOOP; descriptor.BlendState.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; - descriptor.DepthStencilState.DepthEnable = false; - descriptor.DepthStencilState.StencilEnable = false; + DepthStencilState* depthStencilState = ToBackend(GetDepthStencilState()); + descriptor.DepthStencilState = depthStencilState->GetD3D12DepthStencilDescriptor(); + descriptor.SampleMask = UINT_MAX; descriptor.PrimitiveTopologyType = D3D12PrimitiveTopologyType(GetPrimitiveTopology()); descriptor.NumRenderTargets = 1; diff --git a/src/tests/end2end/DepthStencilStateTests.cpp b/src/tests/end2end/DepthStencilStateTests.cpp index 38972ef4d2..55bce41076 100644 --- a/src/tests/end2end/DepthStencilStateTests.cpp +++ b/src/tests/end2end/DepthStencilStateTests.cpp @@ -522,4 +522,4 @@ TEST_P(DepthStencilStateTest, StencilDepthPass) { 2); // Replace the stencil on stencil pass, depth pass, so it should be 2 } -NXT_INSTANTIATE_TEST(DepthStencilStateTest, MetalBackend, OpenGLBackend) +NXT_INSTANTIATE_TEST(DepthStencilStateTest, MetalBackend, OpenGLBackend, D3D12Backend)