[GPU] Initialize GPU registers to hardware reset defaults
RegisterFile zeroes the whole register file at construction, but a real console comes up with non-zero values in several of the context registers. If a game reads one of those before writing it, it gets 0 under emulation and the real default on hardware. I read the reset values off a retail console (read-only) and checked them against the AMD R6xx register reference and the r600g defaults in Mesa, which set the same registers to the same values at context init. Where the hardware read matches the driver default it's a genuine power-on default, not leftover runtime state. Left the tessellation levels out on purpose: they reset to 1.0f too, but the backends do register + 1.0f, so seeding them here would change the effective reset factor. That needs its own change.
This commit is contained in:
committed by
Radosław Gliński
parent
bad346717a
commit
e20f26963f
@@ -15,7 +15,38 @@
|
||||
namespace xe {
|
||||
namespace gpu {
|
||||
|
||||
RegisterFile::RegisterFile() { std::memset(values, 0, sizeof(values)); }
|
||||
RegisterFile::RegisterFile() {
|
||||
std::memset(values, 0, sizeof(values));
|
||||
|
||||
// Several context registers power up with non-zero values on real Xenos
|
||||
// hardware, so a title that reads one of them before writing it would
|
||||
// otherwise observe 0. These are the hardware reset defaults, corroborated by
|
||||
// the AMD R6xx/R7xx 3D register reference and the Mesa r600g driver, which
|
||||
// programs the same registers to the same values at context init.
|
||||
values[XE_GPU_REG_VGT_MAX_VTX_INDX] = 0x0000FFFF;
|
||||
values[XE_GPU_REG_VGT_MULTI_PRIM_IB_RESET_INDX] = 0x0000FFFF;
|
||||
values[XE_GPU_REG_PA_SC_SCREEN_SCISSOR_BR] = 0x20002000; // 8192 x 8192
|
||||
values[XE_GPU_REG_RB_STENCILREFMASK_BF] = 0x00FFFF00;
|
||||
values[XE_GPU_REG_PA_SU_POINT_SIZE] = 0x00080008;
|
||||
values[XE_GPU_REG_PA_SU_POINT_MINMAX] = 0x04000010;
|
||||
values[XE_GPU_REG_PA_SU_LINE_CNTL] = 0x00000008;
|
||||
values[XE_GPU_REG_PA_SC_LINE_CNTL] = 0x00000400;
|
||||
values[XE_GPU_REG_VGT_HOS_REUSE_DEPTH] = 0x0000000E;
|
||||
values[XE_GPU_REG_VGT_VERTEX_REUSE_BLOCK_CNTL] = 0x0000000E;
|
||||
values[XE_GPU_REG_VGT_OUT_DEALLOC_CNTL] = 0x00000010;
|
||||
// Guard-band clip/discard adjust (2.0 clip, 1.0 discard); hardwired on
|
||||
// hardware.
|
||||
values[XE_GPU_REG_PA_CL_GB_VERT_CLIP_ADJ] = 0x40000000; // 2.0f
|
||||
values[XE_GPU_REG_PA_CL_GB_VERT_DISC_ADJ] = 0x3F800000; // 1.0f
|
||||
values[XE_GPU_REG_PA_CL_GB_HORZ_CLIP_ADJ] = 0x40000000; // 2.0f
|
||||
values[XE_GPU_REG_PA_CL_GB_HORZ_DISC_ADJ] = 0x3F800000; // 1.0f
|
||||
values[XE_GPU_REG_PA_SC_AA_MASK] = 0x0000FFFF;
|
||||
// Tessellation levels also reset to 1.0f on hardware, but the backends apply
|
||||
// the effective factor as (register + 1.0f), so initializing them here would
|
||||
// change the effective reset factor; left out for separate review.
|
||||
// values[XE_GPU_REG_VGT_HOS_MAX_TESS_LEVEL] = 0x3F800000; // 1.0f
|
||||
// values[XE_GPU_REG_VGT_HOS_MIN_TESS_LEVEL] = 0x3F800000; // 1.0f
|
||||
}
|
||||
constexpr unsigned int GetHighestRegisterNumber() {
|
||||
uint32_t highest = 0;
|
||||
#define XE_GPU_REGISTER(index, type, name) \
|
||||
|
||||
Reference in New Issue
Block a user