GS:DX11: Use GSHWDrawConfig selector structs

This commit is contained in:
TellowKrinkle 2021-12-12 23:33:09 -06:00 committed by lightningterror
parent a11b8c4750
commit ae8751e9ca
4 changed files with 52 additions and 294 deletions

View File

@ -12,15 +12,14 @@
#ifndef GS_IIP
#define GS_IIP 0
#define GS_PRIM 3
#define GS_POINT 0
#define GS_LINE 0
#define GS_EXPAND 0
#endif
#ifndef PS_FST
#define PS_FST 0
#define PS_WMS 0
#define PS_WMT 0
#define PS_FMT FMT_32
#define PS_AEM_FMT FMT_32
#define PS_AEM 0
#define PS_TFX 0
#define PS_TCC 1
@ -54,7 +53,6 @@
#endif
#define SW_BLEND (PS_BLEND_A || PS_BLEND_B || PS_BLEND_D)
#define PS_AEM_FMT (PS_FMT & 3)
struct VS_INPUT
{
@ -846,7 +844,7 @@ VS_OUTPUT vs_main(VS_INPUT input)
// Geometry Shader
//////////////////////////////////////////////////////////////////////
#if GS_PRIM == 0 && GS_POINT == 0
#if GS_PRIM == 0 && GS_EXPAND == 0
[maxvertexcount(1)]
void gs_main(point VS_OUTPUT input[1], inout PointStream<VS_OUTPUT> stream)
@ -854,7 +852,7 @@ void gs_main(point VS_OUTPUT input[1], inout PointStream<VS_OUTPUT> stream)
stream.Append(input[0]);
}
#elif GS_PRIM == 0 && GS_POINT == 1
#elif GS_PRIM == 0 && GS_EXPAND == 1
[maxvertexcount(6)]
void gs_main(point VS_OUTPUT input[1], inout TriangleStream<VS_OUTPUT> stream)
@ -891,7 +889,7 @@ void gs_main(point VS_OUTPUT input[1], inout TriangleStream<VS_OUTPUT> stream)
stream.Append(Point);
}
#elif GS_PRIM == 1 && GS_LINE == 0
#elif GS_PRIM == 1 && GS_EXPAND == 0
[maxvertexcount(2)]
void gs_main(line VS_OUTPUT input[2], inout LineStream<VS_OUTPUT> stream)
@ -904,7 +902,7 @@ void gs_main(line VS_OUTPUT input[2], inout LineStream<VS_OUTPUT> stream)
stream.Append(input[1]);
}
#elif GS_PRIM == 1 && GS_LINE == 1
#elif GS_PRIM == 1 && GS_EXPAND == 1
[maxvertexcount(6)]
void gs_main(line VS_OUTPUT input[2], inout TriangleStream<VS_OUTPUT> stream)

View File

@ -1524,17 +1524,6 @@ static GSDevice11::PSConstantBuffer convertCB(const GSHWDrawConfig::PSConstantBu
return out;
}
static GSDevice11::OMDepthStencilSelector convertSel(GSHWDrawConfig::DepthStencilSelector sel)
{
GSDevice11::OMDepthStencilSelector out;
out.zwe = sel.zwe;
out.ztst = sel.ztst;
out.date = sel.date;
out.date_one = sel.date_one;
out.fba = 0; // No longer seems to be in use?
return out;
}
static GSDevice11::OMBlendSelector convertSel(GSHWDrawConfig::ColorMaskSelector cm, GSHWDrawConfig::BlendState blend)
{
GSDevice11::OMBlendSelector out;
@ -1546,89 +1535,29 @@ static GSDevice11::OMBlendSelector convertSel(GSHWDrawConfig::ColorMaskSelector
return out;
}
static GSDevice11::VSSelector convertSel(GSHWDrawConfig::VSSelector sel)
/// Checks that we weren't sent things we declared we don't support
/// Clears things we don't support that can be quietly disabled
static void preprocessSel(GSDevice11::PSSelector& sel)
{
GSDevice11::VSSelector out;
out.tme = sel.tme;
out.fst = sel.fst;
return out;
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
ASSERT(sel.tex_is_fb == 0); // Not supported, shouldn't be sent
sel.iip = 0; // Handled in GS, not PS in DX11
sel.automatic_lod = 0; // Not currently supported in DX11
sel.manual_lod = 0; // Not currently supported in DX11
}
static GSDevice11::PSSelector convertSel(GSHWDrawConfig::PSSelector sel)
static void preprocessSel(GSDevice11::PSSamplerSelector& sel)
{
GSDevice11::PSSelector out;
out.fmt = sel.pal_fmt << 2 | sel.aem_fmt;
out.dfmt = sel.dfmt;
out.depth_fmt = sel.depth_fmt;
out.aem = sel.aem;
out.fba = sel.fba;
out.fog = sel.fog;
out.atst = sel.atst;
out.fst = sel.fst;
out.tfx = sel.tfx;
out.tcc = sel.tcc;
out.wms = sel.wms;
out.wmt = sel.wmt;
out.ltf = sel.ltf;
out.shuffle = sel.shuffle;
out.read_ba = sel.read_ba;
out.fbmask = sel.fbmask;
out.hdr = sel.hdr;
out.blend_a = sel.blend_a;
out.blend_b = sel.blend_b;
out.blend_c = sel.blend_c;
out.blend_d = sel.blend_d;
out.clr1 = sel.clr1;
out.colclip = sel.colclip;
out.pabe = sel.pabe;
out.channel = sel.channel;
out.dither = sel.dither;
out.zclamp = sel.zclamp;
out.tcoffsethack = sel.tcoffsethack;
out.urban_chaos_hle = sel.urban_chaos_hle;
out.tales_of_abyss_hle = sel.tales_of_abyss_hle;
out.point_sampler = sel.point_sampler;
out.invalid_tex0 = sel.invalid_tex0;
return out;
}
static GSDevice11::GSSelector convertSel(GSHWDrawConfig::GSSelector sel)
{
GSDevice11::GSSelector out;
out.iip = sel.iip;
switch (sel.topology)
{
case GSHWDrawConfig::GSTopology::Point:
out.point = sel.expand;
out.prim = GS_POINT_CLASS;
break;
case GSHWDrawConfig::GSTopology::Line:
out.line = sel.expand;
out.prim = GS_LINE_CLASS;
break;
case GSHWDrawConfig::GSTopology::Triangle:
out.prim = GS_TRIANGLE_CLASS;
break;
case GSHWDrawConfig::GSTopology::Sprite:
out.cpu_sprite = !sel.expand;
out.prim = GS_SPRITE_CLASS;
break;
}
return out;
}
static GSDevice11::PSSamplerSelector convertSel(GSHWDrawConfig::SamplerSelector sel)
{
GSDevice11::PSSamplerSelector out;
out.tau = sel.tau;
out.tav = sel.tav;
out.ltf = sel.biln;
return out;
sel.aniso = 0; // Not currently supported
sel.triln = 0; // Not currently supported
}
void GSDevice11::RenderHW(GSHWDrawConfig& config)
{
ASSERT(!config.require_full_barrier); // We always specify no support so it shouldn't request this
preprocessSel(config.ps);
preprocessSel(config.sampler);
if (config.destination_alpha != GSHWDrawConfig::DestinationAlphaMode::Off)
{
@ -1693,10 +1622,10 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
const GSConstantBuffer cb_gs = convertCBGS(config.cb_vs);
PSConstantBuffer cb_ps = convertCB(config.cb_ps, config.ps.atst);
SetupOM(convertSel(config.depth), convertSel(config.colormask, config.blend), config.blend.factor);
SetupVS(convertSel(config.vs), &cb_vs);
SetupGS(convertSel(config.gs), &cb_gs);
SetupPS(convertSel(config.ps), &cb_ps, convertSel(config.sampler));
SetupOM(config.depth, convertSel(config.colormask, config.blend), config.blend.factor);
SetupVS(config.vs, &cb_vs);
SetupGS(config.gs, &cb_gs);
SetupPS(config.ps, &cb_ps, config.sampler);
OMSetRenderTargets(hdr_rt ? hdr_rt : config.rt, config.ds, &config.scissor);
@ -1704,12 +1633,13 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config)
if (config.alpha_second_pass.enable)
{
preprocessSel(config.alpha_second_pass.ps);
if (config.cb_ps != config.alpha_second_pass.cb_ps)
{
cb_ps = convertCB(config.alpha_second_pass.cb_ps, config.alpha_second_pass.ps.atst);
}
SetupPS(convertSel(config.alpha_second_pass.ps), &cb_ps, convertSel(config.sampler));
SetupOM(convertSel(config.alpha_second_pass.depth), convertSel(config.alpha_second_pass.colormask, config.blend), config.blend.factor);
SetupPS(config.alpha_second_pass.ps, &cb_ps, config.sampler);
SetupOM(config.alpha_second_pass.depth, convertSel(config.alpha_second_pass.colormask, config.blend), config.blend.factor);
DrawIndexedPrimitive();
}

View File

@ -69,33 +69,6 @@ public:
}
};
struct VSSelector
{
union
{
struct
{
u32 tme : 1;
u32 fst : 1;
u32 _free : 30;
};
u32 key;
};
operator u32() const { return key; }
VSSelector()
: key(0)
{
}
VSSelector(u32 k)
: key(k)
{
}
};
struct alignas(32) PSConstantBuffer
{
GSVector4 FogColor_AREF;
@ -175,151 +148,11 @@ public:
}
};
struct GSSelector
{
union
{
struct
{
u32 iip : 1;
u32 prim : 2;
u32 point : 1;
u32 line : 1;
u32 cpu_sprite : 1;
u32 _free : 26;
};
u32 key;
};
operator u32() { return key; }
GSSelector()
: key(0)
{
}
GSSelector(u32 k)
: key(k)
{
}
};
struct PSSelector
{
union
{
struct
{
// *** Word 1
// Format
u32 fmt : 4;
u32 dfmt : 2;
u32 depth_fmt : 2;
// Alpha extension/Correction
u32 aem : 1;
u32 fba : 1;
// Fog
u32 fog : 1;
// Pixel test
u32 atst : 3;
// Color sampling
u32 fst : 1;
u32 tfx : 3;
u32 tcc : 1;
u32 wms : 2;
u32 wmt : 2;
u32 ltf : 1;
// Shuffle and fbmask effect
u32 shuffle : 1;
u32 read_ba : 1;
u32 fbmask : 1;
// Blend and Colclip
u32 hdr : 1;
u32 blend_a : 2;
u32 blend_b : 2; // bit30/31
u32 blend_c : 2; // bit0
u32 blend_d : 2;
u32 clr1 : 1;
u32 colclip : 1;
u32 pabe : 1;
// Others ways to fetch the texture
u32 channel : 3;
// Dithering
u32 dither : 2;
// Depth clamp
u32 zclamp : 1;
// Hack
u32 tcoffsethack : 1;
u32 urban_chaos_hle : 1;
u32 tales_of_abyss_hle : 1;
u32 point_sampler : 1;
u32 invalid_tex0 : 1; // Lupin the 3rd
u32 _free : 14;
};
u64 key;
};
operator u64() { return key; }
PSSelector()
: key(0)
{
}
};
struct PSSamplerSelector
{
union
{
struct
{
u32 tau : 1;
u32 tav : 1;
u32 ltf : 1;
};
u32 key;
};
operator u32() { return key & 0x7; }
PSSamplerSelector()
: key(0)
{
}
};
struct OMDepthStencilSelector
{
union
{
struct
{
u32 ztst : 2;
u32 zwe : 1;
u32 date : 1;
u32 fba : 1;
u32 date_one : 1;
};
u32 key;
};
operator u32() { return key & 0x3f; }
OMDepthStencilSelector()
: key(0)
{
}
};
using VSSelector = GSHWDrawConfig::VSSelector;
using GSSelector = GSHWDrawConfig::GSSelector;
using PSSelector = GSHWDrawConfig::PSSelector;
using PSSamplerSelector = GSHWDrawConfig::SamplerSelector;
using OMDepthStencilSelector = GSHWDrawConfig::DepthStencilSelector;
struct OMBlendSelector
{

View File

@ -93,7 +93,7 @@ bool GSDevice11::CreateTextureFX()
void GSDevice11::SetupVS(VSSelector sel, const VSConstantBuffer* cb)
{
auto i = std::as_const(m_vs).find(sel);
auto i = std::as_const(m_vs).find(sel.key);
if (i == m_vs.end())
{
@ -116,9 +116,7 @@ void GSDevice11::SetupVS(VSSelector sel, const VSConstantBuffer* cb)
GSVertexShader11 vs;
CreateShader(m_tfx_source, "tfx.fx", nullptr, "vs_main", sm.GetPtr(), &vs.vs, layout, std::size(layout), vs.il.put());
m_vs[sel] = vs;
i = m_vs.try_emplace(sel, std::move(vs)).first;
i = m_vs.try_emplace(sel.key, std::move(vs)).first;
}
if (m_vs_cb_cache.Update(cb))
@ -135,11 +133,11 @@ void GSDevice11::SetupGS(GSSelector sel, const GSConstantBuffer* cb)
{
wil::com_ptr_nothrow<ID3D11GeometryShader> gs;
const bool unscale_pt_ln = (sel.point == 1 || sel.line == 1);
const bool flat_shading_needs_gs = sel.topology == GSHWDrawConfig::GSTopology::Line || sel.topology == GSHWDrawConfig::GSTopology::Triangle;
// Geometry shader is disabled if sprite conversion is done on the cpu (sel.cpu_sprite).
if ((sel.prim > 0 && sel.cpu_sprite == 0 && (sel.iip == 0 || sel.prim == 3)) || unscale_pt_ln)
if (sel.expand || (sel.iip == 0 && flat_shading_needs_gs))
{
const auto i = std::as_const(m_gs).find(sel);
const auto i = std::as_const(m_gs).find(sel.key);
if (i != m_gs.end())
{
@ -150,13 +148,12 @@ void GSDevice11::SetupGS(GSSelector sel, const GSConstantBuffer* cb)
ShaderMacro sm(m_shader.model);
sm.AddMacro("GS_IIP", sel.iip);
sm.AddMacro("GS_PRIM", sel.prim);
sm.AddMacro("GS_POINT", sel.point);
sm.AddMacro("GS_LINE", sel.line);
sm.AddMacro("GS_PRIM", static_cast<int>(sel.topology));
sm.AddMacro("GS_EXPAND", sel.expand);
CreateShader(m_tfx_source, "tfx.fx", nullptr, "gs_main", sm.GetPtr(), gs.put());
m_gs[sel] = gs;
m_gs[sel.key] = gs;
}
}
@ -171,7 +168,7 @@ void GSDevice11::SetupGS(GSSelector sel, const GSConstantBuffer* cb)
void GSDevice11::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel)
{
auto i = std::as_const(m_ps).find(sel);
auto i = std::as_const(m_ps).find(sel.key);
if (i == m_ps.end())
{
@ -181,7 +178,7 @@ void GSDevice11::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSe
sm.AddMacro("PS_FST", sel.fst);
sm.AddMacro("PS_WMS", sel.wms);
sm.AddMacro("PS_WMT", sel.wmt);
sm.AddMacro("PS_FMT", sel.fmt);
sm.AddMacro("PS_AEM_FMT", sel.aem_fmt);
sm.AddMacro("PS_AEM", sel.aem);
sm.AddMacro("PS_TFX", sel.tfx);
sm.AddMacro("PS_TCC", sel.tcc);
@ -200,7 +197,7 @@ void GSDevice11::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSe
sm.AddMacro("PS_URBAN_CHAOS_HLE", sel.urban_chaos_hle);
sm.AddMacro("PS_DFMT", sel.dfmt);
sm.AddMacro("PS_DEPTH_FMT", sel.depth_fmt);
sm.AddMacro("PS_PAL_FMT", sel.fmt >> 2);
sm.AddMacro("PS_PAL_FMT", sel.pal_fmt);
sm.AddMacro("PS_INVALID_TEX0", sel.invalid_tex0);
sm.AddMacro("PS_HDR", sel.hdr);
sm.AddMacro("PS_COLCLIP", sel.colclip);
@ -215,7 +212,7 @@ void GSDevice11::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSe
wil::com_ptr_nothrow<ID3D11PixelShader> ps;
CreateShader(m_tfx_source, "tfx.fx", nullptr, "ps_main", sm.GetPtr(), ps.put());
i = m_ps.try_emplace(sel, std::move(ps)).first;
i = m_ps.try_emplace(sel.key, std::move(ps)).first;
}
if (m_ps_cb_cache.Update(cb))
@ -227,12 +224,12 @@ void GSDevice11::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSe
if (sel.tfx != 4)
{
if (!(sel.fmt < 3 && sel.wms < 3 && sel.wmt < 3))
if (sel.pal_fmt || sel.wms >= 3 || sel.wmt >= 3)
{
ssel.ltf = 0;
ASSERT(ssel.biln == 0);
}
auto i = std::as_const(m_ps_ss).find(ssel);
auto i = std::as_const(m_ps_ss).find(ssel.key);
if (i != m_ps_ss.end())
{
@ -245,7 +242,7 @@ void GSDevice11::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSe
memset(&sd, 0, sizeof(sd));
af.Filter = m_aniso_filter ? D3D11_FILTER_ANISOTROPIC : D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
sd.Filter = ssel.ltf ? af.Filter : D3D11_FILTER_MIN_MAG_MIP_POINT;
sd.Filter = ssel.biln ? af.Filter : D3D11_FILTER_MIN_MAG_MIP_POINT;
sd.AddressU = ssel.tau ? D3D11_TEXTURE_ADDRESS_WRAP : D3D11_TEXTURE_ADDRESS_CLAMP;
sd.AddressV = ssel.tav ? D3D11_TEXTURE_ADDRESS_WRAP : D3D11_TEXTURE_ADDRESS_CLAMP;
@ -257,10 +254,10 @@ void GSDevice11::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSe
m_dev->CreateSamplerState(&sd, &ss0);
m_ps_ss[ssel] = ss0;
m_ps_ss[ssel.key] = ss0;
}
if (sel.fmt >= 3)
if (sel.pal_fmt)
{
ss1 = m_palette_ss;
}
@ -273,7 +270,7 @@ void GSDevice11::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSe
void GSDevice11::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, u8 afix)
{
auto i = std::as_const(m_om_dss).find(dssel);
auto i = std::as_const(m_om_dss).find(dssel.key);
if (i == m_om_dss.end())
{
@ -314,7 +311,7 @@ void GSDevice11::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, u8
wil::com_ptr_nothrow<ID3D11DepthStencilState> dss;
m_dev->CreateDepthStencilState(&dsd, dss.put());
i = m_om_dss.try_emplace(dssel, std::move(dss)).first;
i = m_om_dss.try_emplace(dssel.key, std::move(dss)).first;
}
OMSetDepthStencilState(i->second.get(), 1);