Skip to content

Commit 91592e3

Browse files
GS rasterizer rework (#132)
* [runtime] Memory swizzling rework Reimplementation of memory swizzling supporting all valid GS texture storage types. An additional optimization was done to improve the speed of lookups. Since page access is linear, we can precompute the non-linear bit (blocks and columns) for an entire page for each format. This reduces the runtime calculation to just calculating the correct page in 2d memory space and then performing a lookup in the table to get the location in memory inside a page. Since all page accesses are the same, this works across all pages. Speed improvements should be compounded by the number of accesses but there might be some reductions as a result of actually implementing formats that were not implemented before. I took care to do this with simple math. GS swizzling is complicated and optimizing it for debug builds is outside the scope of my current work. This is just the standalone code. It will be worked into the current rasterizer in a follow up commit. * [runtime] Reimplement GS host -> local transfers Reimplement the host -> local transfers using new swizzling code * [runtime] Reimplement sampling with new swizzling Reimplements the rasterizer sampling code to use the new swizzling code * [runtime] Replace fb writes with new swizzling Replace the framebuffer write code with the new swizzling code * [runtime] Reduce vram read/write to func lookup Reduces the vram read write switches to a function lookup * [tests] fix GS tests not handling depth test * [runtime] z interpolation and write support Add support for interpolating z from primitives and writing to the z buffer after z testing and masking * [runtime] local to local transfer rework * [runtime] host readout uses new sizzling code plus cleanup some dead code * [runtime] rework local->host transfer update to the new swizzling code * [runtime] update clear function with new swizzling
1 parent 790aaf4 commit 91592e3

10 files changed

Lines changed: 1818 additions & 788 deletions

File tree

ps2xRuntime/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ add_library(ps2_runtime STATIC
167167
src/lib/ps2_audio.cpp
168168
src/lib/ps2_audio_vag.cpp
169169
src/lib/ps2_gs_gpu.cpp
170+
src/lib/ps2_gs_memory.cpp
170171
src/lib/ps2_gs_rasterizer.cpp
171172
src/lib/ps2_iop.cpp
172173
src/lib/ps2_iop_audio.cpp

ps2xRuntime/include/runtime/ps2_gs_gpu.h

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
#ifndef PS2_GS_GPU_H
22
#define PS2_GS_GPU_H
33

4-
#include "ps2_gs_rasterizer.h"
4+
#include <functional>
55
#include <cstdint>
66
#include <cstring>
77
#include <mutex>
88
#include <vector>
99

10+
#include "ps2_gs_rasterizer.h"
11+
#include "ps2_gs_memory.h"
12+
1013
enum GSPrimType : uint8_t
1114
{
1215
GS_PRIM_POINT = 0,
@@ -105,7 +108,9 @@ enum GSRegId : uint8_t
105108

106109
struct GSVertex
107110
{
108-
float x, y, z;
111+
float x, y;
112+
// double because float isnt accurate enough for values near UINT32_MAX
113+
double z;
109114
uint8_t r, g, b, a;
110115
float q;
111116
float s, t;
@@ -121,6 +126,13 @@ struct GSFrameReg
121126
uint32_t fbmsk;
122127
};
123128

129+
struct GSZbufReg
130+
{
131+
u32 zbp;
132+
u8 psm;
133+
bool zmask;
134+
};
135+
124136
struct GSScissorReg
125137
{
126138
uint16_t x0, x1, y0, y1;
@@ -168,7 +180,7 @@ struct GSContext
168180
GSScissorReg scissor;
169181
GSTex0Reg tex0;
170182
GSXYOffsetReg xyoffset;
171-
uint64_t zbuf;
183+
GSZbufReg zbuf;
172184
uint64_t tex1;
173185
uint64_t clamp;
174186
uint64_t alpha;
@@ -249,6 +261,9 @@ class GS
249261

250262
void refreshDisplaySnapshot();
251263

264+
inline void WriteVram(u32 psm, uint32_t base, uint32_t bw, uint32_t x, uint32_t y, uint32_t value);
265+
inline u32 ReadVram(u32 psm, u32 base, u32 bw, u32 x, u32 y) const;
266+
252267
private:
253268
void snapshotVRAM();
254269
void writeRegisterPacked(uint8_t regDesc, uint64_t lo, uint64_t hi);
@@ -292,8 +307,14 @@ class GS
292307
GSTrxPos m_trxpos{};
293308
GSTrxReg m_trxreg{};
294309
uint32_t m_trxdir = 3;
295-
uint32_t m_hwregX = 0;
296-
uint32_t m_hwregY = 0;
310+
311+
struct
312+
{
313+
uint32_t x{ 0 };
314+
uint32_t y{ 0 };
315+
uint32_t total_pixels{ 0 };
316+
uint32_t copied_pixels{ 0 };
317+
} m_transferState;
297318

298319
static constexpr int kMaxVerts = 6;
299320
GSVertex m_vtxQueue[kMaxVerts];
@@ -318,6 +339,22 @@ class GS
318339
size_t m_localToHostReadPos = 0;
319340

320341
GSRasterizer m_rasterizer;
342+
343+
using WriteVramFunc = std::function<void(u8*, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t)>;
344+
using ReadVramFunc = std::function<u32(u8*, u32, u32, u32, u32)>;
345+
346+
std::array<ReadVramFunc, 0x3F> m_read_vram_funcs{ };
347+
std::array<WriteVramFunc, 0x3F> m_write_vram_funcs{ };
321348
};
322349

350+
inline u32 GS::ReadVram(u32 psm, u32 base, u32 bw, u32 x, u32 y) const
351+
{
352+
return m_read_vram_funcs[psm & 0x3F](m_vram, base, bw, x, y);
353+
}
354+
355+
inline void GS::WriteVram(u32 psm, u32 base, u32 bw, u32 x, u32 y, u32 value)
356+
{
357+
m_write_vram_funcs[psm & 0x3F](m_vram, base, bw, x, y, value);
358+
}
359+
323360
#endif

0 commit comments

Comments
 (0)