diff --git a/pcsx2/GS/GSLocalMemory.h b/pcsx2/GS/GSLocalMemory.h index 64e8e6b517..61f6c59531 100644 --- a/pcsx2/GS/GSLocalMemory.h +++ b/pcsx2/GS/GSLocalMemory.h @@ -481,7 +481,7 @@ public: static psm_t m_psm[64]; static readImage m_readImageX; - static const int m_vmsize = 1024 * 1024 * 4; + static constexpr int m_vmsize = 1024 * 1024 * 4; u8* m_vm8; diff --git a/pcsx2/GS/GSState.cpp b/pcsx2/GS/GSState.cpp index 9457b4511f..ae93aae7fd 100644 --- a/pcsx2/GS/GSState.cpp +++ b/pcsx2/GS/GSState.cpp @@ -37,14 +37,61 @@ static __fi bool IsFirstProvokingVertex() return (GSConfig.Renderer != GSRendererType::SW && !g_gs_device->Features().provoking_vertex_last); } +constexpr int GSState::GetSaveStateSize() +{ + int size = 0; + + size += sizeof(STATE_VERSION); + size += sizeof(m_env.PRIM); + size += sizeof(m_env.PRMODECONT); + size += sizeof(m_env.TEXCLUT); + size += sizeof(m_env.SCANMSK); + size += sizeof(m_env.TEXA); + size += sizeof(m_env.FOGCOL); + size += sizeof(m_env.DIMX); + size += sizeof(m_env.DTHE); + size += sizeof(m_env.COLCLAMP); + size += sizeof(m_env.PABE); + size += sizeof(m_env.BITBLTBUF); + size += sizeof(m_env.TRXDIR); + size += sizeof(m_env.TRXPOS); + size += sizeof(m_env.TRXREG); + size += sizeof(m_env.TRXREG); // obsolete + + for (int i = 0; i < 2; i++) + { + size += sizeof(m_env.CTXT[i].XYOFFSET); + size += sizeof(m_env.CTXT[i].TEX0); + size += sizeof(m_env.CTXT[i].TEX1); + size += sizeof(m_env.CTXT[i].CLAMP); + size += sizeof(m_env.CTXT[i].MIPTBP1); + size += sizeof(m_env.CTXT[i].MIPTBP2); + size += sizeof(m_env.CTXT[i].SCISSOR); + size += sizeof(m_env.CTXT[i].ALPHA); + size += sizeof(m_env.CTXT[i].TEST); + size += sizeof(m_env.CTXT[i].FBA); + size += sizeof(m_env.CTXT[i].FRAME); + size += sizeof(m_env.CTXT[i].ZBUF); + } + + size += sizeof(m_v.RGBAQ); + size += sizeof(m_v.ST); + size += sizeof(m_v.UV); + size += sizeof(m_v.FOG); + size += sizeof(m_v.XYZ); + size += sizeof(GIFReg); // obsolete + + size += sizeof(m_tr.x); + size += sizeof(m_tr.y); + size += GSLocalMemory::m_vmsize; + size += (sizeof(GIFPath::tag) + sizeof(GIFPath::reg)) * 4 /* std::size(GSState::m_path) */; // std::size won't work without an instance. + size += sizeof(m_q); + + return size; +} + GSState::GSState() - : m_version(STATE_VERSION) - , m_q(1.0f) - , m_scanmask_used(0) - , tex_flushed(true) - , m_vt(this, IsFirstProvokingVertex()) - , m_regs(NULL) - , m_crc(0) + : m_vt(this, IsFirstProvokingVertex()) { // m_nativeres seems to be a hack. Unfortunately it impacts draw call number which make debug painful in the replayer. // Let's keep it disabled to ease debug. @@ -63,54 +110,6 @@ GSState::GSState() m_draw_transfers.clear(); - m_sssize = 0; - - m_sssize += sizeof(m_version); - m_sssize += sizeof(m_env.PRIM); - m_sssize += sizeof(m_env.PRMODECONT); - m_sssize += sizeof(m_env.TEXCLUT); - m_sssize += sizeof(m_env.SCANMSK); - m_sssize += sizeof(m_env.TEXA); - m_sssize += sizeof(m_env.FOGCOL); - m_sssize += sizeof(m_env.DIMX); - m_sssize += sizeof(m_env.DTHE); - m_sssize += sizeof(m_env.COLCLAMP); - m_sssize += sizeof(m_env.PABE); - m_sssize += sizeof(m_env.BITBLTBUF); - m_sssize += sizeof(m_env.TRXDIR); - m_sssize += sizeof(m_env.TRXPOS); - m_sssize += sizeof(m_env.TRXREG); - m_sssize += sizeof(m_env.TRXREG); // obsolete - - for (int i = 0; i < 2; i++) - { - m_sssize += sizeof(m_env.CTXT[i].XYOFFSET); - m_sssize += sizeof(m_env.CTXT[i].TEX0); - m_sssize += sizeof(m_env.CTXT[i].TEX1); - m_sssize += sizeof(m_env.CTXT[i].CLAMP); - m_sssize += sizeof(m_env.CTXT[i].MIPTBP1); - m_sssize += sizeof(m_env.CTXT[i].MIPTBP2); - m_sssize += sizeof(m_env.CTXT[i].SCISSOR); - m_sssize += sizeof(m_env.CTXT[i].ALPHA); - m_sssize += sizeof(m_env.CTXT[i].TEST); - m_sssize += sizeof(m_env.CTXT[i].FBA); - m_sssize += sizeof(m_env.CTXT[i].FRAME); - m_sssize += sizeof(m_env.CTXT[i].ZBUF); - } - - m_sssize += sizeof(m_v.RGBAQ); - m_sssize += sizeof(m_v.ST); - m_sssize += sizeof(m_v.UV); - m_sssize += sizeof(m_v.FOG); - m_sssize += sizeof(m_v.XYZ); - m_sssize += sizeof(GIFReg); // obsolete - - m_sssize += sizeof(m_tr.x); - m_sssize += sizeof(m_tr.y); - m_sssize += m_mem.m_vmsize; - m_sssize += (sizeof(m_path[0].tag) + sizeof(m_path[0].reg)) * std::size(m_path); - m_sssize += sizeof(m_q); - PRIM = &m_env.PRIM; //CSR->rREV = 0x20; m_env.PRMODECONT.AC = 1; @@ -2330,18 +2329,19 @@ int GSState::Freeze(freezeData* fd, bool sizeonly) { if (sizeonly) { - fd->size = m_sssize; + fd->size = GetSaveStateSize(); return 0; } - if (!fd->data || fd->size < m_sssize) + if (!fd->data || fd->size < GetSaveStateSize()) return -1; Flush(GSFlushReason::SAVESTATE); u8* data = fd->data; + const u32 version = STATE_VERSION; - WriteState(data, &m_version); + WriteState(data, &version); WriteState(data, &m_env.PRIM); WriteState(data, &m_env.PRMODECONT); WriteState(data, &m_env.TEXCLUT); @@ -2409,7 +2409,7 @@ int GSState::Defrost(const freezeData* fd) if (!fd || !fd->data || fd->size == 0) return -1; - if (fd->size < m_sssize) + if (fd->size < GetSaveStateSize()) return -1; u8* data = fd->data; @@ -2418,7 +2418,7 @@ int GSState::Defrost(const freezeData* fd) ReadState(&version, data); - if (version > m_version) + if (version > STATE_VERSION) { Console.Error("GS: Savestate version is incompatible. Load aborted."); return -1; @@ -3850,9 +3850,6 @@ GIFRegTEX0 GSState::GetTex0Layer(u32 lod) GSState::GSTransferBuffer::GSTransferBuffer() { - x = y = 0; - start = end = total = 0; - constexpr size_t alloc_size = 1024 * 1024 * 4; buff = reinterpret_cast(_aligned_malloc(alloc_size, 32)); } diff --git a/pcsx2/GS/GSState.h b/pcsx2/GS/GSState.h index 9f16297afb..8036f5a45a 100644 --- a/pcsx2/GS/GSState.h +++ b/pcsx2/GS/GSState.h @@ -35,13 +35,15 @@ public: GSState(); virtual ~GSState(); + static constexpr int GetSaveStateSize(); + private: // RESTRICT prevents multiple loads of the same part of the register when accessing its bitfields (the compiler is happy to know that memory writes in-between will not go there) typedef void (GSState::*GIFPackedRegHandler)(const GIFPackedReg* RESTRICT r); - GIFPackedRegHandler m_fpGIFPackedRegHandlers[16]; - GIFPackedRegHandler m_fpGIFPackedRegHandlerXYZ[8][4]; + GIFPackedRegHandler m_fpGIFPackedRegHandlers[16] = {}; + GIFPackedRegHandler m_fpGIFPackedRegHandlerXYZ[8][4] = {}; void CheckFlushes(); @@ -58,14 +60,14 @@ private: typedef void (GSState::*GIFRegHandler)(const GIFReg* RESTRICT r); - GIFRegHandler m_fpGIFRegHandlers[256]; - GIFRegHandler m_fpGIFRegHandlerXYZ[8][4]; + GIFRegHandler m_fpGIFRegHandlers[256] = {}; + GIFRegHandler m_fpGIFRegHandlerXYZ[8][4] = {}; typedef void (GSState::*GIFPackedRegHandlerC)(const GIFPackedReg* RESTRICT r, u32 size); - GIFPackedRegHandlerC m_fpGIFPackedRegHandlersC[2]; - GIFPackedRegHandlerC m_fpGIFPackedRegHandlerSTQRGBAXYZF2[8]; - GIFPackedRegHandlerC m_fpGIFPackedRegHandlerSTQRGBAXYZ2[8]; + GIFPackedRegHandlerC m_fpGIFPackedRegHandlersC[2] = {}; + GIFPackedRegHandlerC m_fpGIFPackedRegHandlerSTQRGBAXYZF2[8] = {}; + GIFPackedRegHandlerC m_fpGIFPackedRegHandlerSTQRGBAXYZ2[8] = {}; template void GIFPackedRegHandlerSTQRGBAXYZF2(const GIFPackedReg* RESTRICT r, u32 size); template void GIFPackedRegHandlerSTQRGBAXYZ2(const GIFPackedReg* RESTRICT r, u32 size); @@ -117,15 +119,12 @@ private: template void SetPrimHandlers(); - u32 m_version; - int m_sssize; - struct GSTransferBuffer { - int x, y; - int start, end, total; - u8* buff; - GIFRegBITBLTBUF m_blit; + int x = 0, y = 0; + int start = 0, end = 0, total = 0; + u8* buff = nullptr; + GIFRegBITBLTBUF m_blit = {}; GSTransferBuffer(); virtual ~GSTransferBuffer(); @@ -139,14 +138,14 @@ private: void CalcAlphaMinMax(); protected: - GSVertex m_v; - float m_q; - GSVector4i m_scissor; - GSVector4i m_ofxy; + GSVertex m_v = {}; + float m_q = 1.0f; + GSVector4i m_scissor = {}; + GSVector4i m_ofxy = {}; - u8 m_scanmask_used; - bool tex_flushed; - bool m_isPackedUV_HackFlag; + u8 m_scanmask_used = 0; + bool tex_flushed = true; + bool m_isPackedUV_HackFlag = false; struct { @@ -154,13 +153,13 @@ protected: u32 head, tail, next, maxcount; // head: first vertex, tail: last vertex + 1, next: last indexed + 1 u32 xy_tail; u64 xy[4]; - } m_vertex; + } m_vertex = {}; struct { u32* buff; u32 tail; - } m_index; + } m_index = {}; void UpdateContext(); void UpdateScissor(); @@ -213,24 +212,24 @@ public: int draw; }; - GIFPath m_path[4]; - GIFRegPRIM* PRIM; - GSPrivRegSet* m_regs; + GIFPath m_path[4] = {}; + GIFRegPRIM* PRIM = nullptr; + GSPrivRegSet* m_regs = nullptr; GSLocalMemory m_mem; - GSDrawingEnvironment m_env; - GSDrawingEnvironment m_backup_env; - GSDrawingEnvironment m_prev_env; - GSVector4i temp_draw_rect; - GSDrawingContext* m_context; - u32 m_crc; - CRC::Game m_game; + GSDrawingEnvironment m_env = {}; + GSDrawingEnvironment m_backup_env = {}; + GSDrawingEnvironment m_prev_env = {}; + GSVector4i temp_draw_rect = {}; + GSDrawingContext* m_context = nullptr; + u32 m_crc = 0; + CRC::Game m_game = {}; std::unique_ptr m_dump; - bool m_nativeres; - bool m_mipmap; - u32 m_dirty_gs_regs; - int m_backed_up_ctx; + bool m_nativeres = false; + bool m_mipmap = false; + bool m_force_preload = false; + u32 m_dirty_gs_regs = 0; + int m_backed_up_ctx = 0; std::vector m_draw_transfers; - bool m_force_preload; static int s_n; @@ -278,7 +277,7 @@ public: GSREOPEN = 1 << 13, }; - GSFlushReason m_state_flush_reason; + GSFlushReason m_state_flush_reason = UNKNOWN; enum PRIM_OVERLAP { @@ -287,7 +286,7 @@ public: PRIM_OVERLAP_NO }; - PRIM_OVERLAP m_prim_overlap; + PRIM_OVERLAP m_prim_overlap = PRIM_OVERLAP_UNKNOW; std::vector m_drawlist; struct GSPCRTCRegs @@ -297,31 +296,31 @@ public: // these values leave a small black line on the right in a bunch of games, but it's not so bad. // The only conclusion I can come to is there is horizontal overscan expected so there would normally // be black borders either side anyway, or both sides slightly covered. - const GSVector4i VideoModeOffsets[6] = { - GSVector4i(640, 224, 642, 25), - GSVector4i(640, 256, 676, 36), - GSVector4i(640, 480, 276, 34), - GSVector4i(720, 480, 232, 35), - GSVector4i(1280, 720, 302, 24), - GSVector4i(1920, 540, 238, 40) + static inline constexpr GSVector4i VideoModeOffsets[6] = { + GSVector4i::cxpr(640, 224, 642, 25), + GSVector4i::cxpr(640, 256, 676, 36), + GSVector4i::cxpr(640, 480, 276, 34), + GSVector4i::cxpr(720, 480, 232, 35), + GSVector4i::cxpr(1280, 720, 302, 24), + GSVector4i::cxpr(1920, 540, 238, 40) }; - const GSVector4i VideoModeOffsetsOverscan[6] = { - GSVector4i(711, 243, 498, 12), - GSVector4i(702, 288, 532, 18), - GSVector4i(640, 480, 276, 34), - GSVector4i(720, 480, 232, 35), - GSVector4i(1280, 720, 302, 24), - GSVector4i(1920, 540, 238, 40) + static inline constexpr GSVector4i VideoModeOffsetsOverscan[6] = { + GSVector4i::cxpr(711, 243, 498, 12), + GSVector4i::cxpr(702, 288, 532, 18), + GSVector4i::cxpr(640, 480, 276, 34), + GSVector4i::cxpr(720, 480, 232, 35), + GSVector4i::cxpr(1280, 720, 302, 24), + GSVector4i::cxpr(1920, 540, 238, 40) }; - const GSVector4i VideoModeDividers[6] = { - GSVector4i(3, 0, 2559, 239), - GSVector4i(3, 0, 2559, 287), - GSVector4i(1, 0, 1279, 479), - GSVector4i(1, 0, 1439, 479), - GSVector4i(0, 0, 1279, 719), - GSVector4i(0, 0, 1919, 1079) + static inline constexpr GSVector4i VideoModeDividers[6] = { + GSVector4i::cxpr(3, 0, 2559, 239), + GSVector4i::cxpr(3, 0, 2559, 287), + GSVector4i::cxpr(1, 0, 1279, 479), + GSVector4i::cxpr(1, 0, 1439, 479), + GSVector4i::cxpr(0, 0, 1279, 719), + GSVector4i::cxpr(0, 0, 1919, 1079) }; struct PCRTCDisplay @@ -345,12 +344,12 @@ public: } }; - int videomode; - int interlaced; - int FFMD; - bool PCRTCSameSrc; - bool toggling_field; - PCRTCDisplay PCRTCDisplays[2]; + int videomode = 0; + int interlaced = 0; + int FFMD = 0; + bool PCRTCSameSrc = false; + bool toggling_field = false; + PCRTCDisplay PCRTCDisplays[2] = {}; bool IsAnalogue() { diff --git a/pcsx2/GS/Renderers/Common/GSVertexTrace.cpp b/pcsx2/GS/Renderers/Common/GSVertexTrace.cpp index 8062dd0a3a..52bc928879 100644 --- a/pcsx2/GS/Renderers/Common/GSVertexTrace.cpp +++ b/pcsx2/GS/Renderers/Common/GSVertexTrace.cpp @@ -19,10 +19,8 @@ #include "GS/GSState.h" GSVertexTrace::GSVertexTrace(const GSState* state, bool provoking_vertex_first) - : m_accurate_stq(false), m_state(state), m_primclass(GS_INVALID_CLASS) + : m_state(state) { - memset(&m_alpha, 0, sizeof(m_alpha)); - MULTI_ISA_SELECT(GSVertexTracePopulateFunctions)(*this, provoking_vertex_first); } diff --git a/pcsx2/GS/Renderers/Common/GSVertexTrace.h b/pcsx2/GS/Renderers/Common/GSVertexTrace.h index b7e7d0b663..93c507025f 100644 --- a/pcsx2/GS/Renderers/Common/GSVertexTrace.h +++ b/pcsx2/GS/Renderers/Common/GSVertexTrace.h @@ -44,7 +44,7 @@ public: int min, max; bool valid; }; - bool m_accurate_stq; + bool m_accurate_stq = false; protected: const GSState* m_state; @@ -54,25 +54,25 @@ protected: FindMinMaxPtr m_fmm[2][2][2][2][4]; public: - GS_PRIM_CLASS m_primclass; + GS_PRIM_CLASS m_primclass = GS_INVALID_CLASS; - Vertex m_min; - Vertex m_max; - VertexAlpha m_alpha; // source alpha range after tfx, GSRenderer::GetAlphaMinMax() updates it + Vertex m_min = {}; + Vertex m_max = {}; + VertexAlpha m_alpha = {}; // source alpha range after tfx, GSRenderer::GetAlphaMinMax() updates it union { u32 value; struct { u32 r:4, g:4, b:4, a:4, x:1, y:1, z:1, f:1, s:1, t:1, q:1, _pad:1; }; struct { u32 rgba:16, xyzf:4, stq:4; }; - } m_eq; + } m_eq = {}; union { struct { u32 mmag:1, mmin:1, linear:1, opt_linear:1; }; - } m_filter; + } m_filter = {}; - GSVector2 m_lod; // x = min, y = max + GSVector2 m_lod = {}; // x = min, y = max public: GSVertexTrace(const GSState* state, bool provoking_vertex_first); diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp index 75627ca6fb..bc2ca90e32 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp @@ -24,14 +24,6 @@ GSRendererHW::GSRendererHW() : GSRenderer() , m_tc(new GSTextureCache()) - , m_src(nullptr) - , m_reset(false) - , m_tex_is_fb(false) - , m_channel_shuffle(false) - , m_userhacks_tcoffset(false) - , m_userhacks_tcoffset_x(0) - , m_userhacks_tcoffset_y(0) - , m_lod(GSVector2i(0, 0)) { MULTI_ISA_SELECT(GSRendererHWPopulateFunctions)(*this); m_mipmap = (GSConfig.HWMipmap >= HWMipmapLevel::Basic); @@ -44,7 +36,6 @@ GSRendererHW::GSRendererHW() memset(&m_conf, 0, sizeof(m_conf)); - m_prim_overlap = PRIM_OVERLAP_UNKNOW; ResetStates(); } diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.h b/pcsx2/GS/Renderers/HW/GSRendererHW.h index 38443bfd32..fe88fc1011 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.h +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.h @@ -97,8 +97,8 @@ private: void SetTCOffset(); GSTextureCache* m_tc; - GSVector4i m_r; - GSTextureCache::Source* m_src; + GSVector4i m_r = {}; + GSTextureCache::Source* m_src = nullptr; // CRC Hacks bool IsBadFrame(); @@ -107,16 +107,16 @@ private: int m_skip = 0; int m_skip_offset = 0; - bool m_reset; - bool m_tex_is_fb; - bool m_channel_shuffle; - bool m_userhacks_tcoffset; - float m_userhacks_tcoffset_x; - float m_userhacks_tcoffset_y; + bool m_reset = false; + bool m_tex_is_fb = false; + bool m_channel_shuffle = false; + bool m_userhacks_tcoffset = false; + float m_userhacks_tcoffset_x = 0.0f; + float m_userhacks_tcoffset_y = 0.0f; - GSVector2i m_lod; // Min & Max level of detail + GSVector2i m_lod = {}; // Min & Max level of detail - GSHWDrawConfig m_conf; + GSHWDrawConfig m_conf = {}; // software sprite renderer state std::vector m_sw_vertex_buffer;