GS: Move expanded dither storage to software renderer

Hardware doesn't use it.
This commit is contained in:
Stenzek 2023-04-03 02:08:09 +10:00 committed by refractionpcsx2
parent 72802aa125
commit e8dac0051c
5 changed files with 37 additions and 41 deletions

View File

@ -154,8 +154,6 @@ void GSState::Reset(bool hardware_reset)
UpdateVertexKick(); UpdateVertexKick();
UpdateDIMX();
for (u32 i = 0; i < 2; i++) for (u32 i = 0; i < 2; i++)
{ {
m_env.CTXT[i].UpdateScissor(); m_env.CTXT[i].UpdateScissor();
@ -1207,9 +1205,6 @@ void GSState::GIFRegHandlerDIMX(const GIFReg* RESTRICT r)
m_env.DIMX = r->DIMX; m_env.DIMX = r->DIMX;
if (update)
UpdateDIMX();
if (m_prev_env.DIMX != m_env.DIMX) if (m_prev_env.DIMX != m_env.DIMX)
m_dirty_gs_regs |= (1 << DIRTY_REG_DIMX); m_dirty_gs_regs |= (1 << DIRTY_REG_DIMX);
else else
@ -1454,18 +1449,12 @@ void GSState::Flush(GSFlushReason reason)
PRIM = &m_prev_env.PRIM; PRIM = &m_prev_env.PRIM;
UpdateContext(); UpdateContext();
if (m_dirty_gs_regs & (1 << DIRTY_REG_DIMX))
UpdateDIMX();
FlushPrim(); FlushPrim();
m_draw_env = &m_env; m_draw_env = &m_env;
PRIM = &m_env.PRIM; PRIM = &m_env.PRIM;
UpdateContext(); UpdateContext();
if (m_dirty_gs_regs & (1 << DIRTY_REG_DIMX))
UpdateDIMX();
m_backed_up_ctx = -1; m_backed_up_ctx = -1;
} }
else else
@ -2526,8 +2515,6 @@ int GSState::Defrost(const freezeData* fd)
UpdateVertexKick(); UpdateVertexKick();
UpdateDIMX();
for (u32 i = 0; i < 2; i++) for (u32 i = 0; i < 2; i++)
{ {
m_env.CTXT[i].UpdateScissor(); m_env.CTXT[i].UpdateScissor();
@ -2566,7 +2553,6 @@ void GSState::UpdateContext()
if (ctx_switch) if (ctx_switch)
GL_REG("Context Switch %d", PRIM->CTXT); GL_REG("Context Switch %d", PRIM->CTXT);
// TODO: Don't mutate context (looking at you, HW)
m_context = const_cast<GSDrawingContext*>(&m_draw_env->CTXT[PRIM->CTXT]); m_context = const_cast<GSDrawingContext*>(&m_draw_env->CTXT[PRIM->CTXT]);
UpdateScissor(); UpdateScissor();
@ -3814,19 +3800,6 @@ bool GSState::IsCoverageAlpha()
return !PRIM->ABE && PRIM->AA1 && (m_vt.m_primclass == GS_LINE_CLASS || m_vt.m_primclass == GS_TRIANGLE_CLASS); return !PRIM->ABE && PRIM->AA1 && (m_vt.m_primclass == GS_LINE_CLASS || m_vt.m_primclass == GS_TRIANGLE_CLASS);
} }
void GSState::UpdateDIMX()
{
const GIFRegDIMX& DIMX = m_draw_env->DIMX;
dimx[1] = GSVector4i(DIMX.DM00, 0, DIMX.DM01, 0, DIMX.DM02, 0, DIMX.DM03, 0);
dimx[0] = dimx[1].xxzzlh();
dimx[3] = GSVector4i(DIMX.DM10, 0, DIMX.DM11, 0, DIMX.DM12, 0, DIMX.DM13, 0);
dimx[2] = dimx[3].xxzzlh();
dimx[5] = GSVector4i(DIMX.DM20, 0, DIMX.DM21, 0, DIMX.DM22, 0, DIMX.DM23, 0);
dimx[4] = dimx[5].xxzzlh();
dimx[7] = GSVector4i(DIMX.DM30, 0, DIMX.DM31, 0, DIMX.DM32, 0, DIMX.DM33, 0);
dimx[6] = dimx[7].xxzzlh();
}
GIFRegTEX0 GSState::GetTex0Layer(u32 lod) GIFRegTEX0 GSState::GetTex0Layer(u32 lod)
{ {
// Shortcut // Shortcut

View File

@ -205,7 +205,6 @@ protected:
bool IsMipMapDraw(); bool IsMipMapDraw();
bool IsMipMapActive(); bool IsMipMapActive();
bool IsCoverageAlpha(); bool IsCoverageAlpha();
void UpdateDIMX();
public: public:
struct GSUploadQueue struct GSUploadQueue
@ -224,7 +223,6 @@ public:
const GSDrawingEnvironment* m_draw_env = &m_env; const GSDrawingEnvironment* m_draw_env = &m_env;
GSDrawingContext* m_context = nullptr; GSDrawingContext* m_context = nullptr;
GSVector4i temp_draw_rect = {}; GSVector4i temp_draw_rect = {};
GSVector4i dimx[8] = {};
u32 m_crc = 0; u32 m_crc = 0;
CRC::Game m_game = {}; CRC::Game m_game = {};
std::unique_ptr<GSDumpBase> m_dump; std::unique_ptr<GSDumpBase> m_dump;
@ -870,6 +868,9 @@ public:
/// Returns the appropriate directory for draw dumping. /// Returns the appropriate directory for draw dumping.
static std::string GetDrawDumpPath(const char* format, ...); static std::string GetDrawDumpPath(const char* format, ...);
/// Expands dither matrix, suitable for software renderer.
static void ExpandDIMX(GSVector4i* dimx, const GIFRegDIMX DIMX);
void ResetHandlers(); void ResetHandlers();
void ResetPCRTC(); void ResetPCRTC();
@ -920,3 +921,16 @@ public:
PRIM_OVERLAP PrimitiveOverlap(); PRIM_OVERLAP PrimitiveOverlap();
GIFRegTEX0 GetTex0Layer(u32 lod); GIFRegTEX0 GetTex0Layer(u32 lod);
}; };
// We put this in the header because of Multi-ISA.
inline void GSState::ExpandDIMX(GSVector4i* dimx, const GIFRegDIMX DIMX)
{
dimx[1] = GSVector4i(DIMX.DM00, 0, DIMX.DM01, 0, DIMX.DM02, 0, DIMX.DM03, 0);
dimx[0] = dimx[1].xxzzlh();
dimx[3] = GSVector4i(DIMX.DM10, 0, DIMX.DM11, 0, DIMX.DM12, 0, DIMX.DM13, 0);
dimx[2] = dimx[3].xxzzlh();
dimx[5] = GSVector4i(DIMX.DM20, 0, DIMX.DM21, 0, DIMX.DM22, 0, DIMX.DM23, 0);
dimx[4] = dimx[5].xxzzlh();
dimx[7] = GSVector4i(DIMX.DM30, 0, DIMX.DM31, 0, DIMX.DM32, 0, DIMX.DM33, 0);
dimx[6] = dimx[7].xxzzlh();
}

View File

@ -36,6 +36,10 @@ void CURRENT_ISA::GSRendererHWPopulateFunctions(GSRendererHW& renderer)
GSRendererHWFunctions::Populate(renderer); GSRendererHWFunctions::Populate(renderer);
} }
// since there's no overlapping draws, we can just keep this intact
static GSVector4i s_dimx_storage[8];
static GIFRegDIMX s_last_dimx;
bool GSRendererHWFunctions::SwPrimRender(GSRendererHW& hw, bool invalidate_tc) bool GSRendererHWFunctions::SwPrimRender(GSRendererHW& hw, bool invalidate_tc)
{ {
GSVertexTrace& vt = hw.m_vt; GSVertexTrace& vt = hw.m_vt;
@ -47,9 +51,6 @@ bool GSRendererHWFunctions::SwPrimRender(GSRendererHW& hw, bool invalidate_tc)
GSRasterizerData data; GSRasterizerData data;
GSScanlineGlobalData& gd = data.global; GSScanlineGlobalData& gd = data.global;
u32 clut_storage[256];
GSVector4i dimx_storage[8];
hw.m_sw_vertex_buffer.resize(((hw.m_vertex.next + 1) & ~1)); hw.m_sw_vertex_buffer.resize(((hw.m_vertex.next + 1) & ~1));
data.primclass = vt.m_primclass; data.primclass = vt.m_primclass;
@ -180,9 +181,7 @@ bool GSRendererHWFunctions::SwPrimRender(GSRendererHW& hw, bool invalidate_tc)
{ {
gd.sel.tlu = 1; gd.sel.tlu = 1;
gd.clut = clut_storage; // FIXME: might address uninitialized data of the texture (0xCD) that is not in 0-15 range for 4-bpp formats gd.clut = const_cast<u32*>(static_cast<const u32*>(hw.m_mem.m_clut));
memcpy(gd.clut, (const u32*)hw.m_mem.m_clut, sizeof(u32) * GSLocalMemory::m_psm[context->TEX0.PSM].pal);
} }
gd.sel.wms = context->CLAMP.WMS; gd.sel.wms = context->CLAMP.WMS;
@ -452,10 +451,12 @@ bool GSRendererHWFunctions::SwPrimRender(GSRendererHW& hw, bool invalidate_tc)
if (env.DTHE.DTHE) if (env.DTHE.DTHE)
{ {
gd.sel.dthe = 1; gd.sel.dthe = 1;
gd.dimx = s_dimx_storage;
gd.dimx = dimx_storage; if (s_last_dimx != env.DIMX)
{
memcpy(gd.dimx, hw.dimx, sizeof(hw.dimx)); s_last_dimx = env.DIMX;
GSState::ExpandDIMX(s_dimx_storage, env.DIMX);
}
} }
} }

View File

@ -1327,9 +1327,15 @@ bool GSRendererSW::GetScanlineGlobalData(SharedData* data)
{ {
gd.sel.dthe = 1; gd.sel.dthe = 1;
gd.dimx = (GSVector4i*)m_vertex_heap.alloc(sizeof(dimx), 32); if (m_last_dimx != env.DIMX)
{
m_last_dimx = env.DIMX;
ExpandDIMX(m_dimx, env.DIMX);
}
memcpy(gd.dimx, dimx, sizeof(dimx)); gd.dimx = (GSVector4i*)m_vertex_heap.alloc(sizeof(m_dimx), 32);
std::memcpy(gd.dimx, m_dimx, sizeof(m_dimx));
} }
} }

View File

@ -69,6 +69,8 @@ protected:
u32 m_fzb_cur_pages[16]; u32 m_fzb_cur_pages[16];
std::atomic<u32> m_fzb_pages[512]; // u16 frame/zbuf pages interleaved std::atomic<u32> m_fzb_pages[512]; // u16 frame/zbuf pages interleaved
std::atomic<u16> m_tex_pages[512]; std::atomic<u16> m_tex_pages[512];
GIFRegDIMX m_last_dimx = {};
GSVector4i m_dimx[8] = {};
void Reset(bool hardware_reset) override; void Reset(bool hardware_reset) override;
void VSync(u32 field, bool registers_written) override; void VSync(u32 field, bool registers_written) override;