D3D11Device: Fix blend state not applying to MRTs
This commit is contained in:
parent
30c5ebae72
commit
5b590d434b
|
@ -118,9 +118,14 @@ protected:
|
||||||
void DestroyDevice() override;
|
void DestroyDevice() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
using BlendStateMapKey = std::pair<u64, u32>;
|
||||||
|
struct BlendStateMapHash
|
||||||
|
{
|
||||||
|
size_t operator()(const BlendStateMapKey& key) const;
|
||||||
|
};
|
||||||
using RasterizationStateMap = std::unordered_map<u8, ComPtr<ID3D11RasterizerState>>;
|
using RasterizationStateMap = std::unordered_map<u8, ComPtr<ID3D11RasterizerState>>;
|
||||||
using DepthStateMap = std::unordered_map<u8, ComPtr<ID3D11DepthStencilState>>;
|
using DepthStateMap = std::unordered_map<u8, ComPtr<ID3D11DepthStencilState>>;
|
||||||
using BlendStateMap = std::unordered_map<u64, ComPtr<ID3D11BlendState>>;
|
using BlendStateMap = std::unordered_map<BlendStateMapKey, ComPtr<ID3D11BlendState>, BlendStateMapHash>;
|
||||||
using InputLayoutMap =
|
using InputLayoutMap =
|
||||||
std::unordered_map<GPUPipeline::InputLayout, ComPtr<ID3D11InputLayout>, GPUPipeline::InputLayoutHash>;
|
std::unordered_map<GPUPipeline::InputLayout, ComPtr<ID3D11InputLayout>, GPUPipeline::InputLayoutHash>;
|
||||||
|
|
||||||
|
@ -146,7 +151,7 @@ private:
|
||||||
|
|
||||||
ComPtr<ID3D11RasterizerState> GetRasterizationState(const GPUPipeline::RasterizationState& rs, Error* error);
|
ComPtr<ID3D11RasterizerState> GetRasterizationState(const GPUPipeline::RasterizationState& rs, Error* error);
|
||||||
ComPtr<ID3D11DepthStencilState> GetDepthState(const GPUPipeline::DepthState& ds, Error* error);
|
ComPtr<ID3D11DepthStencilState> GetDepthState(const GPUPipeline::DepthState& ds, Error* error);
|
||||||
ComPtr<ID3D11BlendState> GetBlendState(const GPUPipeline::BlendState& bs, Error* error);
|
ComPtr<ID3D11BlendState> GetBlendState(const GPUPipeline::BlendState& bs, u32 num_rts, Error* error);
|
||||||
ComPtr<ID3D11InputLayout> GetInputLayout(const GPUPipeline::InputLayout& il, const D3D11Shader* vs, Error* error);
|
ComPtr<ID3D11InputLayout> GetInputLayout(const GPUPipeline::InputLayout& il, const D3D11Shader* vs, Error* error);
|
||||||
|
|
||||||
bool CreateTimestampQueries();
|
bool CreateTimestampQueries();
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "d3d_common.h"
|
#include "d3d_common.h"
|
||||||
|
|
||||||
#include "common/error.h"
|
#include "common/error.h"
|
||||||
|
#include "common/hash_combine.h"
|
||||||
|
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
|
|
||||||
|
@ -206,11 +207,19 @@ D3D11Device::ComPtr<ID3D11DepthStencilState> D3D11Device::GetDepthState(const GP
|
||||||
return dds;
|
return dds;
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D11Device::ComPtr<ID3D11BlendState> D3D11Device::GetBlendState(const GPUPipeline::BlendState& bs, Error* error)
|
size_t D3D11Device::BlendStateMapHash::operator()(const BlendStateMapKey& key) const
|
||||||
|
{
|
||||||
|
size_t h = std::hash<u64>()(key.first);
|
||||||
|
hash_combine(h, key.second);
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D11Device::ComPtr<ID3D11BlendState> D3D11Device::GetBlendState(const GPUPipeline::BlendState& bs, u32 num_rts, Error* error)
|
||||||
{
|
{
|
||||||
ComPtr<ID3D11BlendState> dbs;
|
ComPtr<ID3D11BlendState> dbs;
|
||||||
|
|
||||||
const auto it = m_blend_states.find(bs.key);
|
const std::pair<u64, u32> key(bs.key, num_rts);
|
||||||
|
const auto it = m_blend_states.find(key);
|
||||||
if (it != m_blend_states.end())
|
if (it != m_blend_states.end())
|
||||||
{
|
{
|
||||||
dbs = it->second;
|
dbs = it->second;
|
||||||
|
@ -243,24 +252,27 @@ D3D11Device::ComPtr<ID3D11BlendState> D3D11Device::GetBlendState(const GPUPipeli
|
||||||
}};
|
}};
|
||||||
|
|
||||||
D3D11_BLEND_DESC blend_desc = {};
|
D3D11_BLEND_DESC blend_desc = {};
|
||||||
D3D11_RENDER_TARGET_BLEND_DESC& tgt_desc = blend_desc.RenderTarget[0];
|
for (u32 i = 0; i < num_rts; i++)
|
||||||
tgt_desc.BlendEnable = bs.enable;
|
|
||||||
tgt_desc.RenderTargetWriteMask = bs.write_mask;
|
|
||||||
if (bs.enable)
|
|
||||||
{
|
{
|
||||||
tgt_desc.SrcBlend = blend_mapping[static_cast<u8>(bs.src_blend.GetValue())];
|
D3D11_RENDER_TARGET_BLEND_DESC& tgt_desc = blend_desc.RenderTarget[i];
|
||||||
tgt_desc.DestBlend = blend_mapping[static_cast<u8>(bs.dst_blend.GetValue())];
|
tgt_desc.BlendEnable = bs.enable;
|
||||||
tgt_desc.BlendOp = op_mapping[static_cast<u8>(bs.blend_op.GetValue())];
|
tgt_desc.RenderTargetWriteMask = bs.write_mask;
|
||||||
tgt_desc.SrcBlendAlpha = blend_mapping[static_cast<u8>(bs.src_alpha_blend.GetValue())];
|
if (bs.enable)
|
||||||
tgt_desc.DestBlendAlpha = blend_mapping[static_cast<u8>(bs.dst_alpha_blend.GetValue())];
|
{
|
||||||
tgt_desc.BlendOpAlpha = op_mapping[static_cast<u8>(bs.alpha_blend_op.GetValue())];
|
tgt_desc.SrcBlend = blend_mapping[static_cast<u8>(bs.src_blend.GetValue())];
|
||||||
|
tgt_desc.DestBlend = blend_mapping[static_cast<u8>(bs.dst_blend.GetValue())];
|
||||||
|
tgt_desc.BlendOp = op_mapping[static_cast<u8>(bs.blend_op.GetValue())];
|
||||||
|
tgt_desc.SrcBlendAlpha = blend_mapping[static_cast<u8>(bs.src_alpha_blend.GetValue())];
|
||||||
|
tgt_desc.DestBlendAlpha = blend_mapping[static_cast<u8>(bs.dst_alpha_blend.GetValue())];
|
||||||
|
tgt_desc.BlendOpAlpha = op_mapping[static_cast<u8>(bs.alpha_blend_op.GetValue())];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT hr = m_device->CreateBlendState(&blend_desc, dbs.GetAddressOf());
|
HRESULT hr = m_device->CreateBlendState(&blend_desc, dbs.GetAddressOf());
|
||||||
if (FAILED(hr)) [[unlikely]]
|
if (FAILED(hr)) [[unlikely]]
|
||||||
Error::SetHResult(error, "CreateBlendState() failed: ", hr);
|
Error::SetHResult(error, "CreateBlendState() failed: ", hr);
|
||||||
else
|
else
|
||||||
m_blend_states.emplace(bs.key, dbs);
|
m_blend_states.emplace(key, dbs);
|
||||||
|
|
||||||
return dbs;
|
return dbs;
|
||||||
}
|
}
|
||||||
|
@ -322,7 +334,7 @@ std::unique_ptr<GPUPipeline> D3D11Device::CreatePipeline(const GPUPipeline::Grap
|
||||||
{
|
{
|
||||||
ComPtr<ID3D11RasterizerState> rs = GetRasterizationState(config.rasterization, error);
|
ComPtr<ID3D11RasterizerState> rs = GetRasterizationState(config.rasterization, error);
|
||||||
ComPtr<ID3D11DepthStencilState> ds = GetDepthState(config.depth, error);
|
ComPtr<ID3D11DepthStencilState> ds = GetDepthState(config.depth, error);
|
||||||
ComPtr<ID3D11BlendState> bs = GetBlendState(config.blend, error);
|
ComPtr<ID3D11BlendState> bs = GetBlendState(config.blend, config.GetRenderTargetCount(), error);
|
||||||
if (!rs || !ds || !bs)
|
if (!rs || !ds || !bs)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
|
|
@ -167,6 +167,17 @@ void GPUPipeline::GraphicsConfig::SetTargetFormats(GPUTexture::Format color_form
|
||||||
depth_format = depth_format_;
|
depth_format = depth_format_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 GPUPipeline::GraphicsConfig::GetRenderTargetCount() const
|
||||||
|
{
|
||||||
|
u32 num_rts = 0;
|
||||||
|
for (; num_rts < static_cast<u32>(std::size(color_formats)); num_rts++)
|
||||||
|
{
|
||||||
|
if (color_formats[num_rts] == GPUTexture::Format::Unknown)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return num_rts;
|
||||||
|
}
|
||||||
|
|
||||||
GPUTextureBuffer::GPUTextureBuffer(Format format, u32 size) : m_format(format), m_size_in_elements(size)
|
GPUTextureBuffer::GPUTextureBuffer(Format format, u32 size) : m_format(format), m_size_in_elements(size)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -413,6 +413,7 @@ public:
|
||||||
|
|
||||||
void SetTargetFormats(GPUTexture::Format color_format,
|
void SetTargetFormats(GPUTexture::Format color_format,
|
||||||
GPUTexture::Format depth_format_ = GPUTexture::Format::Unknown);
|
GPUTexture::Format depth_format_ = GPUTexture::Format::Unknown);
|
||||||
|
u32 GetRenderTargetCount() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
GPUPipeline();
|
GPUPipeline();
|
||||||
|
|
Loading…
Reference in New Issue