summaryrefslogtreecommitdiffstats
path: root/src/video_core/engines
diff options
context:
space:
mode:
authorKelebek1 <eeeedddccc@hotmail.co.uk>2022-08-12 11:58:09 +0200
committerKelebek1 <eeeedddccc@hotmail.co.uk>2022-10-07 15:13:45 +0200
commit752659aef3f16111981a097989dd7a5ddecff316 (patch)
tree775fbe8d1a478b2b8c201d86432743d4f3ddb2a4 /src/video_core/engines
parentMerge pull request #6142 from lat9nq/prog_meta_ref_bind_address (diff)
downloadyuzu-752659aef3f16111981a097989dd7a5ddecff316.tar
yuzu-752659aef3f16111981a097989dd7a5ddecff316.tar.gz
yuzu-752659aef3f16111981a097989dd7a5ddecff316.tar.bz2
yuzu-752659aef3f16111981a097989dd7a5ddecff316.tar.lz
yuzu-752659aef3f16111981a097989dd7a5ddecff316.tar.xz
yuzu-752659aef3f16111981a097989dd7a5ddecff316.tar.zst
yuzu-752659aef3f16111981a097989dd7a5ddecff316.zip
Diffstat (limited to 'src/video_core/engines')
-rw-r--r--src/video_core/engines/maxwell_3d.cpp336
-rw-r--r--src/video_core/engines/maxwell_3d.h3839
2 files changed, 2997 insertions, 1178 deletions
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 3c6e44a25..84c1abf3d 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -56,37 +56,37 @@ void Maxwell3D::InitializeRegisterDefaults() {
// Doom and Bomberman seems to use the uninitialized registers and just enable blend
// so initialize blend registers with sane values
- regs.blend.equation_rgb = Regs::Blend::Equation::Add;
- regs.blend.factor_source_rgb = Regs::Blend::Factor::One;
- regs.blend.factor_dest_rgb = Regs::Blend::Factor::Zero;
- regs.blend.equation_a = Regs::Blend::Equation::Add;
- regs.blend.factor_source_a = Regs::Blend::Factor::One;
- regs.blend.factor_dest_a = Regs::Blend::Factor::Zero;
- for (auto& blend : regs.independent_blend) {
- blend.equation_rgb = Regs::Blend::Equation::Add;
- blend.factor_source_rgb = Regs::Blend::Factor::One;
- blend.factor_dest_rgb = Regs::Blend::Factor::Zero;
- blend.equation_a = Regs::Blend::Equation::Add;
- blend.factor_source_a = Regs::Blend::Factor::One;
- blend.factor_dest_a = Regs::Blend::Factor::Zero;
- }
- regs.stencil_front_op_fail = Regs::StencilOp::Keep;
- regs.stencil_front_op_zfail = Regs::StencilOp::Keep;
- regs.stencil_front_op_zpass = Regs::StencilOp::Keep;
- regs.stencil_front_func_func = Regs::ComparisonOp::Always;
- regs.stencil_front_func_mask = 0xFFFFFFFF;
- regs.stencil_front_mask = 0xFFFFFFFF;
+ regs.blend.color_op = Regs::Blend::Equation::Add_D3D;
+ regs.blend.color_source = Regs::Blend::Factor::One_D3D;
+ regs.blend.color_dest = Regs::Blend::Factor::Zero_D3D;
+ regs.blend.alpha_op = Regs::Blend::Equation::Add_D3D;
+ regs.blend.alpha_source = Regs::Blend::Factor::One_D3D;
+ regs.blend.alpha_dest = Regs::Blend::Factor::Zero_D3D;
+ for (auto& blend : regs.blend_per_target) {
+ blend.color_op = Regs::Blend::Equation::Add_D3D;
+ blend.color_source = Regs::Blend::Factor::One_D3D;
+ blend.color_dest = Regs::Blend::Factor::Zero_D3D;
+ blend.alpha_op = Regs::Blend::Equation::Add_D3D;
+ blend.alpha_source = Regs::Blend::Factor::One_D3D;
+ blend.alpha_dest = Regs::Blend::Factor::Zero_D3D;
+ }
+ regs.stencil_front_op.fail = Regs::StencilOp::Op::Keep_D3D;
+ regs.stencil_front_op.zfail = Regs::StencilOp::Op::Keep_D3D;
+ regs.stencil_front_op.zpass = Regs::StencilOp::Op::Keep_D3D;
+ regs.stencil_front_op.func = Regs::ComparisonOp::Always_GL;
+ regs.stencil_front_func.func_mask = 0xFFFFFFFF;
+ regs.stencil_front_func.mask = 0xFFFFFFFF;
regs.stencil_two_side_enable = 1;
- regs.stencil_back_op_fail = Regs::StencilOp::Keep;
- regs.stencil_back_op_zfail = Regs::StencilOp::Keep;
- regs.stencil_back_op_zpass = Regs::StencilOp::Keep;
- regs.stencil_back_func_func = Regs::ComparisonOp::Always;
- regs.stencil_back_func_mask = 0xFFFFFFFF;
- regs.stencil_back_mask = 0xFFFFFFFF;
+ regs.stencil_back_op.fail = Regs::StencilOp::Op::Keep_D3D;
+ regs.stencil_back_op.zfail = Regs::StencilOp::Op::Keep_D3D;
+ regs.stencil_back_op.zpass = Regs::StencilOp::Op::Keep_D3D;
+ regs.stencil_back_op.func = Regs::ComparisonOp::Always_GL;
+ regs.stencil_back_func.func_mask = 0xFFFFFFFF;
+ regs.stencil_back_func.mask = 0xFFFFFFFF;
- regs.depth_test_func = Regs::ComparisonOp::Always;
- regs.front_face = Regs::FrontFace::CounterClockWise;
- regs.cull_face = Regs::CullFace::Back;
+ regs.depth_test_func = Regs::ComparisonOp::Always_GL;
+ regs.gl_front_face = Regs::FrontFace::CounterClockWise;
+ regs.gl_cull_face = Regs::CullFace::Back;
// TODO(Rodrigo): Most games do not set a point size. I think this is a case of a
// register carrying a default value. Assume it's OpenGL's default (1).
@@ -107,20 +107,20 @@ void Maxwell3D::InitializeRegisterDefaults() {
// NVN games expect these values to be enabled at boot
regs.rasterize_enable = 1;
- regs.rt_separate_frag_data = 1;
+ regs.color_target_mrt_enable = 1;
regs.framebuffer_srgb = 1;
regs.line_width_aliased = 1.0f;
regs.line_width_smooth = 1.0f;
- regs.front_face = Maxwell3D::Regs::FrontFace::ClockWise;
+ regs.gl_front_face = Maxwell3D::Regs::FrontFace::ClockWise;
regs.polygon_mode_back = Maxwell3D::Regs::PolygonMode::Fill;
regs.polygon_mode_front = Maxwell3D::Regs::PolygonMode::Fill;
shadow_state = regs;
- mme_inline[MAXWELL3D_REG_INDEX(draw.vertex_end_gl)] = true;
- mme_inline[MAXWELL3D_REG_INDEX(draw.vertex_begin_gl)] = true;
+ mme_inline[MAXWELL3D_REG_INDEX(draw.end)] = true;
+ mme_inline[MAXWELL3D_REG_INDEX(draw.begin)] = true;
mme_inline[MAXWELL3D_REG_INDEX(vertex_buffer.count)] = true;
- mme_inline[MAXWELL3D_REG_INDEX(index_array.count)] = true;
+ mme_inline[MAXWELL3D_REG_INDEX(index_buffer.count)] = true;
}
void Maxwell3D::ProcessMacro(u32 method, const u32* base_start, u32 amount, bool is_last_call) {
@@ -173,51 +173,56 @@ void Maxwell3D::ProcessMethodCall(u32 method, u32 argument, u32 nonshadow_argume
case MAXWELL3D_REG_INDEX(shadow_ram_control):
shadow_state.shadow_ram_control = static_cast<Regs::ShadowRamControl>(nonshadow_argument);
return;
- case MAXWELL3D_REG_INDEX(macros.upload_address):
- return macro_engine->ClearCode(regs.macros.upload_address);
- case MAXWELL3D_REG_INDEX(macros.data):
- return macro_engine->AddCode(regs.macros.upload_address, argument);
- case MAXWELL3D_REG_INDEX(macros.bind):
+ case MAXWELL3D_REG_INDEX(load_mme.instruction_ptr):
+ return macro_engine->ClearCode(regs.load_mme.instruction_ptr);
+ case MAXWELL3D_REG_INDEX(load_mme.instruction):
+ return macro_engine->AddCode(regs.load_mme.instruction_ptr, argument);
+ case MAXWELL3D_REG_INDEX(load_mme.start_address):
return ProcessMacroBind(argument);
- case MAXWELL3D_REG_INDEX(firmware[4]):
+ case MAXWELL3D_REG_INDEX(falcon[4]):
return ProcessFirmwareCall4();
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 1:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 2:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 3:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 4:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 5:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 6:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 7:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 8:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 9:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 10:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 11:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 12:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 13:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 14:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 15:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer):
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 1:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 2:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 3:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 4:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 5:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 6:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 7:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 8:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 9:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 10:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 11:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 12:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 13:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 14:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 15:
return ProcessCBData(argument);
- case MAXWELL3D_REG_INDEX(cb_bind[0]):
+ case MAXWELL3D_REG_INDEX(bind_groups[0].raw_config):
return ProcessCBBind(0);
- case MAXWELL3D_REG_INDEX(cb_bind[1]):
+ case MAXWELL3D_REG_INDEX(bind_groups[1].raw_config):
return ProcessCBBind(1);
- case MAXWELL3D_REG_INDEX(cb_bind[2]):
+ case MAXWELL3D_REG_INDEX(bind_groups[2].raw_config):
return ProcessCBBind(2);
- case MAXWELL3D_REG_INDEX(cb_bind[3]):
+ case MAXWELL3D_REG_INDEX(bind_groups[3].raw_config):
return ProcessCBBind(3);
- case MAXWELL3D_REG_INDEX(cb_bind[4]):
+ case MAXWELL3D_REG_INDEX(bind_groups[4].raw_config):
return ProcessCBBind(4);
- case MAXWELL3D_REG_INDEX(draw.vertex_end_gl):
+ case MAXWELL3D_REG_INDEX(draw.end):
return DrawArrays();
- case MAXWELL3D_REG_INDEX(small_index):
- regs.index_array.count = regs.small_index.count;
- regs.index_array.first = regs.small_index.first;
+ case MAXWELL3D_REG_INDEX(index_buffer32_first):
+ regs.index_buffer.count = regs.index_buffer32_first.count;
+ regs.index_buffer.first = regs.index_buffer32_first.first;
dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
return DrawArrays();
- case MAXWELL3D_REG_INDEX(small_index_2):
- regs.index_array.count = regs.small_index_2.count;
- regs.index_array.first = regs.small_index_2.first;
+ case MAXWELL3D_REG_INDEX(index_buffer16_first):
+ regs.index_buffer.count = regs.index_buffer16_first.count;
+ regs.index_buffer.first = regs.index_buffer16_first.first;
+ dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
+ return DrawArrays();
+ case MAXWELL3D_REG_INDEX(index_buffer8_first):
+ regs.index_buffer.count = regs.index_buffer8_first.count;
+ regs.index_buffer.first = regs.index_buffer8_first.first;
dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
// a macro calls this one over and over, should it increase instancing?
// Used by Hades and likely other Vulkan games.
@@ -225,28 +230,24 @@ void Maxwell3D::ProcessMethodCall(u32 method, u32 argument, u32 nonshadow_argume
case MAXWELL3D_REG_INDEX(topology_override):
use_topology_override = true;
return;
- case MAXWELL3D_REG_INDEX(clear_buffers):
+ case MAXWELL3D_REG_INDEX(clear_surface):
return ProcessClearBuffers();
- case MAXWELL3D_REG_INDEX(query.query_get):
+ case MAXWELL3D_REG_INDEX(report_semaphore.query):
return ProcessQueryGet();
- case MAXWELL3D_REG_INDEX(condition.mode):
+ case MAXWELL3D_REG_INDEX(render_enable.mode):
return ProcessQueryCondition();
- case MAXWELL3D_REG_INDEX(counter_reset):
+ case MAXWELL3D_REG_INDEX(clear_report_value):
return ProcessCounterReset();
case MAXWELL3D_REG_INDEX(sync_info):
return ProcessSyncPoint();
- case MAXWELL3D_REG_INDEX(exec_upload):
- return upload_state.ProcessExec(regs.exec_upload.linear != 0);
- case MAXWELL3D_REG_INDEX(data_upload):
+ case MAXWELL3D_REG_INDEX(launch_dma):
+ return upload_state.ProcessExec(regs.launch_dma.memory_layout.Value() ==
+ Regs::LaunchDMA::Layout::Pitch);
+ case MAXWELL3D_REG_INDEX(inline_data):
upload_state.ProcessData(argument, is_last_call);
return;
case MAXWELL3D_REG_INDEX(fragment_barrier):
return rasterizer->FragmentBarrier();
- case MAXWELL3D_REG_INDEX(invalidate_texture_data_cache):
- rasterizer->InvalidateGPUCache();
- return rasterizer->WaitForIdle();
- case MAXWELL3D_REG_INDEX(tiled_cache_barrier):
- return rasterizer->TiledCacheBarrier();
}
}
@@ -296,25 +297,25 @@ void Maxwell3D::CallMultiMethod(u32 method, const u32* base_start, u32 amount,
return;
}
switch (method) {
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 1:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 2:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 3:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 4:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 5:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 6:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 7:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 8:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 9:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 10:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 11:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 12:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 13:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 14:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 15:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer):
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 1:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 2:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 3:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 4:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 5:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 6:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 7:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 8:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 9:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 10:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 11:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 12:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 13:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 14:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 15:
ProcessCBMultiData(base_start, amount);
break;
- case MAXWELL3D_REG_INDEX(data_upload):
+ case MAXWELL3D_REG_INDEX(inline_data):
upload_state.ProcessData(base_start, static_cast<size_t>(amount));
return;
default:
@@ -353,14 +354,15 @@ void Maxwell3D::CallMethodFromMME(u32 method, u32 method_argument) {
if (mme_inline[method]) {
regs.reg_array[method] = method_argument;
if (method == MAXWELL3D_REG_INDEX(vertex_buffer.count) ||
- method == MAXWELL3D_REG_INDEX(index_array.count)) {
+ method == MAXWELL3D_REG_INDEX(index_buffer.count)) {
const MMEDrawMode expected_mode = method == MAXWELL3D_REG_INDEX(vertex_buffer.count)
? MMEDrawMode::Array
: MMEDrawMode::Indexed;
StepInstance(expected_mode, method_argument);
- } else if (method == MAXWELL3D_REG_INDEX(draw.vertex_begin_gl)) {
+ } else if (method == MAXWELL3D_REG_INDEX(draw.begin)) {
mme_draw.instance_mode =
- (regs.draw.instance_next != 0) || (regs.draw.instance_cont != 0);
+ (regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::Subsequent) ||
+ (regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::Unchanged);
mme_draw.gl_begin_consume = true;
} else {
mme_draw.gl_end_count++;
@@ -405,11 +407,12 @@ void Maxwell3D::ProcessTopologyOverride() {
void Maxwell3D::FlushMMEInlineDraw() {
LOG_TRACE(HW_GPU, "called, topology={}, count={}", regs.draw.topology.Value(),
regs.vertex_buffer.count);
- ASSERT_MSG(!(regs.index_array.count && regs.vertex_buffer.count), "Both indexed and direct?");
+ ASSERT_MSG(!(regs.index_buffer.count && regs.vertex_buffer.count), "Both indexed and direct?");
ASSERT(mme_draw.instance_count == mme_draw.gl_end_count);
// Both instance configuration registers can not be set at the same time.
- ASSERT_MSG(!regs.draw.instance_next || !regs.draw.instance_cont,
+ ASSERT_MSG(regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::First ||
+ regs.draw.instance_id != Maxwell3D::Regs::Draw::InstanceId::Unchanged,
"Illegal combination of instancing parameters");
ProcessTopologyOverride();
@@ -424,7 +427,7 @@ void Maxwell3D::FlushMMEInlineDraw() {
// it's possible that it is incorrect and that there is some other register used to specify the
// drawing mode.
if (is_indexed) {
- regs.index_array.count = 0;
+ regs.index_buffer.count = 0;
} else {
regs.vertex_buffer.count = 0;
}
@@ -437,11 +440,11 @@ void Maxwell3D::FlushMMEInlineDraw() {
}
void Maxwell3D::ProcessMacroUpload(u32 data) {
- macro_engine->AddCode(regs.macros.upload_address++, data);
+ macro_engine->AddCode(regs.load_mme.instruction_ptr++, data);
}
void Maxwell3D::ProcessMacroBind(u32 data) {
- macro_positions[regs.macros.entry++] = data;
+ macro_positions[regs.load_mme.start_address_ptr++] = data;
}
void Maxwell3D::ProcessFirmwareCall4() {
@@ -449,11 +452,11 @@ void Maxwell3D::ProcessFirmwareCall4() {
// Firmware call 4 is a blob that changes some registers depending on its parameters.
// These registers don't affect emulation and so are stubbed by setting 0xd00 to 1.
- regs.reg_array[0xd00] = 1;
+ regs.shadow_scratch[0] = 1;
}
void Maxwell3D::StampQueryResult(u64 payload, bool long_query) {
- const GPUVAddr sequence_address{regs.query.QueryAddress()};
+ const GPUVAddr sequence_address{regs.report_semaphore.Address()};
if (long_query) {
memory_manager.Write<u64>(sequence_address + sizeof(u64), system.GPU().GetTicks());
memory_manager.Write<u64>(sequence_address, payload);
@@ -464,15 +467,17 @@ void Maxwell3D::StampQueryResult(u64 payload, bool long_query) {
void Maxwell3D::ProcessQueryGet() {
// TODO(Subv): Support the other query units.
- if (regs.query.query_get.unit != Regs::QueryUnit::Crop) {
- LOG_DEBUG(HW_GPU, "Units other than CROP are unimplemented");
+ if (regs.report_semaphore.query.location != Regs::ReportSemaphore::Location::All) {
+ LOG_DEBUG(HW_GPU, "Locations other than ALL are unimplemented");
}
- switch (regs.query.query_get.operation) {
- case Regs::QueryOperation::Release:
- if (regs.query.query_get.fence == 1 || regs.query.query_get.short_query != 0) {
- const GPUVAddr sequence_address{regs.query.QueryAddress()};
- const u32 payload = regs.query.query_sequence;
+ switch (regs.report_semaphore.query.operation) {
+ case Regs::ReportSemaphore::Operation::Release:
+ if (regs.report_semaphore.query.release ==
+ Regs::ReportSemaphore::Release::AfterAllPreceedingWrites ||
+ regs.report_semaphore.query.short_query != 0) {
+ const GPUVAddr sequence_address{regs.report_semaphore.Address()};
+ const u32 payload = regs.report_semaphore.payload;
std::function<void()> operation([this, sequence_address, payload] {
memory_manager.Write<u32>(sequence_address, payload);
});
@@ -482,8 +487,8 @@ void Maxwell3D::ProcessQueryGet() {
u64_le value;
u64_le timestamp;
};
- const GPUVAddr sequence_address{regs.query.QueryAddress()};
- const u32 payload = regs.query.query_sequence;
+ const GPUVAddr sequence_address{regs.report_semaphore.Address()};
+ const u32 payload = regs.report_semaphore.payload;
std::function<void()> operation([this, sequence_address, payload] {
memory_manager.Write<u64>(sequence_address + sizeof(u64), system.GPU().GetTicks());
memory_manager.Write<u64>(sequence_address, payload);
@@ -491,19 +496,19 @@ void Maxwell3D::ProcessQueryGet() {
rasterizer->SyncOperation(std::move(operation));
}
break;
- case Regs::QueryOperation::Acquire:
+ case Regs::ReportSemaphore::Operation::Acquire:
// TODO(Blinkhawk): Under this operation, the GPU waits for the CPU to write a value that
// matches the current payload.
UNIMPLEMENTED_MSG("Unimplemented query operation ACQUIRE");
break;
- case Regs::QueryOperation::Counter:
+ case Regs::ReportSemaphore::Operation::ReportOnly:
if (const std::optional<u64> result = GetQueryResult()) {
// If the query returns an empty optional it means it's cached and deferred.
// In this case we have a non-empty result, so we stamp it immediately.
- StampQueryResult(*result, regs.query.query_get.short_query == 0);
+ StampQueryResult(*result, regs.report_semaphore.query.short_query == 0);
}
break;
- case Regs::QueryOperation::Trap:
+ case Regs::ReportSemaphore::Operation::Trap:
UNIMPLEMENTED_MSG("Unimplemented query operation TRAP");
break;
default:
@@ -513,31 +518,31 @@ void Maxwell3D::ProcessQueryGet() {
}
void Maxwell3D::ProcessQueryCondition() {
- const GPUVAddr condition_address{regs.condition.Address()};
- switch (regs.condition.mode) {
- case Regs::ConditionMode::Always: {
+ const GPUVAddr condition_address{regs.render_enable.Address()};
+ switch (regs.render_enable.mode) {
+ case Regs::RenderEnable::Mode::True: {
execute_on = true;
break;
}
- case Regs::ConditionMode::Never: {
+ case Regs::RenderEnable::Mode::False: {
execute_on = false;
break;
}
- case Regs::ConditionMode::ResNonZero: {
- Regs::QueryCompare cmp;
+ case Regs::RenderEnable::Mode::Conditional: {
+ Regs::ReportSemaphore::Compare cmp;
memory_manager.ReadBlock(condition_address, &cmp, sizeof(cmp));
execute_on = cmp.initial_sequence != 0U && cmp.initial_mode != 0U;
break;
}
- case Regs::ConditionMode::Equal: {
- Regs::QueryCompare cmp;
+ case Regs::RenderEnable::Mode::IfEqual: {
+ Regs::ReportSemaphore::Compare cmp;
memory_manager.ReadBlock(condition_address, &cmp, sizeof(cmp));
execute_on =
cmp.initial_sequence == cmp.current_sequence && cmp.initial_mode == cmp.current_mode;
break;
}
- case Regs::ConditionMode::NotEqual: {
- Regs::QueryCompare cmp;
+ case Regs::RenderEnable::Mode::IfNotEqual: {
+ Regs::ReportSemaphore::Compare cmp;
memory_manager.ReadBlock(condition_address, &cmp, sizeof(cmp));
execute_on =
cmp.initial_sequence != cmp.current_sequence || cmp.initial_mode != cmp.current_mode;
@@ -552,21 +557,21 @@ void Maxwell3D::ProcessQueryCondition() {
}
void Maxwell3D::ProcessCounterReset() {
- switch (regs.counter_reset) {
- case Regs::CounterReset::SampleCnt:
+ switch (regs.clear_report_value) {
+ case Regs::ClearReport::ZPassPixelCount:
rasterizer->ResetCounter(QueryType::SamplesPassed);
break;
default:
- LOG_DEBUG(Render_OpenGL, "Unimplemented counter reset={}", regs.counter_reset);
+ LOG_DEBUG(Render_OpenGL, "Unimplemented counter reset={}", regs.clear_report_value);
break;
}
}
void Maxwell3D::ProcessSyncPoint() {
const u32 sync_point = regs.sync_info.sync_point.Value();
- const u32 increment = regs.sync_info.increment.Value();
- [[maybe_unused]] const u32 cache_flush = regs.sync_info.unknown.Value();
- if (increment) {
+ const auto condition = regs.sync_info.condition.Value();
+ [[maybe_unused]] const u32 cache_flush = regs.sync_info.clean_l2.Value();
+ if (condition == Regs::SyncInfo::Condition::RopWritesDone) {
rasterizer->SignalSyncPoint(sync_point);
}
}
@@ -574,23 +579,24 @@ void Maxwell3D::ProcessSyncPoint() {
void Maxwell3D::DrawArrays() {
LOG_TRACE(HW_GPU, "called, topology={}, count={}", regs.draw.topology.Value(),
regs.vertex_buffer.count);
- ASSERT_MSG(!(regs.index_array.count && regs.vertex_buffer.count), "Both indexed and direct?");
+ ASSERT_MSG(!(regs.index_buffer.count && regs.vertex_buffer.count), "Both indexed and direct?");
// Both instance configuration registers can not be set at the same time.
- ASSERT_MSG(!regs.draw.instance_next || !regs.draw.instance_cont,
+ ASSERT_MSG(regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::First ||
+ regs.draw.instance_id != Maxwell3D::Regs::Draw::InstanceId::Unchanged,
"Illegal combination of instancing parameters");
ProcessTopologyOverride();
- if (regs.draw.instance_next) {
+ if (regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::Subsequent) {
// Increment the current instance *before* drawing.
- state.current_instance += 1;
- } else if (!regs.draw.instance_cont) {
+ state.current_instance++;
+ } else if (regs.draw.instance_id != Maxwell3D::Regs::Draw::InstanceId::Unchanged) {
// Reset the current instance to 0.
state.current_instance = 0;
}
- const bool is_indexed{regs.index_array.count && !regs.vertex_buffer.count};
+ const bool is_indexed{regs.index_buffer.count && !regs.vertex_buffer.count};
if (ShouldExecute()) {
rasterizer->Draw(is_indexed, false);
}
@@ -600,60 +606,60 @@ void Maxwell3D::DrawArrays() {
// it's possible that it is incorrect and that there is some other register used to specify the
// drawing mode.
if (is_indexed) {
- regs.index_array.count = 0;
+ regs.index_buffer.count = 0;
} else {
regs.vertex_buffer.count = 0;
}
}
std::optional<u64> Maxwell3D::GetQueryResult() {
- switch (regs.query.query_get.select) {
- case Regs::QuerySelect::Payload:
- return regs.query.query_sequence;
- case Regs::QuerySelect::SamplesPassed:
+ switch (regs.report_semaphore.query.report) {
+ case Regs::ReportSemaphore::Report::Payload:
+ return regs.report_semaphore.payload;
+ case Regs::ReportSemaphore::Report::ZPassPixelCount64:
// Deferred.
- rasterizer->Query(regs.query.QueryAddress(), QueryType::SamplesPassed,
+ rasterizer->Query(regs.report_semaphore.Address(), QueryType::SamplesPassed,
system.GPU().GetTicks());
return std::nullopt;
default:
- LOG_DEBUG(HW_GPU, "Unimplemented query select type {}",
- regs.query.query_get.select.Value());
+ LOG_DEBUG(HW_GPU, "Unimplemented query report type {}",
+ regs.report_semaphore.query.report.Value());
return 1;
}
}
void Maxwell3D::ProcessCBBind(size_t stage_index) {
// Bind the buffer currently in CB_ADDRESS to the specified index in the desired shader stage.
- const auto& bind_data = regs.cb_bind[stage_index];
- auto& buffer = state.shader_stages[stage_index].const_buffers[bind_data.index];
+ const auto& bind_data = regs.bind_groups[stage_index];
+ auto& buffer = state.shader_stages[stage_index].const_buffers[bind_data.shader_slot];
buffer.enabled = bind_data.valid.Value() != 0;
- buffer.address = regs.const_buffer.BufferAddress();
- buffer.size = regs.const_buffer.cb_size;
+ buffer.address = regs.const_buffer.Address();
+ buffer.size = regs.const_buffer.size;
const bool is_enabled = bind_data.valid.Value() != 0;
if (!is_enabled) {
- rasterizer->DisableGraphicsUniformBuffer(stage_index, bind_data.index);
+ rasterizer->DisableGraphicsUniformBuffer(stage_index, bind_data.shader_slot);
return;
}
- const GPUVAddr gpu_addr = regs.const_buffer.BufferAddress();
- const u32 size = regs.const_buffer.cb_size;
- rasterizer->BindGraphicsUniformBuffer(stage_index, bind_data.index, gpu_addr, size);
+ const GPUVAddr gpu_addr = regs.const_buffer.Address();
+ const u32 size = regs.const_buffer.size;
+ rasterizer->BindGraphicsUniformBuffer(stage_index, bind_data.shader_slot, gpu_addr, size);
}
void Maxwell3D::ProcessCBMultiData(const u32* start_base, u32 amount) {
// Write the input value to the current const buffer at the current position.
- const GPUVAddr buffer_address = regs.const_buffer.BufferAddress();
+ const GPUVAddr buffer_address = regs.const_buffer.Address();
ASSERT(buffer_address != 0);
// Don't allow writing past the end of the buffer.
- ASSERT(regs.const_buffer.cb_pos <= regs.const_buffer.cb_size);
+ ASSERT(regs.const_buffer.offset <= regs.const_buffer.size);
- const GPUVAddr address{buffer_address + regs.const_buffer.cb_pos};
+ const GPUVAddr address{buffer_address + regs.const_buffer.offset};
const size_t copy_size = amount * sizeof(u32);
memory_manager.WriteBlock(address, start_base, copy_size);
// Increment the current buffer position.
- regs.const_buffer.cb_pos += static_cast<u32>(copy_size);
+ regs.const_buffer.offset += static_cast<u32>(copy_size);
}
void Maxwell3D::ProcessCBData(u32 value) {
@@ -661,7 +667,8 @@ void Maxwell3D::ProcessCBData(u32 value) {
}
Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const {
- const GPUVAddr tic_address_gpu{regs.tic.Address() + tic_index * sizeof(Texture::TICEntry)};
+ const GPUVAddr tic_address_gpu{regs.tex_header.Address() +
+ tic_index * sizeof(Texture::TICEntry)};
Texture::TICEntry tic_entry;
memory_manager.ReadBlockUnsafe(tic_address_gpu, &tic_entry, sizeof(Texture::TICEntry));
@@ -670,7 +677,8 @@ Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const {
}
Texture::TSCEntry Maxwell3D::GetTSCEntry(u32 tsc_index) const {
- const GPUVAddr tsc_address_gpu{regs.tsc.Address() + tsc_index * sizeof(Texture::TSCEntry)};
+ const GPUVAddr tsc_address_gpu{regs.tex_sampler.Address() +
+ tsc_index * sizeof(Texture::TSCEntry)};
Texture::TSCEntry tsc_entry;
memory_manager.ReadBlockUnsafe(tsc_address_gpu, &tsc_entry, sizeof(Texture::TSCEntry));
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 5f9eb208c..efe1073b0 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -39,12 +39,15 @@ namespace Tegra::Engines {
/**
* This Engine is known as GF100_3D. Documentation can be found in:
+ * https://github.com/NVIDIA/open-gpu-doc/blob/master/classes/3d/clb197.h
* https://github.com/envytools/envytools/blob/master/rnndb/graph/gf100_3d.xml
* https://cgit.freedesktop.org/mesa/mesa/tree/src/gallium/drivers/nouveau/nvc0/nvc0_3d.xml.h
+ *
+ * Note: nVidia have confirmed that their open docs have had parts redacted, so this list is
+ * currently incomplete, and the gaps are still worth exploring.
*/
-#define MAXWELL3D_REG_INDEX(field_name) \
- (offsetof(Tegra::Engines::Maxwell3D::Regs, field_name) / sizeof(u32))
+#define MAXWELL3D_REG_INDEX(field_name) (offsetof(Maxwell3D::Regs, field_name) / sizeof(u32))
class Maxwell3D final : public EngineInterface {
public:
@@ -55,7 +58,6 @@ public:
void BindRasterizer(VideoCore::RasterizerInterface* rasterizer);
/// Register structure of the Maxwell3D engine.
- /// TODO(Subv): This structure will need to be made bigger as more registers are discovered.
struct Regs {
static constexpr std::size_t NUM_REGS = 0xE00;
@@ -74,90 +76,515 @@ public:
static constexpr std::size_t MaxConstBuffers = 18;
static constexpr std::size_t MaxConstBufferSize = 0x10000;
- enum class QueryOperation : u32 {
- Release = 0,
- Acquire = 1,
- Counter = 2,
- Trap = 3,
+ struct ID {
+ union {
+ BitField<0, 16, u32> cls;
+ BitField<16, 5, u32> engine;
+ };
};
- enum class QueryUnit : u32 {
- VFetch = 1,
- VP = 2,
- Rast = 4,
- StrmOut = 5,
- GP = 6,
- ZCull = 7,
- Prop = 10,
- Crop = 15,
+ struct LoadMME {
+ u32 instruction_ptr;
+ u32 instruction;
+ u32 start_address_ptr;
+ u32 start_address;
};
- enum class QuerySelect : u32 {
- Payload = 0,
- TimeElapsed = 2,
- TransformFeedbackPrimitivesGenerated = 11,
- PrimitivesGenerated = 18,
- SamplesPassed = 21,
- TransformFeedbackUnknown = 26,
+ struct Notify {
+ u32 address_high;
+ u32 address_low;
+ u32 type;
+
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
};
- struct QueryCompare {
- u32 initial_sequence;
- u32 initial_mode;
- u32 unknown1;
- u32 unknown2;
- u32 current_sequence;
- u32 current_mode;
+ struct PeerSemaphore {
+ u32 address_high;
+ u32 address_low;
+
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
};
- enum class QuerySyncCondition : u32 {
- NotEqual = 0,
- GreaterThan = 1,
+ struct GlobalRender {
+ enum class Mode : u32 {
+ False = 0,
+ True = 1,
+ Conditional = 2,
+ IfEqual = 3,
+ IfNotEqual = 4,
+ };
+ u32 offset_high;
+ u32 offset_low;
+ Mode mode;
+
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(offset_high) << 32) |
+ offset_low);
+ }
};
- enum class ConditionMode : u32 {
- Never = 0,
- Always = 1,
- ResNonZero = 2,
- Equal = 3,
- NotEqual = 4,
+ enum class ReductionOp : u32 {
+ RedAdd = 0,
+ RedMin = 1,
+ RedMax = 2,
+ RedInc = 3,
+ RedDec = 4,
+ RedAnd = 5,
+ RedOr = 6,
+ RedXor = 7,
};
- enum class ShaderProgram : u32 {
- VertexA = 0,
- VertexB = 1,
- TesselationControl = 2,
- TesselationEval = 3,
- Geometry = 4,
- Fragment = 5,
+ struct LaunchDMA {
+ enum class Layout : u32 {
+ Blocklinear = 0,
+ Pitch = 1,
+ };
+
+ enum class CompletionType : u32 {
+ FlushDisable = 0,
+ FlushOnly = 1,
+ Release = 2,
+ };
+
+ union {
+ BitField<0, 1, Layout> memory_layout;
+ BitField<4, 2, CompletionType> completion_type;
+ BitField<8, 2, u32> interrupt_type;
+ BitField<12, 1, u32> sem_size;
+ BitField<1, 1, u32> reduction_enable;
+ BitField<13, 3, ReductionOp> reduction_op;
+ BitField<2, 2, u32> reduction_format;
+ BitField<6, 1, u32> sysmembar_disable;
+ };
+ };
+
+ struct I2M {
+ u32 address_high;
+ u32 address_low;
+ u32 payload;
+ INSERT_PADDING_BYTES_NOINIT(0x8);
+ u32 nop0;
+ u32 nop1;
+ u32 nop2;
+ u32 nop3;
+ };
+
+ struct OpportunisticEarlyZ {
+ BitField<0, 5, u32> threshold;
+
+ u32 Threshold() const {
+ switch (threshold) {
+ case 0x0:
+ return 0;
+ case 0x1F:
+ return 0x1F;
+ default:
+ // Thresholds begin at 0x10 (1 << 4)
+ // Threshold is in the range 0x1 to 0x13
+ return 1 << (4 + threshold.Value() - 1);
+ }
+ }
+ };
+
+ struct GeometryShaderDmFifo {
+ union {
+ BitField<0, 13, u32> raster_on;
+ BitField<16, 13, u32> raster_off;
+ BitField<31, 1, u32> spill_enabled;
+ };
+ };
+
+ struct L2CacheControl {
+ enum class EvictPolicy : u32 {
+ First = 0,
+ Normal = 1,
+ Last = 2,
+ };
+
+ union {
+ BitField<4, 2, EvictPolicy> policy;
+ };
+ };
+
+ struct InvalidateShaderCache {
+ union {
+ BitField<0, 1, u32> instruction;
+ BitField<4, 1, u32> data;
+ BitField<12, 1, u32> constant;
+ BitField<1, 1, u32> locks;
+ BitField<2, 1, u32> flush_data;
+ };
+ };
+
+ struct SyncInfo {
+ enum class Condition : u32 {
+ StreamOutWritesDone = 0,
+ RopWritesDone = 1,
+ };
+
+ union {
+ BitField<0, 16, u32> sync_point;
+ BitField<16, 1, u32> clean_l2;
+ BitField<20, 1, Condition> condition;
+ };
+ };
+
+ struct SurfaceClipBlockId {
+ union {
+ BitField<0, 4, u32> block_width;
+ BitField<4, 4, u32> block_height;
+ BitField<8, 4, u32> block_depth;
+ };
+ };
+
+ struct DecompressSurface {
+ union {
+ BitField<0, 3, u32> mrt_select;
+ BitField<4, 16, u32> rt_array_index;
+ };
+ };
+
+ struct ZCullRopBypass {
+ union {
+ BitField<0, 1, u32> enable;
+ BitField<4, 1, u32> no_stall;
+ BitField<8, 1, u32> cull_everything;
+ BitField<12, 4, u32> threshold;
+ };
+ };
+
+ struct ZCullSubregion {
+ union {
+ BitField<0, 1, u32> enable;
+ BitField<4, 24, u32> normalized_aliquots;
+ };
+ };
+
+ struct RasterBoundingBox {
+ enum class Mode : u32 {
+ BoundingBox = 0,
+ FullViewport = 1,
+ };
+
+ union {
+ BitField<0, 1, Mode> mode;
+ BitField<4, 8, u32> pad;
+ };
+ };
+
+ struct IteratedBlendOptimization {
+ enum class Noop : u32 {
+ Never = 0,
+ SourceRGBA0000 = 1,
+ SourceAlpha = 2,
+ SourceRGBA0001 = 3,
+ };
+
+ union {
+ BitField<0, 1, Noop> noop;
+ };
+ };
+
+ struct ZCullSubregionAllocation {
+ enum class Format : u32 {
+ Z_16x16x2_4x4 = 0,
+ ZS_16x16_4x4 = 1,
+ Z_16x16_4x2 = 2,
+ Z_16x16_2x4 = 3,
+ Z_16x8_4x4 = 4,
+ Z_8x8_4x2 = 5,
+ Z_8x8_2x4 = 6,
+ Z_16x16_4x8 = 7,
+ Z_4x8_2x2 = 8,
+ ZS_16x8_4x2 = 9,
+ ZS_16x8_2x4 = 10,
+ ZS_8x8_2x2 = 11,
+ Z_4x8_1x1 = 12,
+ None = 15,
+ };
+
+ union {
+ BitField<0, 8, u32> id;
+ BitField<8, 16, u32> aliquots;
+ BitField<24, 4, Format> format;
+ };
+ };
+
+ enum class ZCullSubregionAlgorithm : u32 {
+ Static = 0,
+ Adaptive = 1,
+ };
+
+ struct PixelShaderOutputSampleMaskUsage {
+ union {
+ BitField<0, 1, u32> enable;
+ BitField<1, 1, u32> qualify_by_aa;
+ };
+ };
+
+ struct L1Configuration {
+ enum class AddressableMemory : u32 {
+ Size16Kb = 0,
+ Size48Kb = 3,
+ };
+ union {
+ BitField<0, 3, AddressableMemory> direct_addressable_memory;
+ };
+ };
+
+ struct SPAVersion {
+ union {
+ BitField<0, 8, u32> minor;
+ BitField<8, 8, u32> major;
+ };
+ };
+
+ struct SnapGrid {
+ enum class Location : u32 {
+ Pixel2x2 = 1,
+ Pixel4x4 = 2,
+ Pixel8x8 = 3,
+ Pixel16x16 = 4,
+ Pixel32x32 = 5,
+ Pixel64x64 = 6,
+ Pixel128x128 = 7,
+ Pixel256x256 = 8,
+ };
+
+ enum class Mode : u32 {
+ RTNE = 0,
+ Tesla = 1,
+ };
+
+ struct {
+ union {
+ BitField<0, 4, Location> location;
+ BitField<8, 1, Mode> rounding_mode;
+ };
+ } line;
+
+ struct {
+ union {
+ BitField<0, 4, Location> location;
+ BitField<8, 1, Mode> rounding_mode;
+ };
+ } non_line;
+ };
+
+ struct Tessellation {
+ enum class DomainType : u32 {
+ Isolines = 0,
+ Triangles = 1,
+ Quads = 2,
+ };
+
+ enum class Spacing : u32 {
+ Integer = 0,
+ FractionalOdd = 1,
+ FractionalEven = 2,
+ };
+
+ enum class OutputPrimitves : u32 {
+ Points = 0,
+ Lines = 1,
+ Triangles_CW = 2,
+ Triangles_CCW = 3,
+ };
+
+ struct Parameters {
+ union {
+ BitField<0, 2, DomainType> domain_type;
+ BitField<4, 2, Spacing> spacing;
+ BitField<8, 2, OutputPrimitves> output_primitives;
+ };
+ } params;
+
+ struct LOD {
+ std::array<f32, 4> outer;
+ std::array<f32, 2> inner;
+ } lod;
+
+ std::array<u32, 9> reserved;
+ };
+
+ struct SubTilingPerf {
+ struct {
+ union {
+ BitField<0, 8, u32> spm_triangle_register_file_per;
+ BitField<8, 8, u32> spm_pixel_output_buffer_per;
+ BitField<16, 8, u32> spm_triangle_ram_per;
+ BitField<24, 8, u32> max_quads_per;
+ };
+ } knob_a;
+
+ struct {
+ union {
+ BitField<0, 8, u32> max_primitives_per;
+ };
+ } knob_b;
+
+ u32 knob_c;
+ };
+
+ struct ZCullSubregionReport {
+ enum class ReportType : u32 {
+ DepthTest = 0,
+ DepthTestNoAccept = 1,
+ DepthTestLateZ = 2,
+ StencilTest = 3,
+ };
+
+ union {
+ BitField<0, 1, u32> enabled;
+ BitField<4, 8, u32> subregion_id;
+ } to_report;
+
+ union {
+ BitField<0, 1, u32> enabled;
+ BitField<4, 3, ReportType> type;
+ } report_type;
+ };
+
+ struct BalancedPrimitiveWorkload {
+ union {
+ BitField<0, 1, u32> unpartitioned_mode;
+ BitField<4, 1, u32> timesliced_mode;
+ };
+ };
+
+ struct TransformFeedback {
+ struct Buffer {
+ u32 enable;
+ u32 address_high;
+ u32 address_low;
+ s32 size;
+ s32 start_offset;
+ INSERT_PADDING_BYTES_NOINIT(0xC);
+
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
+ };
+ static_assert(sizeof(Buffer) == 0x20);
+
+ struct Control {
+ u32 stream;
+ u32 varying_count;
+ u32 stride;
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ };
+ static_assert(sizeof(Control) == 0x10);
+
+ std::array<TransformFeedback::Buffer, NumTransformFeedbackBuffers> buffers;
+
+ INSERT_PADDING_BYTES_NOINIT(0x300);
+
+ std::array<TransformFeedback::Control, NumTransformFeedbackBuffers> controls;
+ };
+
+ struct HybridAntiAliasControl {
+ enum class Centroid : u32 {
+ PerFragment = 0,
+ PerPass = 1,
+ };
+ union {
+ BitField<0, 4, u32> passes;
+ BitField<4, 1, Centroid> centroid;
+ BitField<5, 1, u32> passes_extended;
+ };
+ };
+
+ struct ShaderLocalMemory {
+ u32 base_address;
+ INSERT_PADDING_BYTES_NOINIT(0x10);
+ u32 address_high;
+ u32 address_low;
+ u32 size_high;
+ u32 size_low;
+ u32 default_size_per_warp;
+
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
+
+ u64 Size() const {
+ return (static_cast<u64>(size_high) << 32) | size_low;
+ }
+ };
+
+ struct ZCullRegion {
+ u32 width;
+ u32 height;
+ u32 depth;
+ u32 offset;
+ INSERT_PADDING_BYTES_NOINIT(0xC);
+ u32 fetch_streams_once;
+ union {
+ BitField<0, 16, u32> start_aliquot;
+ BitField<16, 16, u32> aliquot_count;
+ } location;
+ u32 aliquots_per_layer;
+ u32 storage_address_high;
+ u32 storage_address_low;
+ u32 storage_limit_address_high;
+ u32 storage_limit_address_low;
+
+ GPUVAddr StorageAddress() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(storage_address_high) << 32) |
+ storage_address_low);
+ }
+ GPUVAddr StorageLimitAddress() const {
+ return static_cast<GPUVAddr>(
+ (static_cast<GPUVAddr>(storage_limit_address_high) << 32) |
+ storage_limit_address_low);
+ }
+ };
+
+ struct ZetaReadOnly {
+ union {
+ BitField<0, 1, u32> enable_z;
+ BitField<4, 1, u32> enable_stencil;
+ };
};
struct VertexAttribute {
enum class Size : u32 {
Invalid = 0x0,
- Size_32_32_32_32 = 0x01,
- Size_32_32_32 = 0x02,
- Size_16_16_16_16 = 0x03,
- Size_32_32 = 0x04,
- Size_16_16_16 = 0x05,
- Size_8_8_8_8 = 0x0a,
- Size_16_16 = 0x0f,
- Size_32 = 0x12,
- Size_8_8_8 = 0x13,
- Size_8_8 = 0x18,
- Size_16 = 0x1b,
- Size_8 = 0x1d,
- Size_10_10_10_2 = 0x30,
- Size_11_11_10 = 0x31,
+ Size_R32_G32_B32_A32 = 0x01,
+ Size_R32_G32_B32 = 0x02,
+ Size_R16_G16_B16_A16 = 0x03,
+ Size_R32_G32 = 0x04,
+ Size_R16_G16_B16 = 0x05,
+ Size_R8_G8_B8_A8 = 0x0A,
+ Size_R16_G16 = 0x0F,
+ Size_R32 = 0x12,
+ Size_R8_G8_B8 = 0x13,
+ Size_R8_G8 = 0x18,
+ Size_R16 = 0x1B,
+ Size_R8 = 0x1D,
+ Size_A2_B10_G10_R10 = 0x30,
+ Size_B10_G11_R11 = 0x31,
+ Size_G8_R8 = 0x32,
+ Size_X8_B8_G8_R8 = 0x33,
+ Size_A8 = 0x34,
};
enum class Type : u32 {
- SignedNorm = 1,
- UnsignedNorm = 2,
- SignedInt = 3,
- UnsignedInt = 4,
- UnsignedScaled = 5,
- SignedScaled = 6,
+ UnusedEnumDoNotUseBecauseItWillGoAway = 0,
+ SNorm = 1,
+ UNorm = 2,
+ SInt = 3,
+ UInt = 4,
+ UScaled = 5,
+ SScaled = 6,
Float = 7,
};
@@ -173,33 +600,36 @@ public:
u32 ComponentCount() const {
switch (size) {
- case Size::Size_32_32_32_32:
+ case Size::Size_R32_G32_B32_A32:
return 4;
- case Size::Size_32_32_32:
+ case Size::Size_R32_G32_B32:
return 3;
- case Size::Size_16_16_16_16:
+ case Size::Size_R16_G16_B16_A16:
return 4;
- case Size::Size_32_32:
+ case Size::Size_R32_G32:
return 2;
- case Size::Size_16_16_16:
+ case Size::Size_R16_G16_B16:
return 3;
- case Size::Size_8_8_8_8:
+ case Size::Size_R8_G8_B8_A8:
+ case Size::Size_X8_B8_G8_R8:
return 4;
- case Size::Size_16_16:
+ case Size::Size_R16_G16:
return 2;
- case Size::Size_32:
+ case Size::Size_R32:
return 1;
- case Size::Size_8_8_8:
+ case Size::Size_R8_G8_B8:
return 3;
- case Size::Size_8_8:
+ case Size::Size_R8_G8:
+ case Size::Size_G8_R8:
return 2;
- case Size::Size_16:
+ case Size::Size_R16:
return 1;
- case Size::Size_8:
+ case Size::Size_R8:
+ case Size::Size_A8:
return 1;
- case Size::Size_10_10_10_2:
+ case Size::Size_A2_B10_G10_R10:
return 4;
- case Size::Size_11_11_10:
+ case Size::Size_B10_G11_R11:
return 3;
default:
ASSERT(false);
@@ -209,33 +639,36 @@ public:
u32 SizeInBytes() const {
switch (size) {
- case Size::Size_32_32_32_32:
+ case Size::Size_R32_G32_B32_A32:
return 16;
- case Size::Size_32_32_32:
+ case Size::Size_R32_G32_B32:
return 12;
- case Size::Size_16_16_16_16:
+ case Size::Size_R16_G16_B16_A16:
return 8;
- case Size::Size_32_32:
+ case Size::Size_R32_G32:
return 8;
- case Size::Size_16_16_16:
+ case Size::Size_R16_G16_B16:
return 6;
- case Size::Size_8_8_8_8:
+ case Size::Size_R8_G8_B8_A8:
+ case Size::Size_X8_B8_G8_R8:
return 4;
- case Size::Size_16_16:
+ case Size::Size_R16_G16:
return 4;
- case Size::Size_32:
+ case Size::Size_R32:
return 4;
- case Size::Size_8_8_8:
+ case Size::Size_R8_G8_B8:
return 3;
- case Size::Size_8_8:
+ case Size::Size_R8_G8:
+ case Size::Size_G8_R8:
return 2;
- case Size::Size_16:
+ case Size::Size_R16:
return 2;
- case Size::Size_8:
+ case Size::Size_R8:
+ case Size::Size_A8:
return 1;
- case Size::Size_10_10_10_2:
+ case Size::Size_A2_B10_G10_R10:
return 4;
- case Size::Size_11_11_10:
+ case Size::Size_B10_G11_R11:
return 4;
default:
ASSERT(false);
@@ -245,34 +678,36 @@ public:
std::string SizeString() const {
switch (size) {
- case Size::Size_32_32_32_32:
+ case Size::Size_R32_G32_B32_A32:
return "32_32_32_32";
- case Size::Size_32_32_32:
+ case Size::Size_R32_G32_B32:
return "32_32_32";
- case Size::Size_16_16_16_16:
+ case Size::Size_R16_G16_B16_A16:
return "16_16_16_16";
- case Size::Size_32_32:
+ case Size::Size_R32_G32:
return "32_32";
- case Size::Size_16_16_16:
+ case Size::Size_R16_G16_B16:
return "16_16_16";
- case Size::Size_8_8_8_8:
+ case Size::Size_R8_G8_B8_A8:
return "8_8_8_8";
- case Size::Size_16_16:
+ case Size::Size_R16_G16:
return "16_16";
- case Size::Size_32:
+ case Size::Size_R32:
return "32";
- case Size::Size_8_8_8:
+ case Size::Size_R8_G8_B8:
return "8_8_8";
- case Size::Size_8_8:
+ case Size::Size_R8_G8:
+ case Size::Size_G8_R8:
return "8_8";
- case Size::Size_16:
+ case Size::Size_R16:
return "16";
- case Size::Size_8:
+ case Size::Size_R8:
+ case Size::Size_A8:
return "8";
- case Size::Size_10_10_10_2:
- return "10_10_10_2";
- case Size::Size_11_11_10:
- return "11_11_10";
+ case Size::Size_A2_B10_G10_R10:
+ return "2_10_10_10";
+ case Size::Size_B10_G11_R11:
+ return "10_11_12";
default:
ASSERT(false);
return {};
@@ -281,17 +716,19 @@ public:
std::string TypeString() const {
switch (type) {
- case Type::SignedNorm:
+ case Type::UnusedEnumDoNotUseBecauseItWillGoAway:
+ return "Unused";
+ case Type::SNorm:
return "SNORM";
- case Type::UnsignedNorm:
+ case Type::UNorm:
return "UNORM";
- case Type::SignedInt:
+ case Type::SInt:
return "SINT";
- case Type::UnsignedInt:
+ case Type::UInt:
return "UINT";
- case Type::UnsignedScaled:
+ case Type::UScaled:
return "USCALED";
- case Type::SignedScaled:
+ case Type::SScaled:
return "SSCALED";
case Type::Float:
return "FLOAT";
@@ -301,7 +738,7 @@ public:
}
bool IsNormalized() const {
- return (type == Type::SignedNorm) || (type == Type::UnsignedNorm);
+ return (type == Type::SNorm) || (type == Type::UNorm);
}
bool IsValid() const {
@@ -312,6 +749,7 @@ public:
return hex < other.hex;
}
};
+ static_assert(sizeof(VertexAttribute) == 0x4);
struct MsaaSampleLocation {
union {
@@ -342,9 +780,96 @@ public:
}
};
- enum class DepthMode : u32 {
- MinusOneToOne = 0,
- ZeroToOne = 1,
+ struct MultisampleCoverageToColor {
+ union {
+ BitField<0, 1, u32> enable;
+ BitField<4, 3, u32> target;
+ };
+ };
+
+ struct DecompressZetaSurface {
+ union {
+ BitField<0, 1, u32> z_enable;
+ BitField<4, 1, u32> stencil_enable;
+ };
+ };
+
+ struct ZetaSparse {
+ enum class UnmappedCompare : u32 {
+ Unmapped = 0,
+ FailAlways = 1,
+ };
+ union {
+ BitField<0, 1, u32> enable;
+ BitField<1, 1, UnmappedCompare> unmapped_compare;
+ };
+ };
+
+ struct RtControl {
+ union {
+ BitField<0, 4, u32> count;
+ BitField<4, 3, u32> target0;
+ BitField<7, 3, u32> target1;
+ BitField<10, 3, u32> target2;
+ BitField<13, 3, u32> target3;
+ BitField<16, 3, u32> target4;
+ BitField<19, 3, u32> target5;
+ BitField<22, 3, u32> target6;
+ BitField<25, 3, u32> target7;
+ };
+
+ u32 Map(std::size_t index) const {
+ const std::array<u32, NumRenderTargets> maps{target0, target1, target2, target3,
+ target4, target5, target6, target7};
+ ASSERT(index < maps.size());
+ return maps[index];
+ }
+ };
+
+ struct CompressionThresholdSamples {
+ u32 samples;
+
+ u32 Samples() {
+ if (samples == 0) {
+ return 0;
+ }
+ return 1 << (samples - 1);
+ }
+ };
+
+ struct PixelShaderInterlockControl {
+ enum class TileMode : u32 {
+ NoConflictDetect = 0,
+ DetectSampleConflict = 1,
+ DetectPixelConflict = 2,
+ };
+ enum class TileSize : u32 {
+ Size_16x16 = 0,
+ Size_8x8 = 1,
+ };
+ enum class FragmentOrder : u32 {
+ FragmentOrdered = 0,
+ FragmentUnordered = 1,
+ };
+ union {
+ BitField<0, 2, TileMode> tile_mode;
+ BitField<2, 1, TileSize> tile_size;
+ BitField<3, 1, FragmentOrder> fragment_order;
+ };
+ };
+
+ struct ZetaSize {
+ enum class DimensionControl : u32 {
+ DepthDefinesArray = 0,
+ ArraySizeOne = 1,
+ };
+
+ u32 width;
+ u32 height;
+ union {
+ BitField<0, 16, u32> depth;
+ BitField<16, 1, DimensionControl> dim_control;
+ };
};
enum class PrimitiveTopology : u32 {
@@ -358,15 +883,21 @@ public:
Quads = 0x7,
QuadStrip = 0x8,
Polygon = 0x9,
- LinesAdjacency = 0xa,
- LineStripAdjacency = 0xb,
- TrianglesAdjacency = 0xc,
- TriangleStripAdjacency = 0xd,
- Patches = 0xe,
+ LinesAdjacency = 0xA,
+ LineStripAdjacency = 0xB,
+ TrianglesAdjacency = 0xC,
+ TriangleStripAdjacency = 0xD,
+ Patches = 0xE,
+ };
+
+ struct VertexArray {
+ union {
+ BitField<0, 16, u32> start;
+ BitField<16, 12, u32> count;
+ BitField<28, 3, PrimitiveTopology> topology;
+ };
};
- // Constants as from NVC0_3D_UNK1970_D3D
- // https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/src/gallium/drivers/nouveau/nvc0/nvc0_3d.xml.h#L1598
enum class PrimitiveTopologyOverride : u32 {
None = 0x0,
Points = 0x1,
@@ -374,11 +905,32 @@ public:
LineStrip = 0x3,
Triangles = 0x4,
TriangleStrip = 0x5,
- LinesAdjacency = 0xa,
- LineStripAdjacency = 0xb,
- TrianglesAdjacency = 0xc,
- TriangleStripAdjacency = 0xd,
- Patches = 0xe,
+ LinesAdjacency = 0xA,
+ LineStripAdjacency = 0xB,
+ TrianglesAdjacency = 0xC,
+ TriangleStripAdjacency = 0xD,
+ Patches = 0xE,
+
+ LegacyPoints = 0x1001,
+ LegacyIndexedLines = 0x1002,
+ LegacyIndexedTriangles = 0x1003,
+ LegacyLines = 0x100F,
+ LegacyLineStrip = 0x1010,
+ LegacyIndexedLineStrip = 0x1011,
+ LegacyTriangles = 0x1012,
+ LegacyTriangleStrip = 0x1013,
+ LegacyIndexedTriangleStrip = 0x1014,
+ LegacyTriangleFan = 0x1015,
+ LegacyIndexedTriangleFan = 0x1016,
+ LegacyTriangleFanImm = 0x1017,
+ LegacyLinesImm = 0x1018,
+ LegacyIndexedTriangles2 = 0x101A,
+ LegacyIndexedLines2 = 0x101B,
+ };
+
+ enum class DepthMode : u32 {
+ MinusOneToOne = 0,
+ ZeroToOne = 1,
};
enum class IndexFormat : u32 {
@@ -388,183 +940,143 @@ public:
};
enum class ComparisonOp : u32 {
- // These values are used by Nouveau and most games, they correspond to the OpenGL token
- // values for these operations.
- Never = 0x200,
- Less = 0x201,
- Equal = 0x202,
- LessEqual = 0x203,
- Greater = 0x204,
- NotEqual = 0x205,
- GreaterEqual = 0x206,
- Always = 0x207,
-
- // These values are used by some games, they seem to be NV04 values.
- NeverOld = 1,
- LessOld = 2,
- EqualOld = 3,
- LessEqualOld = 4,
- GreaterOld = 5,
- NotEqualOld = 6,
- GreaterEqualOld = 7,
- AlwaysOld = 8,
- };
-
- enum class LogicOperation : u32 {
- Clear = 0x1500,
- And = 0x1501,
- AndReverse = 0x1502,
- Copy = 0x1503,
- AndInverted = 0x1504,
- NoOp = 0x1505,
- Xor = 0x1506,
- Or = 0x1507,
- Nor = 0x1508,
- Equiv = 0x1509,
- Invert = 0x150A,
- OrReverse = 0x150B,
- CopyInverted = 0x150C,
- OrInverted = 0x150D,
- Nand = 0x150E,
- Set = 0x150F,
- };
-
- enum class StencilOp : u32 {
- Keep = 1,
- Zero = 2,
- Replace = 3,
- Incr = 4,
- Decr = 5,
- Invert = 6,
- IncrWrap = 7,
- DecrWrap = 8,
- KeepOGL = 0x1E00,
- ZeroOGL = 0,
- ReplaceOGL = 0x1E01,
- IncrOGL = 0x1E02,
- DecrOGL = 0x1E03,
- InvertOGL = 0x150A,
- IncrWrapOGL = 0x8507,
- DecrWrapOGL = 0x8508,
- };
-
- enum class CounterReset : u32 {
- SampleCnt = 0x01,
- Unk02 = 0x02,
- Unk03 = 0x03,
- Unk04 = 0x04,
- EmittedPrimitives = 0x10, // Not tested
- Unk11 = 0x11,
- Unk12 = 0x12,
- Unk13 = 0x13,
- Unk15 = 0x15,
- Unk16 = 0x16,
- Unk17 = 0x17,
- Unk18 = 0x18,
- Unk1A = 0x1A,
- Unk1B = 0x1B,
- Unk1C = 0x1C,
- Unk1D = 0x1D,
- Unk1E = 0x1E,
- GeneratedPrimitives = 0x1F,
+ Never_D3D = 1,
+ Less_D3D = 2,
+ Equal_D3D = 3,
+ LessEqual_D3D = 4,
+ Greater_D3D = 5,
+ NotEqual_D3D = 6,
+ GreaterEqual_D3D = 7,
+ Always_D3D = 8,
+
+ Never_GL = 0x200,
+ Less_GL = 0x201,
+ Equal_GL = 0x202,
+ LessEqual_GL = 0x203,
+ Greater_GL = 0x204,
+ NotEqual_GL = 0x205,
+ GreaterEqual_GL = 0x206,
+ Always_GL = 0x207,
+ };
+
+ enum class ClearReport : u32 {
+ ZPassPixelCount = 0x01,
+ ZCullStats = 0x02,
+ StreamingPrimitvesNeededMinusSucceeded = 0x03,
+ AlphaBetaClocks = 0x04,
+ StreamingPrimitivesSucceeded = 0x10,
+ StreamingPrimitivesNeeded = 0x11,
+ VerticesGenerated = 0x12,
+ PrimitivesGenerated = 0x13,
+ VertexShaderInvocations = 0x15,
+ TessellationInitInvocations = 0x16,
+ TessellationShaderInvocations = 0x17,
+ TessellationShaderPrimitivesGenerated = 0x18,
+ GeometryShaderInvocations = 0x1A,
+ GeometryShaderPrimitivesGenerated = 0x1B,
+ ClipperInvocations = 0x1C,
+ ClipperPrimitivesGenerated = 0x1D,
+ PixelShaderInvocations = 0x1E,
+ VtgPrimitivesOut = 0x1F,
};
enum class FrontFace : u32 {
- ClockWise = 0x0900,
- CounterClockWise = 0x0901,
+ ClockWise = 0x900,
+ CounterClockWise = 0x901,
};
enum class CullFace : u32 {
- Front = 0x0404,
- Back = 0x0405,
- FrontAndBack = 0x0408,
+ Front = 0x404,
+ Back = 0x405,
+ FrontAndBack = 0x408,
};
struct Blend {
enum class Equation : u32 {
- Add = 1,
- Subtract = 2,
- ReverseSubtract = 3,
- Min = 4,
- Max = 5,
-
- // These values are used by Nouveau and some games.
- AddGL = 0x8006,
- MinGL = 0x8007,
- MaxGL = 0x8008,
- SubtractGL = 0x800a,
- ReverseSubtractGL = 0x800b
+ Add_D3D = 1,
+ Subtract_D3D = 2,
+ ReverseSubtract_D3D = 3,
+ Min_D3D = 4,
+ Max_D3D = 5,
+
+ Add_GL = 0x8006,
+ Min_GL = 0x8007,
+ Max_GL = 0x8008,
+ Subtract_GL = 0x800A,
+ ReverseSubtract_GL = 0x800B
};
enum class Factor : u32 {
- Zero = 0x1,
- One = 0x2,
- SourceColor = 0x3,
- OneMinusSourceColor = 0x4,
- SourceAlpha = 0x5,
- OneMinusSourceAlpha = 0x6,
- DestAlpha = 0x7,
- OneMinusDestAlpha = 0x8,
- DestColor = 0x9,
- OneMinusDestColor = 0xa,
- SourceAlphaSaturate = 0xb,
- Source1Color = 0x10,
- OneMinusSource1Color = 0x11,
- Source1Alpha = 0x12,
- OneMinusSource1Alpha = 0x13,
- ConstantColor = 0x61,
- OneMinusConstantColor = 0x62,
- ConstantAlpha = 0x63,
- OneMinusConstantAlpha = 0x64,
-
- // These values are used by Nouveau and some games.
- ZeroGL = 0x4000,
- OneGL = 0x4001,
- SourceColorGL = 0x4300,
- OneMinusSourceColorGL = 0x4301,
- SourceAlphaGL = 0x4302,
- OneMinusSourceAlphaGL = 0x4303,
- DestAlphaGL = 0x4304,
- OneMinusDestAlphaGL = 0x4305,
- DestColorGL = 0x4306,
- OneMinusDestColorGL = 0x4307,
- SourceAlphaSaturateGL = 0x4308,
- ConstantColorGL = 0xc001,
- OneMinusConstantColorGL = 0xc002,
- ConstantAlphaGL = 0xc003,
- OneMinusConstantAlphaGL = 0xc004,
- Source1ColorGL = 0xc900,
- OneMinusSource1ColorGL = 0xc901,
- Source1AlphaGL = 0xc902,
- OneMinusSource1AlphaGL = 0xc903,
+ Zero_D3D = 0x1,
+ One_D3D = 0x2,
+ SourceColor_D3D = 0x3,
+ OneMinusSourceColor_D3D = 0x4,
+ SourceAlpha_D3D = 0x5,
+ OneMinusSourceAlpha_D3D = 0x6,
+ DestAlpha_D3D = 0x7,
+ OneMinusDestAlpha_D3D = 0x8,
+ DestColor_D3D = 0x9,
+ OneMinusDestColor_D3D = 0xA,
+ SourceAlphaSaturate_D3D = 0xB,
+ BothSourceAlpha_D3D = 0xC,
+ OneMinusBothSourceAlpha_D3D = 0xD,
+ BlendFactor_D3D = 0xE,
+ OneMinusBlendFactor_D3D = 0xF,
+ Source1Color_D3D = 0x10,
+ OneMinusSource1Color_D3D = 0x11,
+ Source1Alpha_D3D = 0x12,
+ OneMinusSource1Alpha_D3D = 0x13,
+
+ Zero_GL = 0x4000,
+ One_GL = 0x4001,
+ SourceColor_GL = 0x4300,
+ OneMinusSourceColor_GL = 0x4301,
+ SourceAlpha_GL = 0x4302,
+ OneMinusSourceAlpha_GL = 0x4303,
+ DestAlpha_GL = 0x4304,
+ OneMinusDestAlpha_GL = 0x4305,
+ DestColor_GL = 0x4306,
+ OneMinusDestColor_GL = 0x4307,
+ SourceAlphaSaturate_GL = 0x4308,
+ ConstantColor_GL = 0xC001,
+ OneMinusConstantColor_GL = 0xC002,
+ ConstantAlpha_GL = 0xC003,
+ OneMinusConstantAlpha_GL = 0xC004,
+ Source1Color_GL = 0xC900,
+ OneMinusSource1Color_GL = 0xC901,
+ Source1Alpha_GL = 0xC902,
+ OneMinusSource1Alpha_GL = 0xC903,
};
u32 separate_alpha;
- Equation equation_rgb;
- Factor factor_source_rgb;
- Factor factor_dest_rgb;
- Equation equation_a;
- Factor factor_source_a;
- Factor factor_dest_a;
- INSERT_PADDING_WORDS_NOINIT(1);
- };
-
- enum class TessellationPrimitive : u32 {
- Isolines = 0,
- Triangles = 1,
- Quads = 2,
+ Equation color_op;
+ Factor color_source;
+ Factor color_dest;
+ Equation alpha_op;
+ Factor alpha_source;
+ u32 enable_global_color_key;
+ Factor alpha_dest;
+
+ u32 single_rop_control_enable;
+ u32 enable[NumRenderTargets];
};
- enum class TessellationSpacing : u32 {
- Equal = 0,
- FractionalOdd = 1,
- FractionalEven = 2,
+ struct BlendPerTarget {
+ u32 separate_alpha;
+ Blend::Equation color_op;
+ Blend::Factor color_source;
+ Blend::Factor color_dest;
+ Blend::Equation alpha_op;
+ Blend::Factor alpha_source;
+ Blend::Factor alpha_dest;
+ INSERT_PADDING_BYTES_NOINIT(0x4);
};
+ static_assert(sizeof(BlendPerTarget) == 0x20);
enum class PolygonMode : u32 {
- Point = 0x1b00,
- Line = 0x1b01,
- Fill = 0x1b02,
+ Point = 0x1B00,
+ Line = 0x1B01,
+ Fill = 0x1B02,
};
enum class ShadowRamControl : u32 {
@@ -589,18 +1101,22 @@ public:
NegativeW = 7,
};
- enum class SamplerIndex : u32 {
+ enum class SamplerBinding : u32 {
Independently = 0,
- ViaHeaderIndex = 1,
+ ViaHeaderBinding = 1,
};
struct TileMode {
+ enum class DimensionControl : u32 {
+ DepthDefinesArray = 0,
+ DepthDefinesDepth = 1,
+ };
union {
BitField<0, 4, u32> block_width;
BitField<4, 4, u32> block_height;
BitField<8, 4, u32> block_depth;
BitField<12, 1, u32> is_pitch_linear;
- BitField<16, 1, u32> is_3d;
+ BitField<16, 1, DimensionControl> dim_control;
};
};
static_assert(sizeof(TileMode) == 4);
@@ -616,23 +1132,25 @@ public:
BitField<0, 16, u32> depth;
BitField<16, 1, u32> volume;
};
- u32 layer_stride;
+ u32 array_pitch;
u32 base_layer;
- INSERT_PADDING_WORDS_NOINIT(7);
+ u32 mark_ieee_clean;
+ INSERT_PADDING_BYTES_NOINIT(0x18);
GPUVAddr Address() const {
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
address_low);
}
};
+ static_assert(sizeof(RenderTargetConfig) == 0x40);
struct ColorMask {
union {
u32 raw;
- BitField<0, 4, u32> R;
- BitField<4, 4, u32> G;
- BitField<8, 4, u32> B;
- BitField<12, 4, u32> A;
+ BitField<0, 1, u32> R;
+ BitField<4, 1, u32> G;
+ BitField<8, 1, u32> B;
+ BitField<12, 1, u32> A;
};
};
@@ -643,6 +1161,7 @@ public:
f32 translate_x;
f32 translate_y;
f32 translate_z;
+
union {
u32 raw;
BitField<0, 3, ViewportSwizzle> x;
@@ -650,7 +1169,11 @@ public:
BitField<8, 3, ViewportSwizzle> z;
BitField<12, 3, ViewportSwizzle> w;
} swizzle;
- INSERT_PADDING_WORDS_NOINIT(1);
+
+ union {
+ BitField<0, 5, u32> x;
+ BitField<8, 5, u32> y;
+ } snap_grid_precision;
Common::Rectangle<f32> GetRect() const {
return {
@@ -677,21 +1200,14 @@ public:
return translate_y + std::fabs(scale_y) - GetY();
}
};
+ static_assert(sizeof(ViewportTransform) == 0x20);
- struct ScissorTest {
- u32 enable;
- union {
- BitField<0, 16, u32> min_x;
- BitField<16, 16, u32> max_x;
+ struct Viewport {
+ enum class PixelCenter : u32 {
+ HalfIntegers = 0,
+ Integers = 1,
};
- union {
- BitField<0, 16, u32> min_y;
- BitField<16, 16, u32> max_y;
- };
- u32 fill;
- };
- struct ViewPort {
union {
BitField<0, 16, u32> x;
BitField<16, 16, u32> width;
@@ -703,726 +1219,1822 @@ public:
float depth_range_near;
float depth_range_far;
};
+ static_assert(sizeof(Viewport) == 0x10);
- struct TransformFeedbackBinding {
- u32 buffer_enable;
- u32 address_high;
- u32 address_low;
- s32 buffer_size;
- s32 buffer_offset;
- INSERT_PADDING_WORDS_NOINIT(3);
-
- GPUVAddr Address() const {
- return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
- address_low);
- }
+ struct Window {
+ union {
+ BitField<0, 16, u32> x_min;
+ BitField<16, 16, u32> x_max;
+ };
+ union {
+ BitField<0, 16, u32> y_min;
+ BitField<16, 16, u32> y_max;
+ };
};
- static_assert(sizeof(TransformFeedbackBinding) == 32);
+ static_assert(sizeof(Window) == 0x8);
- struct TransformFeedbackLayout {
- u32 stream;
- u32 varying_count;
- u32 stride;
- INSERT_PADDING_WORDS_NOINIT(1);
+ struct ClipIdExtent {
+ union {
+ BitField<0, 16, u32> x;
+ BitField<16, 16, u32> width;
+ };
+ union {
+ BitField<0, 16, u32> y;
+ BitField<16, 16, u32> height;
+ };
+ };
+ static_assert(sizeof(ClipIdExtent) == 0x8);
+
+ enum class VisibleCallLimit : u32 {
+ Limit0 = 0,
+ Limit1 = 1,
+ Limit2 = 2,
+ Limit4 = 3,
+ Limit8 = 4,
+ Limit16 = 5,
+ Limit32 = 6,
+ Limit64 = 7,
+ Limit128 = 8,
+ None = 15,
};
- static_assert(sizeof(TransformFeedbackLayout) == 16);
-
- bool IsShaderConfigEnabled(std::size_t index) const {
- // The VertexB is always enabled.
- if (index == static_cast<std::size_t>(Regs::ShaderProgram::VertexB)) {
- return true;
- }
- return shader_config[index].enable != 0;
- }
-
- bool IsShaderConfigEnabled(Regs::ShaderProgram type) const {
- return IsShaderConfigEnabled(static_cast<std::size_t>(type));
- }
- union {
- struct {
- INSERT_PADDING_WORDS_NOINIT(0x44);
+ struct StatisticsCounter {
+ union {
+ BitField<0, 1, u32> da_vertices;
+ BitField<1, 1, u32> da_primitives;
+ BitField<2, 1, u32> vs_invocations;
+ BitField<3, 1, u32> gs_invocations;
+ BitField<4, 1, u32> gs_primitives;
+ BitField<5, 1, u32> streaming_primitives_succeeded;
+ BitField<6, 1, u32> streaming_primitives_needed;
+ BitField<7, 1, u32> clipper_invocations;
+ BitField<8, 1, u32> clipper_primitives;
+ BitField<9, 1, u32> ps_invocations;
+ BitField<11, 1, u32> ti_invocations;
+ BitField<12, 1, u32> ts_invocations;
+ BitField<13, 1, u32> ts_primitives;
+ BitField<14, 1, u32> total_streaming_primitives_needed_succeeded;
+ BitField<10, 1, u32> vtg_primitives_out;
+ BitField<15, 1, u32> alpha_beta_clocks;
+ };
+ };
- u32 wait_for_idle;
+ struct ClearRect {
+ union {
+ BitField<0, 16, u32> x_min;
+ BitField<16, 16, u32> x_max;
+ };
+ union {
+ BitField<0, 16, u32> y_min;
+ BitField<16, 16, u32> y_max;
+ };
+ };
- struct {
- u32 upload_address;
- u32 data;
- u32 entry;
- u32 bind;
- } macros;
+ struct VertexBuffer {
+ u32 first;
+ u32 count;
+ };
- ShadowRamControl shadow_ram_control;
+ struct InvalidateShaderCacheNoWFI {
+ union {
+ BitField<0, 1, u32> instruction;
+ BitField<4, 1, u32> global_data;
+ BitField<12, 1, u32> constant;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x16);
+ struct ZCullSerialization {
+ enum class Applied : u32 {
+ Always = 0,
+ LateZ = 1,
+ OutOfGamutZ = 2,
+ LateZOrOutOfGamutZ = 3,
+ };
+ union {
+ BitField<0, 1, u32> enable;
+ BitField<4, 2, Applied> applied;
+ };
+ };
- Upload::Registers upload;
- struct {
- union {
- BitField<0, 1, u32> linear;
- };
- } exec_upload;
+ struct ZCullDirFormat {
+ enum class Zdir : u32 {
+ Less = 0,
+ Greater = 1,
+ };
+ enum class Zformat : u32 {
+ MSB = 0,
+ FP = 1,
+ Ztrick = 2,
+ Zf32 = 3,
+ };
- u32 data_upload;
+ union {
+ BitField<0, 16, Zdir> dir;
+ BitField<16, 16, Zformat> format;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x16);
+ struct IteratedBlend {
+ union {
+ BitField<0, 1, u32> enable;
+ BitField<1, 1, u32> enable_alpha;
+ };
+ u32 pass_count;
+ };
- u32 force_early_fragment_tests;
+ struct ZCullCriterion {
+ enum class Sfunc : u32 {
+ Never = 0,
+ Less = 1,
+ Equal = 2,
+ LessOrEqual = 3,
+ Greater = 4,
+ NotEqual = 5,
+ GreaterOrEqual = 6,
+ Always = 7,
+ };
- INSERT_PADDING_WORDS_NOINIT(0x2D);
+ union {
+ BitField<0, 8, Sfunc> sfunc;
+ BitField<8, 1, u32> no_invalidate;
+ BitField<9, 1, u32> force_match;
+ BitField<16, 8, u32> sref;
+ BitField<24, 8, u32> smask;
+ };
+ };
- struct {
- union {
- BitField<0, 16, u32> sync_point;
- BitField<16, 1, u32> unknown;
- BitField<20, 1, u32> increment;
- };
- } sync_info;
+ struct LoadIteratedBlend {
+ enum class Test : u32 {
+ False = 0,
+ True = 1,
+ Equal = 2,
+ NotEqual = 3,
+ LessThan = 4,
+ LessOrEqual = 5,
+ Greater = 6,
+ GreaterOrEqual = 7,
+ };
+ enum class Operation : u32 {
+ AddProducts = 0,
+ SubProducts = 1,
+ Min = 2,
+ Max = 3,
+ Reciprocal = 4,
+ Add = 5,
+ Sub = 6,
+ };
+ enum class OperandA : u32 {
+ SrcRGB = 0,
+ DstRGB = 1,
+ SrcAAA = 2,
+ DstAAA = 3,
+ Temp0_RGB = 4,
+ Temp1_RGB = 5,
+ Temp2_RGB = 6,
+ PBR_RGB = 7,
+ };
+ enum class OperandB : u32 {
+ Zero = 0,
+ One = 1,
+ SrcRGB = 2,
+ SrcAAA = 3,
+ OneMinusSrcAAA = 4,
+ DstRGB = 5,
+ DstAAA = 6,
+ OneMinusDstAAA = 7,
+ Temp0_RGB = 9,
+ Temp1_RGB = 10,
+ Temp2_RGB = 11,
+ PBR_RGB = 12,
+ ConstRGB = 13,
+ ZeroATimesB = 14,
+ };
+ enum class Swizzle : u32 {
+ RGB = 0,
+ GBR = 1,
+ RRR = 2,
+ GGG = 3,
+ BBB = 4,
+ RToA = 5,
+ };
+ enum class WriteMask : u32 {
+ RGB = 0,
+ ROnly = 1,
+ GOnly = 2,
+ BOnly = 3,
+ };
+ enum class Pass : u32 {
+ Temp0 = 0,
+ Temp1 = 1,
+ Temp2 = 2,
+ None = 3,
+ };
- INSERT_PADDING_WORDS_NOINIT(0x15);
+ u32 instruction_ptr;
+ union {
+ BitField<0, 3, Test> test;
+ BitField<3, 3, Operation> operation;
+ BitField<6, 3, u32> const_input;
+ BitField<9, 3, OperandA> operand_a;
+ BitField<12, 4, OperandB> operand_b;
+ BitField<16, 3, OperandA> operand_c;
+ BitField<19, 4, OperandB> operand_d;
+ BitField<23, 3, Swizzle> output_swizzle;
+ BitField<26, 2, WriteMask> output_mask;
+ BitField<28, 2, Pass> output_pass;
+ BitField<31, 1, u32> test_enabled;
+ };
+ };
- union {
- BitField<0, 2, TessellationPrimitive> prim;
- BitField<4, 2, TessellationSpacing> spacing;
- BitField<8, 1, u32> cw;
- BitField<9, 1, u32> connected;
- } tess_mode;
+ struct ScissorTest {
+ u32 enable;
+ union {
+ BitField<0, 16, u32> min_x;
+ BitField<16, 16, u32> max_x;
+ };
+ union {
+ BitField<0, 16, u32> min_y;
+ BitField<16, 16, u32> max_y;
+ };
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ };
+ static_assert(sizeof(ScissorTest) == 0x10);
- std::array<f32, 4> tess_level_outer;
- std::array<f32, 2> tess_level_inner;
+ struct VPCPerf {
+ union {
+ BitField<0, 8, u32> culled_small_lines;
+ BitField<8, 8, u32> culled_small_triangles;
+ BitField<16, 8, u32> nonculled_lines_and_points;
+ BitField<24, 8, u32> nonculled_triangles;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x10);
+ struct ConstantColorRendering {
+ u32 enabled;
+ u32 red;
+ u32 green;
+ u32 blue;
+ u32 alpha;
+ };
- u32 rasterize_enable;
+ struct VertexStreamSubstitute {
+ u32 address_high;
+ u32 address_low;
- std::array<TransformFeedbackBinding, NumTransformFeedbackBuffers> tfb_bindings;
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
+ };
- INSERT_PADDING_WORDS_NOINIT(0xC0);
+ struct VTGWarpWatermarks {
+ union {
+ BitField<0, 16, u32> low;
+ BitField<16, 16, u32> high;
+ };
+ };
- std::array<TransformFeedbackLayout, NumTransformFeedbackBuffers> tfb_layouts;
+ struct SampleMask {
+ struct Target {
+ union {
+ BitField<0, 1, u32> raster_out;
+ BitField<4, 1, u32> color_target;
+ };
+ u32 target;
+ };
+ struct Pos {
+ u32 x0_y0;
+ u32 x1_y0;
+ u32 x0_y1;
+ u32 x1_y1;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x1);
+ enum class NonMultisampledZ : u32 {
+ PerSample = 0,
+ PixelCenter = 1,
+ };
- u32 tfb_enabled;
+ enum class TIRMode : u32 {
+ Disabled = 0,
+ RasterNTargetM = 1,
+ };
- INSERT_PADDING_WORDS_NOINIT(0x2E);
+ enum class AntiAliasRaster : u32 {
+ Mode1x1 = 0,
+ Mode2x2 = 2,
+ Mode4x2_D3D = 4,
+ Mode2x1_D3D = 5,
+ Mode4x4 = 6,
+ };
- std::array<RenderTargetConfig, NumRenderTargets> rt;
+ struct SurfaceClipIDMemory {
+ u32 address_high;
+ u32 address_low;
- std::array<ViewportTransform, NumViewports> viewport_transform;
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
+ };
- std::array<ViewPort, NumViewports> viewports;
+ struct TIRModulation {
+ enum class Component : u32 {
+ None = 0,
+ RGB = 1,
+ AlphaOnly = 2,
+ RGBA = 3,
+ };
+ enum class Function : u32 {
+ Linear = 0,
+ Table = 1,
+ };
+ Component component;
+ Function function;
+ };
- INSERT_PADDING_WORDS_NOINIT(0x1D);
+ struct Zeta {
+ u32 address_high;
+ u32 address_low;
+ Tegra::DepthFormat format;
+ TileMode tile_mode;
+ u32 array_pitch;
- struct {
- u32 first;
- u32 count;
- } vertex_buffer;
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
+ };
- DepthMode depth_mode;
+ struct SurfaceClip {
+ union {
+ BitField<0, 16, u32> x;
+ BitField<16, 16, u32> width;
+ };
+ union {
+ BitField<0, 16, u32> y;
+ BitField<16, 16, u32> height;
+ };
+ };
- float clear_color[4];
- float clear_depth;
+ enum class L2CacheControlPolicy : u32 {
+ First = 0,
+ Normal = 1,
+ Last = 2,
+ };
- INSERT_PADDING_WORDS_NOINIT(0x3);
+ struct L2CacheVAFRequests {
+ union {
+ BitField<0, 1, u32> system_memory_volatile;
+ BitField<4, 2, L2CacheControlPolicy> policy;
+ };
+ };
- s32 clear_stencil;
+ enum class ViewportMulticast : u32 {
+ ViewportOrder = 0,
+ PrimitiveOrder = 1,
+ };
- INSERT_PADDING_WORDS_NOINIT(0x2);
+ struct TIRModulationCoeff {
+ union {
+ BitField<0, 8, u32> table_v0;
+ BitField<8, 8, u32> table_v1;
+ BitField<16, 8, u32> table_v2;
+ BitField<24, 8, u32> table_v3;
+ };
+ };
+ static_assert(sizeof(TIRModulationCoeff) == 0x4);
- PolygonMode polygon_mode_front;
- PolygonMode polygon_mode_back;
+ struct ReduceColorThreshold {
+ union {
+ BitField<0, 8, u32> all_hit_once;
+ BitField<16, 8, u32> all_covered;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x3);
+ struct ClearControl {
+ union {
+ BitField<0, 1, u32> respect_stencil_mask;
+ BitField<4, 1, u32> use_clear_rect;
+ BitField<8, 1, u32> use_scissor;
+ BitField<12, 1, u32> use_viewport_clip0;
+ };
+ };
- u32 polygon_offset_point_enable;
- u32 polygon_offset_line_enable;
- u32 polygon_offset_fill_enable;
+ struct L2CacheRopNonInterlockedReads {
+ union {
+ BitField<4, 2, L2CacheControlPolicy> policy;
+ };
+ };
- u32 patch_vertices;
+ struct VertexOutputAttributeSkipMasks {
+ struct Attributes {
+ union {
+ BitField<0, 1, u32> attribute0_comp0;
+ BitField<1, 1, u32> attribute0_comp1;
+ BitField<2, 1, u32> attribute0_comp2;
+ BitField<3, 1, u32> attribute0_comp3;
+ BitField<4, 1, u32> attribute1_comp0;
+ BitField<5, 1, u32> attribute1_comp1;
+ BitField<6, 1, u32> attribute1_comp2;
+ BitField<7, 1, u32> attribute1_comp3;
+ BitField<8, 1, u32> attribute2_comp0;
+ BitField<9, 1, u32> attribute2_comp1;
+ BitField<10, 1, u32> attribute2_comp2;
+ BitField<11, 1, u32> attribute2_comp3;
+ BitField<12, 1, u32> attribute3_comp0;
+ BitField<13, 1, u32> attribute3_comp1;
+ BitField<14, 1, u32> attribute3_comp2;
+ BitField<15, 1, u32> attribute3_comp3;
+ BitField<16, 1, u32> attribute4_comp0;
+ BitField<17, 1, u32> attribute4_comp1;
+ BitField<18, 1, u32> attribute4_comp2;
+ BitField<19, 1, u32> attribute4_comp3;
+ BitField<20, 1, u32> attribute5_comp0;
+ BitField<21, 1, u32> attribute5_comp1;
+ BitField<22, 1, u32> attribute5_comp2;
+ BitField<23, 1, u32> attribute5_comp3;
+ BitField<24, 1, u32> attribute6_comp0;
+ BitField<25, 1, u32> attribute6_comp1;
+ BitField<26, 1, u32> attribute6_comp2;
+ BitField<27, 1, u32> attribute6_comp3;
+ BitField<28, 1, u32> attribute7_comp0;
+ BitField<29, 1, u32> attribute7_comp1;
+ BitField<30, 1, u32> attribute7_comp2;
+ BitField<31, 1, u32> attribute7_comp3;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x4);
+ std::array<Attributes, 2> a;
+ std::array<Attributes, 2> b;
+ };
- u32 fragment_barrier;
+ struct TIRControl {
+ union {
+ BitField<0, 1, u32> z_pass_pixel_count_use_raster_samples;
+ BitField<4, 1, u32> alpha_coverage_use_raster_samples;
+ BitField<1, 1, u32> reduce_coverage;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x7);
+ enum class FillViaTriangleMode : u32 {
+ Disabled = 0,
+ FillAll = 1,
+ FillBoundingBox = 2,
+ };
- std::array<ScissorTest, NumViewports> scissor_test;
+ struct PsTicketDispenserValue {
+ union {
+ BitField<0, 8, u32> index;
+ BitField<8, 16, u32> value;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x15);
+ struct RegisterWatermarks {
+ union {
+ BitField<0, 16, u32> low;
+ BitField<16, 16, u32> high;
+ };
+ };
- s32 stencil_back_func_ref;
- u32 stencil_back_mask;
- u32 stencil_back_func_mask;
+ enum class InvalidateCacheLines : u32 {
+ All = 0,
+ One = 1,
+ };
- INSERT_PADDING_WORDS_NOINIT(0x5);
+ struct InvalidateTextureDataCacheNoWfi {
+ union {
+ BitField<0, 1, InvalidateCacheLines> lines;
+ BitField<4, 22, u32> tag;
+ };
+ };
- u32 invalidate_texture_data_cache;
+ struct ZCullRegionEnable {
+ union {
+ BitField<0, 1, u32> enable_z;
+ BitField<4, 1, u32> enable_stencil;
+ BitField<1, 1, u32> rect_clear;
+ BitField<2, 1, u32> use_rt_array_index;
+ BitField<5, 16, u32> rt_array_index;
+ BitField<3, 1, u32> make_conservative;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x1);
+ enum class FillMode : u32 {
+ Point = 1,
+ Wireframe = 2,
+ Solid = 3,
+ };
- u32 tiled_cache_barrier;
+ enum class ShadeMode : u32 {
+ Flat = 0x1,
+ Gouraud = 0x2,
+ GL_Flat = 0x1D00,
+ GL_Smooth = 0x1D01,
+ };
- INSERT_PADDING_WORDS_NOINIT(0x4);
+ enum class AlphaToCoverageDither : u32 {
+ Footprint_1x1 = 0,
+ Footprint_2x2 = 1,
+ Footprint_1x1_Virtual = 2,
+ };
- u32 color_mask_common;
+ struct InlineIndex4x8Align {
+ union {
+ BitField<0, 30, u32> count;
+ BitField<30, 2, u32> start;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x2);
+ struct InlineIndex4x8Index {
+ union {
+ BitField<0, 8, u32> index0;
+ BitField<8, 8, u32> index1;
+ BitField<16, 8, u32> index2;
+ BitField<24, 8, u32> index3;
+ };
+ };
- f32 depth_bounds[2];
+ enum class D3DCullMode : u32 {
+ None = 0,
+ CW = 1,
+ CCW = 2,
+ };
- INSERT_PADDING_WORDS_NOINIT(0x2);
+ struct BlendColor {
+ f32 r;
+ f32 g;
+ f32 b;
+ f32 a;
+ };
- u32 rt_separate_frag_data;
+ struct StencilOp {
+ enum class Op : u32 {
+ Keep_D3D = 1,
+ Zero_D3D = 2,
+ Replace_D3D = 3,
+ IncrSaturate_D3D = 4,
+ DecrSaturate_D3D = 5,
+ Invert_D3D = 6,
+ Incr_D3D = 7,
+ Decr_D3D = 8,
+
+ Keep_GL = 0x1E00,
+ Zero_GL = 0,
+ Replace_GL = 0x1E01,
+ IncrSaturate_GL = 0x1E02,
+ DecrSaturate_GL = 0x1E03,
+ Invert_GL = 0x150A,
+ Incr_GL = 0x8507,
+ Decr_GL = 0x8508,
+ };
- INSERT_PADDING_WORDS_NOINIT(0x1);
+ Op fail;
+ Op zfail;
+ Op zpass;
+ ComparisonOp func;
+ };
- u32 multisample_raster_enable;
- u32 multisample_raster_samples;
- std::array<u32, 4> multisample_sample_mask;
+ struct StencilFunc {
+ s32 ref;
+ u32 func_mask;
+ u32 mask;
+ };
- INSERT_PADDING_WORDS_NOINIT(0x5);
+ struct PsSaturate {
+ // Opposite of DepthMode
+ enum class Depth : u32 {
+ ZeroToOne = 0,
+ MinusOneToOne = 1,
+ };
- struct {
- u32 address_high;
- u32 address_low;
- Tegra::DepthFormat format;
- TileMode tile_mode;
- u32 layer_stride;
+ union {
+ BitField<0, 1, u32> output0_enable;
+ BitField<1, 1, Depth> output0_range;
+ BitField<4, 1, u32> output1_enable;
+ BitField<5, 1, Depth> output1_range;
+ BitField<8, 1, u32> output2_enable;
+ BitField<9, 1, Depth> output2_range;
+ BitField<12, 1, u32> output3_enable;
+ BitField<13, 1, Depth> output3_range;
+ BitField<16, 1, u32> output4_enable;
+ BitField<17, 1, Depth> output4_range;
+ BitField<20, 1, u32> output5_enable;
+ BitField<21, 1, Depth> output5_range;
+ BitField<24, 1, u32> output6_enable;
+ BitField<25, 1, Depth> output6_range;
+ BitField<28, 1, u32> output7_enable;
+ BitField<29, 1, Depth> output7_range;
+ };
- GPUVAddr Address() const {
- return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
- address_low);
- }
- } zeta;
+ bool AnyEnabled() const {
+ return output0_enable || output1_enable || output2_enable || output3_enable ||
+ output4_enable || output5_enable || output6_enable || output7_enable;
+ }
+ };
- struct {
- union {
- BitField<0, 16, u32> x;
- BitField<16, 16, u32> width;
- };
- union {
- BitField<0, 16, u32> y;
- BitField<16, 16, u32> height;
- };
- } render_area;
+ struct WindowOrigin {
+ enum class Mode : u32 {
+ UpperLeft = 0,
+ LowerLeft = 1,
+ };
+ union {
+ BitField<0, 1, Mode> mode;
+ BitField<4, 1, u32> flip_y;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x3F);
+ struct IteratedBlendConstants {
+ u32 r;
+ u32 g;
+ u32 b;
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ };
+ static_assert(sizeof(IteratedBlendConstants) == 0x10);
+ struct UserClip {
+ struct Enable {
union {
- BitField<0, 4, u32> stencil;
- BitField<4, 4, u32> unknown;
- BitField<8, 4, u32> scissor;
- BitField<12, 4, u32> viewport;
- } clear_flags;
-
- INSERT_PADDING_WORDS_NOINIT(0x10);
-
- u32 fill_rectangle;
-
- INSERT_PADDING_WORDS_NOINIT(0x2);
-
- u32 conservative_raster_enable;
-
- INSERT_PADDING_WORDS_NOINIT(0x5);
-
- std::array<VertexAttribute, NumVertexAttributes> vertex_attrib_format;
+ u32 raw;
+ BitField<0, 1, u32> plane0;
+ BitField<1, 1, u32> plane1;
+ BitField<2, 1, u32> plane2;
+ BitField<3, 1, u32> plane3;
+ BitField<4, 1, u32> plane4;
+ BitField<5, 1, u32> plane5;
+ BitField<6, 1, u32> plane6;
+ BitField<7, 1, u32> plane7;
+ };
- std::array<MsaaSampleLocation, 4> multisample_sample_locations;
+ bool AnyEnabled() const {
+ return plane0 || plane1 || plane2 || plane3 || plane4 || plane5 || plane6 ||
+ plane7;
+ }
+ };
- INSERT_PADDING_WORDS_NOINIT(0x2);
+ struct Op {
+ enum class ClipOrCull : u32 {
+ Clip = 0,
+ Cull = 1,
+ };
union {
- BitField<0, 1, u32> enable;
- BitField<4, 3, u32> target;
- } multisample_coverage_to_color;
-
- INSERT_PADDING_WORDS_NOINIT(0x8);
-
- struct {
- union {
- BitField<0, 4, u32> count;
- BitField<4, 3, u32> map_0;
- BitField<7, 3, u32> map_1;
- BitField<10, 3, u32> map_2;
- BitField<13, 3, u32> map_3;
- BitField<16, 3, u32> map_4;
- BitField<19, 3, u32> map_5;
- BitField<22, 3, u32> map_6;
- BitField<25, 3, u32> map_7;
- };
-
- u32 Map(std::size_t index) const {
- const std::array<u32, NumRenderTargets> maps{map_0, map_1, map_2, map_3,
- map_4, map_5, map_6, map_7};
- ASSERT(index < maps.size());
- return maps[index];
- }
- } rt_control;
-
- INSERT_PADDING_WORDS_NOINIT(0x2);
-
- u32 zeta_width;
- u32 zeta_height;
- union {
- BitField<0, 16, u32> zeta_depth;
- BitField<16, 1, u32> zeta_volume;
+ u32 raw;
+ BitField<0, 1, ClipOrCull> plane0;
+ BitField<4, 1, ClipOrCull> plane1;
+ BitField<8, 1, ClipOrCull> plane2;
+ BitField<12, 1, ClipOrCull> plane3;
+ BitField<16, 1, ClipOrCull> plane4;
+ BitField<20, 1, ClipOrCull> plane5;
+ BitField<24, 1, ClipOrCull> plane6;
+ BitField<28, 1, ClipOrCull> plane7;
};
+ };
+ };
- SamplerIndex sampler_index;
+ struct AntiAliasAlphaControl {
+ union {
+ BitField<0, 1, u32> alpha_to_coverage;
+ BitField<4, 1, u32> alpha_to_one;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x2);
+ struct RenderEnable {
+ enum class Override : u32 {
+ UseRenderEnable = 0,
+ AlwaysRender = 1,
+ NeverRender = 2,
+ };
- std::array<u32, 8> gp_passthrough_mask;
+ enum class Mode : u32 {
+ False = 0,
+ True = 1,
+ Conditional = 2,
+ IfEqual = 3,
+ IfNotEqual = 4,
+ };
- INSERT_PADDING_WORDS_NOINIT(0x1B);
+ u32 address_high;
+ u32 address_low;
+ Mode mode;
- u32 depth_test_enable;
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
+ };
- INSERT_PADDING_WORDS_NOINIT(0x5);
+ struct TexSampler {
+ u32 address_high;
+ u32 address_low;
+ u32 limit;
- u32 independent_blend_enable;
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
+ };
- u32 depth_write_enabled;
+ struct TexHeader {
+ u32 address_high;
+ u32 address_low;
+ u32 limit;
- u32 alpha_test_enabled;
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
+ };
- INSERT_PADDING_WORDS_NOINIT(0x6);
+ enum class ZCullRegionFormat : u32 {
+ Z_4x4 = 0,
+ ZS_4x4 = 1,
+ Z_4x2 = 2,
+ Z_2x4 = 3,
+ Z_16x8_4x4 = 4,
+ Z_8x8_4x2 = 5,
+ Z_8x8_2x4 = 6,
+ Z_16x16_4x8 = 7,
+ Z_4x8_2x2 = 8,
+ ZS_16x8_4x2 = 9,
+ ZS_16x8_2x4 = 10,
+ ZS_8x8_2x2 = 11,
+ Z_4x8_1x1 = 12,
+ };
- u32 d3d_cull_mode;
+ struct RtLayer {
+ enum class Control {
+ LayerSelectsLayer = 0,
+ GeometryShaderSelectsLayer = 1,
+ };
- ComparisonOp depth_test_func;
- float alpha_test_ref;
- ComparisonOp alpha_test_func;
- u32 draw_tfb_stride;
- struct {
- float r;
- float g;
- float b;
- float a;
- } blend_color;
+ union {
+ BitField<0, 16, u32> layer;
+ BitField<16, 1, u32> control;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x4);
+ struct InlineIndex2x16 {
+ union {
+ BitField<0, 31, u32> count;
+ BitField<31, 1, u32> start_odd;
+ };
+ union {
+ BitField<0, 16, u32> even;
+ BitField<16, 16, u32> odd;
+ };
+ };
- struct {
- u32 separate_alpha;
- Blend::Equation equation_rgb;
- Blend::Factor factor_source_rgb;
- Blend::Factor factor_dest_rgb;
- Blend::Equation equation_a;
- Blend::Factor factor_source_a;
- INSERT_PADDING_WORDS_NOINIT(1);
- Blend::Factor factor_dest_a;
+ struct VertexGlobalBaseOffset {
+ u32 address_high;
+ u32 address_low;
- u32 enable_common;
- u32 enable[NumRenderTargets];
- } blend;
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
+ };
- u32 stencil_enable;
- StencilOp stencil_front_op_fail;
- StencilOp stencil_front_op_zfail;
- StencilOp stencil_front_op_zpass;
- ComparisonOp stencil_front_func_func;
- s32 stencil_front_func_ref;
- u32 stencil_front_func_mask;
- u32 stencil_front_mask;
+ struct ZCullRegionPixelOffset {
+ u32 width;
+ u32 height;
+ };
- INSERT_PADDING_WORDS_NOINIT(0x2);
+ struct PointSprite {
+ enum class RMode : u32 {
+ Zero = 0,
+ FromR = 1,
+ FromS = 2,
+ };
+ enum class Origin : u32 {
+ Bottom = 0,
+ Top = 1,
+ };
+ enum class Texture : u32 {
+ Passthrough = 0,
+ Generate = 1,
+ };
+
+ union {
+ BitField<0, 2, RMode> rmode;
+ BitField<2, 1, Origin> origin;
+ BitField<3, 1, Texture> texture0;
+ BitField<4, 1, Texture> texture1;
+ BitField<5, 1, Texture> texture2;
+ BitField<6, 1, Texture> texture3;
+ BitField<7, 1, Texture> texture4;
+ BitField<8, 1, Texture> texture5;
+ BitField<9, 1, Texture> texture6;
+ BitField<10, 1, Texture> texture7;
+ BitField<11, 1, Texture> texture8;
+ BitField<12, 1, Texture> texture9;
+ };
+ };
- u32 frag_color_clamp;
+ struct ProgramRegion {
+ u32 address_high;
+ u32 address_low;
- union {
- BitField<0, 1, u32> y_negate;
- BitField<4, 1, u32> triangle_rast_flip;
- } screen_y_control;
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
+ };
- float line_width_smooth;
- float line_width_aliased;
+ struct DefaultAttributes {
+ enum class Diffuse : u32 {
+ Vector_0001 = 0,
+ Vector_1111 = 1,
+ };
+ enum class Specular : u32 {
+ Vector_0000 = 0,
+ Vector_0001 = 1,
+ };
+ enum class Vector : u32 {
+ Vector_0000 = 0,
+ Vector_0001 = 1,
+ };
+ enum class FixedFncTexture : u32 {
+ Vector_0000 = 0,
+ Vector_0001 = 1,
+ };
+ enum class DX9Color0 : u32 {
+ Vector_0000 = 0,
+ Vector_1111 = 1,
+ };
+ enum class DX9Color1To15 : u32 {
+ Vector_0000 = 0,
+ Vector_0001 = 1,
+ };
- INSERT_PADDING_WORDS_NOINIT(0x1B);
+ union {
+ BitField<0, 1, Diffuse> color_front_diffuse;
+ BitField<1, 1, Specular> color_front_specular;
+ BitField<2, 1, Vector> generic_vector;
+ BitField<3, 1, FixedFncTexture> fixed_fnc_texture;
+ BitField<4, 1, DX9Color0> dx9_color0;
+ BitField<5, 1, DX9Color1To15> dx9_color1_to_15;
+ };
+ };
- u32 invalidate_sampler_cache_no_wfi;
- u32 invalidate_texture_header_cache_no_wfi;
+ struct Draw {
+ enum class PrimitiveId : u32 {
+ First = 0,
+ Unchanged = 1,
+ };
+ enum class InstanceId : u32 {
+ First = 0,
+ Subsequent = 1,
+ Unchanged = 2,
+ };
+ enum class SplitMode : u32 {
+ NormalBeginNormal = 0,
+ NormalBeginOpen = 1,
+ OpenBeginOpen = 2,
+ OpenBeginNormal = 3,
+ };
- INSERT_PADDING_WORDS_NOINIT(0x2);
+ u32 end;
+ union {
+ u32 begin;
+ BitField<0, 16, PrimitiveTopology> topology;
+ BitField<24, 1, PrimitiveId> primitive_id;
+ BitField<26, 2, InstanceId> instance_id;
+ BitField<29, 2, SplitMode> split_mode;
+ };
+ };
- u32 vb_element_base;
- u32 vb_base_instance;
+ struct VertexIdCopy {
+ union {
+ BitField<0, 1, u32> enable;
+ BitField<4, 8, u32> attribute_slot;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x35);
+ struct ShaderBasedCull {
+ union {
+ BitField<1, 1, u32> batch_cull_enable;
+ BitField<0, 1, u32> before_fetch_enable;
+ };
+ };
- u32 clip_distance_enabled;
+ struct ClassVersion {
+ union {
+ BitField<0, 16, u32> current;
+ BitField<16, 16, u32> oldest_supported;
+ };
+ };
- u32 samplecnt_enable;
+ struct PrimitiveRestart {
+ u32 enabled;
+ u32 index;
+ };
- float point_size;
+ struct OutputVertexId {
+ union {
+ BitField<12, 1, u32> uses_array_start;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x1);
+ enum class PointCenterMode : u32 {
+ GL = 0,
+ D3D = 1,
+ };
- u32 point_sprite_enable;
+ enum class LineSmoothParams : u32 {
+ Falloff_1_00 = 0,
+ Falloff_1_33 = 1,
+ Falloff_1_66 = 2,
+ };
- INSERT_PADDING_WORDS_NOINIT(0x3);
+ struct LineSmoothEdgeTable {
+ union {
+ BitField<0, 8, u32> v0;
+ BitField<8, 8, u32> v1;
+ BitField<16, 8, u32> v2;
+ BitField<24, 8, u32> v3;
+ };
+ };
- CounterReset counter_reset;
+ struct LineStippleParams {
+ union {
+ BitField<0, 8, u32> factor;
+ BitField<8, 16, u32> pattern;
+ };
+ };
- u32 multisample_enable;
+ enum class ProvokingVertex : u32 {
+ First = 0,
+ Last = 1,
+ };
- u32 zeta_enable;
+ struct ShaderControl {
+ enum class Partial : u32 {
+ Zero = 0,
+ Infinity = 1,
+ };
+ enum class FP32NanBehavior : u32 {
+ Legacy = 0,
+ FP64Compatible = 1,
+ };
+ enum class FP32F2INanBehavior : u32 {
+ PassZero = 0,
+ PassIndefinite = 1,
+ };
- union {
- BitField<0, 1, u32> alpha_to_coverage;
- BitField<4, 1, u32> alpha_to_one;
- } multisample_control;
+ union {
+ BitField<0, 1, Partial> default_partial;
+ BitField<1, 1, FP32NanBehavior> fp32_nan_behavior;
+ BitField<2, 1, FP32F2INanBehavior> fp32_f2i_nan_behavior;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x4);
+ struct SphVersion {
+ union {
+ BitField<0, 16, u32> current;
+ BitField<16, 16, u32> oldest_supported;
+ };
+ };
- struct {
- u32 address_high;
- u32 address_low;
- ConditionMode mode;
+ struct AlphaToCoverageOverride {
+ union {
+ BitField<0, 1, u32> qualify_by_anti_alias_enable;
+ BitField<1, 1, u32> qualify_by_ps_sample_mask_enable;
+ };
+ };
- GPUVAddr Address() const {
- return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
- address_low);
- }
- } condition;
+ struct AamVersion {
+ union {
+ BitField<0, 16, u32> current;
+ BitField<16, 16, u32> oldest_supported;
+ };
+ };
- struct {
- u32 address_high;
- u32 address_low;
- u32 limit;
+ struct IndexBuffer {
+ u32 start_addr_high;
+ u32 start_addr_low;
+ u32 limit_addr_high;
+ u32 limit_addr_low;
+ IndexFormat format;
+ u32 first;
+ u32 count;
+
+ unsigned FormatSizeInBytes() const {
+ switch (format) {
+ case IndexFormat::UnsignedByte:
+ return 1;
+ case IndexFormat::UnsignedShort:
+ return 2;
+ case IndexFormat::UnsignedInt:
+ return 4;
+ }
+ ASSERT(false);
+ return 1;
+ }
- GPUVAddr Address() const {
- return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
- address_low);
- }
- } tsc;
+ GPUVAddr StartAddress() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(start_addr_high) << 32) |
+ start_addr_low);
+ }
- INSERT_PADDING_WORDS_NOINIT(0x1);
+ GPUVAddr EndAddress() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(limit_addr_high) << 32) |
+ limit_addr_low);
+ }
- float polygon_offset_factor;
+ /// Adjust the index buffer offset so it points to the first desired index.
+ GPUVAddr IndexStart() const {
+ return StartAddress() +
+ static_cast<size_t>(first) * static_cast<size_t>(FormatSizeInBytes());
+ }
+ };
- u32 line_smooth_enable;
+ struct IndexBufferSmall {
+ union {
+ BitField<0, 16, u32> first;
+ BitField<16, 12, u32> count;
+ BitField<28, 4, PrimitiveTopology> topology;
+ };
+ };
- struct {
- u32 address_high;
- u32 address_low;
- u32 limit;
+ struct VertexStreamInstances {
+ std::array<u32, NumVertexArrays> is_instanced;
- GPUVAddr Address() const {
- return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
- address_low);
- }
- } tic;
+ /// Returns whether the vertex array specified by index is supposed to be
+ /// accessed per instance or not.
+ bool IsInstancingEnabled(std::size_t index) const {
+ return is_instanced[index];
+ }
+ };
- INSERT_PADDING_WORDS_NOINIT(0x5);
+ struct AttributePointSize {
+ union {
+ BitField<0, 1, u32> enabled;
+ BitField<4, 8, u32> slot;
+ };
+ };
- u32 stencil_two_side_enable;
- StencilOp stencil_back_op_fail;
- StencilOp stencil_back_op_zfail;
- StencilOp stencil_back_op_zpass;
- ComparisonOp stencil_back_func_func;
+ struct ViewportClipControl {
+ enum class GeometryGuardband : u32 {
+ Scale256 = 0,
+ Scale1 = 1,
+ };
+ enum class GeometryClip : u32 {
+ WZero = 0,
+ Passthrough = 1,
+ FrustumXY = 2,
+ FrustumXYZ = 3,
+ WZeroNoZCull = 4,
+ FrustumZ = 5,
+ WZeroTriFillOrClip = 6,
+ };
+ enum class GeometryGuardbandZ : u32 {
+ SameAsXY = 0,
+ Scale256 = 1,
+ Scale1 = 2,
+ };
- INSERT_PADDING_WORDS_NOINIT(0x4);
+ union {
+ BitField<0, 1, u32> depth_0_to_1;
+ BitField<3, 1, u32> pixel_min_z;
+ BitField<4, 1, u32> pixel_max_z;
+ BitField<7, 1, GeometryGuardband> geometry_guardband;
+ BitField<11, 3, GeometryClip> geometry_clip;
+ BitField<1, 2, GeometryGuardbandZ> geometry_guardband_z;
+ };
+ };
- u32 framebuffer_srgb;
+ enum class PrimitiveTopologyControl : u32 {
+ UseInBeginMethods = 0,
+ UseSeparateState = 1,
+ };
- float polygon_offset_units;
+ struct WindowClip {
+ enum class Type : u32 {
+ Inclusive = 0,
+ Exclusive = 1,
+ ClipAll = 2,
+ };
- INSERT_PADDING_WORDS_NOINIT(0x4);
+ u32 enable;
+ Type type;
+ };
- Tegra::Texture::MsaaMode multisample_mode;
+ enum class InvalidateZCull : u32 {
+ Invalidate = 0,
+ };
- INSERT_PADDING_WORDS_NOINIT(0xC);
+ struct ZCull {
+ union {
+ BitField<0, 1, u32> z_enable;
+ BitField<1, 1, u32> stencil_enable;
+ };
+ union {
+ BitField<0, 1, u32> z_min_enbounded;
+ BitField<1, 1, u32> z_max_unbounded;
+ };
+ };
- union {
- BitField<2, 1, u32> coord_origin;
- BitField<3, 10, u32> enable;
- } point_coord_replace;
-
- struct {
- u32 code_address_high;
- u32 code_address_low;
-
- GPUVAddr CodeAddress() const {
- return static_cast<GPUVAddr>(
- (static_cast<GPUVAddr>(code_address_high) << 32) | code_address_low);
- }
- } code_address;
- INSERT_PADDING_WORDS_NOINIT(1);
-
- struct {
- u32 vertex_end_gl;
- union {
- u32 vertex_begin_gl;
- BitField<0, 16, PrimitiveTopology> topology;
- BitField<26, 1, u32> instance_next;
- BitField<27, 1, u32> instance_cont;
- };
- } draw;
-
- INSERT_PADDING_WORDS_NOINIT(0xA);
-
- struct {
- u32 enabled;
- u32 index;
- } primitive_restart;
-
- INSERT_PADDING_WORDS_NOINIT(0xE);
-
- u32 provoking_vertex_last;
-
- INSERT_PADDING_WORDS_NOINIT(0x50);
-
- struct {
- u32 start_addr_high;
- u32 start_addr_low;
- u32 end_addr_high;
- u32 end_addr_low;
- IndexFormat format;
- u32 first;
- u32 count;
-
- unsigned FormatSizeInBytes() const {
- switch (format) {
- case IndexFormat::UnsignedByte:
- return 1;
- case IndexFormat::UnsignedShort:
- return 2;
- case IndexFormat::UnsignedInt:
- return 4;
- }
- ASSERT(false);
- return 1;
- }
-
- GPUVAddr StartAddress() const {
- return static_cast<GPUVAddr>(
- (static_cast<GPUVAddr>(start_addr_high) << 32) | start_addr_low);
- }
-
- GPUVAddr EndAddress() const {
- return static_cast<GPUVAddr>((static_cast<GPUVAddr>(end_addr_high) << 32) |
- end_addr_low);
- }
-
- /// Adjust the index buffer offset so it points to the first desired index.
- GPUVAddr IndexStart() const {
- return StartAddress() + static_cast<size_t>(first) *
- static_cast<size_t>(FormatSizeInBytes());
- }
- } index_array;
+ struct LogicOp {
+ enum class Op : u32 {
+ Clear = 0x1500,
+ And = 0x1501,
+ AndReverse = 0x1502,
+ Copy = 0x1503,
+ AndInverted = 0x1504,
+ NoOp = 0x1505,
+ Xor = 0x1506,
+ Or = 0x1507,
+ Nor = 0x1508,
+ Equiv = 0x1509,
+ Invert = 0x150A,
+ OrReverse = 0x150B,
+ CopyInverted = 0x150C,
+ OrInverted = 0x150D,
+ Nand = 0x150E,
+ Set = 0x150F,
+ };
- union {
- BitField<0, 16, u32> first;
- BitField<16, 16, u32> count;
- } small_index;
+ u32 enable;
+ Op op;
+ };
- union {
- BitField<0, 16, u32> first;
- BitField<16, 16, u32> count;
- } small_index_2;
+ struct ClearSurface {
+ union {
+ u32 raw;
+ BitField<0, 1, u32> Z;
+ BitField<1, 1, u32> S;
+ BitField<2, 1, u32> R;
+ BitField<3, 1, u32> G;
+ BitField<4, 1, u32> B;
+ BitField<5, 1, u32> A;
+ BitField<6, 4, u32> RT;
+ BitField<10, 16, u32> layer;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x5);
+ struct ReportSemaphore {
+ struct Compare {
+ u32 initial_sequence;
+ u32 initial_mode;
+ u32 unknown1;
+ u32 unknown2;
+ u32 current_sequence;
+ u32 current_mode;
+ };
- INSERT_PADDING_WORDS_NOINIT(0x1F);
+ enum class Operation : u32 {
+ Release = 0,
+ Acquire = 1,
+ ReportOnly = 2,
+ Trap = 3,
+ };
- float polygon_offset_clamp;
+ enum class Release : u32 {
+ AfterAllPreceedingReads = 0,
+ AfterAllPreceedingWrites = 1,
+ };
- struct {
- u32 is_instanced[NumVertexArrays];
+ enum class Acquire : u32 {
+ BeforeAnyFollowingWrites = 0,
+ BeforeAnyFollowingReads = 1,
+ };
- /// Returns whether the vertex array specified by index is supposed to be
- /// accessed per instance or not.
- bool IsInstancingEnabled(std::size_t index) const {
- return is_instanced[index];
- }
- } instanced_arrays;
+ enum class Location : u32 {
+ None = 0,
+ VertexFetch = 1,
+ VertexShader = 2,
+ VPC = 4,
+ StreamingOutput = 5,
+ GeometryShader = 6,
+ ZCull = 7,
+ TessellationInit = 8,
+ TessellationShader = 9,
+ PixelShader = 10,
+ DepthTest = 12,
+ All = 15,
+ };
- INSERT_PADDING_WORDS_NOINIT(0x4);
+ enum class Comparison : u32 {
+ NotEqual = 0,
+ GreaterOrEqual = 1,
+ };
- union {
- BitField<0, 1, u32> enable;
- BitField<4, 8, u32> unk4;
- } vp_point_size;
+ enum class Report : u32 {
+ Payload = 0, // "None" in docs, but confirmed via hardware to return the payload
+ VerticesGenerated = 1,
+ ZPassPixelCount = 2,
+ PrimitivesGenerated = 3,
+ AlphaBetaClocks = 4,
+ VertexShaderInvocations = 5,
+ StreamingPrimitivesNeededMinusSucceeded = 6,
+ GeometryShaderInvocations = 7,
+ GeometryShaderPrimitivesGenerated = 9,
+ ZCullStats0 = 10,
+ StreamingPrimitivesSucceeded = 11,
+ ZCullStats1 = 12,
+ StreamingPrimitivesNeeded = 13,
+ ZCullStats2 = 14,
+ ClipperInvocations = 15,
+ ZCullStats3 = 16,
+ ClipperPrimitivesGenerated = 17,
+ VtgPrimitivesOut = 18,
+ PixelShaderInvocations = 19,
+ ZPassPixelCount64 = 21,
+ IEEECleanColorTarget = 24,
+ IEEECleanZetaTarget = 25,
+ StreamingByteCount = 26,
+ TessellationInitInvocations = 27,
+ BoundingRectangle = 28,
+ TessellationShaderInvocations = 29,
+ TotalStreamingPrimitivesNeededMinusSucceeded = 30,
+ TessellationShaderPrimitivesGenerated = 31,
+ };
- INSERT_PADDING_WORDS_NOINIT(1);
+ u32 address_high;
+ u32 address_low;
+ u32 payload;
+ union {
+ u32 raw;
+ BitField<0, 2, Operation> operation;
+ BitField<4, 1, Release> release;
+ BitField<8, 1, Acquire> acquire;
+ BitField<12, 4, Location> location;
+ BitField<16, 1, Comparison> comparison;
+ BitField<20, 1, u32> awaken_enable;
+ BitField<23, 5, Report> report;
+ BitField<28, 1, u32> short_query;
+ BitField<5, 3, u32> sub_report;
+ BitField<21, 1, u32> dword_number;
+ BitField<2, 1, u32> disable_flush;
+ BitField<3, 1, u32> reduction_enable;
+ BitField<9, 3, ReductionOp> reduction_op;
+ BitField<17, 2, u32> format_signed;
+ } query;
- u32 cull_test_enabled;
- FrontFace front_face;
- CullFace cull_face;
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
+ };
- u32 pixel_center_integer;
+ struct VertexStream {
+ union {
+ BitField<0, 12, u32> stride;
+ BitField<12, 1, u32> enable;
+ };
+ u32 address_high;
+ u32 address_low;
+ u32 frequency;
- INSERT_PADDING_WORDS_NOINIT(0x1);
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
- u32 viewport_transform_enabled;
+ bool IsEnabled() const {
+ return enable != 0 && Address() != 0;
+ }
+ };
+ static_assert(sizeof(VertexStream) == 0x10);
- INSERT_PADDING_WORDS_NOINIT(0x3);
+ struct VertexStreamLimit {
+ u32 address_high;
+ u32 address_low;
- union {
- BitField<0, 1, u32> depth_range_0_1;
- BitField<3, 1, u32> depth_clamp_near;
- BitField<4, 1, u32> depth_clamp_far;
- BitField<11, 1, u32> depth_clamp_disabled;
- } view_volume_clip_control;
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
+ };
+ static_assert(sizeof(VertexStreamLimit) == 0x8);
- INSERT_PADDING_WORDS_NOINIT(0xC);
+ enum class ShaderType : u32 {
+ VertexA = 0,
+ VertexB = 1,
+ TessellationInit = 2,
+ Tessellation = 3,
+ Geometry = 4,
+ Pixel = 5,
+ };
- PrimitiveTopologyOverride topology_override;
+ struct Pipeline {
+ union {
+ BitField<0, 1, u32> enable;
+ BitField<4, 4, ShaderType> program;
+ };
+ u32 offset;
+ u32 reservedA;
+ u32 register_count;
+ u32 binding_group;
+ std::array<u32, 4> reserved;
+ INSERT_PADDING_BYTES_NOINIT(0x1C);
+ };
+ static_assert(sizeof(Pipeline) == 0x40);
- INSERT_PADDING_WORDS_NOINIT(0x12);
+ bool IsShaderConfigEnabled(std::size_t index) const {
+ // The VertexB is always enabled.
+ if (index == static_cast<std::size_t>(ShaderType::VertexB)) {
+ return true;
+ }
+ return pipelines[index].enable != 0;
+ }
- u32 depth_bounds_enable;
+ bool IsShaderConfigEnabled(ShaderType type) const {
+ return IsShaderConfigEnabled(static_cast<std::size_t>(type));
+ }
- INSERT_PADDING_WORDS_NOINIT(1);
+ struct ConstantBuffer {
+ u32 size;
+ u32 address_high;
+ u32 address_low;
+ u32 offset;
+ std::array<u32, NumCBData> buffer;
- struct {
- u32 enable;
- LogicOperation operation;
- } logic_op;
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
+ };
- INSERT_PADDING_WORDS_NOINIT(0x1);
+ struct BindGroup {
+ std::array<u32, 4> reserved;
+ union {
+ u32 raw_config;
+ BitField<0, 1, u32> valid;
+ BitField<4, 5, u32> shader_slot;
+ };
+ INSERT_PADDING_BYTES_NOINIT(0xC);
+ };
+ static_assert(sizeof(BindGroup) == 0x20);
+ struct StreamOutLayout {
+ union {
+ BitField<0, 8, u32> attribute0;
+ BitField<8, 8, u32> attribute1;
+ BitField<16, 8, u32> attribute2;
+ BitField<24, 8, u32> attribute3;
+ };
+ };
+
+ struct ShaderPerformance {
+ struct ControlA {
union {
- u32 raw;
- BitField<0, 1, u32> Z;
- BitField<1, 1, u32> S;
- BitField<2, 1, u32> R;
- BitField<3, 1, u32> G;
- BitField<4, 1, u32> B;
- BitField<5, 1, u32> A;
- BitField<6, 4, u32> RT;
- BitField<10, 11, u32> layer;
- } clear_buffers;
- INSERT_PADDING_WORDS_NOINIT(0xB);
- std::array<ColorMask, NumRenderTargets> color_mask;
- INSERT_PADDING_WORDS_NOINIT(0x38);
-
- struct {
- u32 query_address_high;
- u32 query_address_low;
- u32 query_sequence;
- union {
- u32 raw;
- BitField<0, 2, QueryOperation> operation;
- BitField<4, 1, u32> fence;
- BitField<12, 4, QueryUnit> unit;
- BitField<16, 1, QuerySyncCondition> sync_cond;
- BitField<23, 5, QuerySelect> select;
- BitField<28, 1, u32> short_query;
- } query_get;
-
- GPUVAddr QueryAddress() const {
- return static_cast<GPUVAddr>(
- (static_cast<GPUVAddr>(query_address_high) << 32) | query_address_low);
- }
- } query;
-
- INSERT_PADDING_WORDS_NOINIT(0x3C);
-
- struct {
- union {
- BitField<0, 12, u32> stride;
- BitField<12, 1, u32> enable;
- };
- u32 start_high;
- u32 start_low;
- u32 divisor;
-
- GPUVAddr StartAddress() const {
- return static_cast<GPUVAddr>((static_cast<GPUVAddr>(start_high) << 32) |
- start_low);
- }
-
- bool IsEnabled() const {
- return enable != 0 && StartAddress() != 0;
- }
-
- } vertex_array[NumVertexArrays];
-
- Blend independent_blend[NumRenderTargets];
-
- struct {
- u32 limit_high;
- u32 limit_low;
-
- GPUVAddr LimitAddress() const {
- return static_cast<GPUVAddr>((static_cast<GPUVAddr>(limit_high) << 32) |
- limit_low);
- }
- } vertex_array_limit[NumVertexArrays];
-
- struct {
- union {
- BitField<0, 1, u32> enable;
- BitField<4, 4, ShaderProgram> program;
- };
- u32 offset;
- INSERT_PADDING_WORDS_NOINIT(14);
- } shader_config[MaxShaderProgram];
-
- INSERT_PADDING_WORDS_NOINIT(0x60);
-
- u32 firmware[0x20];
-
- struct {
- u32 cb_size;
- u32 cb_address_high;
- u32 cb_address_low;
- u32 cb_pos;
- std::array<u32, NumCBData> cb_data;
-
- GPUVAddr BufferAddress() const {
- return static_cast<GPUVAddr>(
- (static_cast<GPUVAddr>(cb_address_high) << 32) | cb_address_low);
- }
- } const_buffer;
-
- INSERT_PADDING_WORDS_NOINIT(0x10);
-
- struct {
- union {
- u32 raw_config;
- BitField<0, 1, u32> valid;
- BitField<4, 5, u32> index;
- };
- INSERT_PADDING_WORDS_NOINIT(7);
- } cb_bind[MaxShaderStage];
-
- INSERT_PADDING_WORDS_NOINIT(0x56);
-
- u32 tex_cb_index;
-
- INSERT_PADDING_WORDS_NOINIT(0x7D);
-
- std::array<std::array<u8, 128>, NumTransformFeedbackBuffers> tfb_varying_locs;
-
- INSERT_PADDING_WORDS_NOINIT(0x298);
-
- struct {
- /// Compressed address of a buffer that holds information about bound SSBOs.
- /// This address is usually bound to c0 in the shaders.
- u32 buffer_address;
-
- GPUVAddr BufferAddress() const {
- return static_cast<GPUVAddr>(buffer_address) << 8;
- }
- } ssbo_info;
+ BitField<0, 2, u32> event0;
+ BitField<2, 3, u32> bit0;
+ BitField<5, 2, u32> event1;
+ BitField<7, 3, u32> bit1;
+ BitField<10, 2, u32> event2;
+ BitField<12, 3, u32> bit2;
+ BitField<15, 2, u32> event3;
+ BitField<17, 3, u32> bit3;
+ BitField<20, 2, u32> event4;
+ BitField<22, 3, u32> bit4;
+ BitField<25, 2, u32> event5;
+ BitField<27, 3, u32> bit5;
+ BitField<30, 2, u32> spare;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x11);
+ struct ControlB {
+ union {
+ BitField<0, 1, u32> edge;
+ BitField<1, 2, u32> mode;
+ BitField<3, 1, u32> windowed;
+ BitField<4, 16, u32> func;
+ };
+ };
- struct {
- u32 address[MaxShaderStage];
- u32 size[MaxShaderStage];
- } tex_info_buffers;
+ std::array<u32, 8> values_upper;
+ std::array<u32, 8> values;
+ std::array<u32, 8> events;
+ std::array<ControlA, 8> control_a;
+ std::array<ControlB, 8> control_b;
+ u32 trap_control_mask;
+ u32 start_shader_mask;
+ u32 stop_shader_mask;
+ };
- INSERT_PADDING_WORDS_NOINIT(0xCC);
+ // clang-format off
+ union {
+ struct {
+ ID object_id; ///< 0x0000
+ INSERT_PADDING_BYTES_NOINIT(0xFC);
+ u32 nop; ///< 0x0100
+ Notify notify; ///< 0x0104
+ u32 wait_for_idle; ///< 0x0110
+ LoadMME load_mme; ///< 0x0114
+ ShadowRamControl shadow_ram_control; ///< 0x0124
+ PeerSemaphore peer; ///< 0x0128
+ GlobalRender global_render; ///< 0x0130
+ u32 go_idle; ///< 0x013C
+ u32 trigger; ///< 0x0140
+ u32 trigger_wfi; ///< 0x0144
+ INSERT_PADDING_BYTES_NOINIT(0x8);
+ u32 instrumentation_method_header; ///< 0x0150
+ u32 instrumentation_method_data; ///< 0x0154
+ INSERT_PADDING_BYTES_NOINIT(0x28);
+ Upload::Registers upload; ///< 0x0180
+ LaunchDMA launch_dma; ///< 0x01B0
+ u32 inline_data; ///< 0x01B4
+ INSERT_PADDING_BYTES_NOINIT(0x24);
+ I2M i2m; ///< 0x01DC
+ u32 run_ds_now; ///< 0x0200
+ OpportunisticEarlyZ opportunistic_early_z; ///< 0x0204
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ u32 aliased_line_width_enabled; ///< 0x020C
+ u32 mandated_early_z; ///< 0x0210
+ GeometryShaderDmFifo gs_dm_fifo; ///< 0x0214
+ L2CacheControl l2_cache_control; ///< 0x0218
+ InvalidateShaderCache invalidate_shader_cache; ///< 0x021C
+ INSERT_PADDING_BYTES_NOINIT(0xA8);
+ SyncInfo sync_info; ///< 0x02C8
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ u32 prim_circular_buffer_throttle; ///< 0x02D0
+ u32 flush_invalidate_rop_mini_cache; ///< 0x02D4
+ SurfaceClipBlockId surface_clip_block_id; ///< 0x02D8
+ u32 alpha_circular_buffer_size; ///< 0x02DC
+ DecompressSurface decompress_surface; ///< 0x02E0
+ ZCullRopBypass zcull_rop_bypass; ///< 0x02E4
+ ZCullSubregion zcull_subregion; ///< 0x02E8
+ RasterBoundingBox raster_bounding_box; ///< 0x02EC
+ u32 peer_semaphore_release; ///< 0x02F0
+ u32 iterated_blend_optimization; ///< 0x02F4
+ ZCullSubregionAllocation zcull_subregion_allocation; ///< 0x02F8
+ ZCullSubregionAlgorithm zcull_subregion_algorithm; ///< 0x02FC
+ PixelShaderOutputSampleMaskUsage ps_output_sample_mask_usage; ///< 0x0300
+ u32 draw_zero_index; ///< 0x0304
+ L1Configuration l1_configuration; ///< 0x0308
+ u32 render_enable_control_load_const_buffer; ///< 0x030C
+ SPAVersion spa_version; ///< 0x0310
+ u32 ieee_clean_update; ///< 0x0314
+ SnapGrid snap_grid; ///< 0x0318
+ Tessellation tessellation; ///< 0x0320
+ SubTilingPerf sub_tiling_perf; ///< 0x0360
+ ZCullSubregionReport zcull_subregion_report; ///< 0x036C
+ BalancedPrimitiveWorkload balanced_primitive_workload; ///< 0x0374
+ u32 max_patches_per_batch; ///< 0x0378
+ u32 rasterize_enable; ///< 0x037C
+ TransformFeedback transform_feedback; ///< 0x0380
+ u32 raster_input; ///< 0x0740
+ u32 transform_feedback_enabled; ///< 0x0744
+ u32 primitive_restart_topology_change_enable; ///< 0x0748
+ u32 alpha_fraction; ///< 0x074C
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ HybridAntiAliasControl hybrid_aa_control; ///< 0x0754
+ INSERT_PADDING_BYTES_NOINIT(0x24);
+ ShaderLocalMemory shader_local_memory; ///< 0x077C
+ u32 color_zero_bandwidth_clear; ///< 0x07A4
+ u32 z_zero_bandwidth_clear; ///< 0x07A8
+ u32 isbe_save_restore_program_offset; ///< 0x07AC
+ INSERT_PADDING_BYTES_NOINIT(0x10);
+ ZCullRegion zcull_region; ///< 0x07C0
+ ZetaReadOnly zeta_read_only; ///< 0x07F8
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ std::array<RenderTargetConfig, NumRenderTargets> rt; ///< 0x0800
+ std::array<ViewportTransform, NumViewports> viewport_transform; ///< 0x0A00
+ std::array<Viewport, NumViewports> viewports; ///< 0x0C00
+ std::array<Window, 8> windows; ///< 0x0D00
+ std::array<ClipIdExtent, 4> clip_id_extent; ///< 0x0D40
+ u32 max_geometry_instances_per_task; ///< 0x0D60
+ VisibleCallLimit visible_call_limit; ///< 0x0D64
+ StatisticsCounter statistics_count; ///< 0x0D68
+ ClearRect clear_rect; ///< 0x0D6C
+ VertexBuffer vertex_buffer; ///< 0x0D74
+ DepthMode depth_mode; ///< 0x0D7C
+ std::array<f32, 4> clear_color; ///< 0x0D80
+ f32 clear_depth; ///< 0x0D90
+ u32 shader_cache_icache_prefetch; ///< 0x0D94
+ u32 force_transition_to_beta; ///< 0x0D98
+ u32 reduce_colour_thresholds; ///< 0x0D9C
+ s32 clear_stencil; ///< 0x0DA0
+ InvalidateShaderCacheNoWFI invalidate_shader_cache_no_wfi; ///< 0x0DA4
+ ZCullSerialization zcull_serialization; ///< 0x0DA8
+ PolygonMode polygon_mode_front; ///< 0x0DAC
+ PolygonMode polygon_mode_back; ///< 0x0DB0
+ u32 polygon_smooth; ///< 0x0DB4
+ u32 zeta_mark_clean_ieee; ///< 0x0DB8
+ ZCullDirFormat zcull_dir_format; ///< 0x0DBC
+ u32 polygon_offset_point_enable; ///< 0x0DC0
+ u32 polygon_offset_line_enable; ///< 0x0DC4
+ u32 polygon_offset_fill_enable; ///< 0x0DC8
+ u32 patch_vertices; ///< 0x0DCC
+ IteratedBlend iterated_blend; ///< 0x0DD0
+ ZCullCriterion zcull_criteria; ///< 0x0DD8
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ u32 fragment_barrier; ///< 0x0DE0
+ u32 sm_timeout; ///< 0x0DE4
+ u32 primitive_restart_array; ///< 0x0DE8
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ LoadIteratedBlend load_iterated_blend; ///< 0x0DF0
+ u32 window_offset_x; ///< 0x0DF8
+ u32 window_offset_y; ///< 0x0DFC
+ std::array<ScissorTest, NumViewports> scissor_test; ///< 0x0E00
+ INSERT_PADDING_BYTES_NOINIT(0x10);
+ u32 select_texture_headers; ///< 0x0F10
+ VPCPerf vpc_perf; ///< 0x0F14
+ u32 pm_local_trigger; ///< 0x0F18
+ u32 post_z_pixel_imask; ///< 0x0F1C
+ INSERT_PADDING_BYTES_NOINIT(0x20);
+ ConstantColorRendering const_color_rendering; ///< 0x0F40
+ StencilFunc stencil_back_func; ///< 0x0F54
+ INSERT_PADDING_BYTES_NOINIT(0x24);
+ VertexStreamSubstitute vertex_stream_substitute; ///< 0x0F84
+ u32 line_mode_clip_generated_edge_do_not_draw; ///< 0x0F8C
+ u32 color_mask_common; ///< 0x0F90
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ VTGWarpWatermarks vtg_warp_watermarks; ///< 0x0F98
+ f32 depth_bounds[2]; ///< 0x0F9C
+ SampleMask::Target sample_mask_target; ///< 0x0FA4
+ u32 color_target_mrt_enable; ///< 0x0FAC
+ NonMultisampledZ non_multisampled_z; ///< 0x0FB0
+ TIRMode tir_mode; ///< 0x0FB4
+ AntiAliasRaster anti_alias_raster; ///< 0x0FB8
+ SampleMask::Pos sample_mask_pos; ///< 0x0FBC
+ SurfaceClipIDMemory surface_clip_id_memory; ///< 0x0FCC
+ TIRModulation tir_modulation; ///< 0x0FD4
+ u32 blend_control_allow_float_pixel_kills; ///< 0x0FDC
+ Zeta zeta; ///< 0x0FE0
+ SurfaceClip surface_clip; ///< 0x0FF4
+ u32 tiled_cache_treat_heavy_as_light; ///< 0x0FFC
+ L2CacheVAFRequests l2_cache_vaf; ///< 0x1000
+ ViewportMulticast viewport_multicast; ///< 0x1004
+ u32 tessellation_cut_height; ///< 0x1008
+ u32 max_gs_instances_per_task; ///< 0x100C
+ u32 max_gs_output_vertices_per_task; ///< 0x1010
+ u32 reserved_sw_method0; ///< 0x1014
+ u32 gs_output_cb_storage_multiplier; ///< 0x1018
+ u32 beta_cb_storage_constant; ///< 0x101C
+ u32 ti_output_cb_storage_multiplier; ///< 0x1020
+ u32 alpha_cb_storage_constraint; ///< 0x1024
+ u32 reserved_sw_method1; ///< 0x1028
+ u32 reserved_sw_method2; ///< 0x102C
+ std::array<TIRModulationCoeff, 5> tir_modulation_coeff; ///< 0x1030
+ std::array<u32, 15> spare_nop; ///< 0x1044
+ INSERT_PADDING_BYTES_NOINIT(0x30);
+ std::array<u32, 7> reserved_sw_method3_to_7; ///< 0x10B0
+ ReduceColorThreshold reduce_color_thresholds_unorm8; ///< 0x10CC
+ std::array<u32, 4> reserved_sw_method10_to_13; ///< 0x10D0
+ ReduceColorThreshold reduce_color_thresholds_unorm10; ///< 0x10E0
+ ReduceColorThreshold reduce_color_thresholds_unorm16; ///< 0x10E4
+ ReduceColorThreshold reduce_color_thresholds_fp11; ///< 0x10E8
+ ReduceColorThreshold reduce_color_thresholds_fp16; ///< 0x10EC
+ ReduceColorThreshold reduce_color_thresholds_srgb8; ///< 0x10F0
+ u32 unbind_all_constant_buffers; ///< 0x10F4
+ ClearControl clear_control; ///< 0x10F8
+ L2CacheRopNonInterlockedReads l2_cache_rop_non_interlocked_reads; ///< 0x10FC
+ u32 reserved_sw_method14; ///< 0x1100
+ u32 reserved_sw_method15; ///< 0x1104
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ u32 no_operation_data_high; ///< 0x110C
+ u32 depth_bias_control; ///< 0x1110
+ u32 pm_trigger_end; ///< 0x1114
+ u32 vertex_id_base; ///< 0x1118
+ u32 stencil_compression_enabled; ///< 0x111C
+ VertexOutputAttributeSkipMasks vertex_output_attribute_skip_masks; ///< 0x1120
+ TIRControl tir_control; ///< 0x1130
+ u32 mutable_method_treat_mutable_as_heavy; ///< 0x1134
+ u32 post_ps_use_pre_ps_coverage; ///< 0x1138
+ FillViaTriangleMode fill_via_triangle_mode; ///< 0x113C
+ u32 blend_per_format_snorm8_unorm16_snorm16_enabled; ///< 0x1140
+ u32 flush_pending_writes_sm_gloal_store; ///< 0x1144
+ INSERT_PADDING_BYTES_NOINIT(0x18);
+ std::array<VertexAttribute, NumVertexAttributes> vertex_attrib_format; ///< 0x1160
+ std::array<MsaaSampleLocation, 4> multisample_sample_locations; ///< 0x11E0
+ u32 offset_render_target_index_by_viewport_index; ///< 0x11F0
+ u32 force_heavy_method_sync; ///< 0x11F4
+ MultisampleCoverageToColor multisample_coverage_to_color; ///< 0x11F8
+ DecompressZetaSurface decompress_zeta_surface; ///< 0x11FC
+ INSERT_PADDING_BYTES_NOINIT(0x8);
+ ZetaSparse zeta_sparse; ///< 0x1208
+ u32 invalidate_sampler_cache; ///< 0x120C
+ u32 invalidate_texture_header_cache; ///< 0x1210
+ VertexArray vertex_array_instance_first; ///< 0x1214
+ VertexArray vertex_array_instance_subsequent; ///< 0x1218
+ RtControl rt_control; ///< 0x121C
+ CompressionThresholdSamples compression_threshold_samples; ///< 0x1220
+ PixelShaderInterlockControl ps_interlock_control; ///< 0x1224
+ ZetaSize zeta_size; ///< 0x1228
+ SamplerBinding sampler_binding; ///< 0x1234
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ u32 draw_auto_byte_count; ///< 0x123C
+ std::array<u32, 8> post_vtg_shader_attrib_skip_mask; ///< 0x1240
+ PsTicketDispenserValue ps_ticket_dispenser_value; ///< 0x1260
+ INSERT_PADDING_BYTES_NOINIT(0x1C);
+ u32 circular_buffer_size; ///< 0x1280
+ RegisterWatermarks vtg_register_watermarks; ///< 0x1284
+ InvalidateTextureDataCacheNoWfi invalidate_texture_cache_no_wfi; ///< 0x1288
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ L2CacheRopNonInterlockedReads l2_cache_rop_interlocked_reads; ///< 0x1290
+ INSERT_PADDING_BYTES_NOINIT(0x10);
+ u32 primitive_restart_topology_change_index; ///< 0x12A4
+ INSERT_PADDING_BYTES_NOINIT(0x20);
+ ZCullRegionEnable zcull_region_enable; ///< 0x12C8
+ u32 depth_test_enable; ///< 0x12CC
+ FillMode fill_mode; ///< 0x12D0
+ ShadeMode shade_mode; ///< 0x12D4
+ L2CacheRopNonInterlockedReads l2_cache_rop_non_interlocked_writes; ///< 0x12D8
+ L2CacheRopNonInterlockedReads l2_cache_rop_interlocked_writes; ///< 0x12DC
+ AlphaToCoverageDither alpha_to_coverage_dither; ///< 0x12E0
+ u32 blend_per_target_enabled; ///< 0x12E4
+ u32 depth_write_enabled; ///< 0x12E8
+ u32 alpha_test_enabled; ///< 0x12EC
+ INSERT_PADDING_BYTES_NOINIT(0x10);
+ InlineIndex4x8Align inline_index_4x8_align; ///< 0x1300
+ InlineIndex4x8Index inline_index_4x8_index; ///< 0x1304
+ D3DCullMode d3d_cull_mode; ///< 0x1308
+ ComparisonOp depth_test_func; ///< 0x130C
+ f32 alpha_test_ref; ///< 0x1310
+ ComparisonOp alpha_test_func; ///< 0x1314
+ u32 draw_auto_stride; ///< 0x1318
+ BlendColor blend_color; ///< 0x131C
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ InvalidateCacheLines invalidate_sampler_cache_lines; ///< 0x1330
+ InvalidateCacheLines invalidate_texture_header_cache_lines; ///< 0x1334
+ InvalidateCacheLines invalidate_texture_data_cache_lines; ///< 0x1338
+ Blend blend; ///< 0x133C
+ u32 stencil_enable; ///< 0x1380
+ StencilOp stencil_front_op; ///< 0x1384
+ StencilFunc stencil_front_func; ///< 0x1394
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ u32 draw_auto_start_byte_count; ///< 0x13A4
+ PsSaturate frag_color_clamp; ///< 0x13A8
+ WindowOrigin window_origin; ///< 0x13AC
+ f32 line_width_smooth; ///< 0x13B0
+ f32 line_width_aliased; ///< 0x13B4
+ INSERT_PADDING_BYTES_NOINIT(0x60);
+ u32 line_override_multisample; ///< 0x1418
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ u32 alpha_hysteresis_rounds; ///< 0x1420
+ InvalidateCacheLines invalidate_sampler_cache_no_wfi; ///< 0x1424
+ InvalidateCacheLines invalidate_texture_header_cache_no_wfi; ///< 0x1428
+ INSERT_PADDING_BYTES_NOINIT(0x8);
+ u32 global_base_vertex_index; ///< 0x1434
+ u32 global_base_instance_index; ///< 0x1438
+ INSERT_PADDING_BYTES_NOINIT(0x14);
+ RegisterWatermarks ps_warp_watermarks; ///< 0x1450
+ RegisterWatermarks ps_regster_watermarks; ///< 0x1454
+ INSERT_PADDING_BYTES_NOINIT(0xC);
+ u32 store_zcull; ///< 0x1464
+ INSERT_PADDING_BYTES_NOINIT(0x18);
+ std::array<IteratedBlendConstants, NumRenderTargets>
+ iterated_blend_constants; ///< 0x1480
+ u32 load_zcull; ///< 0x1500
+ u32 surface_clip_id_height; ///< 0x1504
+ Window surface_clip_id_clear_rect; ///< 0x1508
+ UserClip::Enable user_clip_enable; ///< 0x1510
+ u32 zpass_pixel_count_enable; ///< 0x1514
+ f32 point_size; ///< 0x1518
+ u32 zcull_stats_enable; ///< 0x151C
+ u32 point_sprite_enable; ///< 0x1520
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ u32 shader_exceptions_enable; ///< 0x1528
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ ClearReport clear_report_value; ///< 0x1530
+ u32 anti_alias_enable; ///< 0x1534
+ u32 zeta_enable; ///< 0x1538
+ AntiAliasAlphaControl anti_alias_alpha_control; ///< 0x153C
+ INSERT_PADDING_BYTES_NOINIT(0x10);
+ RenderEnable render_enable; ///< 0x1550
+ TexSampler tex_sampler; ///< 0x155C
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ f32 slope_scale_depth_bias; ///< 0x156C
+ u32 line_anti_alias_enable; ///< 0x1570
+ TexHeader tex_header; ///< 0x1574
+ INSERT_PADDING_BYTES_NOINIT(0x10);
+ u32 active_zcull_region_id; ///< 0x1590
+ u32 stencil_two_side_enable; ///< 0x1594
+ StencilOp stencil_back_op; ///< 0x1598
+ INSERT_PADDING_BYTES_NOINIT(0x10);
+ u32 framebuffer_srgb; ///< 0x15B8
+ f32 depth_bias; ///< 0x15BC
+ INSERT_PADDING_BYTES_NOINIT(0x8);
+ ZCullRegionFormat zcull_region_format; ///< 0x15C8
+ RtLayer rt_layer; ///< 0x15CC
+ Tegra::Texture::MsaaMode anti_alias_samples_mode; ///< 0x15D0
+ INSERT_PADDING_BYTES_NOINIT(0x10);
+ u32 edge_flag; ///< 0x15E4
+ u32 draw_inline_index; ///< 0x15E8
+ InlineIndex2x16 inline_index_2x16; ///< 0x15EC
+ VertexGlobalBaseOffset vertex_global_base_offset; ///< 0x15F4
+ ZCullRegionPixelOffset zcull_region_pixel_offset; ///< 0x15FC
+ PointSprite point_sprite; ///< 0x1604
+ ProgramRegion program_region; ///< 0x1608
+ DefaultAttributes default_attributes; ///< 0x1610
+ Draw draw; ///< 0x1614
+ VertexIdCopy vertex_id_copy; ///< 0x161C
+ u32 add_to_primitive_id; ///< 0x1620
+ u32 load_to_primitive_id; ///< 0x1624
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ ShaderBasedCull shader_based_cull; ///< 0x162C
+ INSERT_PADDING_BYTES_NOINIT(0x8);
+ ClassVersion class_version; ///< 0x1638
+ INSERT_PADDING_BYTES_NOINIT(0x8);
+ PrimitiveRestart primitive_restart; ///< 0x1644
+ OutputVertexId output_vertex_id; ///< 0x164C
+ INSERT_PADDING_BYTES_NOINIT(0x8);
+ u32 anti_alias_point_enable; ///< 0x1658
+ PointCenterMode point_center_mode; ///< 0x165C
+ INSERT_PADDING_BYTES_NOINIT(0x8);
+ LineSmoothParams line_smooth_params; ///< 0x1668
+ u32 line_stipple_enable; ///< 0x166C
+ std::array<LineSmoothEdgeTable, 4> line_smooth_edge_table; ///< 0x1670
+ LineStippleParams line_stipple_params; ///< 0x1680
+ ProvokingVertex provoking_vertex; ///< 0x1684
+ u32 two_sided_light_enabled; ///< 0x1688
+ u32 polygon_stipple_enabled; ///< 0x168C
+ ShaderControl shader_control; ///< 0x1690
+ INSERT_PADDING_BYTES_NOINIT(0xC);
+ ClassVersion class_version_check; ///< 0x16A0
+ SphVersion sph_version; ///< 0x16A4
+ SphVersion sph_version_check; ///< 0x16A8
+ INSERT_PADDING_BYTES_NOINIT(0x8);
+ AlphaToCoverageOverride alpha_to_coverage_override; ///< 0x16B4
+ INSERT_PADDING_BYTES_NOINIT(0x48);
+ std::array<u32, 32> polygon_stipple_pattern; ///< 0x1700
+ INSERT_PADDING_BYTES_NOINIT(0x10);
+ AamVersion aam_version; ///< 0x1790
+ AamVersion aam_version_check; ///< 0x1794
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ u32 zeta_layer_offset; ///< 0x179C
+ INSERT_PADDING_BYTES_NOINIT(0x28);
+ IndexBuffer index_buffer; ///< 0x17C8
+ IndexBufferSmall index_buffer32_first; ///< 0x17E4
+ IndexBufferSmall index_buffer16_first; ///< 0x17E8
+ IndexBufferSmall index_buffer8_first; ///< 0x17EC
+ IndexBufferSmall index_buffer32_subsequent; ///< 0x17F0
+ IndexBufferSmall index_buffer16_subsequent; ///< 0x17F4
+ IndexBufferSmall index_buffer8_subsequent; ///< 0x17F8
+ INSERT_PADDING_BYTES_NOINIT(0x80);
+ f32 depth_bias_clamp; ///< 0x187C
+ VertexStreamInstances vertex_stream_instances; ///< 0x1880
+ INSERT_PADDING_BYTES_NOINIT(0x10);
+ AttributePointSize point_size_attribute; ///< 0x1910
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ u32 gl_cull_test_enabled; ///< 0x1918
+ FrontFace gl_front_face; ///< 0x191C
+ CullFace gl_cull_face; ///< 0x1920
+ Viewport::PixelCenter viewport_pixel_center; ///< 0x1924
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ u32 viewport_scale_offset_enbled; ///< 0x192C
+ INSERT_PADDING_BYTES_NOINIT(0xC);
+ ViewportClipControl viewport_clip_control; ///< 0x193C
+ UserClip::Op user_clip_op; ///< 0x1940
+ RenderEnable::Override render_enable_override; ///< 0x1944
+ PrimitiveTopologyControl primitive_topology_control; ///< 0x1948
+ WindowClip window_clip_enable; ///< 0x194C
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ InvalidateZCull invalidate_zcull; ///< 0x1958
+ INSERT_PADDING_BYTES_NOINIT(0xC);
+ ZCull zcull; ///< 0x1968
+ PrimitiveTopologyOverride topology_override; ///< 0x1970
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ u32 zcull_sync; ///< 0x1978
+ u32 clip_id_test_enable; ///< 0x197C
+ u32 surface_clip_id_width; ///< 0x1980
+ u32 clip_id; ///< 0x1984
+ INSERT_PADDING_BYTES_NOINIT(0x34);
+ u32 depth_bounds_enable; ///< 0x19BC
+ u32 blend_float_zero_times_anything_is_zero; ///< 0x19C0
+ LogicOp logic_op; ///< 0x19C4
+ u32 z_compression_enable; ///< 0x19CC
+ ClearSurface clear_surface; ///< 0x19D0
+ u32 clear_clip_id_surface; ///< 0x19D4
+ INSERT_PADDING_BYTES_NOINIT(0x8);
+ std::array<u32, NumRenderTargets> color_compression_enable; ///< 0x19E0
+ std::array<ColorMask, NumRenderTargets> color_mask; ///< 0x1A00
+ INSERT_PADDING_BYTES_NOINIT(0xC);
+ u32 pipe_nop; ///< 0x1A2C
+ std::array<u32, 4> spare; ///< 0x1A30
+ INSERT_PADDING_BYTES_NOINIT(0xC0);
+ ReportSemaphore report_semaphore; ///< 0x1B00
+ INSERT_PADDING_BYTES_NOINIT(0xF0);
+ std::array<VertexStream, NumVertexArrays> vertex_streams; ///< 0x1C00
+ BlendPerTarget blend_per_target[NumRenderTargets]; ///< 0x1E00
+ std::array<VertexStreamLimit, NumVertexArrays> vertex_stream_limits; ///< 0x1F00
+ std::array<Pipeline, MaxShaderProgram> pipelines; ///< 0x2000
+ INSERT_PADDING_BYTES_NOINIT(0x180);
+ u32 falcon[32]; ///< 0x2300
+ ConstantBuffer const_buffer; ///< 0x2380
+ INSERT_PADDING_BYTES_NOINIT(0x30);
+ BindGroup bind_groups[MaxShaderStage]; ///< 0x2400
+ INSERT_PADDING_BYTES_NOINIT(0x160);
+ u32 color_clamp_enable; ///< 0x2600
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ u32 bindless_texture_const_buffer_slot; ///< 0x2608
+ u32 trap_handler; ///< 0x260C
+ INSERT_PADDING_BYTES_NOINIT(0x1F0);
+ std::array<std::array<StreamOutLayout, 32>, NumTransformFeedbackBuffers>
+ stream_out_layout; ///< 0x2800
+ INSERT_PADDING_BYTES_NOINIT(0x93C);
+ ShaderPerformance shader_performance; ///< 0x333C
+ INSERT_PADDING_BYTES_NOINIT(0x18);
+ std::array<u32, 0x100> shadow_scratch; ///< 0x3400
};
std::array<u32, NUM_REGS> reg_array;
};
};
+ // clang-format on
Regs regs{};
@@ -1591,147 +3203,346 @@ private:
};
#define ASSERT_REG_POSITION(field_name, position) \
- static_assert(offsetof(Maxwell3D::Regs, field_name) == position * 4, \
+ static_assert(offsetof(Maxwell3D::Regs, field_name) == position, \
"Field " #field_name " has invalid position")
-ASSERT_REG_POSITION(wait_for_idle, 0x44);
-ASSERT_REG_POSITION(macros, 0x45);
-ASSERT_REG_POSITION(shadow_ram_control, 0x49);
-ASSERT_REG_POSITION(upload, 0x60);
-ASSERT_REG_POSITION(exec_upload, 0x6C);
-ASSERT_REG_POSITION(data_upload, 0x6D);
-ASSERT_REG_POSITION(force_early_fragment_tests, 0x84);
-ASSERT_REG_POSITION(sync_info, 0xB2);
-ASSERT_REG_POSITION(tess_mode, 0xC8);
-ASSERT_REG_POSITION(tess_level_outer, 0xC9);
-ASSERT_REG_POSITION(tess_level_inner, 0xCD);
-ASSERT_REG_POSITION(rasterize_enable, 0xDF);
-ASSERT_REG_POSITION(tfb_bindings, 0xE0);
-ASSERT_REG_POSITION(tfb_layouts, 0x1C0);
-ASSERT_REG_POSITION(tfb_enabled, 0x1D1);
-ASSERT_REG_POSITION(rt, 0x200);
-ASSERT_REG_POSITION(viewport_transform, 0x280);
-ASSERT_REG_POSITION(viewports, 0x300);
-ASSERT_REG_POSITION(vertex_buffer, 0x35D);
-ASSERT_REG_POSITION(depth_mode, 0x35F);
-ASSERT_REG_POSITION(clear_color[0], 0x360);
-ASSERT_REG_POSITION(clear_depth, 0x364);
-ASSERT_REG_POSITION(clear_stencil, 0x368);
-ASSERT_REG_POSITION(polygon_mode_front, 0x36B);
-ASSERT_REG_POSITION(polygon_mode_back, 0x36C);
-ASSERT_REG_POSITION(polygon_offset_point_enable, 0x370);
-ASSERT_REG_POSITION(polygon_offset_line_enable, 0x371);
-ASSERT_REG_POSITION(polygon_offset_fill_enable, 0x372);
-ASSERT_REG_POSITION(patch_vertices, 0x373);
-ASSERT_REG_POSITION(fragment_barrier, 0x378);
-ASSERT_REG_POSITION(scissor_test, 0x380);
-ASSERT_REG_POSITION(stencil_back_func_ref, 0x3D5);
-ASSERT_REG_POSITION(stencil_back_mask, 0x3D6);
-ASSERT_REG_POSITION(stencil_back_func_mask, 0x3D7);
-ASSERT_REG_POSITION(invalidate_texture_data_cache, 0x3DD);
-ASSERT_REG_POSITION(tiled_cache_barrier, 0x3DF);
-ASSERT_REG_POSITION(color_mask_common, 0x3E4);
-ASSERT_REG_POSITION(depth_bounds, 0x3E7);
-ASSERT_REG_POSITION(rt_separate_frag_data, 0x3EB);
-ASSERT_REG_POSITION(multisample_raster_enable, 0x3ED);
-ASSERT_REG_POSITION(multisample_raster_samples, 0x3EE);
-ASSERT_REG_POSITION(multisample_sample_mask, 0x3EF);
-ASSERT_REG_POSITION(zeta, 0x3F8);
-ASSERT_REG_POSITION(render_area, 0x3FD);
-ASSERT_REG_POSITION(clear_flags, 0x43E);
-ASSERT_REG_POSITION(fill_rectangle, 0x44F);
-ASSERT_REG_POSITION(conservative_raster_enable, 0x452);
-ASSERT_REG_POSITION(vertex_attrib_format, 0x458);
-ASSERT_REG_POSITION(multisample_sample_locations, 0x478);
-ASSERT_REG_POSITION(multisample_coverage_to_color, 0x47E);
-ASSERT_REG_POSITION(rt_control, 0x487);
-ASSERT_REG_POSITION(zeta_width, 0x48a);
-ASSERT_REG_POSITION(zeta_height, 0x48b);
-ASSERT_REG_POSITION(zeta_depth, 0x48c);
-ASSERT_REG_POSITION(sampler_index, 0x48D);
-ASSERT_REG_POSITION(gp_passthrough_mask, 0x490);
-ASSERT_REG_POSITION(depth_test_enable, 0x4B3);
-ASSERT_REG_POSITION(independent_blend_enable, 0x4B9);
-ASSERT_REG_POSITION(depth_write_enabled, 0x4BA);
-ASSERT_REG_POSITION(alpha_test_enabled, 0x4BB);
-ASSERT_REG_POSITION(d3d_cull_mode, 0x4C2);
-ASSERT_REG_POSITION(depth_test_func, 0x4C3);
-ASSERT_REG_POSITION(alpha_test_ref, 0x4C4);
-ASSERT_REG_POSITION(alpha_test_func, 0x4C5);
-ASSERT_REG_POSITION(draw_tfb_stride, 0x4C6);
-ASSERT_REG_POSITION(blend_color, 0x4C7);
-ASSERT_REG_POSITION(blend, 0x4CF);
-ASSERT_REG_POSITION(stencil_enable, 0x4E0);
-ASSERT_REG_POSITION(stencil_front_op_fail, 0x4E1);
-ASSERT_REG_POSITION(stencil_front_op_zfail, 0x4E2);
-ASSERT_REG_POSITION(stencil_front_op_zpass, 0x4E3);
-ASSERT_REG_POSITION(stencil_front_func_func, 0x4E4);
-ASSERT_REG_POSITION(stencil_front_func_ref, 0x4E5);
-ASSERT_REG_POSITION(stencil_front_func_mask, 0x4E6);
-ASSERT_REG_POSITION(stencil_front_mask, 0x4E7);
-ASSERT_REG_POSITION(frag_color_clamp, 0x4EA);
-ASSERT_REG_POSITION(screen_y_control, 0x4EB);
-ASSERT_REG_POSITION(line_width_smooth, 0x4EC);
-ASSERT_REG_POSITION(line_width_aliased, 0x4ED);
-ASSERT_REG_POSITION(invalidate_sampler_cache_no_wfi, 0x509);
-ASSERT_REG_POSITION(invalidate_texture_header_cache_no_wfi, 0x50A);
-ASSERT_REG_POSITION(vb_element_base, 0x50D);
-ASSERT_REG_POSITION(vb_base_instance, 0x50E);
-ASSERT_REG_POSITION(clip_distance_enabled, 0x544);
-ASSERT_REG_POSITION(samplecnt_enable, 0x545);
-ASSERT_REG_POSITION(point_size, 0x546);
-ASSERT_REG_POSITION(point_sprite_enable, 0x548);
-ASSERT_REG_POSITION(counter_reset, 0x54C);
-ASSERT_REG_POSITION(multisample_enable, 0x54D);
-ASSERT_REG_POSITION(zeta_enable, 0x54E);
-ASSERT_REG_POSITION(multisample_control, 0x54F);
-ASSERT_REG_POSITION(condition, 0x554);
-ASSERT_REG_POSITION(tsc, 0x557);
-ASSERT_REG_POSITION(polygon_offset_factor, 0x55B);
-ASSERT_REG_POSITION(line_smooth_enable, 0x55C);
-ASSERT_REG_POSITION(tic, 0x55D);
-ASSERT_REG_POSITION(stencil_two_side_enable, 0x565);
-ASSERT_REG_POSITION(stencil_back_op_fail, 0x566);
-ASSERT_REG_POSITION(stencil_back_op_zfail, 0x567);
-ASSERT_REG_POSITION(stencil_back_op_zpass, 0x568);
-ASSERT_REG_POSITION(stencil_back_func_func, 0x569);
-ASSERT_REG_POSITION(framebuffer_srgb, 0x56E);
-ASSERT_REG_POSITION(polygon_offset_units, 0x56F);
-ASSERT_REG_POSITION(multisample_mode, 0x574);
-ASSERT_REG_POSITION(point_coord_replace, 0x581);
-ASSERT_REG_POSITION(code_address, 0x582);
-ASSERT_REG_POSITION(draw, 0x585);
-ASSERT_REG_POSITION(primitive_restart, 0x591);
-ASSERT_REG_POSITION(provoking_vertex_last, 0x5A1);
-ASSERT_REG_POSITION(index_array, 0x5F2);
-ASSERT_REG_POSITION(small_index, 0x5F9);
-ASSERT_REG_POSITION(polygon_offset_clamp, 0x61F);
-ASSERT_REG_POSITION(instanced_arrays, 0x620);
-ASSERT_REG_POSITION(vp_point_size, 0x644);
-ASSERT_REG_POSITION(cull_test_enabled, 0x646);
-ASSERT_REG_POSITION(front_face, 0x647);
-ASSERT_REG_POSITION(cull_face, 0x648);
-ASSERT_REG_POSITION(pixel_center_integer, 0x649);
-ASSERT_REG_POSITION(viewport_transform_enabled, 0x64B);
-ASSERT_REG_POSITION(view_volume_clip_control, 0x64F);
-ASSERT_REG_POSITION(topology_override, 0x65C);
-ASSERT_REG_POSITION(depth_bounds_enable, 0x66F);
-ASSERT_REG_POSITION(logic_op, 0x671);
-ASSERT_REG_POSITION(clear_buffers, 0x674);
-ASSERT_REG_POSITION(color_mask, 0x680);
-ASSERT_REG_POSITION(query, 0x6C0);
-ASSERT_REG_POSITION(vertex_array[0], 0x700);
-ASSERT_REG_POSITION(independent_blend, 0x780);
-ASSERT_REG_POSITION(vertex_array_limit[0], 0x7C0);
-ASSERT_REG_POSITION(shader_config[0], 0x800);
-ASSERT_REG_POSITION(firmware, 0x8C0);
-ASSERT_REG_POSITION(const_buffer, 0x8E0);
-ASSERT_REG_POSITION(cb_bind[0], 0x904);
-ASSERT_REG_POSITION(tex_cb_index, 0x982);
-ASSERT_REG_POSITION(tfb_varying_locs, 0xA00);
-ASSERT_REG_POSITION(ssbo_info, 0xD18);
-ASSERT_REG_POSITION(tex_info_buffers.address[0], 0xD2A);
-ASSERT_REG_POSITION(tex_info_buffers.size[0], 0xD2F);
+ASSERT_REG_POSITION(object_id, 0x0000);
+ASSERT_REG_POSITION(nop, 0x0100);
+ASSERT_REG_POSITION(notify, 0x0104);
+ASSERT_REG_POSITION(wait_for_idle, 0x0110);
+ASSERT_REG_POSITION(load_mme, 0x0114);
+ASSERT_REG_POSITION(shadow_ram_control, 0x0124);
+ASSERT_REG_POSITION(peer, 0x0128);
+ASSERT_REG_POSITION(global_render, 0x0130);
+ASSERT_REG_POSITION(go_idle, 0x013C);
+ASSERT_REG_POSITION(trigger, 0x0140);
+ASSERT_REG_POSITION(trigger_wfi, 0x0144);
+ASSERT_REG_POSITION(instrumentation_method_header, 0x0150);
+ASSERT_REG_POSITION(instrumentation_method_data, 0x0154);
+ASSERT_REG_POSITION(upload, 0x0180);
+ASSERT_REG_POSITION(launch_dma, 0x01B0);
+ASSERT_REG_POSITION(inline_data, 0x01B4);
+ASSERT_REG_POSITION(i2m, 0x01DC);
+ASSERT_REG_POSITION(run_ds_now, 0x0200);
+ASSERT_REG_POSITION(opportunistic_early_z, 0x0204);
+ASSERT_REG_POSITION(aliased_line_width_enabled, 0x020C);
+ASSERT_REG_POSITION(mandated_early_z, 0x0210);
+ASSERT_REG_POSITION(gs_dm_fifo, 0x0214);
+ASSERT_REG_POSITION(l2_cache_control, 0x0218);
+ASSERT_REG_POSITION(invalidate_shader_cache, 0x021C);
+ASSERT_REG_POSITION(sync_info, 0x02C8);
+ASSERT_REG_POSITION(prim_circular_buffer_throttle, 0x02D0);
+ASSERT_REG_POSITION(flush_invalidate_rop_mini_cache, 0x02D4);
+ASSERT_REG_POSITION(surface_clip_block_id, 0x02D8);
+ASSERT_REG_POSITION(alpha_circular_buffer_size, 0x02DC);
+ASSERT_REG_POSITION(decompress_surface, 0x02E0);
+ASSERT_REG_POSITION(zcull_rop_bypass, 0x02E4);
+ASSERT_REG_POSITION(zcull_subregion, 0x02E8);
+ASSERT_REG_POSITION(raster_bounding_box, 0x02EC);
+ASSERT_REG_POSITION(peer_semaphore_release, 0x02F0);
+ASSERT_REG_POSITION(iterated_blend_optimization, 0x02F4);
+ASSERT_REG_POSITION(zcull_subregion_allocation, 0x02F8);
+ASSERT_REG_POSITION(zcull_subregion_algorithm, 0x02FC);
+ASSERT_REG_POSITION(ps_output_sample_mask_usage, 0x0300);
+ASSERT_REG_POSITION(draw_zero_index, 0x0304);
+ASSERT_REG_POSITION(l1_configuration, 0x0308);
+ASSERT_REG_POSITION(render_enable_control_load_const_buffer, 0x030C);
+ASSERT_REG_POSITION(spa_version, 0x0310);
+ASSERT_REG_POSITION(ieee_clean_update, 0x0314);
+ASSERT_REG_POSITION(snap_grid, 0x0318);
+ASSERT_REG_POSITION(tessellation, 0x0320);
+ASSERT_REG_POSITION(sub_tiling_perf, 0x0360);
+ASSERT_REG_POSITION(zcull_subregion_report, 0x036C);
+ASSERT_REG_POSITION(balanced_primitive_workload, 0x0374);
+ASSERT_REG_POSITION(max_patches_per_batch, 0x0378);
+ASSERT_REG_POSITION(rasterize_enable, 0x037C);
+ASSERT_REG_POSITION(transform_feedback, 0x0380);
+ASSERT_REG_POSITION(transform_feedback.controls, 0x0700);
+ASSERT_REG_POSITION(raster_input, 0x0740);
+ASSERT_REG_POSITION(transform_feedback_enabled, 0x0744);
+ASSERT_REG_POSITION(primitive_restart_topology_change_enable, 0x0748);
+ASSERT_REG_POSITION(alpha_fraction, 0x074C);
+ASSERT_REG_POSITION(hybrid_aa_control, 0x0754);
+ASSERT_REG_POSITION(shader_local_memory, 0x077C);
+ASSERT_REG_POSITION(color_zero_bandwidth_clear, 0x07A4);
+ASSERT_REG_POSITION(z_zero_bandwidth_clear, 0x07A8);
+ASSERT_REG_POSITION(isbe_save_restore_program_offset, 0x07AC);
+ASSERT_REG_POSITION(zcull_region, 0x07C0);
+ASSERT_REG_POSITION(zeta_read_only, 0x07F8);
+ASSERT_REG_POSITION(rt, 0x0800);
+ASSERT_REG_POSITION(viewport_transform, 0x0A00);
+ASSERT_REG_POSITION(viewports, 0x0C00);
+ASSERT_REG_POSITION(windows, 0x0D00);
+ASSERT_REG_POSITION(clip_id_extent, 0x0D40);
+ASSERT_REG_POSITION(max_geometry_instances_per_task, 0x0D60);
+ASSERT_REG_POSITION(visible_call_limit, 0x0D64);
+ASSERT_REG_POSITION(statistics_count, 0x0D68);
+ASSERT_REG_POSITION(clear_rect, 0x0D6C);
+ASSERT_REG_POSITION(vertex_buffer, 0x0D74);
+ASSERT_REG_POSITION(depth_mode, 0x0D7C);
+ASSERT_REG_POSITION(clear_color, 0x0D80);
+ASSERT_REG_POSITION(clear_depth, 0x0D90);
+ASSERT_REG_POSITION(shader_cache_icache_prefetch, 0x0D94);
+ASSERT_REG_POSITION(force_transition_to_beta, 0x0D98);
+ASSERT_REG_POSITION(reduce_colour_thresholds, 0x0D9C);
+ASSERT_REG_POSITION(clear_stencil, 0x0DA0);
+ASSERT_REG_POSITION(invalidate_shader_cache_no_wfi, 0x0DA4);
+ASSERT_REG_POSITION(zcull_serialization, 0x0DA8);
+ASSERT_REG_POSITION(polygon_mode_front, 0x0DAC);
+ASSERT_REG_POSITION(polygon_mode_back, 0x0DB0);
+ASSERT_REG_POSITION(polygon_smooth, 0x0DB4);
+ASSERT_REG_POSITION(zeta_mark_clean_ieee, 0x0DB8);
+ASSERT_REG_POSITION(zcull_dir_format, 0x0DBC);
+ASSERT_REG_POSITION(polygon_offset_point_enable, 0x0DC0);
+ASSERT_REG_POSITION(polygon_offset_line_enable, 0x0DC4);
+ASSERT_REG_POSITION(polygon_offset_fill_enable, 0x0DC8);
+ASSERT_REG_POSITION(patch_vertices, 0x0DCC);
+ASSERT_REG_POSITION(iterated_blend, 0x0DD0);
+ASSERT_REG_POSITION(zcull_criteria, 0x0DD8);
+ASSERT_REG_POSITION(fragment_barrier, 0x0DE0);
+ASSERT_REG_POSITION(sm_timeout, 0x0DE4);
+ASSERT_REG_POSITION(primitive_restart_array, 0x0DE8);
+ASSERT_REG_POSITION(load_iterated_blend, 0x0DF0);
+ASSERT_REG_POSITION(window_offset_x, 0x0DF8);
+ASSERT_REG_POSITION(window_offset_y, 0x0DFC);
+ASSERT_REG_POSITION(scissor_test, 0x0E00);
+ASSERT_REG_POSITION(select_texture_headers, 0x0F10);
+ASSERT_REG_POSITION(vpc_perf, 0x0F14);
+ASSERT_REG_POSITION(pm_local_trigger, 0x0F18);
+ASSERT_REG_POSITION(post_z_pixel_imask, 0x0F1C);
+ASSERT_REG_POSITION(const_color_rendering, 0x0F40);
+ASSERT_REG_POSITION(stencil_back_func, 0x0F54);
+ASSERT_REG_POSITION(vertex_stream_substitute, 0x0F84);
+ASSERT_REG_POSITION(line_mode_clip_generated_edge_do_not_draw, 0x0F8C);
+ASSERT_REG_POSITION(color_mask_common, 0x0F90);
+ASSERT_REG_POSITION(vtg_warp_watermarks, 0x0F98);
+ASSERT_REG_POSITION(depth_bounds, 0x0F9C);
+ASSERT_REG_POSITION(sample_mask_target, 0x0FA4);
+ASSERT_REG_POSITION(color_target_mrt_enable, 0x0FAC);
+ASSERT_REG_POSITION(non_multisampled_z, 0x0FB0);
+ASSERT_REG_POSITION(tir_mode, 0x0FB4);
+ASSERT_REG_POSITION(anti_alias_raster, 0x0FB8);
+ASSERT_REG_POSITION(sample_mask_pos, 0x0FBC);
+ASSERT_REG_POSITION(surface_clip_id_memory, 0x0FCC);
+ASSERT_REG_POSITION(tir_modulation, 0x0FD4);
+ASSERT_REG_POSITION(blend_control_allow_float_pixel_kills, 0x0FDC);
+ASSERT_REG_POSITION(zeta, 0x0FE0);
+ASSERT_REG_POSITION(surface_clip, 0x0FF4);
+ASSERT_REG_POSITION(tiled_cache_treat_heavy_as_light, 0x0FFC);
+ASSERT_REG_POSITION(l2_cache_vaf, 0x1000);
+ASSERT_REG_POSITION(viewport_multicast, 0x1004);
+ASSERT_REG_POSITION(tessellation_cut_height, 0x1008);
+ASSERT_REG_POSITION(max_gs_instances_per_task, 0x100C);
+ASSERT_REG_POSITION(max_gs_output_vertices_per_task, 0x1010);
+ASSERT_REG_POSITION(reserved_sw_method0, 0x1014);
+ASSERT_REG_POSITION(gs_output_cb_storage_multiplier, 0x1018);
+ASSERT_REG_POSITION(beta_cb_storage_constant, 0x101C);
+ASSERT_REG_POSITION(ti_output_cb_storage_multiplier, 0x1020);
+ASSERT_REG_POSITION(alpha_cb_storage_constraint, 0x1024);
+ASSERT_REG_POSITION(reserved_sw_method1, 0x1028);
+ASSERT_REG_POSITION(reserved_sw_method2, 0x102C);
+ASSERT_REG_POSITION(tir_modulation_coeff, 0x1030);
+ASSERT_REG_POSITION(spare_nop, 0x1044);
+ASSERT_REG_POSITION(reserved_sw_method3_to_7, 0x10B0);
+ASSERT_REG_POSITION(reduce_color_thresholds_unorm8, 0x10CC);
+ASSERT_REG_POSITION(reserved_sw_method10_to_13, 0x10D0);
+ASSERT_REG_POSITION(reduce_color_thresholds_unorm10, 0x10E0);
+ASSERT_REG_POSITION(reduce_color_thresholds_unorm16, 0x10E4);
+ASSERT_REG_POSITION(reduce_color_thresholds_fp11, 0x10E8);
+ASSERT_REG_POSITION(reduce_color_thresholds_fp16, 0x10EC);
+ASSERT_REG_POSITION(reduce_color_thresholds_srgb8, 0x10F0);
+ASSERT_REG_POSITION(unbind_all_constant_buffers, 0x10F4);
+ASSERT_REG_POSITION(clear_control, 0x10F8);
+ASSERT_REG_POSITION(l2_cache_rop_non_interlocked_reads, 0x10FC);
+ASSERT_REG_POSITION(reserved_sw_method14, 0x1100);
+ASSERT_REG_POSITION(reserved_sw_method15, 0x1104);
+ASSERT_REG_POSITION(no_operation_data_high, 0x110C);
+ASSERT_REG_POSITION(depth_bias_control, 0x1110);
+ASSERT_REG_POSITION(pm_trigger_end, 0x1114);
+ASSERT_REG_POSITION(vertex_id_base, 0x1118);
+ASSERT_REG_POSITION(stencil_compression_enabled, 0x111C);
+ASSERT_REG_POSITION(vertex_output_attribute_skip_masks, 0x1120);
+ASSERT_REG_POSITION(tir_control, 0x1130);
+ASSERT_REG_POSITION(mutable_method_treat_mutable_as_heavy, 0x1134);
+ASSERT_REG_POSITION(post_ps_use_pre_ps_coverage, 0x1138);
+ASSERT_REG_POSITION(fill_via_triangle_mode, 0x113C);
+ASSERT_REG_POSITION(blend_per_format_snorm8_unorm16_snorm16_enabled, 0x1140);
+ASSERT_REG_POSITION(flush_pending_writes_sm_gloal_store, 0x1144);
+ASSERT_REG_POSITION(vertex_attrib_format, 0x1160);
+ASSERT_REG_POSITION(multisample_sample_locations, 0x11E0);
+ASSERT_REG_POSITION(offset_render_target_index_by_viewport_index, 0x11F0);
+ASSERT_REG_POSITION(force_heavy_method_sync, 0x11F4);
+ASSERT_REG_POSITION(multisample_coverage_to_color, 0x11F8);
+ASSERT_REG_POSITION(decompress_zeta_surface, 0x11FC);
+ASSERT_REG_POSITION(zeta_sparse, 0x1208);
+ASSERT_REG_POSITION(invalidate_sampler_cache, 0x120C);
+ASSERT_REG_POSITION(invalidate_texture_header_cache, 0x1210);
+ASSERT_REG_POSITION(vertex_array_instance_first, 0x1214);
+ASSERT_REG_POSITION(vertex_array_instance_subsequent, 0x1218);
+ASSERT_REG_POSITION(rt_control, 0x121C);
+ASSERT_REG_POSITION(compression_threshold_samples, 0x1220);
+ASSERT_REG_POSITION(ps_interlock_control, 0x1224);
+ASSERT_REG_POSITION(zeta_size, 0x1228);
+ASSERT_REG_POSITION(sampler_binding, 0x1234);
+ASSERT_REG_POSITION(draw_auto_byte_count, 0x123C);
+ASSERT_REG_POSITION(post_vtg_shader_attrib_skip_mask, 0x1240);
+ASSERT_REG_POSITION(ps_ticket_dispenser_value, 0x1260);
+ASSERT_REG_POSITION(circular_buffer_size, 0x1280);
+ASSERT_REG_POSITION(vtg_register_watermarks, 0x1284);
+ASSERT_REG_POSITION(invalidate_texture_cache_no_wfi, 0x1288);
+ASSERT_REG_POSITION(l2_cache_rop_interlocked_reads, 0x1290);
+ASSERT_REG_POSITION(primitive_restart_topology_change_index, 0x12A4);
+ASSERT_REG_POSITION(zcull_region_enable, 0x12C8);
+ASSERT_REG_POSITION(depth_test_enable, 0x12CC);
+ASSERT_REG_POSITION(fill_mode, 0x12D0);
+ASSERT_REG_POSITION(shade_mode, 0x12D4);
+ASSERT_REG_POSITION(l2_cache_rop_non_interlocked_writes, 0x12D8);
+ASSERT_REG_POSITION(l2_cache_rop_interlocked_writes, 0x12DC);
+ASSERT_REG_POSITION(alpha_to_coverage_dither, 0x12E0);
+ASSERT_REG_POSITION(blend_per_target_enabled, 0x12E4);
+ASSERT_REG_POSITION(depth_write_enabled, 0x12E8);
+ASSERT_REG_POSITION(alpha_test_enabled, 0x12EC);
+ASSERT_REG_POSITION(inline_index_4x8_align, 0x1300);
+ASSERT_REG_POSITION(inline_index_4x8_index, 0x1304);
+ASSERT_REG_POSITION(d3d_cull_mode, 0x1308);
+ASSERT_REG_POSITION(depth_test_func, 0x130C);
+ASSERT_REG_POSITION(alpha_test_ref, 0x1310);
+ASSERT_REG_POSITION(alpha_test_func, 0x1314);
+ASSERT_REG_POSITION(draw_auto_stride, 0x1318);
+ASSERT_REG_POSITION(blend_color, 0x131C);
+ASSERT_REG_POSITION(invalidate_sampler_cache_lines, 0x1330);
+ASSERT_REG_POSITION(invalidate_texture_header_cache_lines, 0x1334);
+ASSERT_REG_POSITION(invalidate_texture_data_cache_lines, 0x1338);
+ASSERT_REG_POSITION(blend, 0x133C);
+ASSERT_REG_POSITION(stencil_enable, 0x1380);
+ASSERT_REG_POSITION(stencil_front_op, 0x1384);
+ASSERT_REG_POSITION(stencil_front_func, 0x1394);
+ASSERT_REG_POSITION(draw_auto_start_byte_count, 0x13A4);
+ASSERT_REG_POSITION(frag_color_clamp, 0x13A8);
+ASSERT_REG_POSITION(window_origin, 0x13AC);
+ASSERT_REG_POSITION(line_width_smooth, 0x13B0);
+ASSERT_REG_POSITION(line_width_aliased, 0x13B4);
+ASSERT_REG_POSITION(line_override_multisample, 0x1418);
+ASSERT_REG_POSITION(alpha_hysteresis_rounds, 0x1420);
+ASSERT_REG_POSITION(invalidate_sampler_cache_no_wfi, 0x1424);
+ASSERT_REG_POSITION(invalidate_texture_header_cache_no_wfi, 0x1428);
+ASSERT_REG_POSITION(global_base_vertex_index, 0x1434);
+ASSERT_REG_POSITION(global_base_instance_index, 0x1438);
+ASSERT_REG_POSITION(ps_warp_watermarks, 0x1450);
+ASSERT_REG_POSITION(ps_regster_watermarks, 0x1454);
+ASSERT_REG_POSITION(store_zcull, 0x1464);
+ASSERT_REG_POSITION(iterated_blend_constants, 0x1480);
+ASSERT_REG_POSITION(load_zcull, 0x1500);
+ASSERT_REG_POSITION(surface_clip_id_height, 0x1504);
+ASSERT_REG_POSITION(surface_clip_id_clear_rect, 0x1508);
+ASSERT_REG_POSITION(user_clip_enable, 0x1510);
+ASSERT_REG_POSITION(zpass_pixel_count_enable, 0x1514);
+ASSERT_REG_POSITION(point_size, 0x1518);
+ASSERT_REG_POSITION(zcull_stats_enable, 0x151C);
+ASSERT_REG_POSITION(point_sprite_enable, 0x1520);
+ASSERT_REG_POSITION(shader_exceptions_enable, 0x1528);
+ASSERT_REG_POSITION(clear_report_value, 0x1530);
+ASSERT_REG_POSITION(anti_alias_enable, 0x1534);
+ASSERT_REG_POSITION(zeta_enable, 0x1538);
+ASSERT_REG_POSITION(anti_alias_alpha_control, 0x153C);
+ASSERT_REG_POSITION(render_enable, 0x1550);
+ASSERT_REG_POSITION(tex_sampler, 0x155C);
+ASSERT_REG_POSITION(slope_scale_depth_bias, 0x156C);
+ASSERT_REG_POSITION(line_anti_alias_enable, 0x1570);
+ASSERT_REG_POSITION(tex_header, 0x1574);
+ASSERT_REG_POSITION(active_zcull_region_id, 0x1590);
+ASSERT_REG_POSITION(stencil_two_side_enable, 0x1594);
+ASSERT_REG_POSITION(stencil_back_op, 0x1598);
+ASSERT_REG_POSITION(framebuffer_srgb, 0x15B8);
+ASSERT_REG_POSITION(depth_bias, 0x15BC);
+ASSERT_REG_POSITION(zcull_region_format, 0x15C8);
+ASSERT_REG_POSITION(rt_layer, 0x15CC);
+ASSERT_REG_POSITION(anti_alias_samples_mode, 0x15D0);
+ASSERT_REG_POSITION(edge_flag, 0x15E4);
+ASSERT_REG_POSITION(draw_inline_index, 0x15E8);
+ASSERT_REG_POSITION(inline_index_2x16, 0x15EC);
+ASSERT_REG_POSITION(vertex_global_base_offset, 0x15F4);
+ASSERT_REG_POSITION(zcull_region_pixel_offset, 0x15FC);
+ASSERT_REG_POSITION(point_sprite, 0x1604);
+ASSERT_REG_POSITION(program_region, 0x1608);
+ASSERT_REG_POSITION(default_attributes, 0x1610);
+ASSERT_REG_POSITION(draw, 0x1614);
+ASSERT_REG_POSITION(vertex_id_copy, 0x161C);
+ASSERT_REG_POSITION(add_to_primitive_id, 0x1620);
+ASSERT_REG_POSITION(load_to_primitive_id, 0x1624);
+ASSERT_REG_POSITION(shader_based_cull, 0x162C);
+ASSERT_REG_POSITION(class_version, 0x1638);
+ASSERT_REG_POSITION(primitive_restart, 0x1644);
+ASSERT_REG_POSITION(output_vertex_id, 0x164C);
+ASSERT_REG_POSITION(anti_alias_point_enable, 0x1658);
+ASSERT_REG_POSITION(point_center_mode, 0x165C);
+ASSERT_REG_POSITION(line_smooth_params, 0x1668);
+ASSERT_REG_POSITION(line_stipple_enable, 0x166C);
+ASSERT_REG_POSITION(line_smooth_edge_table, 0x1670);
+ASSERT_REG_POSITION(line_stipple_params, 0x1680);
+ASSERT_REG_POSITION(provoking_vertex, 0x1684);
+ASSERT_REG_POSITION(two_sided_light_enabled, 0x1688);
+ASSERT_REG_POSITION(polygon_stipple_enabled, 0x168C);
+ASSERT_REG_POSITION(shader_control, 0x1690);
+ASSERT_REG_POSITION(class_version_check, 0x16A0);
+ASSERT_REG_POSITION(sph_version, 0x16A4);
+ASSERT_REG_POSITION(sph_version_check, 0x16A8);
+ASSERT_REG_POSITION(alpha_to_coverage_override, 0x16B4);
+ASSERT_REG_POSITION(polygon_stipple_pattern, 0x1700);
+ASSERT_REG_POSITION(aam_version, 0x1790);
+ASSERT_REG_POSITION(aam_version_check, 0x1794);
+ASSERT_REG_POSITION(zeta_layer_offset, 0x179C);
+ASSERT_REG_POSITION(index_buffer, 0x17C8);
+ASSERT_REG_POSITION(index_buffer32_first, 0x17E4);
+ASSERT_REG_POSITION(index_buffer16_first, 0x17E8);
+ASSERT_REG_POSITION(index_buffer8_first, 0x17EC);
+ASSERT_REG_POSITION(index_buffer32_subsequent, 0x17F0);
+ASSERT_REG_POSITION(index_buffer16_subsequent, 0x17F4);
+ASSERT_REG_POSITION(index_buffer8_subsequent, 0x17F8);
+ASSERT_REG_POSITION(depth_bias_clamp, 0x187C);
+ASSERT_REG_POSITION(vertex_stream_instances, 0x1880);
+ASSERT_REG_POSITION(point_size_attribute, 0x1910);
+ASSERT_REG_POSITION(gl_cull_test_enabled, 0x1918);
+ASSERT_REG_POSITION(gl_front_face, 0x191C);
+ASSERT_REG_POSITION(gl_cull_face, 0x1920);
+ASSERT_REG_POSITION(viewport_pixel_center, 0x1924);
+ASSERT_REG_POSITION(viewport_scale_offset_enbled, 0x192C);
+ASSERT_REG_POSITION(viewport_clip_control, 0x193C);
+ASSERT_REG_POSITION(user_clip_op, 0x1940);
+ASSERT_REG_POSITION(render_enable_override, 0x1944);
+ASSERT_REG_POSITION(primitive_topology_control, 0x1948);
+ASSERT_REG_POSITION(window_clip_enable, 0x194C);
+ASSERT_REG_POSITION(invalidate_zcull, 0x1958);
+ASSERT_REG_POSITION(zcull, 0x1968);
+ASSERT_REG_POSITION(topology_override, 0x1970);
+ASSERT_REG_POSITION(zcull_sync, 0x1978);
+ASSERT_REG_POSITION(clip_id_test_enable, 0x197C);
+ASSERT_REG_POSITION(surface_clip_id_width, 0x1980);
+ASSERT_REG_POSITION(clip_id, 0x1984);
+ASSERT_REG_POSITION(depth_bounds_enable, 0x19BC);
+ASSERT_REG_POSITION(blend_float_zero_times_anything_is_zero, 0x19C0);
+ASSERT_REG_POSITION(logic_op, 0x19C4);
+ASSERT_REG_POSITION(z_compression_enable, 0x19CC);
+ASSERT_REG_POSITION(clear_surface, 0x19D0);
+ASSERT_REG_POSITION(clear_clip_id_surface, 0x19D4);
+ASSERT_REG_POSITION(color_compression_enable, 0x19E0);
+ASSERT_REG_POSITION(color_mask, 0x1A00);
+ASSERT_REG_POSITION(pipe_nop, 0x1A2C);
+ASSERT_REG_POSITION(spare, 0x1A30);
+ASSERT_REG_POSITION(report_semaphore, 0x1B00);
+ASSERT_REG_POSITION(vertex_streams, 0x1C00);
+ASSERT_REG_POSITION(blend_per_target, 0x1E00);
+ASSERT_REG_POSITION(vertex_stream_limits, 0x1F00);
+ASSERT_REG_POSITION(pipelines, 0x2000);
+ASSERT_REG_POSITION(falcon, 0x2300);
+ASSERT_REG_POSITION(const_buffer, 0x2380);
+ASSERT_REG_POSITION(bind_groups, 0x2400);
+ASSERT_REG_POSITION(color_clamp_enable, 0x2600);
+ASSERT_REG_POSITION(bindless_texture_const_buffer_slot, 0x2608);
+ASSERT_REG_POSITION(trap_handler, 0x260C);
+ASSERT_REG_POSITION(stream_out_layout, 0x2800);
+ASSERT_REG_POSITION(shader_performance, 0x333C);
+ASSERT_REG_POSITION(shadow_scratch, 0x3400);
#undef ASSERT_REG_POSITION