From f2381ac4eb99e019b9e8db873a3a64c53b0ac60a Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 11 Aug 2018 22:11:18 +0200 Subject: [PATCH] [d3d10] Implement D3D10BlendState --- src/d3d10/d3d10_blend.cpp | 81 ++++++++++++++++++++++++++++++++++++++ src/d3d10/d3d10_blend.h | 58 +++++++++++++++++++++++++++ src/d3d10/d3d10_device.cpp | 46 ++++++++++++++++++++-- src/d3d11/d3d11_blend.cpp | 9 ++++- src/d3d11/d3d11_blend.h | 12 ++++-- src/d3d11/meson.build | 1 + 6 files changed, 199 insertions(+), 8 deletions(-) create mode 100644 src/d3d10/d3d10_blend.cpp create mode 100644 src/d3d10/d3d10_blend.h diff --git a/src/d3d10/d3d10_blend.cpp b/src/d3d10/d3d10_blend.cpp new file mode 100644 index 000000000..3dc637d1d --- /dev/null +++ b/src/d3d10/d3d10_blend.cpp @@ -0,0 +1,81 @@ +#include "d3d10_blend.h" + +#include "../d3d11/d3d11_blend.h" +#include "../d3d11/d3d11_device.h" + +namespace dxvk { + + HRESULT STDMETHODCALLTYPE D3D10BlendState::QueryInterface( + REFIID riid, + void** ppvObject) { + return m_d3d11->QueryInterface(riid, ppvObject); + } + + + ULONG STDMETHODCALLTYPE D3D10BlendState::AddRef() { + return m_d3d11->AddRef(); + } + + + ULONG STDMETHODCALLTYPE D3D10BlendState::Release() { + return m_d3d11->Release(); + } + + + void STDMETHODCALLTYPE D3D10BlendState::GetDevice( + ID3D10Device** ppDevice) { + GetD3D10Device(m_d3d11, ppDevice); + } + + + HRESULT STDMETHODCALLTYPE D3D10BlendState::GetPrivateData( + REFGUID guid, + UINT* pDataSize, + void* pData) { + return m_d3d11->GetPrivateData(guid, pDataSize, pData); + } + + + HRESULT STDMETHODCALLTYPE D3D10BlendState::SetPrivateData( + REFGUID guid, + UINT DataSize, + const void* pData) { + return m_d3d11->SetPrivateData(guid, DataSize, pData); + } + + + HRESULT STDMETHODCALLTYPE D3D10BlendState::SetPrivateDataInterface( + REFGUID guid, + const IUnknown* pData) { + return m_d3d11->SetPrivateDataInterface(guid, pData); + } + + + void STDMETHODCALLTYPE D3D10BlendState::GetDesc( + D3D10_BLEND_DESC* pDesc) { + D3D11_BLEND_DESC d3d11Desc; + m_d3d11->GetDesc(&d3d11Desc); + + pDesc->AlphaToCoverageEnable = d3d11Desc.AlphaToCoverageEnable; + pDesc->SrcBlend = D3D10_BLEND (d3d11Desc.RenderTarget[0].SrcBlend); + pDesc->DestBlend = D3D10_BLEND (d3d11Desc.RenderTarget[0].DestBlend); + pDesc->BlendOp = D3D10_BLEND_OP(d3d11Desc.RenderTarget[0].BlendOp); + pDesc->SrcBlendAlpha = D3D10_BLEND (d3d11Desc.RenderTarget[0].SrcBlendAlpha); + pDesc->DestBlendAlpha = D3D10_BLEND (d3d11Desc.RenderTarget[0].DestBlendAlpha); + pDesc->BlendOpAlpha = D3D10_BLEND_OP(d3d11Desc.RenderTarget[0].BlendOpAlpha); + + for (uint32_t i = 0; i < 8; i++) { + uint32_t srcId = d3d11Desc.IndependentBlendEnable ? i : 0; + pDesc->BlendEnable[i] = d3d11Desc.RenderTarget[srcId].BlendEnable; + pDesc->RenderTargetWriteMask[i] = d3d11Desc.RenderTarget[srcId].RenderTargetWriteMask; + } + } + + + void STDMETHODCALLTYPE D3D10BlendState::GetDesc1( + D3D10_BLEND_DESC1* pDesc) { + static_assert(sizeof(D3D10_BLEND_DESC1) == sizeof(D3D11_BLEND_DESC)); + m_d3d11->GetDesc(reinterpret_cast(pDesc)); + } + +} \ No newline at end of file diff --git a/src/d3d10/d3d10_blend.h b/src/d3d10/d3d10_blend.h new file mode 100644 index 000000000..d5d201d7b --- /dev/null +++ b/src/d3d10/d3d10_blend.h @@ -0,0 +1,58 @@ +#pragma once + +#include "d3d10_util.h" + +namespace dxvk { + + class D3D11BlendState; + class D3D11Device; + + class D3D10BlendState : public ID3D10BlendState1 { + + public: + + D3D10BlendState(D3D11BlendState* pParent) + : m_d3d11(pParent) { } + + HRESULT STDMETHODCALLTYPE QueryInterface( + REFIID riid, + void** ppvObject); + + ULONG STDMETHODCALLTYPE AddRef(); + + ULONG STDMETHODCALLTYPE Release(); + + void STDMETHODCALLTYPE GetDevice( + ID3D10Device** ppDevice); + + HRESULT STDMETHODCALLTYPE GetPrivateData( + REFGUID guid, + UINT* pDataSize, + void* pData); + + HRESULT STDMETHODCALLTYPE SetPrivateData( + REFGUID guid, + UINT DataSize, + const void* pData); + + HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( + REFGUID guid, + const IUnknown* pData); + + void STDMETHODCALLTYPE GetDesc( + D3D10_BLEND_DESC* pDesc); + + void STDMETHODCALLTYPE GetDesc1( + D3D10_BLEND_DESC1* pDesc); + + D3D11BlendState* GetD3D11Iface() { + return m_d3d11; + } + + private: + + D3D11BlendState* m_d3d11; + + }; + +} \ No newline at end of file diff --git a/src/d3d10/d3d10_device.cpp b/src/d3d10/d3d10_device.cpp index 0e52c6a29..dc2192bad 100644 --- a/src/d3d10/d3d10_device.cpp +++ b/src/d3d10/d3d10_device.cpp @@ -319,16 +319,54 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE D3D10Device::CreateBlendState( const D3D10_BLEND_DESC* pBlendStateDesc, ID3D10BlendState** ppBlendState) { - Logger::err("D3D10Device::CreateBlendState: Not implemented"); - return E_NOTIMPL; + InitReturnPtr(ppBlendState); + + D3D11_BLEND_DESC d3d11Desc; + d3d11Desc.AlphaToCoverageEnable = pBlendStateDesc->AlphaToCoverageEnable; + d3d11Desc.IndependentBlendEnable = TRUE; + + for (uint32_t i = 0; i < 8; i++) { + d3d11Desc.RenderTarget[i].BlendEnable = pBlendStateDesc->BlendEnable[i]; + d3d11Desc.RenderTarget[i].SrcBlend = D3D11_BLEND (pBlendStateDesc->SrcBlend); + d3d11Desc.RenderTarget[i].DestBlend = D3D11_BLEND (pBlendStateDesc->DestBlend); + d3d11Desc.RenderTarget[i].BlendOp = D3D11_BLEND_OP(pBlendStateDesc->BlendOp); + d3d11Desc.RenderTarget[i].SrcBlendAlpha = D3D11_BLEND (pBlendStateDesc->SrcBlendAlpha); + d3d11Desc.RenderTarget[i].DestBlendAlpha = D3D11_BLEND (pBlendStateDesc->DestBlendAlpha); + d3d11Desc.RenderTarget[i].BlendOpAlpha = D3D11_BLEND_OP(pBlendStateDesc->BlendOpAlpha); + d3d11Desc.RenderTarget[i].RenderTargetWriteMask = pBlendStateDesc->RenderTargetWriteMask[i]; + } + + ID3D11BlendState* d3d11BlendState = nullptr; + HRESULT hr = m_device->CreateBlendState(&d3d11Desc, + ppBlendState ? &d3d11BlendState : nullptr); + + if (FAILED(hr)) + return hr; + + if (ppBlendState != nullptr) { + *ppBlendState = static_cast(d3d11BlendState)->GetD3D10Iface(); + return S_OK; + } return S_FALSE; } HRESULT STDMETHODCALLTYPE D3D10Device::CreateBlendState1( const D3D10_BLEND_DESC1* pBlendStateDesc, ID3D10BlendState1** ppBlendState) { - Logger::err("D3D10Device::CreateBlendState1: Not implemented"); - return E_NOTIMPL; + InitReturnPtr(ppBlendState); + + ID3D11BlendState* d3d11BlendState = nullptr; + HRESULT hr = m_device->CreateBlendState( + reinterpret_cast(pBlendStateDesc), + ppBlendState ? &d3d11BlendState : nullptr); + + if (FAILED(hr)) + return hr; + + if (ppBlendState != nullptr) { + *ppBlendState = static_cast(d3d11BlendState)->GetD3D10Iface(); + return S_OK; + } return S_FALSE; } diff --git a/src/d3d11/d3d11_blend.cpp b/src/d3d11/d3d11_blend.cpp index accfd7302..d83d6616f 100644 --- a/src/d3d11/d3d11_blend.cpp +++ b/src/d3d11/d3d11_blend.cpp @@ -6,7 +6,7 @@ namespace dxvk { D3D11BlendState::D3D11BlendState( D3D11Device* device, const D3D11_BLEND_DESC1& desc) - : m_device(device), m_desc(desc) { + : m_device(device), m_desc(desc), m_d3d10(this) { // If Independent Blend is disabled, we must ignore the // blend modes for render target 1 to 7. In Vulkan, all // blend modes need to be identical in that case. @@ -48,6 +48,13 @@ namespace dxvk { return S_OK; } + if (riid == __uuidof(ID3D10DeviceChild) + || riid == __uuidof(ID3D10BlendState) + || riid == __uuidof(ID3D10BlendState1)) { + *ppvObject = ref(&m_d3d10); + return S_OK; + } + Logger::warn("D3D11BlendState::QueryInterface: Unknown interface query"); Logger::warn(str::format(riid)); return E_NOINTERFACE; diff --git a/src/d3d11/d3d11_blend.h b/src/d3d11/d3d11_blend.h index 3b5054143..dcb2789c3 100644 --- a/src/d3d11/d3d11_blend.h +++ b/src/d3d11/d3d11_blend.h @@ -1,6 +1,8 @@ #pragma once -#include +#include "../dxvk/dxvk_device.h" + +#include "../d3d10/d3d10_blend.h" #include "d3d11_device_child.h" #include "d3d11_util.h" @@ -37,6 +39,10 @@ namespace dxvk { const Rc& ctx, UINT sampleMask) const; + D3D10BlendState* GetD3D10Iface() { + return &m_d3d10; + } + static D3D11_BLEND_DESC1 DefaultDesc(); static D3D11_BLEND_DESC1 PromoteDesc( @@ -45,8 +51,6 @@ namespace dxvk { static HRESULT NormalizeDesc( D3D11_BLEND_DESC1* pDesc); - - private: D3D11Device* const m_device; @@ -55,6 +59,8 @@ namespace dxvk { std::array m_blendModes; DxvkMultisampleState m_msState; DxvkLogicOpState m_loState; + + D3D10BlendState m_d3d10; static DxvkBlendMode DecodeBlendMode( const D3D11_RENDER_TARGET_BLEND_DESC1& BlendDesc); diff --git a/src/d3d11/meson.build b/src/d3d11/meson.build index 0c8800c0b..a3bcd7825 100644 --- a/src/d3d11/meson.build +++ b/src/d3d11/meson.build @@ -1,4 +1,5 @@ d3d10_src = [ + '../d3d10/d3d10_blend.cpp', '../d3d10/d3d10_buffer.cpp', '../d3d10/d3d10_device.cpp', '../d3d10/d3d10_input_layout.cpp',