mirror of https://github.com/PCSX2/pcsx2.git
GS:DX11: Add primid destination alpha support
This commit is contained in:
parent
1b34eb14f8
commit
95ad6b8ab4
|
@ -45,7 +45,7 @@ GSDevice11::GSDevice11()
|
|||
m_state.bf = -1;
|
||||
|
||||
m_features.geometry_shader = true;
|
||||
m_features.primitive_id = false;
|
||||
m_features.primitive_id = true;
|
||||
m_features.texture_barrier = false;
|
||||
m_features.provoking_vertex_last = false;
|
||||
m_features.point_expand = false;
|
||||
|
@ -132,11 +132,11 @@ bool GSDevice11::Create(HostDisplay* display)
|
|||
|
||||
ShaderMacro sm_model(m_shader_cache.GetFeatureLevel());
|
||||
|
||||
shader = Host::ReadResourceFileToString("shaders/dx11/convert.fx");
|
||||
if (!shader.has_value())
|
||||
std::optional<std::string> convert_hlsl = Host::ReadResourceFileToString("shaders/dx11/convert.fx");
|
||||
if (!convert_hlsl.has_value())
|
||||
return false;
|
||||
if (!m_shader_cache.GetVertexShaderAndInputLayout(m_dev.get(), m_convert.vs.put(), m_convert.il.put(),
|
||||
il_convert, std::size(il_convert), *shader, sm_model.GetPtr(), "vs_main"))
|
||||
il_convert, std::size(il_convert), *convert_hlsl, sm_model.GetPtr(), "vs_main"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ bool GSDevice11::Create(HostDisplay* display)
|
|||
|
||||
for (size_t i = 0; i < std::size(m_convert.ps); i++)
|
||||
{
|
||||
m_convert.ps[i] = m_shader_cache.GetPixelShader(m_dev.get(), *shader, sm_convert_ptr, shaderName(static_cast<ShaderConvert>(i)));
|
||||
m_convert.ps[i] = m_shader_cache.GetPixelShader(m_dev.get(), *convert_hlsl, sm_convert_ptr, shaderName(static_cast<ShaderConvert>(i)));
|
||||
if (!m_convert.ps[i])
|
||||
return false;
|
||||
}
|
||||
|
@ -341,6 +341,14 @@ bool GSDevice11::Create(HostDisplay* display)
|
|||
|
||||
m_dev->CreateBlendState(&blend, m_date.bs.put());
|
||||
|
||||
for (size_t i = 0; i < std::size(m_date.primid_init_ps); i++)
|
||||
{
|
||||
const std::string entry_point(StringUtil::StdStringFromFormat("ps_stencil_image_init_%d", i));
|
||||
m_date.primid_init_ps[i] = m_shader_cache.GetPixelShader(m_dev.get(), *convert_hlsl, sm_model.GetPtr(), entry_point.c_str());
|
||||
if (!m_date.primid_init_ps[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -462,7 +470,7 @@ GSTexture* GSDevice11::CreateSurface(GSTexture::Type type, int width, int height
|
|||
case GSTexture::Format::UNorm8: dxformat = DXGI_FORMAT_A8_UNORM; break;
|
||||
case GSTexture::Format::UInt16: dxformat = DXGI_FORMAT_R16_UINT; break;
|
||||
case GSTexture::Format::UInt32: dxformat = DXGI_FORMAT_R32_UINT; break;
|
||||
case GSTexture::Format::PrimID: dxformat = DXGI_FORMAT_R32_SINT; break;
|
||||
case GSTexture::Format::PrimID: dxformat = DXGI_FORMAT_R32_FLOAT; break;
|
||||
case GSTexture::Format::BC1: dxformat = DXGI_FORMAT_BC1_UNORM; break;
|
||||
case GSTexture::Format::BC2: dxformat = DXGI_FORMAT_BC2_UNORM; break;
|
||||
case GSTexture::Format::BC3: dxformat = DXGI_FORMAT_BC3_UNORM; break;
|
||||
|
@ -1336,7 +1344,6 @@ static GSDevice11::OMBlendSelector convertSel(GSHWDrawConfig::ColorMaskSelector
|
|||
/// Clears things we don't support that can be quietly disabled
|
||||
static void preprocessSel(GSDevice11::PSSelector& sel)
|
||||
{
|
||||
ASSERT(sel.date == 0); // In-shader destination alpha not supported and shouldn't be sent
|
||||
ASSERT(sel.write_rg == 0); // Not supported, shouldn't be sent
|
||||
}
|
||||
|
||||
|
@ -1345,7 +1352,16 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
|
|||
ASSERT(!config.require_full_barrier); // We always specify no support so it shouldn't request this
|
||||
preprocessSel(config.ps);
|
||||
|
||||
if (config.destination_alpha != GSHWDrawConfig::DestinationAlphaMode::Off)
|
||||
GSVector2i rtsize = (config.rt ? config.rt : config.ds)->GetSize();
|
||||
|
||||
GSTexture* primid_tex = nullptr;
|
||||
if (config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::PrimIDTracking)
|
||||
{
|
||||
primid_tex = CreateRenderTarget(rtsize.x, rtsize.y, GSTexture::Format::PrimID, false);
|
||||
StretchRect(config.rt, GSVector4(config.drawarea) / GSVector4(rtsize).xyxy(),
|
||||
primid_tex, GSVector4(config.drawarea), m_date.primid_init_ps[config.datm].get(), nullptr, false);
|
||||
}
|
||||
else if (config.destination_alpha != GSHWDrawConfig::DestinationAlphaMode::Off)
|
||||
{
|
||||
const GSVector4 src = GSVector4(config.drawarea) / GSVector4(config.ds->GetSize()).xyxy();
|
||||
const GSVector4 dst = src * 2.0f - 1.0f;
|
||||
|
@ -1364,10 +1380,9 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
|
|||
GSTexture* hdr_rt = nullptr;
|
||||
if (config.ps.hdr)
|
||||
{
|
||||
const GSVector2i size = config.rt->GetSize();
|
||||
const GSVector4 dRect(config.drawarea);
|
||||
const GSVector4 sRect = dRect / GSVector4(size.x, size.y).xyxy();
|
||||
hdr_rt = CreateRenderTarget(size.x, size.y, GSTexture::Format::FloatColor);
|
||||
const GSVector4 sRect = dRect / GSVector4(rtsize.x, rtsize.y).xyxy();
|
||||
hdr_rt = CreateRenderTarget(rtsize.x, rtsize.y, GSTexture::Format::FloatColor);
|
||||
// Warning: StretchRect must be called before BeginScene otherwise
|
||||
// vertices will be overwritten. Trust me you don't want to do that.
|
||||
StretchRect(config.rt, sRect, hdr_rt, dRect, ShaderConvert::COPY, false);
|
||||
|
@ -1391,8 +1406,6 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
|
|||
}
|
||||
IASetPrimitiveTopology(topology);
|
||||
|
||||
OMSetRenderTargets(hdr_rt ? hdr_rt : config.rt, config.ds, &config.scissor);
|
||||
|
||||
PSSetShaderResources(config.tex, config.pal);
|
||||
|
||||
GSTexture* rt_copy = nullptr;
|
||||
|
@ -1422,11 +1435,35 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
|
|||
PSSetShaderResource(0, ds_copy);
|
||||
}
|
||||
|
||||
SetupOM(config.depth, convertSel(config.colormask, config.blend), config.blend.constant);
|
||||
SetupVS(config.vs, &config.cb_vs);
|
||||
SetupGS(config.gs);
|
||||
SetupPS(config.ps, &config.cb_ps, config.sampler);
|
||||
|
||||
if (config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::PrimIDTracking)
|
||||
{
|
||||
OMDepthStencilSelector dss = config.depth;
|
||||
dss.zwe = 0;
|
||||
OMBlendSelector blend;
|
||||
blend.wrgba = 0;
|
||||
blend.wr = 1;
|
||||
blend.blend_enable = 1;
|
||||
blend.blend_src_factor = CONST_ONE;
|
||||
blend.blend_dst_factor = CONST_ONE;
|
||||
blend.blend_op = 3; // MIN
|
||||
SetupOM(dss, blend, 0);
|
||||
OMSetRenderTargets(primid_tex, config.ds, &config.scissor);
|
||||
|
||||
DrawIndexedPrimitive();
|
||||
|
||||
config.ps.date = 3;
|
||||
config.alpha_second_pass.ps.date = 3;
|
||||
SetupPS(config.ps, nullptr, config.sampler);
|
||||
PSSetShaderResource(3, primid_tex);
|
||||
}
|
||||
|
||||
SetupOM(config.depth, convertSel(config.colormask, config.blend), config.blend.constant);
|
||||
OMSetRenderTargets(hdr_rt ? hdr_rt : config.rt, config.ds, &config.scissor);
|
||||
|
||||
DrawIndexedPrimitive();
|
||||
|
||||
if (config.separate_alpha_pass)
|
||||
|
@ -1474,6 +1511,8 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
|
|||
Recycle(rt_copy);
|
||||
if (ds_copy)
|
||||
Recycle(ds_copy);
|
||||
if (primid_tex)
|
||||
Recycle(primid_tex);
|
||||
|
||||
if (hdr_rt)
|
||||
{
|
||||
|
|
|
@ -111,7 +111,7 @@ private:
|
|||
// Increment this constant whenever shaders change, to invalidate user's shader cache.
|
||||
static constexpr u32 SHADER_VERSION = 1;
|
||||
|
||||
static constexpr u32 MAX_TEXTURES = 3;
|
||||
static constexpr u32 MAX_TEXTURES = 4;
|
||||
static constexpr u32 MAX_SAMPLERS = 2;
|
||||
|
||||
int m_d3d_texsize;
|
||||
|
@ -209,6 +209,7 @@ private:
|
|||
{
|
||||
wil::com_ptr_nothrow<ID3D11DepthStencilState> dss;
|
||||
wil::com_ptr_nothrow<ID3D11BlendState> bs;
|
||||
wil::com_ptr_nothrow<ID3D11PixelShader> primid_init_ps[2];
|
||||
} m_date;
|
||||
|
||||
// Shaders...
|
||||
|
|
|
@ -164,6 +164,7 @@ void GSDevice11::SetupPS(const PSSelector& sel, const GSHWDrawConfig::PSConstant
|
|||
sm.AddMacro("PS_AEM", sel.aem);
|
||||
sm.AddMacro("PS_TFX", sel.tfx);
|
||||
sm.AddMacro("PS_TCC", sel.tcc);
|
||||
sm.AddMacro("PS_DATE", sel.date);
|
||||
sm.AddMacro("PS_ATST", sel.atst);
|
||||
sm.AddMacro("PS_FOG", sel.fog);
|
||||
sm.AddMacro("PS_IIP", sel.iip);
|
||||
|
@ -290,8 +291,8 @@ static constexpr std::array<D3D11_BLEND, 16> s_d3d11_blend_factors = { {
|
|||
D3D11_BLEND_DEST_ALPHA, D3D11_BLEND_INV_DEST_ALPHA, D3D11_BLEND_SRC1_ALPHA, D3D11_BLEND_INV_SRC1_ALPHA,
|
||||
D3D11_BLEND_BLEND_FACTOR, D3D11_BLEND_INV_BLEND_FACTOR, D3D11_BLEND_ONE, D3D11_BLEND_ZERO
|
||||
} };
|
||||
static constexpr std::array<D3D11_BLEND_OP, 3> s_d3d11_blend_ops = { {
|
||||
D3D11_BLEND_OP_ADD, D3D11_BLEND_OP_SUBTRACT, D3D11_BLEND_OP_REV_SUBTRACT
|
||||
static constexpr std::array<D3D11_BLEND_OP, 4> s_d3d11_blend_ops = { {
|
||||
D3D11_BLEND_OP_ADD, D3D11_BLEND_OP_SUBTRACT, D3D11_BLEND_OP_REV_SUBTRACT, D3D11_BLEND_OP_MIN
|
||||
} };
|
||||
// clang-format on
|
||||
|
||||
|
|
Loading…
Reference in New Issue