1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-11-30 04:24:11 +01:00

[d3d10] Implement D3D10BlendState

This commit is contained in:
Philip Rebohle 2018-08-11 22:11:18 +02:00
parent 5a84f35d08
commit f2381ac4eb
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
6 changed files with 199 additions and 8 deletions

81
src/d3d10/d3d10_blend.cpp Normal file
View File

@ -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<D3D11_BLEND_DESC*>(pDesc));
}
}

58
src/d3d10/d3d10_blend.h Normal file
View File

@ -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;
};
}

View File

@ -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*>(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<const D3D11_BLEND_DESC*>(pBlendStateDesc),
ppBlendState ? &d3d11BlendState : nullptr);
if (FAILED(hr))
return hr;
if (ppBlendState != nullptr) {
*ppBlendState = static_cast<D3D11BlendState*>(d3d11BlendState)->GetD3D10Iface();
return S_OK;
} return S_FALSE;
}

View File

@ -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;

View File

@ -1,6 +1,8 @@
#pragma once
#include <dxvk_device.h>
#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<DxvkContext>& 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<DxvkBlendMode, 8> m_blendModes;
DxvkMultisampleState m_msState;
DxvkLogicOpState m_loState;
D3D10BlendState m_d3d10;
static DxvkBlendMode DecodeBlendMode(
const D3D11_RENDER_TARGET_BLEND_DESC1& BlendDesc);

View File

@ -1,4 +1,5 @@
d3d10_src = [
'../d3d10/d3d10_blend.cpp',
'../d3d10/d3d10_buffer.cpp',
'../d3d10/d3d10_device.cpp',
'../d3d10/d3d10_input_layout.cpp',