From 9b9840754d625d576c2aea48b4495f53c66edd30 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 11 Dec 2017 01:43:15 +0100 Subject: [PATCH] [d3d11] Added depth-stencil state objects --- src/d3d11/d3d11_depth_stencil.cpp | 89 +++++++++++++++++++++++++++++++ src/d3d11/d3d11_depth_stencil.h | 52 ++++++++++++++++++ src/d3d11/d3d11_device.cpp | 60 +++++++++------------ src/d3d11/d3d11_device.h | 7 ++- src/d3d11/d3d11_state.cpp | 44 +++++++++++++++ src/d3d11/d3d11_state.h | 5 ++ src/d3d11/d3d11_util.cpp | 38 +++++++++++++ src/d3d11/d3d11_util.h | 13 +++++ src/d3d11/meson.build | 2 + 9 files changed, 270 insertions(+), 40 deletions(-) create mode 100644 src/d3d11/d3d11_depth_stencil.cpp create mode 100644 src/d3d11/d3d11_depth_stencil.h create mode 100644 src/d3d11/d3d11_util.cpp create mode 100644 src/d3d11/d3d11_util.h diff --git a/src/d3d11/d3d11_depth_stencil.cpp b/src/d3d11/d3d11_depth_stencil.cpp new file mode 100644 index 000000000..535723912 --- /dev/null +++ b/src/d3d11/d3d11_depth_stencil.cpp @@ -0,0 +1,89 @@ +#include "d3d11_depth_stencil.h" +#include "d3d11_device.h" + +namespace dxvk { + + D3D11DepthStencilState::D3D11DepthStencilState( + D3D11Device* device, + const D3D11_DEPTH_STENCIL_DESC& desc) + : m_device(device), m_desc(desc) { + m_state.enableDepthTest = desc.DepthEnable; + m_state.enableDepthWrite = desc.DepthWriteMask == D3D11_DEPTH_WRITE_MASK_ALL; + m_state.enableDepthBounds = false; // TODO check if this is correct + m_state.enableStencilTest = desc.StencilEnable; + m_state.depthCompareOp = VK_COMPARE_OP_LESS; + m_state.stencilOpFront = DecodeStencilOpState(desc.FrontFace, desc); + m_state.stencilOpBack = DecodeStencilOpState(desc.BackFace, desc); + m_state.depthBoundsMin = 0.0f; + m_state.depthBoundsMax = 1.0f; + + if (desc.DepthEnable) + DecodeCompareOp(desc.DepthFunc); + } + + + D3D11DepthStencilState::~D3D11DepthStencilState() { + + } + + + HRESULT D3D11DepthStencilState::QueryInterface(REFIID riid, void** ppvObject) { + COM_QUERY_IFACE(riid, ppvObject, IUnknown); + COM_QUERY_IFACE(riid, ppvObject, ID3D11DeviceChild); + COM_QUERY_IFACE(riid, ppvObject, ID3D11DepthStencilState); + + Logger::warn("D3D11DepthStencilState::QueryInterface: Unknown interface query"); + return E_NOINTERFACE; + } + + + void D3D11DepthStencilState::GetDevice(ID3D11Device** ppDevice) { + *ppDevice = ref(m_device); + } + + + void D3D11DepthStencilState::GetDesc(D3D11_DEPTH_STENCIL_DESC* pDesc) { + *pDesc = m_desc; + } + + + VkStencilOpState D3D11DepthStencilState::DecodeStencilOpState( + const D3D11_DEPTH_STENCILOP_DESC& stencilDesc, + const D3D11_DEPTH_STENCIL_DESC& desc) const { + VkStencilOpState result; + result.failOp = VK_STENCIL_OP_KEEP; + result.passOp = VK_STENCIL_OP_KEEP; + result.depthFailOp = VK_STENCIL_OP_KEEP; + result.compareOp = VK_COMPARE_OP_ALWAYS; + result.compareMask = desc.StencilReadMask; + result.writeMask = desc.StencilWriteMask; + result.reference = 0; + + if (desc.StencilEnable) { + result.failOp = DecodeStencilOp(stencilDesc.StencilFailOp); + result.passOp = DecodeStencilOp(stencilDesc.StencilPassOp); + result.depthFailOp = DecodeStencilOp(stencilDesc.StencilDepthFailOp); + result.compareOp = DecodeCompareOp(stencilDesc.StencilFunc); + } + + return result; + } + + + VkStencilOp D3D11DepthStencilState::DecodeStencilOp(D3D11_STENCIL_OP op) const { + switch (op) { + case D3D11_STENCIL_OP_KEEP: return VK_STENCIL_OP_KEEP; + case D3D11_STENCIL_OP_ZERO: return VK_STENCIL_OP_ZERO; + case D3D11_STENCIL_OP_REPLACE: return VK_STENCIL_OP_REPLACE; + case D3D11_STENCIL_OP_INCR_SAT: return VK_STENCIL_OP_INCREMENT_AND_CLAMP; + case D3D11_STENCIL_OP_DECR_SAT: return VK_STENCIL_OP_DECREMENT_AND_CLAMP; + case D3D11_STENCIL_OP_INVERT: return VK_STENCIL_OP_INVERT; + case D3D11_STENCIL_OP_INCR: return VK_STENCIL_OP_INCREMENT_AND_WRAP; + case D3D11_STENCIL_OP_DECR: return VK_STENCIL_OP_DECREMENT_AND_WRAP; + } + + Logger::err(str::format("D3D11: Invalid stencil op: ", op)); + return VK_STENCIL_OP_KEEP; + } + +} diff --git a/src/d3d11/d3d11_depth_stencil.h b/src/d3d11/d3d11_depth_stencil.h new file mode 100644 index 000000000..b17697a9b --- /dev/null +++ b/src/d3d11/d3d11_depth_stencil.h @@ -0,0 +1,52 @@ +#pragma once + +#include + +#include "d3d11_device_child.h" +#include "d3d11_util.h" + +namespace dxvk { + + class D3D11Device; + + class D3D11DepthStencilState : public D3D11DeviceChild { + + public: + + using DescType = D3D11_DEPTH_STENCIL_DESC; + + D3D11DepthStencilState( + D3D11Device* device, + const D3D11_DEPTH_STENCIL_DESC& desc); + ~D3D11DepthStencilState(); + + HRESULT QueryInterface( + REFIID riid, + void** ppvObject) final; + + void GetDevice( + ID3D11Device **ppDevice) final; + + void GetDesc( + D3D11_DEPTH_STENCIL_DESC* pDesc) final; + + const DxvkDepthStencilState& GetDXVKDepthStencilState() const { + return m_state; + } + + private: + + D3D11Device* const m_device; + D3D11_DEPTH_STENCIL_DESC m_desc; + DxvkDepthStencilState m_state; + + VkStencilOpState DecodeStencilOpState( + const D3D11_DEPTH_STENCILOP_DESC& stencilDesc, + const D3D11_DEPTH_STENCIL_DESC& desc) const; + + VkStencilOp DecodeStencilOp( + D3D11_STENCIL_OP op) const; + + }; + +} diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index e0623aac2..c4fe30bf5 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -810,8 +810,30 @@ namespace dxvk { HRESULT D3D11Device::CreateDepthStencilState( const D3D11_DEPTH_STENCIL_DESC* pDepthStencilDesc, ID3D11DepthStencilState** ppDepthStencilState) { - Logger::err("D3D11Device::CreateDepthStencilState: Not implemented"); - return E_NOTIMPL; + D3D11_DEPTH_STENCIL_DESC desc; + + if (pDepthStencilDesc != nullptr) { + desc = *pDepthStencilDesc; + } else { + D3D11_DEPTH_STENCILOP_DESC stencilOp; + stencilOp.StencilFunc = D3D11_COMPARISON_ALWAYS; + stencilOp.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + stencilOp.StencilPassOp = D3D11_STENCIL_OP_KEEP; + stencilOp.StencilFailOp = D3D11_STENCIL_OP_KEEP; + + desc.DepthEnable = TRUE; + desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; + desc.DepthFunc = D3D11_COMPARISON_LESS; + desc.StencilEnable = FALSE; + desc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; + desc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; + desc.FrontFace = stencilOp; + desc.BackFace = stencilOp; + } + + if (ppDepthStencilState != nullptr) + *ppDepthStencilState = m_dsStateObjects.Create(this, desc); + return S_OK; } @@ -1448,38 +1470,4 @@ namespace dxvk { } } - - VkCompareOp D3D11Device::DecodeCompareOp( - D3D11_COMPARISON_FUNC mode) const { - switch (mode) { - case D3D11_COMPARISON_NEVER: - return VK_COMPARE_OP_NEVER; - - case D3D11_COMPARISON_LESS: - return VK_COMPARE_OP_LESS; - - case D3D11_COMPARISON_EQUAL: - return VK_COMPARE_OP_EQUAL; - - case D3D11_COMPARISON_LESS_EQUAL: - return VK_COMPARE_OP_LESS_OR_EQUAL; - - case D3D11_COMPARISON_GREATER: - return VK_COMPARE_OP_GREATER; - - case D3D11_COMPARISON_NOT_EQUAL: - return VK_COMPARE_OP_NOT_EQUAL; - - case D3D11_COMPARISON_GREATER_EQUAL: - return VK_COMPARE_OP_GREATER_OR_EQUAL; - - case D3D11_COMPARISON_ALWAYS: - return VK_COMPARE_OP_ALWAYS; - - default: - Logger::err(str::format("D3D11: Unsupported compare op: ", mode)); - return VK_COMPARE_OP_ALWAYS; - } - } - } diff --git a/src/d3d11/d3d11_device.h b/src/d3d11/d3d11_device.h index c60fd1ef6..39d65baf4 100644 --- a/src/d3d11/d3d11_device.h +++ b/src/d3d11/d3d11_device.h @@ -5,6 +5,7 @@ #include "d3d11_interfaces.h" #include "d3d11_state.h" +#include "d3d11_util.h" #include "../util/com/com_private_data.h" @@ -247,7 +248,8 @@ namespace dxvk { std::mutex m_resourceInitMutex; Rc m_resourceInitContext; - D3D11StateObjectSet m_rsStateObjects; + D3D11StateObjectSet m_dsStateObjects; + D3D11StateObjectSet m_rsStateObjects; HRESULT CreateShaderModule( D3D11ShaderModule* pShaderModule, @@ -291,9 +293,6 @@ namespace dxvk { VkSamplerAddressMode DecodeAddressMode( D3D11_TEXTURE_ADDRESS_MODE mode) const; - VkCompareOp DecodeCompareOp( - D3D11_COMPARISON_FUNC mode) const; - }; } diff --git a/src/d3d11/d3d11_state.cpp b/src/d3d11/d3d11_state.cpp index 1925df793..b2d6ea21f 100644 --- a/src/d3d11/d3d11_state.cpp +++ b/src/d3d11/d3d11_state.cpp @@ -2,6 +2,30 @@ namespace dxvk { + size_t D3D11StateDescHash::operator () (const D3D11_DEPTH_STENCILOP_DESC& desc) const { + DxvkHashState hash; + hash.add(desc.StencilFunc); + hash.add(desc.StencilDepthFailOp); + hash.add(desc.StencilPassOp); + hash.add(desc.StencilFailOp); + return hash; + } + + + size_t D3D11StateDescHash::operator () (const D3D11_DEPTH_STENCIL_DESC& desc) const { + DxvkHashState hash; + hash.add(desc.DepthEnable); + hash.add(desc.DepthWriteMask); + hash.add(desc.DepthFunc); + hash.add(desc.StencilEnable); + hash.add(desc.StencilReadMask); + hash.add(desc.StencilWriteMask); + hash.add(this->operator () (desc.FrontFace)); + hash.add(this->operator () (desc.BackFace)); + return hash; + } + + size_t D3D11StateDescHash::operator () (const D3D11_RASTERIZER_DESC& desc) const { DxvkHashState hash; hash.add(desc.FillMode); @@ -18,6 +42,26 @@ namespace dxvk { } + bool D3D11StateDescEqual::operator () (const D3D11_DEPTH_STENCILOP_DESC& a, const D3D11_DEPTH_STENCILOP_DESC& b) const { + return a.StencilFunc == b.StencilFunc + && a.StencilDepthFailOp == b.StencilDepthFailOp + && a.StencilPassOp == b.StencilPassOp + && a.StencilFailOp == b.StencilFailOp; + } + + + bool D3D11StateDescEqual::operator () (const D3D11_DEPTH_STENCIL_DESC& a, const D3D11_DEPTH_STENCIL_DESC& b) const { + return a.DepthEnable == b.DepthEnable + && a.DepthWriteMask == b.DepthWriteMask + && a.DepthFunc == b.DepthFunc + && a.StencilEnable == b.StencilEnable + && a.StencilReadMask == b.StencilReadMask + && a.StencilWriteMask == b.StencilWriteMask + && this->operator () (a.FrontFace, b.FrontFace) + && this->operator () (a.BackFace, b.BackFace); + } + + bool D3D11StateDescEqual::operator () (const D3D11_RASTERIZER_DESC& a, const D3D11_RASTERIZER_DESC& b) const { return a.FillMode == b.FillMode && a.CullMode == b.CullMode diff --git a/src/d3d11/d3d11_state.h b/src/d3d11/d3d11_state.h index c71cba16f..3d9b8b34a 100644 --- a/src/d3d11/d3d11_state.h +++ b/src/d3d11/d3d11_state.h @@ -2,6 +2,7 @@ #include +#include "d3d11_depth_stencil.h" #include "d3d11_rasterizer.h" namespace dxvk { @@ -9,11 +10,15 @@ namespace dxvk { class D3D11Device; struct D3D11StateDescHash { + size_t operator () (const D3D11_DEPTH_STENCILOP_DESC& desc) const; + size_t operator () (const D3D11_DEPTH_STENCIL_DESC& desc) const; size_t operator () (const D3D11_RASTERIZER_DESC& desc) const; }; struct D3D11StateDescEqual { + bool operator () (const D3D11_DEPTH_STENCILOP_DESC& a, const D3D11_DEPTH_STENCILOP_DESC& b) const; + bool operator () (const D3D11_DEPTH_STENCIL_DESC& a, const D3D11_DEPTH_STENCIL_DESC& b) const; bool operator () (const D3D11_RASTERIZER_DESC& a, const D3D11_RASTERIZER_DESC& b) const; }; diff --git a/src/d3d11/d3d11_util.cpp b/src/d3d11/d3d11_util.cpp new file mode 100644 index 000000000..ce30bc9c6 --- /dev/null +++ b/src/d3d11/d3d11_util.cpp @@ -0,0 +1,38 @@ +#include "d3d11_util.h" + +namespace dxvk { + + VkCompareOp DecodeCompareOp( + D3D11_COMPARISON_FUNC mode) { + switch (mode) { + case D3D11_COMPARISON_NEVER: + return VK_COMPARE_OP_NEVER; + + case D3D11_COMPARISON_LESS: + return VK_COMPARE_OP_LESS; + + case D3D11_COMPARISON_EQUAL: + return VK_COMPARE_OP_EQUAL; + + case D3D11_COMPARISON_LESS_EQUAL: + return VK_COMPARE_OP_LESS_OR_EQUAL; + + case D3D11_COMPARISON_GREATER: + return VK_COMPARE_OP_GREATER; + + case D3D11_COMPARISON_NOT_EQUAL: + return VK_COMPARE_OP_NOT_EQUAL; + + case D3D11_COMPARISON_GREATER_EQUAL: + return VK_COMPARE_OP_GREATER_OR_EQUAL; + + case D3D11_COMPARISON_ALWAYS: + return VK_COMPARE_OP_ALWAYS; + + default: + Logger::err(str::format("D3D11: Unsupported compare op: ", mode)); + return VK_COMPARE_OP_ALWAYS; + } + } + +} \ No newline at end of file diff --git a/src/d3d11/d3d11_util.h b/src/d3d11/d3d11_util.h new file mode 100644 index 000000000..0c0d978e3 --- /dev/null +++ b/src/d3d11/d3d11_util.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +#include "d3d11_include.h" + +namespace dxvk { + + VkCompareOp DecodeCompareOp( + D3D11_COMPARISON_FUNC mode); + + +} \ No newline at end of file diff --git a/src/d3d11/meson.build b/src/d3d11/meson.build index f1708f143..ba991110d 100644 --- a/src/d3d11/meson.build +++ b/src/d3d11/meson.build @@ -1,6 +1,7 @@ d3d11_src = [ 'd3d11_buffer.cpp', 'd3d11_context.cpp', + 'd3d11_depth_stencil.cpp', 'd3d11_device.cpp', 'd3d11_enums.cpp', 'd3d11_input_layout.cpp', @@ -11,6 +12,7 @@ d3d11_src = [ 'd3d11_shader.cpp', 'd3d11_state.cpp', 'd3d11_texture.cpp', + 'd3d11_util.cpp', ] d3d11_dll = shared_library('d3d11', d3d11_src,