2017-12-11 01:43:15 +01:00
|
|
|
#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;
|
2018-02-18 11:16:18 +01:00
|
|
|
m_state.enableDepthBounds = false;
|
2017-12-11 01:43:15 +01:00
|
|
|
m_state.enableStencilTest = desc.StencilEnable;
|
2018-02-18 11:16:18 +01:00
|
|
|
m_state.depthCompareOp = DecodeCompareOp(desc.DepthFunc);
|
2017-12-11 01:43:15 +01:00
|
|
|
m_state.stencilOpFront = DecodeStencilOpState(desc.FrontFace, desc);
|
|
|
|
m_state.stencilOpBack = DecodeStencilOpState(desc.BackFace, desc);
|
|
|
|
m_state.depthBoundsMin = 0.0f;
|
|
|
|
m_state.depthBoundsMax = 1.0f;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
D3D11DepthStencilState::~D3D11DepthStencilState() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
HRESULT STDMETHODCALLTYPE D3D11DepthStencilState::QueryInterface(REFIID riid, void** ppvObject) {
|
2018-04-02 12:52:02 +02:00
|
|
|
*ppvObject = nullptr;
|
|
|
|
|
|
|
|
if (riid == __uuidof(IUnknown)
|
|
|
|
|| riid == __uuidof(ID3D11DeviceChild)
|
|
|
|
|| riid == __uuidof(ID3D11DepthStencilState)) {
|
|
|
|
*ppvObject = ref(this);
|
|
|
|
return S_OK;
|
|
|
|
}
|
2017-12-11 01:43:15 +01:00
|
|
|
|
|
|
|
Logger::warn("D3D11DepthStencilState::QueryInterface: Unknown interface query");
|
2018-03-12 12:05:43 +01:00
|
|
|
Logger::warn(str::format(riid));
|
2017-12-11 01:43:15 +01:00
|
|
|
return E_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DepthStencilState::GetDevice(ID3D11Device** ppDevice) {
|
2017-12-11 01:43:15 +01:00
|
|
|
*ppDevice = ref(m_device);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-12 12:50:52 +01:00
|
|
|
void STDMETHODCALLTYPE D3D11DepthStencilState::GetDesc(D3D11_DEPTH_STENCIL_DESC* pDesc) {
|
2017-12-11 01:43:15 +01:00
|
|
|
*pDesc = m_desc;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-11 13:07:27 +01:00
|
|
|
void D3D11DepthStencilState::BindToContext(
|
2017-12-11 14:11:18 +01:00
|
|
|
const Rc<DxvkContext>& ctx) {
|
2017-12-11 13:07:27 +01:00
|
|
|
ctx->setDepthStencilState(m_state);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-03-18 23:32:01 +01:00
|
|
|
D3D11_DEPTH_STENCIL_DESC D3D11DepthStencilState::DefaultDesc() {
|
|
|
|
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;
|
|
|
|
|
|
|
|
D3D11_DEPTH_STENCIL_DESC dstDesc;
|
|
|
|
dstDesc.DepthEnable = TRUE;
|
|
|
|
dstDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
|
|
|
|
dstDesc.DepthFunc = D3D11_COMPARISON_LESS;
|
|
|
|
dstDesc.StencilEnable = FALSE;
|
|
|
|
dstDesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
|
|
|
|
dstDesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
|
|
|
|
dstDesc.FrontFace = stencilOp;
|
|
|
|
dstDesc.BackFace = stencilOp;
|
|
|
|
return dstDesc;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT D3D11DepthStencilState::NormalizeDesc(D3D11_DEPTH_STENCIL_DESC* pDesc) {
|
|
|
|
// TODO validate
|
|
|
|
// TODO clear unused values
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-11 01:43:15 +01:00
|
|
|
VkStencilOpState D3D11DepthStencilState::DecodeStencilOpState(
|
2018-01-16 20:10:49 +01:00
|
|
|
const D3D11_DEPTH_STENCILOP_DESC& StencilDesc,
|
|
|
|
const D3D11_DEPTH_STENCIL_DESC& Desc) const {
|
2017-12-11 01:43:15 +01:00
|
|
|
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;
|
2018-01-16 20:10:49 +01:00
|
|
|
result.compareMask = Desc.StencilReadMask;
|
|
|
|
result.writeMask = Desc.StencilWriteMask;
|
2017-12-11 01:43:15 +01:00
|
|
|
result.reference = 0;
|
|
|
|
|
2018-01-16 20:10:49 +01:00
|
|
|
if (Desc.StencilEnable) {
|
|
|
|
result.failOp = DecodeStencilOp(StencilDesc.StencilFailOp);
|
|
|
|
result.passOp = DecodeStencilOp(StencilDesc.StencilPassOp);
|
|
|
|
result.depthFailOp = DecodeStencilOp(StencilDesc.StencilDepthFailOp);
|
|
|
|
result.compareOp = DecodeCompareOp(StencilDesc.StencilFunc);
|
2017-12-11 01:43:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-01-16 20:10:49 +01:00
|
|
|
VkStencilOp D3D11DepthStencilState::DecodeStencilOp(D3D11_STENCIL_OP Op) const {
|
|
|
|
switch (Op) {
|
2017-12-11 01:43:15 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2018-01-16 20:10:49 +01:00
|
|
|
if (Op != 0)
|
|
|
|
Logger::err(str::format("D3D11: Invalid stencil op: ", Op));
|
2017-12-11 01:43:15 +01:00
|
|
|
return VK_STENCIL_OP_KEEP;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|