summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h34
-rw-r--r--src/video_core/dirty_flags.cpp24
-rw-r--r--src/video_core/engines/maxwell_3d.cpp336
-rw-r--r--src/video_core/engines/maxwell_3d.h3839
-rw-r--r--src/video_core/gpu.h50
-rw-r--r--src/video_core/macro/macro_hle.cpp48
-rw-r--r--src/video_core/query_cache.h2
-rw-r--r--src/video_core/renderer_opengl/gl_graphics_pipeline.cpp29
-rw-r--r--src/video_core/renderer_opengl/gl_graphics_pipeline.h4
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp140
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp43
-rw-r--r--src/video_core/renderer_opengl/gl_state_tracker.cpp57
-rw-r--r--src/video_core/renderer_opengl/maxwell_to_gl.h287
-rw-r--r--src/video_core/renderer_vulkan/fixed_pipeline_state.cpp299
-rw-r--r--src/video_core/renderer_vulkan/fixed_pipeline_state.h15
-rw-r--r--src/video_core/renderer_vulkan/maxwell_to_vk.cpp337
-rw-r--r--src/video_core/renderer_vulkan/maxwell_to_vk.h2
-rw-r--r--src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp14
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp67
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp104
-rw-r--r--src/video_core/renderer_vulkan/vk_state_tracker.cpp58
-rw-r--r--src/video_core/shader_cache.cpp12
-rw-r--r--src/video_core/shader_environment.cpp23
-rw-r--r--src/video_core/shader_environment.h2
-rw-r--r--src/video_core/surface.cpp14
-rw-r--r--src/video_core/texture_cache/image_info.cpp37
-rw-r--r--src/video_core/texture_cache/texture_cache.h19
-rw-r--r--src/video_core/transform_feedback.cpp118
-rw-r--r--src/video_core/transform_feedback.h3
29 files changed, 3974 insertions, 2043 deletions
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index 8e26b3f95..2ba33543c 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -994,13 +994,13 @@ void BufferCache<P>::BindHostIndexBuffer() {
994 const u32 size = index_buffer.size; 994 const u32 size = index_buffer.size;
995 SynchronizeBuffer(buffer, index_buffer.cpu_addr, size); 995 SynchronizeBuffer(buffer, index_buffer.cpu_addr, size);
996 if constexpr (HAS_FULL_INDEX_AND_PRIMITIVE_SUPPORT) { 996 if constexpr (HAS_FULL_INDEX_AND_PRIMITIVE_SUPPORT) {
997 const u32 new_offset = offset + maxwell3d->regs.index_array.first * 997 const u32 new_offset = offset + maxwell3d->regs.index_buffer.first *
998 maxwell3d->regs.index_array.FormatSizeInBytes(); 998 maxwell3d->regs.index_buffer.FormatSizeInBytes();
999 runtime.BindIndexBuffer(buffer, new_offset, size); 999 runtime.BindIndexBuffer(buffer, new_offset, size);
1000 } else { 1000 } else {
1001 runtime.BindIndexBuffer(maxwell3d->regs.draw.topology, maxwell3d->regs.index_array.format, 1001 runtime.BindIndexBuffer(maxwell3d->regs.draw.topology, maxwell3d->regs.index_buffer.format,
1002 maxwell3d->regs.index_array.first, 1002 maxwell3d->regs.index_buffer.first,
1003 maxwell3d->regs.index_array.count, buffer, offset, size); 1003 maxwell3d->regs.index_buffer.count, buffer, offset, size);
1004 } 1004 }
1005} 1005}
1006 1006
@@ -1017,7 +1017,7 @@ void BufferCache<P>::BindHostVertexBuffers() {
1017 } 1017 }
1018 flags[Dirty::VertexBuffer0 + index] = false; 1018 flags[Dirty::VertexBuffer0 + index] = false;
1019 1019
1020 const u32 stride = maxwell3d->regs.vertex_array[index].stride; 1020 const u32 stride = maxwell3d->regs.vertex_streams[index].stride;
1021 const u32 offset = buffer.Offset(binding.cpu_addr); 1021 const u32 offset = buffer.Offset(binding.cpu_addr);
1022 runtime.BindVertexBuffer(index, buffer, offset, binding.size, stride); 1022 runtime.BindVertexBuffer(index, buffer, offset, binding.size, stride);
1023 } 1023 }
@@ -1157,7 +1157,7 @@ void BufferCache<P>::BindHostGraphicsTextureBuffers(size_t stage) {
1157 1157
1158template <class P> 1158template <class P>
1159void BufferCache<P>::BindHostTransformFeedbackBuffers() { 1159void BufferCache<P>::BindHostTransformFeedbackBuffers() {
1160 if (maxwell3d->regs.tfb_enabled == 0) { 1160 if (maxwell3d->regs.transform_feedback_enabled == 0) {
1161 return; 1161 return;
1162 } 1162 }
1163 for (u32 index = 0; index < NUM_TRANSFORM_FEEDBACK_BUFFERS; ++index) { 1163 for (u32 index = 0; index < NUM_TRANSFORM_FEEDBACK_BUFFERS; ++index) {
@@ -1268,7 +1268,7 @@ template <class P>
1268void BufferCache<P>::UpdateIndexBuffer() { 1268void BufferCache<P>::UpdateIndexBuffer() {
1269 // We have to check for the dirty flags and index count 1269 // We have to check for the dirty flags and index count
1270 // The index count is currently changed without updating the dirty flags 1270 // The index count is currently changed without updating the dirty flags
1271 const auto& index_array = maxwell3d->regs.index_array; 1271 const auto& index_array = maxwell3d->regs.index_buffer;
1272 auto& flags = maxwell3d->dirty.flags; 1272 auto& flags = maxwell3d->dirty.flags;
1273 if (!flags[Dirty::IndexBuffer] && last_index_count == index_array.count) { 1273 if (!flags[Dirty::IndexBuffer] && last_index_count == index_array.count) {
1274 return; 1274 return;
@@ -1311,10 +1311,10 @@ void BufferCache<P>::UpdateVertexBuffer(u32 index) {
1311 if (!maxwell3d->dirty.flags[Dirty::VertexBuffer0 + index]) { 1311 if (!maxwell3d->dirty.flags[Dirty::VertexBuffer0 + index]) {
1312 return; 1312 return;
1313 } 1313 }
1314 const auto& array = maxwell3d->regs.vertex_array[index]; 1314 const auto& array = maxwell3d->regs.vertex_streams[index];
1315 const auto& limit = maxwell3d->regs.vertex_array_limit[index]; 1315 const auto& limit = maxwell3d->regs.vertex_stream_limits[index];
1316 const GPUVAddr gpu_addr_begin = array.StartAddress(); 1316 const GPUVAddr gpu_addr_begin = array.Address();
1317 const GPUVAddr gpu_addr_end = limit.LimitAddress() + 1; 1317 const GPUVAddr gpu_addr_end = limit.Address() + 1;
1318 const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr_begin); 1318 const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr_begin);
1319 u32 address_size = static_cast<u32>( 1319 u32 address_size = static_cast<u32>(
1320 std::min(gpu_addr_end - gpu_addr_begin, static_cast<u64>(std::numeric_limits<u32>::max()))); 1320 std::min(gpu_addr_end - gpu_addr_begin, static_cast<u64>(std::numeric_limits<u32>::max())));
@@ -1380,7 +1380,7 @@ void BufferCache<P>::UpdateTextureBuffers(size_t stage) {
1380 1380
1381template <class P> 1381template <class P>
1382void BufferCache<P>::UpdateTransformFeedbackBuffers() { 1382void BufferCache<P>::UpdateTransformFeedbackBuffers() {
1383 if (maxwell3d->regs.tfb_enabled == 0) { 1383 if (maxwell3d->regs.transform_feedback_enabled == 0) {
1384 return; 1384 return;
1385 } 1385 }
1386 for (u32 index = 0; index < NUM_TRANSFORM_FEEDBACK_BUFFERS; ++index) { 1386 for (u32 index = 0; index < NUM_TRANSFORM_FEEDBACK_BUFFERS; ++index) {
@@ -1390,11 +1390,11 @@ void BufferCache<P>::UpdateTransformFeedbackBuffers() {
1390 1390
1391template <class P> 1391template <class P>
1392void BufferCache<P>::UpdateTransformFeedbackBuffer(u32 index) { 1392void BufferCache<P>::UpdateTransformFeedbackBuffer(u32 index) {
1393 const auto& binding = maxwell3d->regs.tfb_bindings[index]; 1393 const auto& binding = maxwell3d->regs.transform_feedback.buffers[index];
1394 const GPUVAddr gpu_addr = binding.Address() + binding.buffer_offset; 1394 const GPUVAddr gpu_addr = binding.Address() + binding.start_offset;
1395 const u32 size = binding.buffer_size; 1395 const u32 size = binding.size;
1396 const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr); 1396 const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr);
1397 if (binding.buffer_enable == 0 || size == 0 || !cpu_addr) { 1397 if (binding.enable == 0 || size == 0 || !cpu_addr) {
1398 transform_feedback_buffers[index] = NULL_BINDING; 1398 transform_feedback_buffers[index] = NULL_BINDING;
1399 return; 1399 return;
1400 } 1400 }
diff --git a/src/video_core/dirty_flags.cpp b/src/video_core/dirty_flags.cpp
index 9dc4341f0..1039e036f 100644
--- a/src/video_core/dirty_flags.cpp
+++ b/src/video_core/dirty_flags.cpp
@@ -17,21 +17,23 @@ using Tegra::Engines::Maxwell3D;
17void SetupDirtyVertexBuffers(Maxwell3D::DirtyState::Tables& tables) { 17void SetupDirtyVertexBuffers(Maxwell3D::DirtyState::Tables& tables) {
18 static constexpr std::size_t num_array = 3; 18 static constexpr std::size_t num_array = 3;
19 for (std::size_t i = 0; i < Maxwell3D::Regs::NumVertexArrays; ++i) { 19 for (std::size_t i = 0; i < Maxwell3D::Regs::NumVertexArrays; ++i) {
20 const std::size_t array_offset = OFF(vertex_array) + i * NUM(vertex_array[0]); 20 const std::size_t array_offset = OFF(vertex_streams) + i * NUM(vertex_streams[0]);
21 const std::size_t limit_offset = OFF(vertex_array_limit) + i * NUM(vertex_array_limit[0]); 21 const std::size_t limit_offset =
22 OFF(vertex_stream_limits) + i * NUM(vertex_stream_limits[0]);
22 23
23 FillBlock(tables, array_offset, num_array, VertexBuffer0 + i, VertexBuffers); 24 FillBlock(tables, array_offset, num_array, VertexBuffer0 + i, VertexBuffers);
24 FillBlock(tables, limit_offset, NUM(vertex_array_limit), VertexBuffer0 + i, VertexBuffers); 25 FillBlock(tables, limit_offset, NUM(vertex_stream_limits), VertexBuffer0 + i,
26 VertexBuffers);
25 } 27 }
26} 28}
27 29
28void SetupIndexBuffer(Maxwell3D::DirtyState::Tables& tables) { 30void SetupIndexBuffer(Maxwell3D::DirtyState::Tables& tables) {
29 FillBlock(tables[0], OFF(index_array), NUM(index_array), IndexBuffer); 31 FillBlock(tables[0], OFF(index_buffer), NUM(index_buffer), IndexBuffer);
30} 32}
31 33
32void SetupDirtyDescriptors(Maxwell3D::DirtyState::Tables& tables) { 34void SetupDirtyDescriptors(Maxwell3D::DirtyState::Tables& tables) {
33 FillBlock(tables[0], OFF(tic), NUM(tic), Descriptors); 35 FillBlock(tables[0], OFF(tex_header), NUM(tex_header), Descriptors);
34 FillBlock(tables[0], OFF(tsc), NUM(tsc), Descriptors); 36 FillBlock(tables[0], OFF(tex_sampler), NUM(tex_sampler), Descriptors);
35} 37}
36 38
37void SetupDirtyRenderTargets(Maxwell3D::DirtyState::Tables& tables) { 39void SetupDirtyRenderTargets(Maxwell3D::DirtyState::Tables& tables) {
@@ -42,7 +44,7 @@ void SetupDirtyRenderTargets(Maxwell3D::DirtyState::Tables& tables) {
42 FillBlock(tables[0], begin + rt * num_per_rt, num_per_rt, ColorBuffer0 + rt); 44 FillBlock(tables[0], begin + rt * num_per_rt, num_per_rt, ColorBuffer0 + rt);
43 } 45 }
44 FillBlock(tables[1], begin, num, RenderTargets); 46 FillBlock(tables[1], begin, num, RenderTargets);
45 FillBlock(tables[0], OFF(render_area), NUM(render_area), RenderTargets); 47 FillBlock(tables[0], OFF(surface_clip), NUM(surface_clip), RenderTargets);
46 48
47 tables[0][OFF(rt_control)] = RenderTargets; 49 tables[0][OFF(rt_control)] = RenderTargets;
48 tables[1][OFF(rt_control)] = RenderTargetControl; 50 tables[1][OFF(rt_control)] = RenderTargetControl;
@@ -52,15 +54,15 @@ void SetupDirtyRenderTargets(Maxwell3D::DirtyState::Tables& tables) {
52 const u8 flag = zeta_flags[i]; 54 const u8 flag = zeta_flags[i];
53 auto& table = tables[i]; 55 auto& table = tables[i];
54 table[OFF(zeta_enable)] = flag; 56 table[OFF(zeta_enable)] = flag;
55 table[OFF(zeta_width)] = flag; 57 table[OFF(zeta_size.width)] = flag;
56 table[OFF(zeta_height)] = flag; 58 table[OFF(zeta_size.height)] = flag;
57 FillBlock(table, OFF(zeta), NUM(zeta), flag); 59 FillBlock(table, OFF(zeta), NUM(zeta), flag);
58 } 60 }
59} 61}
60 62
61void SetupDirtyShaders(Maxwell3D::DirtyState::Tables& tables) { 63void SetupDirtyShaders(Maxwell3D::DirtyState::Tables& tables) {
62 FillBlock(tables[0], OFF(shader_config[0]), 64 FillBlock(tables[0], OFF(pipelines), NUM(pipelines) * Maxwell3D::Regs::MaxShaderProgram,
63 NUM(shader_config[0]) * Maxwell3D::Regs::MaxShaderProgram, Shaders); 65 Shaders);
64} 66}
65} // Anonymous namespace 67} // Anonymous namespace
66 68
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() {
56 56
57 // Doom and Bomberman seems to use the uninitialized registers and just enable blend 57 // Doom and Bomberman seems to use the uninitialized registers and just enable blend
58 // so initialize blend registers with sane values 58 // so initialize blend registers with sane values
59 regs.blend.equation_rgb = Regs::Blend::Equation::Add; 59 regs.blend.color_op = Regs::Blend::Equation::Add_D3D;
60 regs.blend.factor_source_rgb = Regs::Blend::Factor::One; 60 regs.blend.color_source = Regs::Blend::Factor::One_D3D;
61 regs.blend.factor_dest_rgb = Regs::Blend::Factor::Zero; 61 regs.blend.color_dest = Regs::Blend::Factor::Zero_D3D;
62 regs.blend.equation_a = Regs::Blend::Equation::Add; 62 regs.blend.alpha_op = Regs::Blend::Equation::Add_D3D;
63 regs.blend.factor_source_a = Regs::Blend::Factor::One; 63 regs.blend.alpha_source = Regs::Blend::Factor::One_D3D;
64 regs.blend.factor_dest_a = Regs::Blend::Factor::Zero; 64 regs.blend.alpha_dest = Regs::Blend::Factor::Zero_D3D;
65 for (auto& blend : regs.independent_blend) { 65 for (auto& blend : regs.blend_per_target) {
66 blend.equation_rgb = Regs::Blend::Equation::Add; 66 blend.color_op = Regs::Blend::Equation::Add_D3D;
67 blend.factor_source_rgb = Regs::Blend::Factor::One; 67 blend.color_source = Regs::Blend::Factor::One_D3D;
68 blend.factor_dest_rgb = Regs::Blend::Factor::Zero; 68 blend.color_dest = Regs::Blend::Factor::Zero_D3D;
69 blend.equation_a = Regs::Blend::Equation::Add; 69 blend.alpha_op = Regs::Blend::Equation::Add_D3D;
70 blend.factor_source_a = Regs::Blend::Factor::One; 70 blend.alpha_source = Regs::Blend::Factor::One_D3D;
71 blend.factor_dest_a = Regs::Blend::Factor::Zero; 71 blend.alpha_dest = Regs::Blend::Factor::Zero_D3D;
72 } 72 }
73 regs.stencil_front_op_fail = Regs::StencilOp::Keep; 73 regs.stencil_front_op.fail = Regs::StencilOp::Op::Keep_D3D;
74 regs.stencil_front_op_zfail = Regs::StencilOp::Keep; 74 regs.stencil_front_op.zfail = Regs::StencilOp::Op::Keep_D3D;
75 regs.stencil_front_op_zpass = Regs::StencilOp::Keep; 75 regs.stencil_front_op.zpass = Regs::StencilOp::Op::Keep_D3D;
76 regs.stencil_front_func_func = Regs::ComparisonOp::Always; 76 regs.stencil_front_op.func = Regs::ComparisonOp::Always_GL;
77 regs.stencil_front_func_mask = 0xFFFFFFFF; 77 regs.stencil_front_func.func_mask = 0xFFFFFFFF;
78 regs.stencil_front_mask = 0xFFFFFFFF; 78 regs.stencil_front_func.mask = 0xFFFFFFFF;
79 regs.stencil_two_side_enable = 1; 79 regs.stencil_two_side_enable = 1;
80 regs.stencil_back_op_fail = Regs::StencilOp::Keep; 80 regs.stencil_back_op.fail = Regs::StencilOp::Op::Keep_D3D;
81 regs.stencil_back_op_zfail = Regs::StencilOp::Keep; 81 regs.stencil_back_op.zfail = Regs::StencilOp::Op::Keep_D3D;
82 regs.stencil_back_op_zpass = Regs::StencilOp::Keep; 82 regs.stencil_back_op.zpass = Regs::StencilOp::Op::Keep_D3D;
83 regs.stencil_back_func_func = Regs::ComparisonOp::Always; 83 regs.stencil_back_op.func = Regs::ComparisonOp::Always_GL;
84 regs.stencil_back_func_mask = 0xFFFFFFFF; 84 regs.stencil_back_func.func_mask = 0xFFFFFFFF;
85 regs.stencil_back_mask = 0xFFFFFFFF; 85 regs.stencil_back_func.mask = 0xFFFFFFFF;
86 86
87 regs.depth_test_func = Regs::ComparisonOp::Always; 87 regs.depth_test_func = Regs::ComparisonOp::Always_GL;
88 regs.front_face = Regs::FrontFace::CounterClockWise; 88 regs.gl_front_face = Regs::FrontFace::CounterClockWise;
89 regs.cull_face = Regs::CullFace::Back; 89 regs.gl_cull_face = Regs::CullFace::Back;
90 90
91 // TODO(Rodrigo): Most games do not set a point size. I think this is a case of a 91 // TODO(Rodrigo): Most games do not set a point size. I think this is a case of a
92 // register carrying a default value. Assume it's OpenGL's default (1). 92 // register carrying a default value. Assume it's OpenGL's default (1).
@@ -107,20 +107,20 @@ void Maxwell3D::InitializeRegisterDefaults() {
107 107
108 // NVN games expect these values to be enabled at boot 108 // NVN games expect these values to be enabled at boot
109 regs.rasterize_enable = 1; 109 regs.rasterize_enable = 1;
110 regs.rt_separate_frag_data = 1; 110 regs.color_target_mrt_enable = 1;
111 regs.framebuffer_srgb = 1; 111 regs.framebuffer_srgb = 1;
112 regs.line_width_aliased = 1.0f; 112 regs.line_width_aliased = 1.0f;
113 regs.line_width_smooth = 1.0f; 113 regs.line_width_smooth = 1.0f;
114 regs.front_face = Maxwell3D::Regs::FrontFace::ClockWise; 114 regs.gl_front_face = Maxwell3D::Regs::FrontFace::ClockWise;
115 regs.polygon_mode_back = Maxwell3D::Regs::PolygonMode::Fill; 115 regs.polygon_mode_back = Maxwell3D::Regs::PolygonMode::Fill;
116 regs.polygon_mode_front = Maxwell3D::Regs::PolygonMode::Fill; 116 regs.polygon_mode_front = Maxwell3D::Regs::PolygonMode::Fill;
117 117
118 shadow_state = regs; 118 shadow_state = regs;
119 119
120 mme_inline[MAXWELL3D_REG_INDEX(draw.vertex_end_gl)] = true; 120 mme_inline[MAXWELL3D_REG_INDEX(draw.end)] = true;
121 mme_inline[MAXWELL3D_REG_INDEX(draw.vertex_begin_gl)] = true; 121 mme_inline[MAXWELL3D_REG_INDEX(draw.begin)] = true;
122 mme_inline[MAXWELL3D_REG_INDEX(vertex_buffer.count)] = true; 122 mme_inline[MAXWELL3D_REG_INDEX(vertex_buffer.count)] = true;
123 mme_inline[MAXWELL3D_REG_INDEX(index_array.count)] = true; 123 mme_inline[MAXWELL3D_REG_INDEX(index_buffer.count)] = true;
124} 124}
125 125
126void Maxwell3D::ProcessMacro(u32 method, const u32* base_start, u32 amount, bool is_last_call) { 126void 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
173 case MAXWELL3D_REG_INDEX(shadow_ram_control): 173 case MAXWELL3D_REG_INDEX(shadow_ram_control):
174 shadow_state.shadow_ram_control = static_cast<Regs::ShadowRamControl>(nonshadow_argument); 174 shadow_state.shadow_ram_control = static_cast<Regs::ShadowRamControl>(nonshadow_argument);
175 return; 175 return;
176 case MAXWELL3D_REG_INDEX(macros.upload_address): 176 case MAXWELL3D_REG_INDEX(load_mme.instruction_ptr):
177 return macro_engine->ClearCode(regs.macros.upload_address); 177 return macro_engine->ClearCode(regs.load_mme.instruction_ptr);
178 case MAXWELL3D_REG_INDEX(macros.data): 178 case MAXWELL3D_REG_INDEX(load_mme.instruction):
179 return macro_engine->AddCode(regs.macros.upload_address, argument); 179 return macro_engine->AddCode(regs.load_mme.instruction_ptr, argument);
180 case MAXWELL3D_REG_INDEX(macros.bind): 180 case MAXWELL3D_REG_INDEX(load_mme.start_address):
181 return ProcessMacroBind(argument); 181 return ProcessMacroBind(argument);
182 case MAXWELL3D_REG_INDEX(firmware[4]): 182 case MAXWELL3D_REG_INDEX(falcon[4]):
183 return ProcessFirmwareCall4(); 183 return ProcessFirmwareCall4();
184 case MAXWELL3D_REG_INDEX(const_buffer.cb_data): 184 case MAXWELL3D_REG_INDEX(const_buffer.buffer):
185 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 1: 185 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 1:
186 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 2: 186 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 2:
187 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 3: 187 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 3:
188 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 4: 188 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 4:
189 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 5: 189 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 5:
190 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 6: 190 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 6:
191 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 7: 191 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 7:
192 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 8: 192 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 8:
193 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 9: 193 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 9:
194 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 10: 194 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 10:
195 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 11: 195 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 11:
196 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 12: 196 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 12:
197 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 13: 197 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 13:
198 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 14: 198 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 14:
199 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 15: 199 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 15:
200 return ProcessCBData(argument); 200 return ProcessCBData(argument);
201 case MAXWELL3D_REG_INDEX(cb_bind[0]): 201 case MAXWELL3D_REG_INDEX(bind_groups[0].raw_config):
202 return ProcessCBBind(0); 202 return ProcessCBBind(0);
203 case MAXWELL3D_REG_INDEX(cb_bind[1]): 203 case MAXWELL3D_REG_INDEX(bind_groups[1].raw_config):
204 return ProcessCBBind(1); 204 return ProcessCBBind(1);
205 case MAXWELL3D_REG_INDEX(cb_bind[2]): 205 case MAXWELL3D_REG_INDEX(bind_groups[2].raw_config):
206 return ProcessCBBind(2); 206 return ProcessCBBind(2);
207 case MAXWELL3D_REG_INDEX(cb_bind[3]): 207 case MAXWELL3D_REG_INDEX(bind_groups[3].raw_config):
208 return ProcessCBBind(3); 208 return ProcessCBBind(3);
209 case MAXWELL3D_REG_INDEX(cb_bind[4]): 209 case MAXWELL3D_REG_INDEX(bind_groups[4].raw_config):
210 return ProcessCBBind(4); 210 return ProcessCBBind(4);
211 case MAXWELL3D_REG_INDEX(draw.vertex_end_gl): 211 case MAXWELL3D_REG_INDEX(draw.end):
212 return DrawArrays(); 212 return DrawArrays();
213 case MAXWELL3D_REG_INDEX(small_index): 213 case MAXWELL3D_REG_INDEX(index_buffer32_first):
214 regs.index_array.count = regs.small_index.count; 214 regs.index_buffer.count = regs.index_buffer32_first.count;
215 regs.index_array.first = regs.small_index.first; 215 regs.index_buffer.first = regs.index_buffer32_first.first;
216 dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; 216 dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
217 return DrawArrays(); 217 return DrawArrays();
218 case MAXWELL3D_REG_INDEX(small_index_2): 218 case MAXWELL3D_REG_INDEX(index_buffer16_first):
219 regs.index_array.count = regs.small_index_2.count; 219 regs.index_buffer.count = regs.index_buffer16_first.count;
220 regs.index_array.first = regs.small_index_2.first; 220 regs.index_buffer.first = regs.index_buffer16_first.first;
221 dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
222 return DrawArrays();
223 case MAXWELL3D_REG_INDEX(index_buffer8_first):
224 regs.index_buffer.count = regs.index_buffer8_first.count;
225 regs.index_buffer.first = regs.index_buffer8_first.first;
221 dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; 226 dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
222 // a macro calls this one over and over, should it increase instancing? 227 // a macro calls this one over and over, should it increase instancing?
223 // Used by Hades and likely other Vulkan games. 228 // Used by Hades and likely other Vulkan games.
@@ -225,28 +230,24 @@ void Maxwell3D::ProcessMethodCall(u32 method, u32 argument, u32 nonshadow_argume
225 case MAXWELL3D_REG_INDEX(topology_override): 230 case MAXWELL3D_REG_INDEX(topology_override):
226 use_topology_override = true; 231 use_topology_override = true;
227 return; 232 return;
228 case MAXWELL3D_REG_INDEX(clear_buffers): 233 case MAXWELL3D_REG_INDEX(clear_surface):
229 return ProcessClearBuffers(); 234 return ProcessClearBuffers();
230 case MAXWELL3D_REG_INDEX(query.query_get): 235 case MAXWELL3D_REG_INDEX(report_semaphore.query):
231 return ProcessQueryGet(); 236 return ProcessQueryGet();
232 case MAXWELL3D_REG_INDEX(condition.mode): 237 case MAXWELL3D_REG_INDEX(render_enable.mode):
233 return ProcessQueryCondition(); 238 return ProcessQueryCondition();
234 case MAXWELL3D_REG_INDEX(counter_reset): 239 case MAXWELL3D_REG_INDEX(clear_report_value):
235 return ProcessCounterReset(); 240 return ProcessCounterReset();
236 case MAXWELL3D_REG_INDEX(sync_info): 241 case MAXWELL3D_REG_INDEX(sync_info):
237 return ProcessSyncPoint(); 242 return ProcessSyncPoint();
238 case MAXWELL3D_REG_INDEX(exec_upload): 243 case MAXWELL3D_REG_INDEX(launch_dma):
239 return upload_state.ProcessExec(regs.exec_upload.linear != 0); 244 return upload_state.ProcessExec(regs.launch_dma.memory_layout.Value() ==
240 case MAXWELL3D_REG_INDEX(data_upload): 245 Regs::LaunchDMA::Layout::Pitch);
246 case MAXWELL3D_REG_INDEX(inline_data):
241 upload_state.ProcessData(argument, is_last_call); 247 upload_state.ProcessData(argument, is_last_call);
242 return; 248 return;
243 case MAXWELL3D_REG_INDEX(fragment_barrier): 249 case MAXWELL3D_REG_INDEX(fragment_barrier):
244 return rasterizer->FragmentBarrier(); 250 return rasterizer->FragmentBarrier();
245 case MAXWELL3D_REG_INDEX(invalidate_texture_data_cache):
246 rasterizer->InvalidateGPUCache();
247 return rasterizer->WaitForIdle();
248 case MAXWELL3D_REG_INDEX(tiled_cache_barrier):
249 return rasterizer->TiledCacheBarrier();
250 } 251 }
251} 252}
252 253
@@ -296,25 +297,25 @@ void Maxwell3D::CallMultiMethod(u32 method, const u32* base_start, u32 amount,
296 return; 297 return;
297 } 298 }
298 switch (method) { 299 switch (method) {
299 case MAXWELL3D_REG_INDEX(const_buffer.cb_data): 300 case MAXWELL3D_REG_INDEX(const_buffer.buffer):
300 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 1: 301 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 1:
301 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 2: 302 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 2:
302 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 3: 303 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 3:
303 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 4: 304 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 4:
304 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 5: 305 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 5:
305 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 6: 306 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 6:
306 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 7: 307 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 7:
307 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 8: 308 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 8:
308 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 9: 309 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 9:
309 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 10: 310 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 10:
310 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 11: 311 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 11:
311 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 12: 312 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 12:
312 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 13: 313 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 13:
313 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 14: 314 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 14:
314 case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 15: 315 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 15:
315 ProcessCBMultiData(base_start, amount); 316 ProcessCBMultiData(base_start, amount);
316 break; 317 break;
317 case MAXWELL3D_REG_INDEX(data_upload): 318 case MAXWELL3D_REG_INDEX(inline_data):
318 upload_state.ProcessData(base_start, static_cast<size_t>(amount)); 319 upload_state.ProcessData(base_start, static_cast<size_t>(amount));
319 return; 320 return;
320 default: 321 default:
@@ -353,14 +354,15 @@ void Maxwell3D::CallMethodFromMME(u32 method, u32 method_argument) {
353 if (mme_inline[method]) { 354 if (mme_inline[method]) {
354 regs.reg_array[method] = method_argument; 355 regs.reg_array[method] = method_argument;
355 if (method == MAXWELL3D_REG_INDEX(vertex_buffer.count) || 356 if (method == MAXWELL3D_REG_INDEX(vertex_buffer.count) ||
356 method == MAXWELL3D_REG_INDEX(index_array.count)) { 357 method == MAXWELL3D_REG_INDEX(index_buffer.count)) {
357 const MMEDrawMode expected_mode = method == MAXWELL3D_REG_INDEX(vertex_buffer.count) 358 const MMEDrawMode expected_mode = method == MAXWELL3D_REG_INDEX(vertex_buffer.count)
358 ? MMEDrawMode::Array 359 ? MMEDrawMode::Array
359 : MMEDrawMode::Indexed; 360 : MMEDrawMode::Indexed;
360 StepInstance(expected_mode, method_argument); 361 StepInstance(expected_mode, method_argument);
361 } else if (method == MAXWELL3D_REG_INDEX(draw.vertex_begin_gl)) { 362 } else if (method == MAXWELL3D_REG_INDEX(draw.begin)) {
362 mme_draw.instance_mode = 363 mme_draw.instance_mode =
363 (regs.draw.instance_next != 0) || (regs.draw.instance_cont != 0); 364 (regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::Subsequent) ||
365 (regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::Unchanged);
364 mme_draw.gl_begin_consume = true; 366 mme_draw.gl_begin_consume = true;
365 } else { 367 } else {
366 mme_draw.gl_end_count++; 368 mme_draw.gl_end_count++;
@@ -405,11 +407,12 @@ void Maxwell3D::ProcessTopologyOverride() {
405void Maxwell3D::FlushMMEInlineDraw() { 407void Maxwell3D::FlushMMEInlineDraw() {
406 LOG_TRACE(HW_GPU, "called, topology={}, count={}", regs.draw.topology.Value(), 408 LOG_TRACE(HW_GPU, "called, topology={}, count={}", regs.draw.topology.Value(),
407 regs.vertex_buffer.count); 409 regs.vertex_buffer.count);
408 ASSERT_MSG(!(regs.index_array.count && regs.vertex_buffer.count), "Both indexed and direct?"); 410 ASSERT_MSG(!(regs.index_buffer.count && regs.vertex_buffer.count), "Both indexed and direct?");
409 ASSERT(mme_draw.instance_count == mme_draw.gl_end_count); 411 ASSERT(mme_draw.instance_count == mme_draw.gl_end_count);
410 412
411 // Both instance configuration registers can not be set at the same time. 413 // Both instance configuration registers can not be set at the same time.
412 ASSERT_MSG(!regs.draw.instance_next || !regs.draw.instance_cont, 414 ASSERT_MSG(regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::First ||
415 regs.draw.instance_id != Maxwell3D::Regs::Draw::InstanceId::Unchanged,
413 "Illegal combination of instancing parameters"); 416 "Illegal combination of instancing parameters");
414 417
415 ProcessTopologyOverride(); 418 ProcessTopologyOverride();
@@ -424,7 +427,7 @@ void Maxwell3D::FlushMMEInlineDraw() {
424 // it's possible that it is incorrect and that there is some other register used to specify the 427 // it's possible that it is incorrect and that there is some other register used to specify the
425 // drawing mode. 428 // drawing mode.
426 if (is_indexed) { 429 if (is_indexed) {
427 regs.index_array.count = 0; 430 regs.index_buffer.count = 0;
428 } else { 431 } else {
429 regs.vertex_buffer.count = 0; 432 regs.vertex_buffer.count = 0;
430 } 433 }
@@ -437,11 +440,11 @@ void Maxwell3D::FlushMMEInlineDraw() {
437} 440}
438 441
439void Maxwell3D::ProcessMacroUpload(u32 data) { 442void Maxwell3D::ProcessMacroUpload(u32 data) {
440 macro_engine->AddCode(regs.macros.upload_address++, data); 443 macro_engine->AddCode(regs.load_mme.instruction_ptr++, data);
441} 444}
442 445
443void Maxwell3D::ProcessMacroBind(u32 data) { 446void Maxwell3D::ProcessMacroBind(u32 data) {
444 macro_positions[regs.macros.entry++] = data; 447 macro_positions[regs.load_mme.start_address_ptr++] = data;
445} 448}
446 449
447void Maxwell3D::ProcessFirmwareCall4() { 450void Maxwell3D::ProcessFirmwareCall4() {
@@ -449,11 +452,11 @@ void Maxwell3D::ProcessFirmwareCall4() {
449 452
450 // Firmware call 4 is a blob that changes some registers depending on its parameters. 453 // Firmware call 4 is a blob that changes some registers depending on its parameters.
451 // These registers don't affect emulation and so are stubbed by setting 0xd00 to 1. 454 // These registers don't affect emulation and so are stubbed by setting 0xd00 to 1.
452 regs.reg_array[0xd00] = 1; 455 regs.shadow_scratch[0] = 1;
453} 456}
454 457
455void Maxwell3D::StampQueryResult(u64 payload, bool long_query) { 458void Maxwell3D::StampQueryResult(u64 payload, bool long_query) {
456 const GPUVAddr sequence_address{regs.query.QueryAddress()}; 459 const GPUVAddr sequence_address{regs.report_semaphore.Address()};
457 if (long_query) { 460 if (long_query) {
458 memory_manager.Write<u64>(sequence_address + sizeof(u64), system.GPU().GetTicks()); 461 memory_manager.Write<u64>(sequence_address + sizeof(u64), system.GPU().GetTicks());
459 memory_manager.Write<u64>(sequence_address, payload); 462 memory_manager.Write<u64>(sequence_address, payload);
@@ -464,15 +467,17 @@ void Maxwell3D::StampQueryResult(u64 payload, bool long_query) {
464 467
465void Maxwell3D::ProcessQueryGet() { 468void Maxwell3D::ProcessQueryGet() {
466 // TODO(Subv): Support the other query units. 469 // TODO(Subv): Support the other query units.
467 if (regs.query.query_get.unit != Regs::QueryUnit::Crop) { 470 if (regs.report_semaphore.query.location != Regs::ReportSemaphore::Location::All) {
468 LOG_DEBUG(HW_GPU, "Units other than CROP are unimplemented"); 471 LOG_DEBUG(HW_GPU, "Locations other than ALL are unimplemented");
469 } 472 }
470 473
471 switch (regs.query.query_get.operation) { 474 switch (regs.report_semaphore.query.operation) {
472 case Regs::QueryOperation::Release: 475 case Regs::ReportSemaphore::Operation::Release:
473 if (regs.query.query_get.fence == 1 || regs.query.query_get.short_query != 0) { 476 if (regs.report_semaphore.query.release ==
474 const GPUVAddr sequence_address{regs.query.QueryAddress()}; 477 Regs::ReportSemaphore::Release::AfterAllPreceedingWrites ||
475 const u32 payload = regs.query.query_sequence; 478 regs.report_semaphore.query.short_query != 0) {
479 const GPUVAddr sequence_address{regs.report_semaphore.Address()};
480 const u32 payload = regs.report_semaphore.payload;
476 std::function<void()> operation([this, sequence_address, payload] { 481 std::function<void()> operation([this, sequence_address, payload] {
477 memory_manager.Write<u32>(sequence_address, payload); 482 memory_manager.Write<u32>(sequence_address, payload);
478 }); 483 });
@@ -482,8 +487,8 @@ void Maxwell3D::ProcessQueryGet() {
482 u64_le value; 487 u64_le value;
483 u64_le timestamp; 488 u64_le timestamp;
484 }; 489 };
485 const GPUVAddr sequence_address{regs.query.QueryAddress()}; 490 const GPUVAddr sequence_address{regs.report_semaphore.Address()};
486 const u32 payload = regs.query.query_sequence; 491 const u32 payload = regs.report_semaphore.payload;
487 std::function<void()> operation([this, sequence_address, payload] { 492 std::function<void()> operation([this, sequence_address, payload] {
488 memory_manager.Write<u64>(sequence_address + sizeof(u64), system.GPU().GetTicks()); 493 memory_manager.Write<u64>(sequence_address + sizeof(u64), system.GPU().GetTicks());
489 memory_manager.Write<u64>(sequence_address, payload); 494 memory_manager.Write<u64>(sequence_address, payload);
@@ -491,19 +496,19 @@ void Maxwell3D::ProcessQueryGet() {
491 rasterizer->SyncOperation(std::move(operation)); 496 rasterizer->SyncOperation(std::move(operation));
492 } 497 }
493 break; 498 break;
494 case Regs::QueryOperation::Acquire: 499 case Regs::ReportSemaphore::Operation::Acquire:
495 // TODO(Blinkhawk): Under this operation, the GPU waits for the CPU to write a value that 500 // TODO(Blinkhawk): Under this operation, the GPU waits for the CPU to write a value that
496 // matches the current payload. 501 // matches the current payload.
497 UNIMPLEMENTED_MSG("Unimplemented query operation ACQUIRE"); 502 UNIMPLEMENTED_MSG("Unimplemented query operation ACQUIRE");
498 break; 503 break;
499 case Regs::QueryOperation::Counter: 504 case Regs::ReportSemaphore::Operation::ReportOnly:
500 if (const std::optional<u64> result = GetQueryResult()) { 505 if (const std::optional<u64> result = GetQueryResult()) {
501 // If the query returns an empty optional it means it's cached and deferred. 506 // If the query returns an empty optional it means it's cached and deferred.
502 // In this case we have a non-empty result, so we stamp it immediately. 507 // In this case we have a non-empty result, so we stamp it immediately.
503 StampQueryResult(*result, regs.query.query_get.short_query == 0); 508 StampQueryResult(*result, regs.report_semaphore.query.short_query == 0);
504 } 509 }
505 break; 510 break;
506 case Regs::QueryOperation::Trap: 511 case Regs::ReportSemaphore::Operation::Trap:
507 UNIMPLEMENTED_MSG("Unimplemented query operation TRAP"); 512 UNIMPLEMENTED_MSG("Unimplemented query operation TRAP");
508 break; 513 break;
509 default: 514 default:
@@ -513,31 +518,31 @@ void Maxwell3D::ProcessQueryGet() {
513} 518}
514 519
515void Maxwell3D::ProcessQueryCondition() { 520void Maxwell3D::ProcessQueryCondition() {
516 const GPUVAddr condition_address{regs.condition.Address()}; 521 const GPUVAddr condition_address{regs.render_enable.Address()};
517 switch (regs.condition.mode) { 522 switch (regs.render_enable.mode) {
518 case Regs::ConditionMode::Always: { 523 case Regs::RenderEnable::Mode::True: {
519 execute_on = true; 524 execute_on = true;
520 break; 525 break;
521 } 526 }
522 case Regs::ConditionMode::Never: { 527 case Regs::RenderEnable::Mode::False: {
523 execute_on = false; 528 execute_on = false;
524 break; 529 break;
525 } 530 }
526 case Regs::ConditionMode::ResNonZero: { 531 case Regs::RenderEnable::Mode::Conditional: {
527 Regs::QueryCompare cmp; 532 Regs::ReportSemaphore::Compare cmp;
528 memory_manager.ReadBlock(condition_address, &cmp, sizeof(cmp)); 533 memory_manager.ReadBlock(condition_address, &cmp, sizeof(cmp));
529 execute_on = cmp.initial_sequence != 0U && cmp.initial_mode != 0U; 534 execute_on = cmp.initial_sequence != 0U && cmp.initial_mode != 0U;
530 break; 535 break;
531 } 536 }
532 case Regs::ConditionMode::Equal: { 537 case Regs::RenderEnable::Mode::IfEqual: {
533 Regs::QueryCompare cmp; 538 Regs::ReportSemaphore::Compare cmp;
534 memory_manager.ReadBlock(condition_address, &cmp, sizeof(cmp)); 539 memory_manager.ReadBlock(condition_address, &cmp, sizeof(cmp));
535 execute_on = 540 execute_on =
536 cmp.initial_sequence == cmp.current_sequence && cmp.initial_mode == cmp.current_mode; 541 cmp.initial_sequence == cmp.current_sequence && cmp.initial_mode == cmp.current_mode;
537 break; 542 break;
538 } 543 }
539 case Regs::ConditionMode::NotEqual: { 544 case Regs::RenderEnable::Mode::IfNotEqual: {
540 Regs::QueryCompare cmp; 545 Regs::ReportSemaphore::Compare cmp;
541 memory_manager.ReadBlock(condition_address, &cmp, sizeof(cmp)); 546 memory_manager.ReadBlock(condition_address, &cmp, sizeof(cmp));
542 execute_on = 547 execute_on =
543 cmp.initial_sequence != cmp.current_sequence || cmp.initial_mode != cmp.current_mode; 548 cmp.initial_sequence != cmp.current_sequence || cmp.initial_mode != cmp.current_mode;
@@ -552,21 +557,21 @@ void Maxwell3D::ProcessQueryCondition() {
552} 557}
553 558
554void Maxwell3D::ProcessCounterReset() { 559void Maxwell3D::ProcessCounterReset() {
555 switch (regs.counter_reset) { 560 switch (regs.clear_report_value) {
556 case Regs::CounterReset::SampleCnt: 561 case Regs::ClearReport::ZPassPixelCount:
557 rasterizer->ResetCounter(QueryType::SamplesPassed); 562 rasterizer->ResetCounter(QueryType::SamplesPassed);
558 break; 563 break;
559 default: 564 default:
560 LOG_DEBUG(Render_OpenGL, "Unimplemented counter reset={}", regs.counter_reset); 565 LOG_DEBUG(Render_OpenGL, "Unimplemented counter reset={}", regs.clear_report_value);
561 break; 566 break;
562 } 567 }
563} 568}
564 569
565void Maxwell3D::ProcessSyncPoint() { 570void Maxwell3D::ProcessSyncPoint() {
566 const u32 sync_point = regs.sync_info.sync_point.Value(); 571 const u32 sync_point = regs.sync_info.sync_point.Value();
567 const u32 increment = regs.sync_info.increment.Value(); 572 const auto condition = regs.sync_info.condition.Value();
568 [[maybe_unused]] const u32 cache_flush = regs.sync_info.unknown.Value(); 573 [[maybe_unused]] const u32 cache_flush = regs.sync_info.clean_l2.Value();
569 if (increment) { 574 if (condition == Regs::SyncInfo::Condition::RopWritesDone) {
570 rasterizer->SignalSyncPoint(sync_point); 575 rasterizer->SignalSyncPoint(sync_point);
571 } 576 }
572} 577}
@@ -574,23 +579,24 @@ void Maxwell3D::ProcessSyncPoint() {
574void Maxwell3D::DrawArrays() { 579void Maxwell3D::DrawArrays() {
575 LOG_TRACE(HW_GPU, "called, topology={}, count={}", regs.draw.topology.Value(), 580 LOG_TRACE(HW_GPU, "called, topology={}, count={}", regs.draw.topology.Value(),
576 regs.vertex_buffer.count); 581 regs.vertex_buffer.count);
577 ASSERT_MSG(!(regs.index_array.count && regs.vertex_buffer.count), "Both indexed and direct?"); 582 ASSERT_MSG(!(regs.index_buffer.count && regs.vertex_buffer.count), "Both indexed and direct?");
578 583
579 // Both instance configuration registers can not be set at the same time. 584 // Both instance configuration registers can not be set at the same time.
580 ASSERT_MSG(!regs.draw.instance_next || !regs.draw.instance_cont, 585 ASSERT_MSG(regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::First ||
586 regs.draw.instance_id != Maxwell3D::Regs::Draw::InstanceId::Unchanged,
581 "Illegal combination of instancing parameters"); 587 "Illegal combination of instancing parameters");
582 588
583 ProcessTopologyOverride(); 589 ProcessTopologyOverride();
584 590
585 if (regs.draw.instance_next) { 591 if (regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::Subsequent) {
586 // Increment the current instance *before* drawing. 592 // Increment the current instance *before* drawing.
587 state.current_instance += 1; 593 state.current_instance++;
588 } else if (!regs.draw.instance_cont) { 594 } else if (regs.draw.instance_id != Maxwell3D::Regs::Draw::InstanceId::Unchanged) {
589 // Reset the current instance to 0. 595 // Reset the current instance to 0.
590 state.current_instance = 0; 596 state.current_instance = 0;
591 } 597 }
592 598
593 const bool is_indexed{regs.index_array.count && !regs.vertex_buffer.count}; 599 const bool is_indexed{regs.index_buffer.count && !regs.vertex_buffer.count};
594 if (ShouldExecute()) { 600 if (ShouldExecute()) {
595 rasterizer->Draw(is_indexed, false); 601 rasterizer->Draw(is_indexed, false);
596 } 602 }
@@ -600,60 +606,60 @@ void Maxwell3D::DrawArrays() {
600 // it's possible that it is incorrect and that there is some other register used to specify the 606 // it's possible that it is incorrect and that there is some other register used to specify the
601 // drawing mode. 607 // drawing mode.
602 if (is_indexed) { 608 if (is_indexed) {
603 regs.index_array.count = 0; 609 regs.index_buffer.count = 0;
604 } else { 610 } else {
605 regs.vertex_buffer.count = 0; 611 regs.vertex_buffer.count = 0;
606 } 612 }
607} 613}
608 614
609std::optional<u64> Maxwell3D::GetQueryResult() { 615std::optional<u64> Maxwell3D::GetQueryResult() {
610 switch (regs.query.query_get.select) { 616 switch (regs.report_semaphore.query.report) {
611 case Regs::QuerySelect::Payload: 617 case Regs::ReportSemaphore::Report::Payload:
612 return regs.query.query_sequence; 618 return regs.report_semaphore.payload;
613 case Regs::QuerySelect::SamplesPassed: 619 case Regs::ReportSemaphore::Report::ZPassPixelCount64:
614 // Deferred. 620 // Deferred.
615 rasterizer->Query(regs.query.QueryAddress(), QueryType::SamplesPassed, 621 rasterizer->Query(regs.report_semaphore.Address(), QueryType::SamplesPassed,
616 system.GPU().GetTicks()); 622 system.GPU().GetTicks());
617 return std::nullopt; 623 return std::nullopt;
618 default: 624 default:
619 LOG_DEBUG(HW_GPU, "Unimplemented query select type {}", 625 LOG_DEBUG(HW_GPU, "Unimplemented query report type {}",
620 regs.query.query_get.select.Value()); 626 regs.report_semaphore.query.report.Value());
621 return 1; 627 return 1;
622 } 628 }
623} 629}
624 630
625void Maxwell3D::ProcessCBBind(size_t stage_index) { 631void Maxwell3D::ProcessCBBind(size_t stage_index) {
626 // Bind the buffer currently in CB_ADDRESS to the specified index in the desired shader stage. 632 // Bind the buffer currently in CB_ADDRESS to the specified index in the desired shader stage.
627 const auto& bind_data = regs.cb_bind[stage_index]; 633 const auto& bind_data = regs.bind_groups[stage_index];
628 auto& buffer = state.shader_stages[stage_index].const_buffers[bind_data.index]; 634 auto& buffer = state.shader_stages[stage_index].const_buffers[bind_data.shader_slot];
629 buffer.enabled = bind_data.valid.Value() != 0; 635 buffer.enabled = bind_data.valid.Value() != 0;
630 buffer.address = regs.const_buffer.BufferAddress(); 636 buffer.address = regs.const_buffer.Address();
631 buffer.size = regs.const_buffer.cb_size; 637 buffer.size = regs.const_buffer.size;
632 638
633 const bool is_enabled = bind_data.valid.Value() != 0; 639 const bool is_enabled = bind_data.valid.Value() != 0;
634 if (!is_enabled) { 640 if (!is_enabled) {
635 rasterizer->DisableGraphicsUniformBuffer(stage_index, bind_data.index); 641 rasterizer->DisableGraphicsUniformBuffer(stage_index, bind_data.shader_slot);
636 return; 642 return;
637 } 643 }
638 const GPUVAddr gpu_addr = regs.const_buffer.BufferAddress(); 644 const GPUVAddr gpu_addr = regs.const_buffer.Address();
639 const u32 size = regs.const_buffer.cb_size; 645 const u32 size = regs.const_buffer.size;
640 rasterizer->BindGraphicsUniformBuffer(stage_index, bind_data.index, gpu_addr, size); 646 rasterizer->BindGraphicsUniformBuffer(stage_index, bind_data.shader_slot, gpu_addr, size);
641} 647}
642 648
643void Maxwell3D::ProcessCBMultiData(const u32* start_base, u32 amount) { 649void Maxwell3D::ProcessCBMultiData(const u32* start_base, u32 amount) {
644 // Write the input value to the current const buffer at the current position. 650 // Write the input value to the current const buffer at the current position.
645 const GPUVAddr buffer_address = regs.const_buffer.BufferAddress(); 651 const GPUVAddr buffer_address = regs.const_buffer.Address();
646 ASSERT(buffer_address != 0); 652 ASSERT(buffer_address != 0);
647 653
648 // Don't allow writing past the end of the buffer. 654 // Don't allow writing past the end of the buffer.
649 ASSERT(regs.const_buffer.cb_pos <= regs.const_buffer.cb_size); 655 ASSERT(regs.const_buffer.offset <= regs.const_buffer.size);
650 656
651 const GPUVAddr address{buffer_address + regs.const_buffer.cb_pos}; 657 const GPUVAddr address{buffer_address + regs.const_buffer.offset};
652 const size_t copy_size = amount * sizeof(u32); 658 const size_t copy_size = amount * sizeof(u32);
653 memory_manager.WriteBlock(address, start_base, copy_size); 659 memory_manager.WriteBlock(address, start_base, copy_size);
654 660
655 // Increment the current buffer position. 661 // Increment the current buffer position.
656 regs.const_buffer.cb_pos += static_cast<u32>(copy_size); 662 regs.const_buffer.offset += static_cast<u32>(copy_size);
657} 663}
658 664
659void Maxwell3D::ProcessCBData(u32 value) { 665void Maxwell3D::ProcessCBData(u32 value) {
@@ -661,7 +667,8 @@ void Maxwell3D::ProcessCBData(u32 value) {
661} 667}
662 668
663Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const { 669Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const {
664 const GPUVAddr tic_address_gpu{regs.tic.Address() + tic_index * sizeof(Texture::TICEntry)}; 670 const GPUVAddr tic_address_gpu{regs.tex_header.Address() +
671 tic_index * sizeof(Texture::TICEntry)};
665 672
666 Texture::TICEntry tic_entry; 673 Texture::TICEntry tic_entry;
667 memory_manager.ReadBlockUnsafe(tic_address_gpu, &tic_entry, sizeof(Texture::TICEntry)); 674 memory_manager.ReadBlockUnsafe(tic_address_gpu, &tic_entry, sizeof(Texture::TICEntry));
@@ -670,7 +677,8 @@ Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const {
670} 677}
671 678
672Texture::TSCEntry Maxwell3D::GetTSCEntry(u32 tsc_index) const { 679Texture::TSCEntry Maxwell3D::GetTSCEntry(u32 tsc_index) const {
673 const GPUVAddr tsc_address_gpu{regs.tsc.Address() + tsc_index * sizeof(Texture::TSCEntry)}; 680 const GPUVAddr tsc_address_gpu{regs.tex_sampler.Address() +
681 tsc_index * sizeof(Texture::TSCEntry)};
674 682
675 Texture::TSCEntry tsc_entry; 683 Texture::TSCEntry tsc_entry;
676 memory_manager.ReadBlockUnsafe(tsc_address_gpu, &tsc_entry, sizeof(Texture::TSCEntry)); 684 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 {
39 39
40/** 40/**
41 * This Engine is known as GF100_3D. Documentation can be found in: 41 * This Engine is known as GF100_3D. Documentation can be found in:
42 * https://github.com/NVIDIA/open-gpu-doc/blob/master/classes/3d/clb197.h
42 * https://github.com/envytools/envytools/blob/master/rnndb/graph/gf100_3d.xml 43 * https://github.com/envytools/envytools/blob/master/rnndb/graph/gf100_3d.xml
43 * https://cgit.freedesktop.org/mesa/mesa/tree/src/gallium/drivers/nouveau/nvc0/nvc0_3d.xml.h 44 * https://cgit.freedesktop.org/mesa/mesa/tree/src/gallium/drivers/nouveau/nvc0/nvc0_3d.xml.h
45 *
46 * Note: nVidia have confirmed that their open docs have had parts redacted, so this list is
47 * currently incomplete, and the gaps are still worth exploring.
44 */ 48 */
45 49
46#define MAXWELL3D_REG_INDEX(field_name) \ 50#define MAXWELL3D_REG_INDEX(field_name) (offsetof(Maxwell3D::Regs, field_name) / sizeof(u32))
47 (offsetof(Tegra::Engines::Maxwell3D::Regs, field_name) / sizeof(u32))
48 51
49class Maxwell3D final : public EngineInterface { 52class Maxwell3D final : public EngineInterface {
50public: 53public:
@@ -55,7 +58,6 @@ public:
55 void BindRasterizer(VideoCore::RasterizerInterface* rasterizer); 58 void BindRasterizer(VideoCore::RasterizerInterface* rasterizer);
56 59
57 /// Register structure of the Maxwell3D engine. 60 /// Register structure of the Maxwell3D engine.
58 /// TODO(Subv): This structure will need to be made bigger as more registers are discovered.
59 struct Regs { 61 struct Regs {
60 static constexpr std::size_t NUM_REGS = 0xE00; 62 static constexpr std::size_t NUM_REGS = 0xE00;
61 63
@@ -74,90 +76,515 @@ public:
74 static constexpr std::size_t MaxConstBuffers = 18; 76 static constexpr std::size_t MaxConstBuffers = 18;
75 static constexpr std::size_t MaxConstBufferSize = 0x10000; 77 static constexpr std::size_t MaxConstBufferSize = 0x10000;
76 78
77 enum class QueryOperation : u32 { 79 struct ID {
78 Release = 0, 80 union {
79 Acquire = 1, 81 BitField<0, 16, u32> cls;
80 Counter = 2, 82 BitField<16, 5, u32> engine;
81 Trap = 3, 83 };
82 }; 84 };
83 85
84 enum class QueryUnit : u32 { 86 struct LoadMME {
85 VFetch = 1, 87 u32 instruction_ptr;
86 VP = 2, 88 u32 instruction;
87 Rast = 4, 89 u32 start_address_ptr;
88 StrmOut = 5, 90 u32 start_address;
89 GP = 6,
90 ZCull = 7,
91 Prop = 10,
92 Crop = 15,
93 }; 91 };
94 92
95 enum class QuerySelect : u32 { 93 struct Notify {
96 Payload = 0, 94 u32 address_high;
97 TimeElapsed = 2, 95 u32 address_low;
98 TransformFeedbackPrimitivesGenerated = 11, 96 u32 type;
99 PrimitivesGenerated = 18, 97
100 SamplesPassed = 21, 98 GPUVAddr Address() const {
101 TransformFeedbackUnknown = 26, 99 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
100 address_low);
101 }
102 }; 102 };
103 103
104 struct QueryCompare { 104 struct PeerSemaphore {
105 u32 initial_sequence; 105 u32 address_high;
106 u32 initial_mode; 106 u32 address_low;
107 u32 unknown1; 107
108 u32 unknown2; 108 GPUVAddr Address() const {
109 u32 current_sequence; 109 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
110 u32 current_mode; 110 address_low);
111 }
111 }; 112 };
112 113
113 enum class QuerySyncCondition : u32 { 114 struct GlobalRender {
114 NotEqual = 0, 115 enum class Mode : u32 {
115 GreaterThan = 1, 116 False = 0,
117 True = 1,
118 Conditional = 2,
119 IfEqual = 3,
120 IfNotEqual = 4,
121 };
122 u32 offset_high;
123 u32 offset_low;
124 Mode mode;
125
126 GPUVAddr Address() const {
127 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(offset_high) << 32) |
128 offset_low);
129 }
116 }; 130 };
117 131
118 enum class ConditionMode : u32 { 132 enum class ReductionOp : u32 {
119 Never = 0, 133 RedAdd = 0,
120 Always = 1, 134 RedMin = 1,
121 ResNonZero = 2, 135 RedMax = 2,
122 Equal = 3, 136 RedInc = 3,
123 NotEqual = 4, 137 RedDec = 4,
138 RedAnd = 5,
139 RedOr = 6,
140 RedXor = 7,
124 }; 141 };
125 142
126 enum class ShaderProgram : u32 { 143 struct LaunchDMA {
127 VertexA = 0, 144 enum class Layout : u32 {
128 VertexB = 1, 145 Blocklinear = 0,
129 TesselationControl = 2, 146 Pitch = 1,
130 TesselationEval = 3, 147 };
131 Geometry = 4, 148
132 Fragment = 5, 149 enum class CompletionType : u32 {
150 FlushDisable = 0,
151 FlushOnly = 1,
152 Release = 2,
153 };
154
155 union {
156 BitField<0, 1, Layout> memory_layout;
157 BitField<4, 2, CompletionType> completion_type;
158 BitField<8, 2, u32> interrupt_type;
159 BitField<12, 1, u32> sem_size;
160 BitField<1, 1, u32> reduction_enable;
161 BitField<13, 3, ReductionOp> reduction_op;
162 BitField<2, 2, u32> reduction_format;
163 BitField<6, 1, u32> sysmembar_disable;
164 };
165 };
166
167 struct I2M {
168 u32 address_high;
169 u32 address_low;
170 u32 payload;
171 INSERT_PADDING_BYTES_NOINIT(0x8);
172 u32 nop0;
173 u32 nop1;
174 u32 nop2;
175 u32 nop3;
176 };
177
178 struct OpportunisticEarlyZ {
179 BitField<0, 5, u32> threshold;
180
181 u32 Threshold() const {
182 switch (threshold) {
183 case 0x0:
184 return 0;
185 case 0x1F:
186 return 0x1F;
187 default:
188 // Thresholds begin at 0x10 (1 << 4)
189 // Threshold is in the range 0x1 to 0x13
190 return 1 << (4 + threshold.Value() - 1);
191 }
192 }
193 };
194
195 struct GeometryShaderDmFifo {
196 union {
197 BitField<0, 13, u32> raster_on;
198 BitField<16, 13, u32> raster_off;
199 BitField<31, 1, u32> spill_enabled;
200 };
201 };
202
203 struct L2CacheControl {
204 enum class EvictPolicy : u32 {
205 First = 0,
206 Normal = 1,
207 Last = 2,
208 };
209
210 union {
211 BitField<4, 2, EvictPolicy> policy;
212 };
213 };
214
215 struct InvalidateShaderCache {
216 union {
217 BitField<0, 1, u32> instruction;
218 BitField<4, 1, u32> data;
219 BitField<12, 1, u32> constant;
220 BitField<1, 1, u32> locks;
221 BitField<2, 1, u32> flush_data;
222 };
223 };
224
225 struct SyncInfo {
226 enum class Condition : u32 {
227 StreamOutWritesDone = 0,
228 RopWritesDone = 1,
229 };
230
231 union {
232 BitField<0, 16, u32> sync_point;
233 BitField<16, 1, u32> clean_l2;
234 BitField<20, 1, Condition> condition;
235 };
236 };
237
238 struct SurfaceClipBlockId {
239 union {
240 BitField<0, 4, u32> block_width;
241 BitField<4, 4, u32> block_height;
242 BitField<8, 4, u32> block_depth;
243 };
244 };
245
246 struct DecompressSurface {
247 union {
248 BitField<0, 3, u32> mrt_select;
249 BitField<4, 16, u32> rt_array_index;
250 };
251 };
252
253 struct ZCullRopBypass {
254 union {
255 BitField<0, 1, u32> enable;
256 BitField<4, 1, u32> no_stall;
257 BitField<8, 1, u32> cull_everything;
258 BitField<12, 4, u32> threshold;
259 };
260 };
261
262 struct ZCullSubregion {
263 union {
264 BitField<0, 1, u32> enable;
265 BitField<4, 24, u32> normalized_aliquots;
266 };
267 };
268
269 struct RasterBoundingBox {
270 enum class Mode : u32 {
271 BoundingBox = 0,
272 FullViewport = 1,
273 };
274
275 union {
276 BitField<0, 1, Mode> mode;
277 BitField<4, 8, u32> pad;
278 };
279 };
280
281 struct IteratedBlendOptimization {
282 enum class Noop : u32 {
283 Never = 0,
284 SourceRGBA0000 = 1,
285 SourceAlpha = 2,
286 SourceRGBA0001 = 3,
287 };
288
289 union {
290 BitField<0, 1, Noop> noop;
291 };
292 };
293
294 struct ZCullSubregionAllocation {
295 enum class Format : u32 {
296 Z_16x16x2_4x4 = 0,
297 ZS_16x16_4x4 = 1,
298 Z_16x16_4x2 = 2,
299 Z_16x16_2x4 = 3,
300 Z_16x8_4x4 = 4,
301 Z_8x8_4x2 = 5,
302 Z_8x8_2x4 = 6,
303 Z_16x16_4x8 = 7,
304 Z_4x8_2x2 = 8,
305 ZS_16x8_4x2 = 9,
306 ZS_16x8_2x4 = 10,
307 ZS_8x8_2x2 = 11,
308 Z_4x8_1x1 = 12,
309 None = 15,
310 };
311
312 union {
313 BitField<0, 8, u32> id;
314 BitField<8, 16, u32> aliquots;
315 BitField<24, 4, Format> format;
316 };
317 };
318
319 enum class ZCullSubregionAlgorithm : u32 {
320 Static = 0,
321 Adaptive = 1,
322 };
323
324 struct PixelShaderOutputSampleMaskUsage {
325 union {
326 BitField<0, 1, u32> enable;
327 BitField<1, 1, u32> qualify_by_aa;
328 };
329 };
330
331 struct L1Configuration {
332 enum class AddressableMemory : u32 {
333 Size16Kb = 0,
334 Size48Kb = 3,
335 };
336 union {
337 BitField<0, 3, AddressableMemory> direct_addressable_memory;
338 };
339 };
340
341 struct SPAVersion {
342 union {
343 BitField<0, 8, u32> minor;
344 BitField<8, 8, u32> major;
345 };
346 };
347
348 struct SnapGrid {
349 enum class Location : u32 {
350 Pixel2x2 = 1,
351 Pixel4x4 = 2,
352 Pixel8x8 = 3,
353 Pixel16x16 = 4,
354 Pixel32x32 = 5,
355 Pixel64x64 = 6,
356 Pixel128x128 = 7,
357 Pixel256x256 = 8,
358 };
359
360 enum class Mode : u32 {
361 RTNE = 0,
362 Tesla = 1,
363 };
364
365 struct {
366 union {
367 BitField<0, 4, Location> location;
368 BitField<8, 1, Mode> rounding_mode;
369 };
370 } line;
371
372 struct {
373 union {
374 BitField<0, 4, Location> location;
375 BitField<8, 1, Mode> rounding_mode;
376 };
377 } non_line;
378 };
379
380 struct Tessellation {
381 enum class DomainType : u32 {
382 Isolines = 0,
383 Triangles = 1,
384 Quads = 2,
385 };
386
387 enum class Spacing : u32 {
388 Integer = 0,
389 FractionalOdd = 1,
390 FractionalEven = 2,
391 };
392
393 enum class OutputPrimitves : u32 {
394 Points = 0,
395 Lines = 1,
396 Triangles_CW = 2,
397 Triangles_CCW = 3,
398 };
399
400 struct Parameters {
401 union {
402 BitField<0, 2, DomainType> domain_type;
403 BitField<4, 2, Spacing> spacing;
404 BitField<8, 2, OutputPrimitves> output_primitives;
405 };
406 } params;
407
408 struct LOD {
409 std::array<f32, 4> outer;
410 std::array<f32, 2> inner;
411 } lod;
412
413 std::array<u32, 9> reserved;
414 };
415
416 struct SubTilingPerf {
417 struct {
418 union {
419 BitField<0, 8, u32> spm_triangle_register_file_per;
420 BitField<8, 8, u32> spm_pixel_output_buffer_per;
421 BitField<16, 8, u32> spm_triangle_ram_per;
422 BitField<24, 8, u32> max_quads_per;
423 };
424 } knob_a;
425
426 struct {
427 union {
428 BitField<0, 8, u32> max_primitives_per;
429 };
430 } knob_b;
431
432 u32 knob_c;
433 };
434
435 struct ZCullSubregionReport {
436 enum class ReportType : u32 {
437 DepthTest = 0,
438 DepthTestNoAccept = 1,
439 DepthTestLateZ = 2,
440 StencilTest = 3,
441 };
442
443 union {
444 BitField<0, 1, u32> enabled;
445 BitField<4, 8, u32> subregion_id;
446 } to_report;
447
448 union {
449 BitField<0, 1, u32> enabled;
450 BitField<4, 3, ReportType> type;
451 } report_type;
452 };
453
454 struct BalancedPrimitiveWorkload {
455 union {
456 BitField<0, 1, u32> unpartitioned_mode;
457 BitField<4, 1, u32> timesliced_mode;
458 };
459 };
460
461 struct TransformFeedback {
462 struct Buffer {
463 u32 enable;
464 u32 address_high;
465 u32 address_low;
466 s32 size;
467 s32 start_offset;
468 INSERT_PADDING_BYTES_NOINIT(0xC);
469
470 GPUVAddr Address() const {
471 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
472 address_low);
473 }
474 };
475 static_assert(sizeof(Buffer) == 0x20);
476
477 struct Control {
478 u32 stream;
479 u32 varying_count;
480 u32 stride;
481 INSERT_PADDING_BYTES_NOINIT(0x4);
482 };
483 static_assert(sizeof(Control) == 0x10);
484
485 std::array<TransformFeedback::Buffer, NumTransformFeedbackBuffers> buffers;
486
487 INSERT_PADDING_BYTES_NOINIT(0x300);
488
489 std::array<TransformFeedback::Control, NumTransformFeedbackBuffers> controls;
490 };
491
492 struct HybridAntiAliasControl {
493 enum class Centroid : u32 {
494 PerFragment = 0,
495 PerPass = 1,
496 };
497 union {
498 BitField<0, 4, u32> passes;
499 BitField<4, 1, Centroid> centroid;
500 BitField<5, 1, u32> passes_extended;
501 };
502 };
503
504 struct ShaderLocalMemory {
505 u32 base_address;
506 INSERT_PADDING_BYTES_NOINIT(0x10);
507 u32 address_high;
508 u32 address_low;
509 u32 size_high;
510 u32 size_low;
511 u32 default_size_per_warp;
512
513 GPUVAddr Address() const {
514 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
515 address_low);
516 }
517
518 u64 Size() const {
519 return (static_cast<u64>(size_high) << 32) | size_low;
520 }
521 };
522
523 struct ZCullRegion {
524 u32 width;
525 u32 height;
526 u32 depth;
527 u32 offset;
528 INSERT_PADDING_BYTES_NOINIT(0xC);
529 u32 fetch_streams_once;
530 union {
531 BitField<0, 16, u32> start_aliquot;
532 BitField<16, 16, u32> aliquot_count;
533 } location;
534 u32 aliquots_per_layer;
535 u32 storage_address_high;
536 u32 storage_address_low;
537 u32 storage_limit_address_high;
538 u32 storage_limit_address_low;
539
540 GPUVAddr StorageAddress() const {
541 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(storage_address_high) << 32) |
542 storage_address_low);
543 }
544 GPUVAddr StorageLimitAddress() const {
545 return static_cast<GPUVAddr>(
546 (static_cast<GPUVAddr>(storage_limit_address_high) << 32) |
547 storage_limit_address_low);
548 }
549 };
550
551 struct ZetaReadOnly {
552 union {
553 BitField<0, 1, u32> enable_z;
554 BitField<4, 1, u32> enable_stencil;
555 };
133 }; 556 };
134 557
135 struct VertexAttribute { 558 struct VertexAttribute {
136 enum class Size : u32 { 559 enum class Size : u32 {
137 Invalid = 0x0, 560 Invalid = 0x0,
138 Size_32_32_32_32 = 0x01, 561 Size_R32_G32_B32_A32 = 0x01,
139 Size_32_32_32 = 0x02, 562 Size_R32_G32_B32 = 0x02,
140 Size_16_16_16_16 = 0x03, 563 Size_R16_G16_B16_A16 = 0x03,
141 Size_32_32 = 0x04, 564 Size_R32_G32 = 0x04,
142 Size_16_16_16 = 0x05, 565 Size_R16_G16_B16 = 0x05,
143 Size_8_8_8_8 = 0x0a, 566 Size_R8_G8_B8_A8 = 0x0A,
144 Size_16_16 = 0x0f, 567 Size_R16_G16 = 0x0F,
145 Size_32 = 0x12, 568 Size_R32 = 0x12,
146 Size_8_8_8 = 0x13, 569 Size_R8_G8_B8 = 0x13,
147 Size_8_8 = 0x18, 570 Size_R8_G8 = 0x18,
148 Size_16 = 0x1b, 571 Size_R16 = 0x1B,
149 Size_8 = 0x1d, 572 Size_R8 = 0x1D,
150 Size_10_10_10_2 = 0x30, 573 Size_A2_B10_G10_R10 = 0x30,
151 Size_11_11_10 = 0x31, 574 Size_B10_G11_R11 = 0x31,
575 Size_G8_R8 = 0x32,
576 Size_X8_B8_G8_R8 = 0x33,
577 Size_A8 = 0x34,
152 }; 578 };
153 579
154 enum class Type : u32 { 580 enum class Type : u32 {
155 SignedNorm = 1, 581 UnusedEnumDoNotUseBecauseItWillGoAway = 0,
156 UnsignedNorm = 2, 582 SNorm = 1,
157 SignedInt = 3, 583 UNorm = 2,
158 UnsignedInt = 4, 584 SInt = 3,
159 UnsignedScaled = 5, 585 UInt = 4,
160 SignedScaled = 6, 586 UScaled = 5,
587 SScaled = 6,
161 Float = 7, 588 Float = 7,
162 }; 589 };
163 590
@@ -173,33 +600,36 @@ public:
173 600
174 u32 ComponentCount() const { 601 u32 ComponentCount() const {
175 switch (size) { 602 switch (size) {
176 case Size::Size_32_32_32_32: 603 case Size::Size_R32_G32_B32_A32:
177 return 4; 604 return 4;
178 case Size::Size_32_32_32: 605 case Size::Size_R32_G32_B32:
179 return 3; 606 return 3;
180 case Size::Size_16_16_16_16: 607 case Size::Size_R16_G16_B16_A16:
181 return 4; 608 return 4;
182 case Size::Size_32_32: 609 case Size::Size_R32_G32:
183 return 2; 610 return 2;
184 case Size::Size_16_16_16: 611 case Size::Size_R16_G16_B16:
185 return 3; 612 return 3;
186 case Size::Size_8_8_8_8: 613 case Size::Size_R8_G8_B8_A8:
614 case Size::Size_X8_B8_G8_R8:
187 return 4; 615 return 4;
188 case Size::Size_16_16: 616 case Size::Size_R16_G16:
189 return 2; 617 return 2;
190 case Size::Size_32: 618 case Size::Size_R32:
191 return 1; 619 return 1;
192 case Size::Size_8_8_8: 620 case Size::Size_R8_G8_B8:
193 return 3; 621 return 3;
194 case Size::Size_8_8: 622 case Size::Size_R8_G8:
623 case Size::Size_G8_R8:
195 return 2; 624 return 2;
196 case Size::Size_16: 625 case Size::Size_R16:
197 return 1; 626 return 1;
198 case Size::Size_8: 627 case Size::Size_R8:
628 case Size::Size_A8:
199 return 1; 629 return 1;
200 case Size::Size_10_10_10_2: 630 case Size::Size_A2_B10_G10_R10:
201 return 4; 631 return 4;
202 case Size::Size_11_11_10: 632 case Size::Size_B10_G11_R11:
203 return 3; 633 return 3;
204 default: 634 default:
205 ASSERT(false); 635 ASSERT(false);
@@ -209,33 +639,36 @@ public:
209 639
210 u32 SizeInBytes() const { 640 u32 SizeInBytes() const {
211 switch (size) { 641 switch (size) {
212 case Size::Size_32_32_32_32: 642 case Size::Size_R32_G32_B32_A32:
213 return 16; 643 return 16;
214 case Size::Size_32_32_32: 644 case Size::Size_R32_G32_B32:
215 return 12; 645 return 12;
216 case Size::Size_16_16_16_16: 646 case Size::Size_R16_G16_B16_A16:
217 return 8; 647 return 8;
218 case Size::Size_32_32: 648 case Size::Size_R32_G32:
219 return 8; 649 return 8;
220 case Size::Size_16_16_16: 650 case Size::Size_R16_G16_B16:
221 return 6; 651 return 6;
222 case Size::Size_8_8_8_8: 652 case Size::Size_R8_G8_B8_A8:
653 case Size::Size_X8_B8_G8_R8:
223 return 4; 654 return 4;
224 case Size::Size_16_16: 655 case Size::Size_R16_G16:
225 return 4; 656 return 4;
226 case Size::Size_32: 657 case Size::Size_R32:
227 return 4; 658 return 4;
228 case Size::Size_8_8_8: 659 case Size::Size_R8_G8_B8:
229 return 3; 660 return 3;
230 case Size::Size_8_8: 661 case Size::Size_R8_G8:
662 case Size::Size_G8_R8:
231 return 2; 663 return 2;
232 case Size::Size_16: 664 case Size::Size_R16:
233 return 2; 665 return 2;
234 case Size::Size_8: 666 case Size::Size_R8:
667 case Size::Size_A8:
235 return 1; 668 return 1;
236 case Size::Size_10_10_10_2: 669 case Size::Size_A2_B10_G10_R10:
237 return 4; 670 return 4;
238 case Size::Size_11_11_10: 671 case Size::Size_B10_G11_R11:
239 return 4; 672 return 4;
240 default: 673 default:
241 ASSERT(false); 674 ASSERT(false);
@@ -245,34 +678,36 @@ public:
245 678
246 std::string SizeString() const { 679 std::string SizeString() const {
247 switch (size) { 680 switch (size) {
248 case Size::Size_32_32_32_32: 681 case Size::Size_R32_G32_B32_A32:
249 return "32_32_32_32"; 682 return "32_32_32_32";
250 case Size::Size_32_32_32: 683 case Size::Size_R32_G32_B32:
251 return "32_32_32"; 684 return "32_32_32";
252 case Size::Size_16_16_16_16: 685 case Size::Size_R16_G16_B16_A16:
253 return "16_16_16_16"; 686 return "16_16_16_16";
254 case Size::Size_32_32: 687 case Size::Size_R32_G32:
255 return "32_32"; 688 return "32_32";
256 case Size::Size_16_16_16: 689 case Size::Size_R16_G16_B16:
257 return "16_16_16"; 690 return "16_16_16";
258 case Size::Size_8_8_8_8: 691 case Size::Size_R8_G8_B8_A8:
259 return "8_8_8_8"; 692 return "8_8_8_8";
260 case Size::Size_16_16: 693 case Size::Size_R16_G16:
261 return "16_16"; 694 return "16_16";
262 case Size::Size_32: 695 case Size::Size_R32:
263 return "32"; 696 return "32";
264 case Size::Size_8_8_8: 697 case Size::Size_R8_G8_B8:
265 return "8_8_8"; 698 return "8_8_8";
266 case Size::Size_8_8: 699 case Size::Size_R8_G8:
700 case Size::Size_G8_R8:
267 return "8_8"; 701 return "8_8";
268 case Size::Size_16: 702 case Size::Size_R16:
269 return "16"; 703 return "16";
270 case Size::Size_8: 704 case Size::Size_R8:
705 case Size::Size_A8:
271 return "8"; 706 return "8";
272 case Size::Size_10_10_10_2: 707 case Size::Size_A2_B10_G10_R10:
273 return "10_10_10_2"; 708 return "2_10_10_10";
274 case Size::Size_11_11_10: 709 case Size::Size_B10_G11_R11:
275 return "11_11_10"; 710 return "10_11_12";
276 default: 711 default:
277 ASSERT(false); 712 ASSERT(false);
278 return {}; 713 return {};
@@ -281,17 +716,19 @@ public:
281 716
282 std::string TypeString() const { 717 std::string TypeString() const {
283 switch (type) { 718 switch (type) {
284 case Type::SignedNorm: 719 case Type::UnusedEnumDoNotUseBecauseItWillGoAway:
720 return "Unused";
721 case Type::SNorm:
285 return "SNORM"; 722 return "SNORM";
286 case Type::UnsignedNorm: 723 case Type::UNorm:
287 return "UNORM"; 724 return "UNORM";
288 case Type::SignedInt: 725 case Type::SInt:
289 return "SINT"; 726 return "SINT";
290 case Type::UnsignedInt: 727 case Type::UInt:
291 return "UINT"; 728 return "UINT";
292 case Type::UnsignedScaled: 729 case Type::UScaled:
293 return "USCALED"; 730 return "USCALED";
294 case Type::SignedScaled: 731 case Type::SScaled:
295 return "SSCALED"; 732 return "SSCALED";
296 case Type::Float: 733 case Type::Float:
297 return "FLOAT"; 734 return "FLOAT";
@@ -301,7 +738,7 @@ public:
301 } 738 }
302 739
303 bool IsNormalized() const { 740 bool IsNormalized() const {
304 return (type == Type::SignedNorm) || (type == Type::UnsignedNorm); 741 return (type == Type::SNorm) || (type == Type::UNorm);
305 } 742 }
306 743
307 bool IsValid() const { 744 bool IsValid() const {
@@ -312,6 +749,7 @@ public:
312 return hex < other.hex; 749 return hex < other.hex;
313 } 750 }
314 }; 751 };
752 static_assert(sizeof(VertexAttribute) == 0x4);
315 753
316 struct MsaaSampleLocation { 754 struct MsaaSampleLocation {
317 union { 755 union {
@@ -342,9 +780,96 @@ public:
342 } 780 }
343 }; 781 };
344 782
345 enum class DepthMode : u32 { 783 struct MultisampleCoverageToColor {
346 MinusOneToOne = 0, 784 union {
347 ZeroToOne = 1, 785 BitField<0, 1, u32> enable;
786 BitField<4, 3, u32> target;
787 };
788 };
789
790 struct DecompressZetaSurface {
791 union {
792 BitField<0, 1, u32> z_enable;
793 BitField<4, 1, u32> stencil_enable;
794 };
795 };
796
797 struct ZetaSparse {
798 enum class UnmappedCompare : u32 {
799 Unmapped = 0,
800 FailAlways = 1,
801 };
802 union {
803 BitField<0, 1, u32> enable;
804 BitField<1, 1, UnmappedCompare> unmapped_compare;
805 };
806 };
807
808 struct RtControl {
809 union {
810 BitField<0, 4, u32> count;
811 BitField<4, 3, u32> target0;
812 BitField<7, 3, u32> target1;
813 BitField<10, 3, u32> target2;
814 BitField<13, 3, u32> target3;
815 BitField<16, 3, u32> target4;
816 BitField<19, 3, u32> target5;
817 BitField<22, 3, u32> target6;
818 BitField<25, 3, u32> target7;
819 };
820
821 u32 Map(std::size_t index) const {
822 const std::array<u32, NumRenderTargets> maps{target0, target1, target2, target3,
823 target4, target5, target6, target7};
824 ASSERT(index < maps.size());
825 return maps[index];
826 }
827 };
828
829 struct CompressionThresholdSamples {
830 u32 samples;
831
832 u32 Samples() {
833 if (samples == 0) {
834 return 0;
835 }
836 return 1 << (samples - 1);
837 }
838 };
839
840 struct PixelShaderInterlockControl {
841 enum class TileMode : u32 {
842 NoConflictDetect = 0,
843 DetectSampleConflict = 1,
844 DetectPixelConflict = 2,
845 };
846 enum class TileSize : u32 {
847 Size_16x16 = 0,
848 Size_8x8 = 1,
849 };
850 enum class FragmentOrder : u32 {
851 FragmentOrdered = 0,
852 FragmentUnordered = 1,
853 };
854 union {
855 BitField<0, 2, TileMode> tile_mode;
856 BitField<2, 1, TileSize> tile_size;
857 BitField<3, 1, FragmentOrder> fragment_order;
858 };
859 };
860
861 struct ZetaSize {
862 enum class DimensionControl : u32 {
863 DepthDefinesArray = 0,
864 ArraySizeOne = 1,
865 };
866
867 u32 width;
868 u32 height;
869 union {
870 BitField<0, 16, u32> depth;
871 BitField<16, 1, DimensionControl> dim_control;
872 };
348 }; 873 };
349 874
350 enum class PrimitiveTopology : u32 { 875 enum class PrimitiveTopology : u32 {
@@ -358,15 +883,21 @@ public:
358 Quads = 0x7, 883 Quads = 0x7,
359 QuadStrip = 0x8, 884 QuadStrip = 0x8,
360 Polygon = 0x9, 885 Polygon = 0x9,
361 LinesAdjacency = 0xa, 886 LinesAdjacency = 0xA,
362 LineStripAdjacency = 0xb, 887 LineStripAdjacency = 0xB,
363 TrianglesAdjacency = 0xc, 888 TrianglesAdjacency = 0xC,
364 TriangleStripAdjacency = 0xd, 889 TriangleStripAdjacency = 0xD,
365 Patches = 0xe, 890 Patches = 0xE,
891 };
892
893 struct VertexArray {
894 union {
895 BitField<0, 16, u32> start;
896 BitField<16, 12, u32> count;
897 BitField<28, 3, PrimitiveTopology> topology;
898 };
366 }; 899 };
367 900
368 // Constants as from NVC0_3D_UNK1970_D3D
369 // https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/src/gallium/drivers/nouveau/nvc0/nvc0_3d.xml.h#L1598
370 enum class PrimitiveTopologyOverride : u32 { 901 enum class PrimitiveTopologyOverride : u32 {
371 None = 0x0, 902 None = 0x0,
372 Points = 0x1, 903 Points = 0x1,
@@ -374,11 +905,32 @@ public:
374 LineStrip = 0x3, 905 LineStrip = 0x3,
375 Triangles = 0x4, 906 Triangles = 0x4,
376 TriangleStrip = 0x5, 907 TriangleStrip = 0x5,
377 LinesAdjacency = 0xa, 908 LinesAdjacency = 0xA,
378 LineStripAdjacency = 0xb, 909 LineStripAdjacency = 0xB,
379 TrianglesAdjacency = 0xc, 910 TrianglesAdjacency = 0xC,
380 TriangleStripAdjacency = 0xd, 911 TriangleStripAdjacency = 0xD,
381 Patches = 0xe, 912 Patches = 0xE,
913
914 LegacyPoints = 0x1001,
915 LegacyIndexedLines = 0x1002,
916 LegacyIndexedTriangles = 0x1003,
917 LegacyLines = 0x100F,
918 LegacyLineStrip = 0x1010,
919 LegacyIndexedLineStrip = 0x1011,
920 LegacyTriangles = 0x1012,
921 LegacyTriangleStrip = 0x1013,
922 LegacyIndexedTriangleStrip = 0x1014,
923 LegacyTriangleFan = 0x1015,
924 LegacyIndexedTriangleFan = 0x1016,
925 LegacyTriangleFanImm = 0x1017,
926 LegacyLinesImm = 0x1018,
927 LegacyIndexedTriangles2 = 0x101A,
928 LegacyIndexedLines2 = 0x101B,
929 };
930
931 enum class DepthMode : u32 {
932 MinusOneToOne = 0,
933 ZeroToOne = 1,
382 }; 934 };
383 935
384 enum class IndexFormat : u32 { 936 enum class IndexFormat : u32 {
@@ -388,183 +940,143 @@ public:
388 }; 940 };
389 941
390 enum class ComparisonOp : u32 { 942 enum class ComparisonOp : u32 {
391 // These values are used by Nouveau and most games, they correspond to the OpenGL token 943 Never_D3D = 1,
392 // values for these operations. 944 Less_D3D = 2,
393 Never = 0x200, 945 Equal_D3D = 3,
394 Less = 0x201, 946 LessEqual_D3D = 4,
395 Equal = 0x202, 947 Greater_D3D = 5,
396 LessEqual = 0x203, 948 NotEqual_D3D = 6,
397 Greater = 0x204, 949 GreaterEqual_D3D = 7,
398 NotEqual = 0x205, 950 Always_D3D = 8,
399 GreaterEqual = 0x206, 951
400 Always = 0x207, 952 Never_GL = 0x200,
401 953 Less_GL = 0x201,
402 // These values are used by some games, they seem to be NV04 values. 954 Equal_GL = 0x202,
403 NeverOld = 1, 955 LessEqual_GL = 0x203,
404 LessOld = 2, 956 Greater_GL = 0x204,
405 EqualOld = 3, 957 NotEqual_GL = 0x205,
406 LessEqualOld = 4, 958 GreaterEqual_GL = 0x206,
407 GreaterOld = 5, 959 Always_GL = 0x207,
408 NotEqualOld = 6, 960 };
409 GreaterEqualOld = 7, 961
410 AlwaysOld = 8, 962 enum class ClearReport : u32 {
411 }; 963 ZPassPixelCount = 0x01,
412 964 ZCullStats = 0x02,
413 enum class LogicOperation : u32 { 965 StreamingPrimitvesNeededMinusSucceeded = 0x03,
414 Clear = 0x1500, 966 AlphaBetaClocks = 0x04,
415 And = 0x1501, 967 StreamingPrimitivesSucceeded = 0x10,
416 AndReverse = 0x1502, 968 StreamingPrimitivesNeeded = 0x11,
417 Copy = 0x1503, 969 VerticesGenerated = 0x12,
418 AndInverted = 0x1504, 970 PrimitivesGenerated = 0x13,
419 NoOp = 0x1505, 971 VertexShaderInvocations = 0x15,
420 Xor = 0x1506, 972 TessellationInitInvocations = 0x16,
421 Or = 0x1507, 973 TessellationShaderInvocations = 0x17,
422 Nor = 0x1508, 974 TessellationShaderPrimitivesGenerated = 0x18,
423 Equiv = 0x1509, 975 GeometryShaderInvocations = 0x1A,
424 Invert = 0x150A, 976 GeometryShaderPrimitivesGenerated = 0x1B,
425 OrReverse = 0x150B, 977 ClipperInvocations = 0x1C,
426 CopyInverted = 0x150C, 978 ClipperPrimitivesGenerated = 0x1D,
427 OrInverted = 0x150D, 979 PixelShaderInvocations = 0x1E,
428 Nand = 0x150E, 980 VtgPrimitivesOut = 0x1F,
429 Set = 0x150F,
430 };
431
432 enum class StencilOp : u32 {
433 Keep = 1,
434 Zero = 2,
435 Replace = 3,
436 Incr = 4,
437 Decr = 5,
438 Invert = 6,
439 IncrWrap = 7,
440 DecrWrap = 8,
441 KeepOGL = 0x1E00,
442 ZeroOGL = 0,
443 ReplaceOGL = 0x1E01,
444 IncrOGL = 0x1E02,
445 DecrOGL = 0x1E03,
446 InvertOGL = 0x150A,
447 IncrWrapOGL = 0x8507,
448 DecrWrapOGL = 0x8508,
449 };
450
451 enum class CounterReset : u32 {
452 SampleCnt = 0x01,
453 Unk02 = 0x02,
454 Unk03 = 0x03,
455 Unk04 = 0x04,
456 EmittedPrimitives = 0x10, // Not tested
457 Unk11 = 0x11,
458 Unk12 = 0x12,
459 Unk13 = 0x13,
460 Unk15 = 0x15,
461 Unk16 = 0x16,
462 Unk17 = 0x17,
463 Unk18 = 0x18,
464 Unk1A = 0x1A,
465 Unk1B = 0x1B,
466 Unk1C = 0x1C,
467 Unk1D = 0x1D,
468 Unk1E = 0x1E,
469 GeneratedPrimitives = 0x1F,
470 }; 981 };
471 982
472 enum class FrontFace : u32 { 983 enum class FrontFace : u32 {
473 ClockWise = 0x0900, 984 ClockWise = 0x900,
474 CounterClockWise = 0x0901, 985 CounterClockWise = 0x901,
475 }; 986 };
476 987
477 enum class CullFace : u32 { 988 enum class CullFace : u32 {
478 Front = 0x0404, 989 Front = 0x404,
479 Back = 0x0405, 990 Back = 0x405,
480 FrontAndBack = 0x0408, 991 FrontAndBack = 0x408,
481 }; 992 };
482 993
483 struct Blend { 994 struct Blend {
484 enum class Equation : u32 { 995 enum class Equation : u32 {
485 Add = 1, 996 Add_D3D = 1,
486 Subtract = 2, 997 Subtract_D3D = 2,
487 ReverseSubtract = 3, 998 ReverseSubtract_D3D = 3,
488 Min = 4, 999 Min_D3D = 4,
489 Max = 5, 1000 Max_D3D = 5,
490 1001
491 // These values are used by Nouveau and some games. 1002 Add_GL = 0x8006,
492 AddGL = 0x8006, 1003 Min_GL = 0x8007,
493 MinGL = 0x8007, 1004 Max_GL = 0x8008,
494 MaxGL = 0x8008, 1005 Subtract_GL = 0x800A,
495 SubtractGL = 0x800a, 1006 ReverseSubtract_GL = 0x800B
496 ReverseSubtractGL = 0x800b
497 }; 1007 };
498 1008
499 enum class Factor : u32 { 1009 enum class Factor : u32 {
500 Zero = 0x1, 1010 Zero_D3D = 0x1,
501 One = 0x2, 1011 One_D3D = 0x2,
502 SourceColor = 0x3, 1012 SourceColor_D3D = 0x3,
503 OneMinusSourceColor = 0x4, 1013 OneMinusSourceColor_D3D = 0x4,
504 SourceAlpha = 0x5, 1014 SourceAlpha_D3D = 0x5,
505 OneMinusSourceAlpha = 0x6, 1015 OneMinusSourceAlpha_D3D = 0x6,
506 DestAlpha = 0x7, 1016 DestAlpha_D3D = 0x7,
507 OneMinusDestAlpha = 0x8, 1017 OneMinusDestAlpha_D3D = 0x8,
508 DestColor = 0x9, 1018 DestColor_D3D = 0x9,
509 OneMinusDestColor = 0xa, 1019 OneMinusDestColor_D3D = 0xA,
510 SourceAlphaSaturate = 0xb, 1020 SourceAlphaSaturate_D3D = 0xB,
511 Source1Color = 0x10, 1021 BothSourceAlpha_D3D = 0xC,
512 OneMinusSource1Color = 0x11, 1022 OneMinusBothSourceAlpha_D3D = 0xD,
513 Source1Alpha = 0x12, 1023 BlendFactor_D3D = 0xE,
514 OneMinusSource1Alpha = 0x13, 1024 OneMinusBlendFactor_D3D = 0xF,
515 ConstantColor = 0x61, 1025 Source1Color_D3D = 0x10,
516 OneMinusConstantColor = 0x62, 1026 OneMinusSource1Color_D3D = 0x11,
517 ConstantAlpha = 0x63, 1027 Source1Alpha_D3D = 0x12,
518 OneMinusConstantAlpha = 0x64, 1028 OneMinusSource1Alpha_D3D = 0x13,
519 1029
520 // These values are used by Nouveau and some games. 1030 Zero_GL = 0x4000,
521 ZeroGL = 0x4000, 1031 One_GL = 0x4001,
522 OneGL = 0x4001, 1032 SourceColor_GL = 0x4300,
523 SourceColorGL = 0x4300, 1033 OneMinusSourceColor_GL = 0x4301,
524 OneMinusSourceColorGL = 0x4301, 1034 SourceAlpha_GL = 0x4302,
525 SourceAlphaGL = 0x4302, 1035 OneMinusSourceAlpha_GL = 0x4303,
526 OneMinusSourceAlphaGL = 0x4303, 1036 DestAlpha_GL = 0x4304,
527 DestAlphaGL = 0x4304, 1037 OneMinusDestAlpha_GL = 0x4305,
528 OneMinusDestAlphaGL = 0x4305, 1038 DestColor_GL = 0x4306,
529 DestColorGL = 0x4306, 1039 OneMinusDestColor_GL = 0x4307,
530 OneMinusDestColorGL = 0x4307, 1040 SourceAlphaSaturate_GL = 0x4308,
531 SourceAlphaSaturateGL = 0x4308, 1041 ConstantColor_GL = 0xC001,
532 ConstantColorGL = 0xc001, 1042 OneMinusConstantColor_GL = 0xC002,
533 OneMinusConstantColorGL = 0xc002, 1043 ConstantAlpha_GL = 0xC003,
534 ConstantAlphaGL = 0xc003, 1044 OneMinusConstantAlpha_GL = 0xC004,
535 OneMinusConstantAlphaGL = 0xc004, 1045 Source1Color_GL = 0xC900,
536 Source1ColorGL = 0xc900, 1046 OneMinusSource1Color_GL = 0xC901,
537 OneMinusSource1ColorGL = 0xc901, 1047 Source1Alpha_GL = 0xC902,
538 Source1AlphaGL = 0xc902, 1048 OneMinusSource1Alpha_GL = 0xC903,
539 OneMinusSource1AlphaGL = 0xc903,
540 }; 1049 };
541 1050
542 u32 separate_alpha; 1051 u32 separate_alpha;
543 Equation equation_rgb; 1052 Equation color_op;
544 Factor factor_source_rgb; 1053 Factor color_source;
545 Factor factor_dest_rgb; 1054 Factor color_dest;
546 Equation equation_a; 1055 Equation alpha_op;
547 Factor factor_source_a; 1056 Factor alpha_source;
548 Factor factor_dest_a; 1057 u32 enable_global_color_key;
549 INSERT_PADDING_WORDS_NOINIT(1); 1058 Factor alpha_dest;
550 }; 1059
551 1060 u32 single_rop_control_enable;
552 enum class TessellationPrimitive : u32 { 1061 u32 enable[NumRenderTargets];
553 Isolines = 0,
554 Triangles = 1,
555 Quads = 2,
556 }; 1062 };
557 1063
558 enum class TessellationSpacing : u32 { 1064 struct BlendPerTarget {
559 Equal = 0, 1065 u32 separate_alpha;
560 FractionalOdd = 1, 1066 Blend::Equation color_op;
561 FractionalEven = 2, 1067 Blend::Factor color_source;
1068 Blend::Factor color_dest;
1069 Blend::Equation alpha_op;
1070 Blend::Factor alpha_source;
1071 Blend::Factor alpha_dest;
1072 INSERT_PADDING_BYTES_NOINIT(0x4);
562 }; 1073 };
1074 static_assert(sizeof(BlendPerTarget) == 0x20);
563 1075
564 enum class PolygonMode : u32 { 1076 enum class PolygonMode : u32 {
565 Point = 0x1b00, 1077 Point = 0x1B00,
566 Line = 0x1b01, 1078 Line = 0x1B01,
567 Fill = 0x1b02, 1079 Fill = 0x1B02,
568 }; 1080 };
569 1081
570 enum class ShadowRamControl : u32 { 1082 enum class ShadowRamControl : u32 {
@@ -589,18 +1101,22 @@ public:
589 NegativeW = 7, 1101 NegativeW = 7,
590 }; 1102 };
591 1103
592 enum class SamplerIndex : u32 { 1104 enum class SamplerBinding : u32 {
593 Independently = 0, 1105 Independently = 0,
594 ViaHeaderIndex = 1, 1106 ViaHeaderBinding = 1,
595 }; 1107 };
596 1108
597 struct TileMode { 1109 struct TileMode {
1110 enum class DimensionControl : u32 {
1111 DepthDefinesArray = 0,
1112 DepthDefinesDepth = 1,
1113 };
598 union { 1114 union {
599 BitField<0, 4, u32> block_width; 1115 BitField<0, 4, u32> block_width;
600 BitField<4, 4, u32> block_height; 1116 BitField<4, 4, u32> block_height;
601 BitField<8, 4, u32> block_depth; 1117 BitField<8, 4, u32> block_depth;
602 BitField<12, 1, u32> is_pitch_linear; 1118 BitField<12, 1, u32> is_pitch_linear;
603 BitField<16, 1, u32> is_3d; 1119 BitField<16, 1, DimensionControl> dim_control;
604 }; 1120 };
605 }; 1121 };
606 static_assert(sizeof(TileMode) == 4); 1122 static_assert(sizeof(TileMode) == 4);
@@ -616,23 +1132,25 @@ public:
616 BitField<0, 16, u32> depth; 1132 BitField<0, 16, u32> depth;
617 BitField<16, 1, u32> volume; 1133 BitField<16, 1, u32> volume;
618 }; 1134 };
619 u32 layer_stride; 1135 u32 array_pitch;
620 u32 base_layer; 1136 u32 base_layer;
621 INSERT_PADDING_WORDS_NOINIT(7); 1137 u32 mark_ieee_clean;
1138 INSERT_PADDING_BYTES_NOINIT(0x18);
622 1139
623 GPUVAddr Address() const { 1140 GPUVAddr Address() const {
624 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | 1141 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
625 address_low); 1142 address_low);
626 } 1143 }
627 }; 1144 };
1145 static_assert(sizeof(RenderTargetConfig) == 0x40);
628 1146
629 struct ColorMask { 1147 struct ColorMask {
630 union { 1148 union {
631 u32 raw; 1149 u32 raw;
632 BitField<0, 4, u32> R; 1150 BitField<0, 1, u32> R;
633 BitField<4, 4, u32> G; 1151 BitField<4, 1, u32> G;
634 BitField<8, 4, u32> B; 1152 BitField<8, 1, u32> B;
635 BitField<12, 4, u32> A; 1153 BitField<12, 1, u32> A;
636 }; 1154 };
637 }; 1155 };
638 1156
@@ -643,6 +1161,7 @@ public:
643 f32 translate_x; 1161 f32 translate_x;
644 f32 translate_y; 1162 f32 translate_y;
645 f32 translate_z; 1163 f32 translate_z;
1164
646 union { 1165 union {
647 u32 raw; 1166 u32 raw;
648 BitField<0, 3, ViewportSwizzle> x; 1167 BitField<0, 3, ViewportSwizzle> x;
@@ -650,7 +1169,11 @@ public:
650 BitField<8, 3, ViewportSwizzle> z; 1169 BitField<8, 3, ViewportSwizzle> z;
651 BitField<12, 3, ViewportSwizzle> w; 1170 BitField<12, 3, ViewportSwizzle> w;
652 } swizzle; 1171 } swizzle;
653 INSERT_PADDING_WORDS_NOINIT(1); 1172
1173 union {
1174 BitField<0, 5, u32> x;
1175 BitField<8, 5, u32> y;
1176 } snap_grid_precision;
654 1177
655 Common::Rectangle<f32> GetRect() const { 1178 Common::Rectangle<f32> GetRect() const {
656 return { 1179 return {
@@ -677,21 +1200,14 @@ public:
677 return translate_y + std::fabs(scale_y) - GetY(); 1200 return translate_y + std::fabs(scale_y) - GetY();
678 } 1201 }
679 }; 1202 };
1203 static_assert(sizeof(ViewportTransform) == 0x20);
680 1204
681 struct ScissorTest { 1205 struct Viewport {
682 u32 enable; 1206 enum class PixelCenter : u32 {
683 union { 1207 HalfIntegers = 0,
684 BitField<0, 16, u32> min_x; 1208 Integers = 1,
685 BitField<16, 16, u32> max_x;
686 }; 1209 };
687 union {
688 BitField<0, 16, u32> min_y;
689 BitField<16, 16, u32> max_y;
690 };
691 u32 fill;
692 };
693 1210
694 struct ViewPort {
695 union { 1211 union {
696 BitField<0, 16, u32> x; 1212 BitField<0, 16, u32> x;
697 BitField<16, 16, u32> width; 1213 BitField<16, 16, u32> width;
@@ -703,726 +1219,1822 @@ public:
703 float depth_range_near; 1219 float depth_range_near;
704 float depth_range_far; 1220 float depth_range_far;
705 }; 1221 };
1222 static_assert(sizeof(Viewport) == 0x10);
706 1223
707 struct TransformFeedbackBinding { 1224 struct Window {
708 u32 buffer_enable; 1225 union {
709 u32 address_high; 1226 BitField<0, 16, u32> x_min;
710 u32 address_low; 1227 BitField<16, 16, u32> x_max;
711 s32 buffer_size; 1228 };
712 s32 buffer_offset; 1229 union {
713 INSERT_PADDING_WORDS_NOINIT(3); 1230 BitField<0, 16, u32> y_min;
714 1231 BitField<16, 16, u32> y_max;
715 GPUVAddr Address() const { 1232 };
716 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
717 address_low);
718 }
719 }; 1233 };
720 static_assert(sizeof(TransformFeedbackBinding) == 32); 1234 static_assert(sizeof(Window) == 0x8);
721 1235
722 struct TransformFeedbackLayout { 1236 struct ClipIdExtent {
723 u32 stream; 1237 union {
724 u32 varying_count; 1238 BitField<0, 16, u32> x;
725 u32 stride; 1239 BitField<16, 16, u32> width;
726 INSERT_PADDING_WORDS_NOINIT(1); 1240 };
1241 union {
1242 BitField<0, 16, u32> y;
1243 BitField<16, 16, u32> height;
1244 };
1245 };
1246 static_assert(sizeof(ClipIdExtent) == 0x8);
1247
1248 enum class VisibleCallLimit : u32 {
1249 Limit0 = 0,
1250 Limit1 = 1,
1251 Limit2 = 2,
1252 Limit4 = 3,
1253 Limit8 = 4,
1254 Limit16 = 5,
1255 Limit32 = 6,
1256 Limit64 = 7,
1257 Limit128 = 8,
1258 None = 15,
727 }; 1259 };
728 static_assert(sizeof(TransformFeedbackLayout) == 16);
729
730 bool IsShaderConfigEnabled(std::size_t index) const {
731 // The VertexB is always enabled.
732 if (index == static_cast<std::size_t>(Regs::ShaderProgram::VertexB)) {
733 return true;
734 }
735 return shader_config[index].enable != 0;
736 }
737
738 bool IsShaderConfigEnabled(Regs::ShaderProgram type) const {
739 return IsShaderConfigEnabled(static_cast<std::size_t>(type));
740 }
741 1260
742 union { 1261 struct StatisticsCounter {
743 struct { 1262 union {
744 INSERT_PADDING_WORDS_NOINIT(0x44); 1263 BitField<0, 1, u32> da_vertices;
1264 BitField<1, 1, u32> da_primitives;
1265 BitField<2, 1, u32> vs_invocations;
1266 BitField<3, 1, u32> gs_invocations;
1267 BitField<4, 1, u32> gs_primitives;
1268 BitField<5, 1, u32> streaming_primitives_succeeded;
1269 BitField<6, 1, u32> streaming_primitives_needed;
1270 BitField<7, 1, u32> clipper_invocations;
1271 BitField<8, 1, u32> clipper_primitives;
1272 BitField<9, 1, u32> ps_invocations;
1273 BitField<11, 1, u32> ti_invocations;
1274 BitField<12, 1, u32> ts_invocations;
1275 BitField<13, 1, u32> ts_primitives;
1276 BitField<14, 1, u32> total_streaming_primitives_needed_succeeded;
1277 BitField<10, 1, u32> vtg_primitives_out;
1278 BitField<15, 1, u32> alpha_beta_clocks;
1279 };
1280 };
745 1281
746 u32 wait_for_idle; 1282 struct ClearRect {
1283 union {
1284 BitField<0, 16, u32> x_min;
1285 BitField<16, 16, u32> x_max;
1286 };
1287 union {
1288 BitField<0, 16, u32> y_min;
1289 BitField<16, 16, u32> y_max;
1290 };
1291 };
747 1292
748 struct { 1293 struct VertexBuffer {
749 u32 upload_address; 1294 u32 first;
750 u32 data; 1295 u32 count;
751 u32 entry; 1296 };
752 u32 bind;
753 } macros;
754 1297
755 ShadowRamControl shadow_ram_control; 1298 struct InvalidateShaderCacheNoWFI {
1299 union {
1300 BitField<0, 1, u32> instruction;
1301 BitField<4, 1, u32> global_data;
1302 BitField<12, 1, u32> constant;
1303 };
1304 };
756 1305
757 INSERT_PADDING_WORDS_NOINIT(0x16); 1306 struct ZCullSerialization {
1307 enum class Applied : u32 {
1308 Always = 0,
1309 LateZ = 1,
1310 OutOfGamutZ = 2,
1311 LateZOrOutOfGamutZ = 3,
1312 };
1313 union {
1314 BitField<0, 1, u32> enable;
1315 BitField<4, 2, Applied> applied;
1316 };
1317 };
758 1318
759 Upload::Registers upload; 1319 struct ZCullDirFormat {
760 struct { 1320 enum class Zdir : u32 {
761 union { 1321 Less = 0,
762 BitField<0, 1, u32> linear; 1322 Greater = 1,
763 }; 1323 };
764 } exec_upload; 1324 enum class Zformat : u32 {
1325 MSB = 0,
1326 FP = 1,
1327 Ztrick = 2,
1328 Zf32 = 3,
1329 };
765 1330
766 u32 data_upload; 1331 union {
1332 BitField<0, 16, Zdir> dir;
1333 BitField<16, 16, Zformat> format;
1334 };
1335 };
767 1336
768 INSERT_PADDING_WORDS_NOINIT(0x16); 1337 struct IteratedBlend {
1338 union {
1339 BitField<0, 1, u32> enable;
1340 BitField<1, 1, u32> enable_alpha;
1341 };
1342 u32 pass_count;
1343 };
769 1344
770 u32 force_early_fragment_tests; 1345 struct ZCullCriterion {
1346 enum class Sfunc : u32 {
1347 Never = 0,
1348 Less = 1,
1349 Equal = 2,
1350 LessOrEqual = 3,
1351 Greater = 4,
1352 NotEqual = 5,
1353 GreaterOrEqual = 6,
1354 Always = 7,
1355 };
771 1356
772 INSERT_PADDING_WORDS_NOINIT(0x2D); 1357 union {
1358 BitField<0, 8, Sfunc> sfunc;
1359 BitField<8, 1, u32> no_invalidate;
1360 BitField<9, 1, u32> force_match;
1361 BitField<16, 8, u32> sref;
1362 BitField<24, 8, u32> smask;
1363 };
1364 };
773 1365
774 struct { 1366 struct LoadIteratedBlend {
775 union { 1367 enum class Test : u32 {
776 BitField<0, 16, u32> sync_point; 1368 False = 0,
777 BitField<16, 1, u32> unknown; 1369 True = 1,
778 BitField<20, 1, u32> increment; 1370 Equal = 2,
779 }; 1371 NotEqual = 3,
780 } sync_info; 1372 LessThan = 4,
1373 LessOrEqual = 5,
1374 Greater = 6,
1375 GreaterOrEqual = 7,
1376 };
1377 enum class Operation : u32 {
1378 AddProducts = 0,
1379 SubProducts = 1,
1380 Min = 2,
1381 Max = 3,
1382 Reciprocal = 4,
1383 Add = 5,
1384 Sub = 6,
1385 };
1386 enum class OperandA : u32 {
1387 SrcRGB = 0,
1388 DstRGB = 1,
1389 SrcAAA = 2,
1390 DstAAA = 3,
1391 Temp0_RGB = 4,
1392 Temp1_RGB = 5,
1393 Temp2_RGB = 6,
1394 PBR_RGB = 7,
1395 };
1396 enum class OperandB : u32 {
1397 Zero = 0,
1398 One = 1,
1399 SrcRGB = 2,
1400 SrcAAA = 3,
1401 OneMinusSrcAAA = 4,
1402 DstRGB = 5,
1403 DstAAA = 6,
1404 OneMinusDstAAA = 7,
1405 Temp0_RGB = 9,
1406 Temp1_RGB = 10,
1407 Temp2_RGB = 11,
1408 PBR_RGB = 12,
1409 ConstRGB = 13,
1410 ZeroATimesB = 14,
1411 };
1412 enum class Swizzle : u32 {
1413 RGB = 0,
1414 GBR = 1,
1415 RRR = 2,
1416 GGG = 3,
1417 BBB = 4,
1418 RToA = 5,
1419 };
1420 enum class WriteMask : u32 {
1421 RGB = 0,
1422 ROnly = 1,
1423 GOnly = 2,
1424 BOnly = 3,
1425 };
1426 enum class Pass : u32 {
1427 Temp0 = 0,
1428 Temp1 = 1,
1429 Temp2 = 2,
1430 None = 3,
1431 };
781 1432
782 INSERT_PADDING_WORDS_NOINIT(0x15); 1433 u32 instruction_ptr;
1434 union {
1435 BitField<0, 3, Test> test;
1436 BitField<3, 3, Operation> operation;
1437 BitField<6, 3, u32> const_input;
1438 BitField<9, 3, OperandA> operand_a;
1439 BitField<12, 4, OperandB> operand_b;
1440 BitField<16, 3, OperandA> operand_c;
1441 BitField<19, 4, OperandB> operand_d;
1442 BitField<23, 3, Swizzle> output_swizzle;
1443 BitField<26, 2, WriteMask> output_mask;
1444 BitField<28, 2, Pass> output_pass;
1445 BitField<31, 1, u32> test_enabled;
1446 };
1447 };
783 1448
784 union { 1449 struct ScissorTest {
785 BitField<0, 2, TessellationPrimitive> prim; 1450 u32 enable;
786 BitField<4, 2, TessellationSpacing> spacing; 1451 union {
787 BitField<8, 1, u32> cw; 1452 BitField<0, 16, u32> min_x;
788 BitField<9, 1, u32> connected; 1453 BitField<16, 16, u32> max_x;
789 } tess_mode; 1454 };
1455 union {
1456 BitField<0, 16, u32> min_y;
1457 BitField<16, 16, u32> max_y;
1458 };
1459 INSERT_PADDING_BYTES_NOINIT(0x4);
1460 };
1461 static_assert(sizeof(ScissorTest) == 0x10);
790 1462
791 std::array<f32, 4> tess_level_outer; 1463 struct VPCPerf {
792 std::array<f32, 2> tess_level_inner; 1464 union {
1465 BitField<0, 8, u32> culled_small_lines;
1466 BitField<8, 8, u32> culled_small_triangles;
1467 BitField<16, 8, u32> nonculled_lines_and_points;
1468 BitField<24, 8, u32> nonculled_triangles;
1469 };
1470 };
793 1471
794 INSERT_PADDING_WORDS_NOINIT(0x10); 1472 struct ConstantColorRendering {
1473 u32 enabled;
1474 u32 red;
1475 u32 green;
1476 u32 blue;
1477 u32 alpha;
1478 };
795 1479
796 u32 rasterize_enable; 1480 struct VertexStreamSubstitute {
1481 u32 address_high;
1482 u32 address_low;
797 1483
798 std::array<TransformFeedbackBinding, NumTransformFeedbackBuffers> tfb_bindings; 1484 GPUVAddr Address() const {
1485 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
1486 address_low);
1487 }
1488 };
799 1489
800 INSERT_PADDING_WORDS_NOINIT(0xC0); 1490 struct VTGWarpWatermarks {
1491 union {
1492 BitField<0, 16, u32> low;
1493 BitField<16, 16, u32> high;
1494 };
1495 };
801 1496
802 std::array<TransformFeedbackLayout, NumTransformFeedbackBuffers> tfb_layouts; 1497 struct SampleMask {
1498 struct Target {
1499 union {
1500 BitField<0, 1, u32> raster_out;
1501 BitField<4, 1, u32> color_target;
1502 };
1503 u32 target;
1504 };
1505 struct Pos {
1506 u32 x0_y0;
1507 u32 x1_y0;
1508 u32 x0_y1;
1509 u32 x1_y1;
1510 };
1511 };
803 1512
804 INSERT_PADDING_WORDS_NOINIT(0x1); 1513 enum class NonMultisampledZ : u32 {
1514 PerSample = 0,
1515 PixelCenter = 1,
1516 };
805 1517
806 u32 tfb_enabled; 1518 enum class TIRMode : u32 {
1519 Disabled = 0,
1520 RasterNTargetM = 1,
1521 };
807 1522
808 INSERT_PADDING_WORDS_NOINIT(0x2E); 1523 enum class AntiAliasRaster : u32 {
1524 Mode1x1 = 0,
1525 Mode2x2 = 2,
1526 Mode4x2_D3D = 4,
1527 Mode2x1_D3D = 5,
1528 Mode4x4 = 6,
1529 };
809 1530
810 std::array<RenderTargetConfig, NumRenderTargets> rt; 1531 struct SurfaceClipIDMemory {
1532 u32 address_high;
1533 u32 address_low;
811 1534
812 std::array<ViewportTransform, NumViewports> viewport_transform; 1535 GPUVAddr Address() const {
1536 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
1537 address_low);
1538 }
1539 };
813 1540
814 std::array<ViewPort, NumViewports> viewports; 1541 struct TIRModulation {
1542 enum class Component : u32 {
1543 None = 0,
1544 RGB = 1,
1545 AlphaOnly = 2,
1546 RGBA = 3,
1547 };
1548 enum class Function : u32 {
1549 Linear = 0,
1550 Table = 1,
1551 };
1552 Component component;
1553 Function function;
1554 };
815 1555
816 INSERT_PADDING_WORDS_NOINIT(0x1D); 1556 struct Zeta {
1557 u32 address_high;
1558 u32 address_low;
1559 Tegra::DepthFormat format;
1560 TileMode tile_mode;
1561 u32 array_pitch;
817 1562
818 struct { 1563 GPUVAddr Address() const {
819 u32 first; 1564 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
820 u32 count; 1565 address_low);
821 } vertex_buffer; 1566 }
1567 };
822 1568
823 DepthMode depth_mode; 1569 struct SurfaceClip {
1570 union {
1571 BitField<0, 16, u32> x;
1572 BitField<16, 16, u32> width;
1573 };
1574 union {
1575 BitField<0, 16, u32> y;
1576 BitField<16, 16, u32> height;
1577 };
1578 };
824 1579
825 float clear_color[4]; 1580 enum class L2CacheControlPolicy : u32 {
826 float clear_depth; 1581 First = 0,
1582 Normal = 1,
1583 Last = 2,
1584 };
827 1585
828 INSERT_PADDING_WORDS_NOINIT(0x3); 1586 struct L2CacheVAFRequests {
1587 union {
1588 BitField<0, 1, u32> system_memory_volatile;
1589 BitField<4, 2, L2CacheControlPolicy> policy;
1590 };
1591 };
829 1592
830 s32 clear_stencil; 1593 enum class ViewportMulticast : u32 {
1594 ViewportOrder = 0,
1595 PrimitiveOrder = 1,
1596 };
831 1597
832 INSERT_PADDING_WORDS_NOINIT(0x2); 1598 struct TIRModulationCoeff {
1599 union {
1600 BitField<0, 8, u32> table_v0;
1601 BitField<8, 8, u32> table_v1;
1602 BitField<16, 8, u32> table_v2;
1603 BitField<24, 8, u32> table_v3;
1604 };
1605 };
1606 static_assert(sizeof(TIRModulationCoeff) == 0x4);
833 1607
834 PolygonMode polygon_mode_front; 1608 struct ReduceColorThreshold {
835 PolygonMode polygon_mode_back; 1609 union {
1610 BitField<0, 8, u32> all_hit_once;
1611 BitField<16, 8, u32> all_covered;
1612 };
1613 };
836 1614
837 INSERT_PADDING_WORDS_NOINIT(0x3); 1615 struct ClearControl {
1616 union {
1617 BitField<0, 1, u32> respect_stencil_mask;
1618 BitField<4, 1, u32> use_clear_rect;
1619 BitField<8, 1, u32> use_scissor;
1620 BitField<12, 1, u32> use_viewport_clip0;
1621 };
1622 };
838 1623
839 u32 polygon_offset_point_enable; 1624 struct L2CacheRopNonInterlockedReads {
840 u32 polygon_offset_line_enable; 1625 union {
841 u32 polygon_offset_fill_enable; 1626 BitField<4, 2, L2CacheControlPolicy> policy;
1627 };
1628 };
842 1629
843 u32 patch_vertices; 1630 struct VertexOutputAttributeSkipMasks {
1631 struct Attributes {
1632 union {
1633 BitField<0, 1, u32> attribute0_comp0;
1634 BitField<1, 1, u32> attribute0_comp1;
1635 BitField<2, 1, u32> attribute0_comp2;
1636 BitField<3, 1, u32> attribute0_comp3;
1637 BitField<4, 1, u32> attribute1_comp0;
1638 BitField<5, 1, u32> attribute1_comp1;
1639 BitField<6, 1, u32> attribute1_comp2;
1640 BitField<7, 1, u32> attribute1_comp3;
1641 BitField<8, 1, u32> attribute2_comp0;
1642 BitField<9, 1, u32> attribute2_comp1;
1643 BitField<10, 1, u32> attribute2_comp2;
1644 BitField<11, 1, u32> attribute2_comp3;
1645 BitField<12, 1, u32> attribute3_comp0;
1646 BitField<13, 1, u32> attribute3_comp1;
1647 BitField<14, 1, u32> attribute3_comp2;
1648 BitField<15, 1, u32> attribute3_comp3;
1649 BitField<16, 1, u32> attribute4_comp0;
1650 BitField<17, 1, u32> attribute4_comp1;
1651 BitField<18, 1, u32> attribute4_comp2;
1652 BitField<19, 1, u32> attribute4_comp3;
1653 BitField<20, 1, u32> attribute5_comp0;
1654 BitField<21, 1, u32> attribute5_comp1;
1655 BitField<22, 1, u32> attribute5_comp2;
1656 BitField<23, 1, u32> attribute5_comp3;
1657 BitField<24, 1, u32> attribute6_comp0;
1658 BitField<25, 1, u32> attribute6_comp1;
1659 BitField<26, 1, u32> attribute6_comp2;
1660 BitField<27, 1, u32> attribute6_comp3;
1661 BitField<28, 1, u32> attribute7_comp0;
1662 BitField<29, 1, u32> attribute7_comp1;
1663 BitField<30, 1, u32> attribute7_comp2;
1664 BitField<31, 1, u32> attribute7_comp3;
1665 };
1666 };
844 1667
845 INSERT_PADDING_WORDS_NOINIT(0x4); 1668 std::array<Attributes, 2> a;
1669 std::array<Attributes, 2> b;
1670 };
846 1671
847 u32 fragment_barrier; 1672 struct TIRControl {
1673 union {
1674 BitField<0, 1, u32> z_pass_pixel_count_use_raster_samples;
1675 BitField<4, 1, u32> alpha_coverage_use_raster_samples;
1676 BitField<1, 1, u32> reduce_coverage;
1677 };
1678 };
848 1679
849 INSERT_PADDING_WORDS_NOINIT(0x7); 1680 enum class FillViaTriangleMode : u32 {
1681 Disabled = 0,
1682 FillAll = 1,
1683 FillBoundingBox = 2,
1684 };
850 1685
851 std::array<ScissorTest, NumViewports> scissor_test; 1686 struct PsTicketDispenserValue {
1687 union {
1688 BitField<0, 8, u32> index;
1689 BitField<8, 16, u32> value;
1690 };
1691 };
852 1692
853 INSERT_PADDING_WORDS_NOINIT(0x15); 1693 struct RegisterWatermarks {
1694 union {
1695 BitField<0, 16, u32> low;
1696 BitField<16, 16, u32> high;
1697 };
1698 };
854 1699
855 s32 stencil_back_func_ref; 1700 enum class InvalidateCacheLines : u32 {
856 u32 stencil_back_mask; 1701 All = 0,
857 u32 stencil_back_func_mask; 1702 One = 1,
1703 };
858 1704
859 INSERT_PADDING_WORDS_NOINIT(0x5); 1705 struct InvalidateTextureDataCacheNoWfi {
1706 union {
1707 BitField<0, 1, InvalidateCacheLines> lines;
1708 BitField<4, 22, u32> tag;
1709 };
1710 };
860 1711
861 u32 invalidate_texture_data_cache; 1712 struct ZCullRegionEnable {
1713 union {
1714 BitField<0, 1, u32> enable_z;
1715 BitField<4, 1, u32> enable_stencil;
1716 BitField<1, 1, u32> rect_clear;
1717 BitField<2, 1, u32> use_rt_array_index;
1718 BitField<5, 16, u32> rt_array_index;
1719 BitField<3, 1, u32> make_conservative;
1720 };
1721 };
862 1722
863 INSERT_PADDING_WORDS_NOINIT(0x1); 1723 enum class FillMode : u32 {
1724 Point = 1,
1725 Wireframe = 2,
1726 Solid = 3,
1727 };
864 1728
865 u32 tiled_cache_barrier; 1729 enum class ShadeMode : u32 {
1730 Flat = 0x1,
1731 Gouraud = 0x2,
1732 GL_Flat = 0x1D00,
1733 GL_Smooth = 0x1D01,
1734 };
866 1735
867 INSERT_PADDING_WORDS_NOINIT(0x4); 1736 enum class AlphaToCoverageDither : u32 {
1737 Footprint_1x1 = 0,
1738 Footprint_2x2 = 1,
1739 Footprint_1x1_Virtual = 2,
1740 };
868 1741
869 u32 color_mask_common; 1742 struct InlineIndex4x8Align {
1743 union {
1744 BitField<0, 30, u32> count;
1745 BitField<30, 2, u32> start;
1746 };
1747 };
870 1748
871 INSERT_PADDING_WORDS_NOINIT(0x2); 1749 struct InlineIndex4x8Index {
1750 union {
1751 BitField<0, 8, u32> index0;
1752 BitField<8, 8, u32> index1;
1753 BitField<16, 8, u32> index2;
1754 BitField<24, 8, u32> index3;
1755 };
1756 };
872 1757
873 f32 depth_bounds[2]; 1758 enum class D3DCullMode : u32 {
1759 None = 0,
1760 CW = 1,
1761 CCW = 2,
1762 };
874 1763
875 INSERT_PADDING_WORDS_NOINIT(0x2); 1764 struct BlendColor {
1765 f32 r;
1766 f32 g;
1767 f32 b;
1768 f32 a;
1769 };
876 1770
877 u32 rt_separate_frag_data; 1771 struct StencilOp {
1772 enum class Op : u32 {
1773 Keep_D3D = 1,
1774 Zero_D3D = 2,
1775 Replace_D3D = 3,
1776 IncrSaturate_D3D = 4,
1777 DecrSaturate_D3D = 5,
1778 Invert_D3D = 6,
1779 Incr_D3D = 7,
1780 Decr_D3D = 8,
1781
1782 Keep_GL = 0x1E00,
1783 Zero_GL = 0,
1784 Replace_GL = 0x1E01,
1785 IncrSaturate_GL = 0x1E02,
1786 DecrSaturate_GL = 0x1E03,
1787 Invert_GL = 0x150A,
1788 Incr_GL = 0x8507,
1789 Decr_GL = 0x8508,
1790 };
878 1791
879 INSERT_PADDING_WORDS_NOINIT(0x1); 1792 Op fail;
1793 Op zfail;
1794 Op zpass;
1795 ComparisonOp func;
1796 };
880 1797
881 u32 multisample_raster_enable; 1798 struct StencilFunc {
882 u32 multisample_raster_samples; 1799 s32 ref;
883 std::array<u32, 4> multisample_sample_mask; 1800 u32 func_mask;
1801 u32 mask;
1802 };
884 1803
885 INSERT_PADDING_WORDS_NOINIT(0x5); 1804 struct PsSaturate {
1805 // Opposite of DepthMode
1806 enum class Depth : u32 {
1807 ZeroToOne = 0,
1808 MinusOneToOne = 1,
1809 };
886 1810
887 struct { 1811 union {
888 u32 address_high; 1812 BitField<0, 1, u32> output0_enable;
889 u32 address_low; 1813 BitField<1, 1, Depth> output0_range;
890 Tegra::DepthFormat format; 1814 BitField<4, 1, u32> output1_enable;
891 TileMode tile_mode; 1815 BitField<5, 1, Depth> output1_range;
892 u32 layer_stride; 1816 BitField<8, 1, u32> output2_enable;
1817 BitField<9, 1, Depth> output2_range;
1818 BitField<12, 1, u32> output3_enable;
1819 BitField<13, 1, Depth> output3_range;
1820 BitField<16, 1, u32> output4_enable;
1821 BitField<17, 1, Depth> output4_range;
1822 BitField<20, 1, u32> output5_enable;
1823 BitField<21, 1, Depth> output5_range;
1824 BitField<24, 1, u32> output6_enable;
1825 BitField<25, 1, Depth> output6_range;
1826 BitField<28, 1, u32> output7_enable;
1827 BitField<29, 1, Depth> output7_range;
1828 };
893 1829
894 GPUVAddr Address() const { 1830 bool AnyEnabled() const {
895 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | 1831 return output0_enable || output1_enable || output2_enable || output3_enable ||
896 address_low); 1832 output4_enable || output5_enable || output6_enable || output7_enable;
897 } 1833 }
898 } zeta; 1834 };
899 1835
900 struct { 1836 struct WindowOrigin {
901 union { 1837 enum class Mode : u32 {
902 BitField<0, 16, u32> x; 1838 UpperLeft = 0,
903 BitField<16, 16, u32> width; 1839 LowerLeft = 1,
904 }; 1840 };
905 union { 1841 union {
906 BitField<0, 16, u32> y; 1842 BitField<0, 1, Mode> mode;
907 BitField<16, 16, u32> height; 1843 BitField<4, 1, u32> flip_y;
908 }; 1844 };
909 } render_area; 1845 };
910 1846
911 INSERT_PADDING_WORDS_NOINIT(0x3F); 1847 struct IteratedBlendConstants {
1848 u32 r;
1849 u32 g;
1850 u32 b;
1851 INSERT_PADDING_BYTES_NOINIT(0x4);
1852 };
1853 static_assert(sizeof(IteratedBlendConstants) == 0x10);
912 1854
1855 struct UserClip {
1856 struct Enable {
913 union { 1857 union {
914 BitField<0, 4, u32> stencil; 1858 u32 raw;
915 BitField<4, 4, u32> unknown; 1859 BitField<0, 1, u32> plane0;
916 BitField<8, 4, u32> scissor; 1860 BitField<1, 1, u32> plane1;
917 BitField<12, 4, u32> viewport; 1861 BitField<2, 1, u32> plane2;
918 } clear_flags; 1862 BitField<3, 1, u32> plane3;
919 1863 BitField<4, 1, u32> plane4;
920 INSERT_PADDING_WORDS_NOINIT(0x10); 1864 BitField<5, 1, u32> plane5;
921 1865 BitField<6, 1, u32> plane6;
922 u32 fill_rectangle; 1866 BitField<7, 1, u32> plane7;
923 1867 };
924 INSERT_PADDING_WORDS_NOINIT(0x2);
925
926 u32 conservative_raster_enable;
927
928 INSERT_PADDING_WORDS_NOINIT(0x5);
929
930 std::array<VertexAttribute, NumVertexAttributes> vertex_attrib_format;
931 1868
932 std::array<MsaaSampleLocation, 4> multisample_sample_locations; 1869 bool AnyEnabled() const {
1870 return plane0 || plane1 || plane2 || plane3 || plane4 || plane5 || plane6 ||
1871 plane7;
1872 }
1873 };
933 1874
934 INSERT_PADDING_WORDS_NOINIT(0x2); 1875 struct Op {
1876 enum class ClipOrCull : u32 {
1877 Clip = 0,
1878 Cull = 1,
1879 };
935 1880
936 union { 1881 union {
937 BitField<0, 1, u32> enable; 1882 u32 raw;
938 BitField<4, 3, u32> target; 1883 BitField<0, 1, ClipOrCull> plane0;
939 } multisample_coverage_to_color; 1884 BitField<4, 1, ClipOrCull> plane1;
940 1885 BitField<8, 1, ClipOrCull> plane2;
941 INSERT_PADDING_WORDS_NOINIT(0x8); 1886 BitField<12, 1, ClipOrCull> plane3;
942 1887 BitField<16, 1, ClipOrCull> plane4;
943 struct { 1888 BitField<20, 1, ClipOrCull> plane5;
944 union { 1889 BitField<24, 1, ClipOrCull> plane6;
945 BitField<0, 4, u32> count; 1890 BitField<28, 1, ClipOrCull> plane7;
946 BitField<4, 3, u32> map_0;
947 BitField<7, 3, u32> map_1;
948 BitField<10, 3, u32> map_2;
949 BitField<13, 3, u32> map_3;
950 BitField<16, 3, u32> map_4;
951 BitField<19, 3, u32> map_5;
952 BitField<22, 3, u32> map_6;
953 BitField<25, 3, u32> map_7;
954 };
955
956 u32 Map(std::size_t index) const {
957 const std::array<u32, NumRenderTargets> maps{map_0, map_1, map_2, map_3,
958 map_4, map_5, map_6, map_7};
959 ASSERT(index < maps.size());
960 return maps[index];
961 }
962 } rt_control;
963
964 INSERT_PADDING_WORDS_NOINIT(0x2);
965
966 u32 zeta_width;
967 u32 zeta_height;
968 union {
969 BitField<0, 16, u32> zeta_depth;
970 BitField<16, 1, u32> zeta_volume;
971 }; 1891 };
1892 };
1893 };
972 1894
973 SamplerIndex sampler_index; 1895 struct AntiAliasAlphaControl {
1896 union {
1897 BitField<0, 1, u32> alpha_to_coverage;
1898 BitField<4, 1, u32> alpha_to_one;
1899 };
1900 };
974 1901
975 INSERT_PADDING_WORDS_NOINIT(0x2); 1902 struct RenderEnable {
1903 enum class Override : u32 {
1904 UseRenderEnable = 0,
1905 AlwaysRender = 1,
1906 NeverRender = 2,
1907 };
976 1908
977 std::array<u32, 8> gp_passthrough_mask; 1909 enum class Mode : u32 {
1910 False = 0,
1911 True = 1,
1912 Conditional = 2,
1913 IfEqual = 3,
1914 IfNotEqual = 4,
1915 };
978 1916
979 INSERT_PADDING_WORDS_NOINIT(0x1B); 1917 u32 address_high;
1918 u32 address_low;
1919 Mode mode;
980 1920
981 u32 depth_test_enable; 1921 GPUVAddr Address() const {
1922 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
1923 address_low);
1924 }
1925 };
982 1926
983 INSERT_PADDING_WORDS_NOINIT(0x5); 1927 struct TexSampler {
1928 u32 address_high;
1929 u32 address_low;
1930 u32 limit;
984 1931
985 u32 independent_blend_enable; 1932 GPUVAddr Address() const {
1933 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
1934 address_low);
1935 }
1936 };
986 1937
987 u32 depth_write_enabled; 1938 struct TexHeader {
1939 u32 address_high;
1940 u32 address_low;
1941 u32 limit;
988 1942
989 u32 alpha_test_enabled; 1943 GPUVAddr Address() const {
1944 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
1945 address_low);
1946 }
1947 };
990 1948
991 INSERT_PADDING_WORDS_NOINIT(0x6); 1949 enum class ZCullRegionFormat : u32 {
1950 Z_4x4 = 0,
1951 ZS_4x4 = 1,
1952 Z_4x2 = 2,
1953 Z_2x4 = 3,
1954 Z_16x8_4x4 = 4,
1955 Z_8x8_4x2 = 5,
1956 Z_8x8_2x4 = 6,
1957 Z_16x16_4x8 = 7,
1958 Z_4x8_2x2 = 8,
1959 ZS_16x8_4x2 = 9,
1960 ZS_16x8_2x4 = 10,
1961 ZS_8x8_2x2 = 11,
1962 Z_4x8_1x1 = 12,
1963 };
992 1964
993 u32 d3d_cull_mode; 1965 struct RtLayer {
1966 enum class Control {
1967 LayerSelectsLayer = 0,
1968 GeometryShaderSelectsLayer = 1,
1969 };
994 1970
995 ComparisonOp depth_test_func; 1971 union {
996 float alpha_test_ref; 1972 BitField<0, 16, u32> layer;
997 ComparisonOp alpha_test_func; 1973 BitField<16, 1, u32> control;
998 u32 draw_tfb_stride; 1974 };
999 struct { 1975 };
1000 float r;
1001 float g;
1002 float b;
1003 float a;
1004 } blend_color;
1005 1976
1006 INSERT_PADDING_WORDS_NOINIT(0x4); 1977 struct InlineIndex2x16 {
1978 union {
1979 BitField<0, 31, u32> count;
1980 BitField<31, 1, u32> start_odd;
1981 };
1982 union {
1983 BitField<0, 16, u32> even;
1984 BitField<16, 16, u32> odd;
1985 };
1986 };
1007 1987
1008 struct { 1988 struct VertexGlobalBaseOffset {
1009 u32 separate_alpha; 1989 u32 address_high;
1010 Blend::Equation equation_rgb; 1990 u32 address_low;
1011 Blend::Factor factor_source_rgb;
1012 Blend::Factor factor_dest_rgb;
1013 Blend::Equation equation_a;
1014 Blend::Factor factor_source_a;
1015 INSERT_PADDING_WORDS_NOINIT(1);
1016 Blend::Factor factor_dest_a;
1017 1991
1018 u32 enable_common; 1992 GPUVAddr Address() const {
1019 u32 enable[NumRenderTargets]; 1993 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
1020 } blend; 1994 address_low);
1995 }
1996 };
1021 1997
1022 u32 stencil_enable; 1998 struct ZCullRegionPixelOffset {
1023 StencilOp stencil_front_op_fail; 1999 u32 width;
1024 StencilOp stencil_front_op_zfail; 2000 u32 height;
1025 StencilOp stencil_front_op_zpass; 2001 };
1026 ComparisonOp stencil_front_func_func;
1027 s32 stencil_front_func_ref;
1028 u32 stencil_front_func_mask;
1029 u32 stencil_front_mask;
1030 2002
1031 INSERT_PADDING_WORDS_NOINIT(0x2); 2003 struct PointSprite {
2004 enum class RMode : u32 {
2005 Zero = 0,
2006 FromR = 1,
2007 FromS = 2,
2008 };
2009 enum class Origin : u32 {
2010 Bottom = 0,
2011 Top = 1,
2012 };
2013 enum class Texture : u32 {
2014 Passthrough = 0,
2015 Generate = 1,
2016 };
2017
2018 union {
2019 BitField<0, 2, RMode> rmode;
2020 BitField<2, 1, Origin> origin;
2021 BitField<3, 1, Texture> texture0;
2022 BitField<4, 1, Texture> texture1;
2023 BitField<5, 1, Texture> texture2;
2024 BitField<6, 1, Texture> texture3;
2025 BitField<7, 1, Texture> texture4;
2026 BitField<8, 1, Texture> texture5;
2027 BitField<9, 1, Texture> texture6;
2028 BitField<10, 1, Texture> texture7;
2029 BitField<11, 1, Texture> texture8;
2030 BitField<12, 1, Texture> texture9;
2031 };
2032 };
1032 2033
1033 u32 frag_color_clamp; 2034 struct ProgramRegion {
2035 u32 address_high;
2036 u32 address_low;
1034 2037
1035 union { 2038 GPUVAddr Address() const {
1036 BitField<0, 1, u32> y_negate; 2039 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
1037 BitField<4, 1, u32> triangle_rast_flip; 2040 address_low);
1038 } screen_y_control; 2041 }
2042 };
1039 2043
1040 float line_width_smooth; 2044 struct DefaultAttributes {
1041 float line_width_aliased; 2045 enum class Diffuse : u32 {
2046 Vector_0001 = 0,
2047 Vector_1111 = 1,
2048 };
2049 enum class Specular : u32 {
2050 Vector_0000 = 0,
2051 Vector_0001 = 1,
2052 };
2053 enum class Vector : u32 {
2054 Vector_0000 = 0,
2055 Vector_0001 = 1,
2056 };
2057 enum class FixedFncTexture : u32 {
2058 Vector_0000 = 0,
2059 Vector_0001 = 1,
2060 };
2061 enum class DX9Color0 : u32 {
2062 Vector_0000 = 0,
2063 Vector_1111 = 1,
2064 };
2065 enum class DX9Color1To15 : u32 {
2066 Vector_0000 = 0,
2067 Vector_0001 = 1,
2068 };
1042 2069
1043 INSERT_PADDING_WORDS_NOINIT(0x1B); 2070 union {
2071 BitField<0, 1, Diffuse> color_front_diffuse;
2072 BitField<1, 1, Specular> color_front_specular;
2073 BitField<2, 1, Vector> generic_vector;
2074 BitField<3, 1, FixedFncTexture> fixed_fnc_texture;
2075 BitField<4, 1, DX9Color0> dx9_color0;
2076 BitField<5, 1, DX9Color1To15> dx9_color1_to_15;
2077 };
2078 };
1044 2079
1045 u32 invalidate_sampler_cache_no_wfi; 2080 struct Draw {
1046 u32 invalidate_texture_header_cache_no_wfi; 2081 enum class PrimitiveId : u32 {
2082 First = 0,
2083 Unchanged = 1,
2084 };
2085 enum class InstanceId : u32 {
2086 First = 0,
2087 Subsequent = 1,
2088 Unchanged = 2,
2089 };
2090 enum class SplitMode : u32 {
2091 NormalBeginNormal = 0,
2092 NormalBeginOpen = 1,
2093 OpenBeginOpen = 2,
2094 OpenBeginNormal = 3,
2095 };
1047 2096
1048 INSERT_PADDING_WORDS_NOINIT(0x2); 2097 u32 end;
2098 union {
2099 u32 begin;
2100 BitField<0, 16, PrimitiveTopology> topology;
2101 BitField<24, 1, PrimitiveId> primitive_id;
2102 BitField<26, 2, InstanceId> instance_id;
2103 BitField<29, 2, SplitMode> split_mode;
2104 };
2105 };
1049 2106
1050 u32 vb_element_base; 2107 struct VertexIdCopy {
1051 u32 vb_base_instance; 2108 union {
2109 BitField<0, 1, u32> enable;
2110 BitField<4, 8, u32> attribute_slot;
2111 };
2112 };
1052 2113
1053 INSERT_PADDING_WORDS_NOINIT(0x35); 2114 struct ShaderBasedCull {
2115 union {
2116 BitField<1, 1, u32> batch_cull_enable;
2117 BitField<0, 1, u32> before_fetch_enable;
2118 };
2119 };
1054 2120
1055 u32 clip_distance_enabled; 2121 struct ClassVersion {
2122 union {
2123 BitField<0, 16, u32> current;
2124 BitField<16, 16, u32> oldest_supported;
2125 };
2126 };
1056 2127
1057 u32 samplecnt_enable; 2128 struct PrimitiveRestart {
2129 u32 enabled;
2130 u32 index;
2131 };
1058 2132
1059 float point_size; 2133 struct OutputVertexId {
2134 union {
2135 BitField<12, 1, u32> uses_array_start;
2136 };
2137 };
1060 2138
1061 INSERT_PADDING_WORDS_NOINIT(0x1); 2139 enum class PointCenterMode : u32 {
2140 GL = 0,
2141 D3D = 1,
2142 };
1062 2143
1063 u32 point_sprite_enable; 2144 enum class LineSmoothParams : u32 {
2145 Falloff_1_00 = 0,
2146 Falloff_1_33 = 1,
2147 Falloff_1_66 = 2,
2148 };
1064 2149
1065 INSERT_PADDING_WORDS_NOINIT(0x3); 2150 struct LineSmoothEdgeTable {
2151 union {
2152 BitField<0, 8, u32> v0;
2153 BitField<8, 8, u32> v1;
2154 BitField<16, 8, u32> v2;
2155 BitField<24, 8, u32> v3;
2156 };
2157 };
1066 2158
1067 CounterReset counter_reset; 2159 struct LineStippleParams {
2160 union {
2161 BitField<0, 8, u32> factor;
2162 BitField<8, 16, u32> pattern;
2163 };
2164 };
1068 2165
1069 u32 multisample_enable; 2166 enum class ProvokingVertex : u32 {
2167 First = 0,
2168 Last = 1,
2169 };
1070 2170
1071 u32 zeta_enable; 2171 struct ShaderControl {
2172 enum class Partial : u32 {
2173 Zero = 0,
2174 Infinity = 1,
2175 };
2176 enum class FP32NanBehavior : u32 {
2177 Legacy = 0,
2178 FP64Compatible = 1,
2179 };
2180 enum class FP32F2INanBehavior : u32 {
2181 PassZero = 0,
2182 PassIndefinite = 1,
2183 };
1072 2184
1073 union { 2185 union {
1074 BitField<0, 1, u32> alpha_to_coverage; 2186 BitField<0, 1, Partial> default_partial;
1075 BitField<4, 1, u32> alpha_to_one; 2187 BitField<1, 1, FP32NanBehavior> fp32_nan_behavior;
1076 } multisample_control; 2188 BitField<2, 1, FP32F2INanBehavior> fp32_f2i_nan_behavior;
2189 };
2190 };
1077 2191
1078 INSERT_PADDING_WORDS_NOINIT(0x4); 2192 struct SphVersion {
2193 union {
2194 BitField<0, 16, u32> current;
2195 BitField<16, 16, u32> oldest_supported;
2196 };
2197 };
1079 2198
1080 struct { 2199 struct AlphaToCoverageOverride {
1081 u32 address_high; 2200 union {
1082 u32 address_low; 2201 BitField<0, 1, u32> qualify_by_anti_alias_enable;
1083 ConditionMode mode; 2202 BitField<1, 1, u32> qualify_by_ps_sample_mask_enable;
2203 };
2204 };
1084 2205
1085 GPUVAddr Address() const { 2206 struct AamVersion {
1086 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | 2207 union {
1087 address_low); 2208 BitField<0, 16, u32> current;
1088 } 2209 BitField<16, 16, u32> oldest_supported;
1089 } condition; 2210 };
2211 };
1090 2212
1091 struct { 2213 struct IndexBuffer {
1092 u32 address_high; 2214 u32 start_addr_high;
1093 u32 address_low; 2215 u32 start_addr_low;
1094 u32 limit; 2216 u32 limit_addr_high;
2217 u32 limit_addr_low;
2218 IndexFormat format;
2219 u32 first;
2220 u32 count;
2221
2222 unsigned FormatSizeInBytes() const {
2223 switch (format) {
2224 case IndexFormat::UnsignedByte:
2225 return 1;
2226 case IndexFormat::UnsignedShort:
2227 return 2;
2228 case IndexFormat::UnsignedInt:
2229 return 4;
2230 }
2231 ASSERT(false);
2232 return 1;
2233 }
1095 2234
1096 GPUVAddr Address() const { 2235 GPUVAddr StartAddress() const {
1097 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | 2236 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(start_addr_high) << 32) |
1098 address_low); 2237 start_addr_low);
1099 } 2238 }
1100 } tsc;
1101 2239
1102 INSERT_PADDING_WORDS_NOINIT(0x1); 2240 GPUVAddr EndAddress() const {
2241 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(limit_addr_high) << 32) |
2242 limit_addr_low);
2243 }
1103 2244
1104 float polygon_offset_factor; 2245 /// Adjust the index buffer offset so it points to the first desired index.
2246 GPUVAddr IndexStart() const {
2247 return StartAddress() +
2248 static_cast<size_t>(first) * static_cast<size_t>(FormatSizeInBytes());
2249 }
2250 };
1105 2251
1106 u32 line_smooth_enable; 2252 struct IndexBufferSmall {
2253 union {
2254 BitField<0, 16, u32> first;
2255 BitField<16, 12, u32> count;
2256 BitField<28, 4, PrimitiveTopology> topology;
2257 };
2258 };
1107 2259
1108 struct { 2260 struct VertexStreamInstances {
1109 u32 address_high; 2261 std::array<u32, NumVertexArrays> is_instanced;
1110 u32 address_low;
1111 u32 limit;
1112 2262
1113 GPUVAddr Address() const { 2263 /// Returns whether the vertex array specified by index is supposed to be
1114 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | 2264 /// accessed per instance or not.
1115 address_low); 2265 bool IsInstancingEnabled(std::size_t index) const {
1116 } 2266 return is_instanced[index];
1117 } tic; 2267 }
2268 };
1118 2269
1119 INSERT_PADDING_WORDS_NOINIT(0x5); 2270 struct AttributePointSize {
2271 union {
2272 BitField<0, 1, u32> enabled;
2273 BitField<4, 8, u32> slot;
2274 };
2275 };
1120 2276
1121 u32 stencil_two_side_enable; 2277 struct ViewportClipControl {
1122 StencilOp stencil_back_op_fail; 2278 enum class GeometryGuardband : u32 {
1123 StencilOp stencil_back_op_zfail; 2279 Scale256 = 0,
1124 StencilOp stencil_back_op_zpass; 2280 Scale1 = 1,
1125 ComparisonOp stencil_back_func_func; 2281 };
2282 enum class GeometryClip : u32 {
2283 WZero = 0,
2284 Passthrough = 1,
2285 FrustumXY = 2,
2286 FrustumXYZ = 3,
2287 WZeroNoZCull = 4,
2288 FrustumZ = 5,
2289 WZeroTriFillOrClip = 6,
2290 };
2291 enum class GeometryGuardbandZ : u32 {
2292 SameAsXY = 0,
2293 Scale256 = 1,
2294 Scale1 = 2,
2295 };
1126 2296
1127 INSERT_PADDING_WORDS_NOINIT(0x4); 2297 union {
2298 BitField<0, 1, u32> depth_0_to_1;
2299 BitField<3, 1, u32> pixel_min_z;
2300 BitField<4, 1, u32> pixel_max_z;
2301 BitField<7, 1, GeometryGuardband> geometry_guardband;
2302 BitField<11, 3, GeometryClip> geometry_clip;
2303 BitField<1, 2, GeometryGuardbandZ> geometry_guardband_z;
2304 };
2305 };
1128 2306
1129 u32 framebuffer_srgb; 2307 enum class PrimitiveTopologyControl : u32 {
2308 UseInBeginMethods = 0,
2309 UseSeparateState = 1,
2310 };
1130 2311
1131 float polygon_offset_units; 2312 struct WindowClip {
2313 enum class Type : u32 {
2314 Inclusive = 0,
2315 Exclusive = 1,
2316 ClipAll = 2,
2317 };
1132 2318
1133 INSERT_PADDING_WORDS_NOINIT(0x4); 2319 u32 enable;
2320 Type type;
2321 };
1134 2322
1135 Tegra::Texture::MsaaMode multisample_mode; 2323 enum class InvalidateZCull : u32 {
2324 Invalidate = 0,
2325 };
1136 2326
1137 INSERT_PADDING_WORDS_NOINIT(0xC); 2327 struct ZCull {
2328 union {
2329 BitField<0, 1, u32> z_enable;
2330 BitField<1, 1, u32> stencil_enable;
2331 };
2332 union {
2333 BitField<0, 1, u32> z_min_enbounded;
2334 BitField<1, 1, u32> z_max_unbounded;
2335 };
2336 };
1138 2337
1139 union { 2338 struct LogicOp {
1140 BitField<2, 1, u32> coord_origin; 2339 enum class Op : u32 {
1141 BitField<3, 10, u32> enable; 2340 Clear = 0x1500,
1142 } point_coord_replace; 2341 And = 0x1501,
1143 2342 AndReverse = 0x1502,
1144 struct { 2343 Copy = 0x1503,
1145 u32 code_address_high; 2344 AndInverted = 0x1504,
1146 u32 code_address_low; 2345 NoOp = 0x1505,
1147 2346 Xor = 0x1506,
1148 GPUVAddr CodeAddress() const { 2347 Or = 0x1507,
1149 return static_cast<GPUVAddr>( 2348 Nor = 0x1508,
1150 (static_cast<GPUVAddr>(code_address_high) << 32) | code_address_low); 2349 Equiv = 0x1509,
1151 } 2350 Invert = 0x150A,
1152 } code_address; 2351 OrReverse = 0x150B,
1153 INSERT_PADDING_WORDS_NOINIT(1); 2352 CopyInverted = 0x150C,
1154 2353 OrInverted = 0x150D,
1155 struct { 2354 Nand = 0x150E,
1156 u32 vertex_end_gl; 2355 Set = 0x150F,
1157 union { 2356 };
1158 u32 vertex_begin_gl;
1159 BitField<0, 16, PrimitiveTopology> topology;
1160 BitField<26, 1, u32> instance_next;
1161 BitField<27, 1, u32> instance_cont;
1162 };
1163 } draw;
1164
1165 INSERT_PADDING_WORDS_NOINIT(0xA);
1166
1167 struct {
1168 u32 enabled;
1169 u32 index;
1170 } primitive_restart;
1171
1172 INSERT_PADDING_WORDS_NOINIT(0xE);
1173
1174 u32 provoking_vertex_last;
1175
1176 INSERT_PADDING_WORDS_NOINIT(0x50);
1177
1178 struct {
1179 u32 start_addr_high;
1180 u32 start_addr_low;
1181 u32 end_addr_high;
1182 u32 end_addr_low;
1183 IndexFormat format;
1184 u32 first;
1185 u32 count;
1186
1187 unsigned FormatSizeInBytes() const {
1188 switch (format) {
1189 case IndexFormat::UnsignedByte:
1190 return 1;
1191 case IndexFormat::UnsignedShort:
1192 return 2;
1193 case IndexFormat::UnsignedInt:
1194 return 4;
1195 }
1196 ASSERT(false);
1197 return 1;
1198 }
1199
1200 GPUVAddr StartAddress() const {
1201 return static_cast<GPUVAddr>(
1202 (static_cast<GPUVAddr>(start_addr_high) << 32) | start_addr_low);
1203 }
1204
1205 GPUVAddr EndAddress() const {
1206 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(end_addr_high) << 32) |
1207 end_addr_low);
1208 }
1209
1210 /// Adjust the index buffer offset so it points to the first desired index.
1211 GPUVAddr IndexStart() const {
1212 return StartAddress() + static_cast<size_t>(first) *
1213 static_cast<size_t>(FormatSizeInBytes());
1214 }
1215 } index_array;
1216 2357
1217 union { 2358 u32 enable;
1218 BitField<0, 16, u32> first; 2359 Op op;
1219 BitField<16, 16, u32> count; 2360 };
1220 } small_index;
1221 2361
1222 union { 2362 struct ClearSurface {
1223 BitField<0, 16, u32> first; 2363 union {
1224 BitField<16, 16, u32> count; 2364 u32 raw;
1225 } small_index_2; 2365 BitField<0, 1, u32> Z;
2366 BitField<1, 1, u32> S;
2367 BitField<2, 1, u32> R;
2368 BitField<3, 1, u32> G;
2369 BitField<4, 1, u32> B;
2370 BitField<5, 1, u32> A;
2371 BitField<6, 4, u32> RT;
2372 BitField<10, 16, u32> layer;
2373 };
2374 };
1226 2375
1227 INSERT_PADDING_WORDS_NOINIT(0x5); 2376 struct ReportSemaphore {
2377 struct Compare {
2378 u32 initial_sequence;
2379 u32 initial_mode;
2380 u32 unknown1;
2381 u32 unknown2;
2382 u32 current_sequence;
2383 u32 current_mode;
2384 };
1228 2385
1229 INSERT_PADDING_WORDS_NOINIT(0x1F); 2386 enum class Operation : u32 {
2387 Release = 0,
2388 Acquire = 1,
2389 ReportOnly = 2,
2390 Trap = 3,
2391 };
1230 2392
1231 float polygon_offset_clamp; 2393 enum class Release : u32 {
2394 AfterAllPreceedingReads = 0,
2395 AfterAllPreceedingWrites = 1,
2396 };
1232 2397
1233 struct { 2398 enum class Acquire : u32 {
1234 u32 is_instanced[NumVertexArrays]; 2399 BeforeAnyFollowingWrites = 0,
2400 BeforeAnyFollowingReads = 1,
2401 };
1235 2402
1236 /// Returns whether the vertex array specified by index is supposed to be 2403 enum class Location : u32 {
1237 /// accessed per instance or not. 2404 None = 0,
1238 bool IsInstancingEnabled(std::size_t index) const { 2405 VertexFetch = 1,
1239 return is_instanced[index]; 2406 VertexShader = 2,
1240 } 2407 VPC = 4,
1241 } instanced_arrays; 2408 StreamingOutput = 5,
2409 GeometryShader = 6,
2410 ZCull = 7,
2411 TessellationInit = 8,
2412 TessellationShader = 9,
2413 PixelShader = 10,
2414 DepthTest = 12,
2415 All = 15,
2416 };
1242 2417
1243 INSERT_PADDING_WORDS_NOINIT(0x4); 2418 enum class Comparison : u32 {
2419 NotEqual = 0,
2420 GreaterOrEqual = 1,
2421 };
1244 2422
1245 union { 2423 enum class Report : u32 {
1246 BitField<0, 1, u32> enable; 2424 Payload = 0, // "None" in docs, but confirmed via hardware to return the payload
1247 BitField<4, 8, u32> unk4; 2425 VerticesGenerated = 1,
1248 } vp_point_size; 2426 ZPassPixelCount = 2,
2427 PrimitivesGenerated = 3,
2428 AlphaBetaClocks = 4,
2429 VertexShaderInvocations = 5,
2430 StreamingPrimitivesNeededMinusSucceeded = 6,
2431 GeometryShaderInvocations = 7,
2432 GeometryShaderPrimitivesGenerated = 9,
2433 ZCullStats0 = 10,
2434 StreamingPrimitivesSucceeded = 11,
2435 ZCullStats1 = 12,
2436 StreamingPrimitivesNeeded = 13,
2437 ZCullStats2 = 14,
2438 ClipperInvocations = 15,
2439 ZCullStats3 = 16,
2440 ClipperPrimitivesGenerated = 17,
2441 VtgPrimitivesOut = 18,
2442 PixelShaderInvocations = 19,
2443 ZPassPixelCount64 = 21,
2444 IEEECleanColorTarget = 24,
2445 IEEECleanZetaTarget = 25,
2446 StreamingByteCount = 26,
2447 TessellationInitInvocations = 27,
2448 BoundingRectangle = 28,
2449 TessellationShaderInvocations = 29,
2450 TotalStreamingPrimitivesNeededMinusSucceeded = 30,
2451 TessellationShaderPrimitivesGenerated = 31,
2452 };
1249 2453
1250 INSERT_PADDING_WORDS_NOINIT(1); 2454 u32 address_high;
2455 u32 address_low;
2456 u32 payload;
2457 union {
2458 u32 raw;
2459 BitField<0, 2, Operation> operation;
2460 BitField<4, 1, Release> release;
2461 BitField<8, 1, Acquire> acquire;
2462 BitField<12, 4, Location> location;
2463 BitField<16, 1, Comparison> comparison;
2464 BitField<20, 1, u32> awaken_enable;
2465 BitField<23, 5, Report> report;
2466 BitField<28, 1, u32> short_query;
2467 BitField<5, 3, u32> sub_report;
2468 BitField<21, 1, u32> dword_number;
2469 BitField<2, 1, u32> disable_flush;
2470 BitField<3, 1, u32> reduction_enable;
2471 BitField<9, 3, ReductionOp> reduction_op;
2472 BitField<17, 2, u32> format_signed;
2473 } query;
1251 2474
1252 u32 cull_test_enabled; 2475 GPUVAddr Address() const {
1253 FrontFace front_face; 2476 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
1254 CullFace cull_face; 2477 address_low);
2478 }
2479 };
1255 2480
1256 u32 pixel_center_integer; 2481 struct VertexStream {
2482 union {
2483 BitField<0, 12, u32> stride;
2484 BitField<12, 1, u32> enable;
2485 };
2486 u32 address_high;
2487 u32 address_low;
2488 u32 frequency;
1257 2489
1258 INSERT_PADDING_WORDS_NOINIT(0x1); 2490 GPUVAddr Address() const {
2491 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
2492 address_low);
2493 }
1259 2494
1260 u32 viewport_transform_enabled; 2495 bool IsEnabled() const {
2496 return enable != 0 && Address() != 0;
2497 }
2498 };
2499 static_assert(sizeof(VertexStream) == 0x10);
1261 2500
1262 INSERT_PADDING_WORDS_NOINIT(0x3); 2501 struct VertexStreamLimit {
2502 u32 address_high;
2503 u32 address_low;
1263 2504
1264 union { 2505 GPUVAddr Address() const {
1265 BitField<0, 1, u32> depth_range_0_1; 2506 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
1266 BitField<3, 1, u32> depth_clamp_near; 2507 address_low);
1267 BitField<4, 1, u32> depth_clamp_far; 2508 }
1268 BitField<11, 1, u32> depth_clamp_disabled; 2509 };
1269 } view_volume_clip_control; 2510 static_assert(sizeof(VertexStreamLimit) == 0x8);
1270 2511
1271 INSERT_PADDING_WORDS_NOINIT(0xC); 2512 enum class ShaderType : u32 {
2513 VertexA = 0,
2514 VertexB = 1,
2515 TessellationInit = 2,
2516 Tessellation = 3,
2517 Geometry = 4,
2518 Pixel = 5,
2519 };
1272 2520
1273 PrimitiveTopologyOverride topology_override; 2521 struct Pipeline {
2522 union {
2523 BitField<0, 1, u32> enable;
2524 BitField<4, 4, ShaderType> program;
2525 };
2526 u32 offset;
2527 u32 reservedA;
2528 u32 register_count;
2529 u32 binding_group;
2530 std::array<u32, 4> reserved;
2531 INSERT_PADDING_BYTES_NOINIT(0x1C);
2532 };
2533 static_assert(sizeof(Pipeline) == 0x40);
1274 2534
1275 INSERT_PADDING_WORDS_NOINIT(0x12); 2535 bool IsShaderConfigEnabled(std::size_t index) const {
2536 // The VertexB is always enabled.
2537 if (index == static_cast<std::size_t>(ShaderType::VertexB)) {
2538 return true;
2539 }
2540 return pipelines[index].enable != 0;
2541 }
1276 2542
1277 u32 depth_bounds_enable; 2543 bool IsShaderConfigEnabled(ShaderType type) const {
2544 return IsShaderConfigEnabled(static_cast<std::size_t>(type));
2545 }
1278 2546
1279 INSERT_PADDING_WORDS_NOINIT(1); 2547 struct ConstantBuffer {
2548 u32 size;
2549 u32 address_high;
2550 u32 address_low;
2551 u32 offset;
2552 std::array<u32, NumCBData> buffer;
1280 2553
1281 struct { 2554 GPUVAddr Address() const {
1282 u32 enable; 2555 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
1283 LogicOperation operation; 2556 address_low);
1284 } logic_op; 2557 }
2558 };
1285 2559
1286 INSERT_PADDING_WORDS_NOINIT(0x1); 2560 struct BindGroup {
2561 std::array<u32, 4> reserved;
2562 union {
2563 u32 raw_config;
2564 BitField<0, 1, u32> valid;
2565 BitField<4, 5, u32> shader_slot;
2566 };
2567 INSERT_PADDING_BYTES_NOINIT(0xC);
2568 };
2569 static_assert(sizeof(BindGroup) == 0x20);
1287 2570
2571 struct StreamOutLayout {
2572 union {
2573 BitField<0, 8, u32> attribute0;
2574 BitField<8, 8, u32> attribute1;
2575 BitField<16, 8, u32> attribute2;
2576 BitField<24, 8, u32> attribute3;
2577 };
2578 };
2579
2580 struct ShaderPerformance {
2581 struct ControlA {
1288 union { 2582 union {
1289 u32 raw; 2583 BitField<0, 2, u32> event0;
1290 BitField<0, 1, u32> Z; 2584 BitField<2, 3, u32> bit0;
1291 BitField<1, 1, u32> S; 2585 BitField<5, 2, u32> event1;
1292 BitField<2, 1, u32> R; 2586 BitField<7, 3, u32> bit1;
1293 BitField<3, 1, u32> G; 2587 BitField<10, 2, u32> event2;
1294 BitField<4, 1, u32> B; 2588 BitField<12, 3, u32> bit2;
1295 BitField<5, 1, u32> A; 2589 BitField<15, 2, u32> event3;
1296 BitField<6, 4, u32> RT; 2590 BitField<17, 3, u32> bit3;
1297 BitField<10, 11, u32> layer; 2591 BitField<20, 2, u32> event4;
1298 } clear_buffers; 2592 BitField<22, 3, u32> bit4;
1299 INSERT_PADDING_WORDS_NOINIT(0xB); 2593 BitField<25, 2, u32> event5;
1300 std::array<ColorMask, NumRenderTargets> color_mask; 2594 BitField<27, 3, u32> bit5;
1301 INSERT_PADDING_WORDS_NOINIT(0x38); 2595 BitField<30, 2, u32> spare;
1302 2596 };
1303 struct { 2597 };
1304 u32 query_address_high;
1305 u32 query_address_low;
1306 u32 query_sequence;
1307 union {
1308 u32 raw;
1309 BitField<0, 2, QueryOperation> operation;
1310 BitField<4, 1, u32> fence;
1311 BitField<12, 4, QueryUnit> unit;
1312 BitField<16, 1, QuerySyncCondition> sync_cond;
1313 BitField<23, 5, QuerySelect> select;
1314 BitField<28, 1, u32> short_query;
1315 } query_get;
1316
1317 GPUVAddr QueryAddress() const {
1318 return static_cast<GPUVAddr>(
1319 (static_cast<GPUVAddr>(query_address_high) << 32) | query_address_low);
1320 }
1321 } query;
1322
1323 INSERT_PADDING_WORDS_NOINIT(0x3C);
1324
1325 struct {
1326 union {
1327 BitField<0, 12, u32> stride;
1328 BitField<12, 1, u32> enable;
1329 };
1330 u32 start_high;
1331 u32 start_low;
1332 u32 divisor;
1333
1334 GPUVAddr StartAddress() const {
1335 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(start_high) << 32) |
1336 start_low);
1337 }
1338
1339 bool IsEnabled() const {
1340 return enable != 0 && StartAddress() != 0;
1341 }
1342
1343 } vertex_array[NumVertexArrays];
1344
1345 Blend independent_blend[NumRenderTargets];
1346
1347 struct {
1348 u32 limit_high;
1349 u32 limit_low;
1350
1351 GPUVAddr LimitAddress() const {
1352 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(limit_high) << 32) |
1353 limit_low);
1354 }
1355 } vertex_array_limit[NumVertexArrays];
1356
1357 struct {
1358 union {
1359 BitField<0, 1, u32> enable;
1360 BitField<4, 4, ShaderProgram> program;
1361 };
1362 u32 offset;
1363 INSERT_PADDING_WORDS_NOINIT(14);
1364 } shader_config[MaxShaderProgram];
1365
1366 INSERT_PADDING_WORDS_NOINIT(0x60);
1367
1368 u32 firmware[0x20];
1369
1370 struct {
1371 u32 cb_size;
1372 u32 cb_address_high;
1373 u32 cb_address_low;
1374 u32 cb_pos;
1375 std::array<u32, NumCBData> cb_data;
1376
1377 GPUVAddr BufferAddress() const {
1378 return static_cast<GPUVAddr>(
1379 (static_cast<GPUVAddr>(cb_address_high) << 32) | cb_address_low);
1380 }
1381 } const_buffer;
1382
1383 INSERT_PADDING_WORDS_NOINIT(0x10);
1384
1385 struct {
1386 union {
1387 u32 raw_config;
1388 BitField<0, 1, u32> valid;
1389 BitField<4, 5, u32> index;
1390 };
1391 INSERT_PADDING_WORDS_NOINIT(7);
1392 } cb_bind[MaxShaderStage];
1393
1394 INSERT_PADDING_WORDS_NOINIT(0x56);
1395
1396 u32 tex_cb_index;
1397
1398 INSERT_PADDING_WORDS_NOINIT(0x7D);
1399
1400 std::array<std::array<u8, 128>, NumTransformFeedbackBuffers> tfb_varying_locs;
1401
1402 INSERT_PADDING_WORDS_NOINIT(0x298);
1403
1404 struct {
1405 /// Compressed address of a buffer that holds information about bound SSBOs.
1406 /// This address is usually bound to c0 in the shaders.
1407 u32 buffer_address;
1408
1409 GPUVAddr BufferAddress() const {
1410 return static_cast<GPUVAddr>(buffer_address) << 8;
1411 }
1412 } ssbo_info;
1413 2598
1414 INSERT_PADDING_WORDS_NOINIT(0x11); 2599 struct ControlB {
2600 union {
2601 BitField<0, 1, u32> edge;
2602 BitField<1, 2, u32> mode;
2603 BitField<3, 1, u32> windowed;
2604 BitField<4, 16, u32> func;
2605 };
2606 };
1415 2607
1416 struct { 2608 std::array<u32, 8> values_upper;
1417 u32 address[MaxShaderStage]; 2609 std::array<u32, 8> values;
1418 u32 size[MaxShaderStage]; 2610 std::array<u32, 8> events;
1419 } tex_info_buffers; 2611 std::array<ControlA, 8> control_a;
2612 std::array<ControlB, 8> control_b;
2613 u32 trap_control_mask;
2614 u32 start_shader_mask;
2615 u32 stop_shader_mask;
2616 };
1420 2617
1421 INSERT_PADDING_WORDS_NOINIT(0xCC); 2618 // clang-format off
2619 union {
2620 struct {
2621 ID object_id; ///< 0x0000
2622 INSERT_PADDING_BYTES_NOINIT(0xFC);
2623 u32 nop; ///< 0x0100
2624 Notify notify; ///< 0x0104
2625 u32 wait_for_idle; ///< 0x0110
2626 LoadMME load_mme; ///< 0x0114
2627 ShadowRamControl shadow_ram_control; ///< 0x0124
2628 PeerSemaphore peer; ///< 0x0128
2629 GlobalRender global_render; ///< 0x0130
2630 u32 go_idle; ///< 0x013C
2631 u32 trigger; ///< 0x0140
2632 u32 trigger_wfi; ///< 0x0144
2633 INSERT_PADDING_BYTES_NOINIT(0x8);
2634 u32 instrumentation_method_header; ///< 0x0150
2635 u32 instrumentation_method_data; ///< 0x0154
2636 INSERT_PADDING_BYTES_NOINIT(0x28);
2637 Upload::Registers upload; ///< 0x0180
2638 LaunchDMA launch_dma; ///< 0x01B0
2639 u32 inline_data; ///< 0x01B4
2640 INSERT_PADDING_BYTES_NOINIT(0x24);
2641 I2M i2m; ///< 0x01DC
2642 u32 run_ds_now; ///< 0x0200
2643 OpportunisticEarlyZ opportunistic_early_z; ///< 0x0204
2644 INSERT_PADDING_BYTES_NOINIT(0x4);
2645 u32 aliased_line_width_enabled; ///< 0x020C
2646 u32 mandated_early_z; ///< 0x0210
2647 GeometryShaderDmFifo gs_dm_fifo; ///< 0x0214
2648 L2CacheControl l2_cache_control; ///< 0x0218
2649 InvalidateShaderCache invalidate_shader_cache; ///< 0x021C
2650 INSERT_PADDING_BYTES_NOINIT(0xA8);
2651 SyncInfo sync_info; ///< 0x02C8
2652 INSERT_PADDING_BYTES_NOINIT(0x4);
2653 u32 prim_circular_buffer_throttle; ///< 0x02D0
2654 u32 flush_invalidate_rop_mini_cache; ///< 0x02D4
2655 SurfaceClipBlockId surface_clip_block_id; ///< 0x02D8
2656 u32 alpha_circular_buffer_size; ///< 0x02DC
2657 DecompressSurface decompress_surface; ///< 0x02E0
2658 ZCullRopBypass zcull_rop_bypass; ///< 0x02E4
2659 ZCullSubregion zcull_subregion; ///< 0x02E8
2660 RasterBoundingBox raster_bounding_box; ///< 0x02EC
2661 u32 peer_semaphore_release; ///< 0x02F0
2662 u32 iterated_blend_optimization; ///< 0x02F4
2663 ZCullSubregionAllocation zcull_subregion_allocation; ///< 0x02F8
2664 ZCullSubregionAlgorithm zcull_subregion_algorithm; ///< 0x02FC
2665 PixelShaderOutputSampleMaskUsage ps_output_sample_mask_usage; ///< 0x0300
2666 u32 draw_zero_index; ///< 0x0304
2667 L1Configuration l1_configuration; ///< 0x0308
2668 u32 render_enable_control_load_const_buffer; ///< 0x030C
2669 SPAVersion spa_version; ///< 0x0310
2670 u32 ieee_clean_update; ///< 0x0314
2671 SnapGrid snap_grid; ///< 0x0318
2672 Tessellation tessellation; ///< 0x0320
2673 SubTilingPerf sub_tiling_perf; ///< 0x0360
2674 ZCullSubregionReport zcull_subregion_report; ///< 0x036C
2675 BalancedPrimitiveWorkload balanced_primitive_workload; ///< 0x0374
2676 u32 max_patches_per_batch; ///< 0x0378
2677 u32 rasterize_enable; ///< 0x037C
2678 TransformFeedback transform_feedback; ///< 0x0380
2679 u32 raster_input; ///< 0x0740
2680 u32 transform_feedback_enabled; ///< 0x0744
2681 u32 primitive_restart_topology_change_enable; ///< 0x0748
2682 u32 alpha_fraction; ///< 0x074C
2683 INSERT_PADDING_BYTES_NOINIT(0x4);
2684 HybridAntiAliasControl hybrid_aa_control; ///< 0x0754
2685 INSERT_PADDING_BYTES_NOINIT(0x24);
2686 ShaderLocalMemory shader_local_memory; ///< 0x077C
2687 u32 color_zero_bandwidth_clear; ///< 0x07A4
2688 u32 z_zero_bandwidth_clear; ///< 0x07A8
2689 u32 isbe_save_restore_program_offset; ///< 0x07AC
2690 INSERT_PADDING_BYTES_NOINIT(0x10);
2691 ZCullRegion zcull_region; ///< 0x07C0
2692 ZetaReadOnly zeta_read_only; ///< 0x07F8
2693 INSERT_PADDING_BYTES_NOINIT(0x4);
2694 std::array<RenderTargetConfig, NumRenderTargets> rt; ///< 0x0800
2695 std::array<ViewportTransform, NumViewports> viewport_transform; ///< 0x0A00
2696 std::array<Viewport, NumViewports> viewports; ///< 0x0C00
2697 std::array<Window, 8> windows; ///< 0x0D00
2698 std::array<ClipIdExtent, 4> clip_id_extent; ///< 0x0D40
2699 u32 max_geometry_instances_per_task; ///< 0x0D60
2700 VisibleCallLimit visible_call_limit; ///< 0x0D64
2701 StatisticsCounter statistics_count; ///< 0x0D68
2702 ClearRect clear_rect; ///< 0x0D6C
2703 VertexBuffer vertex_buffer; ///< 0x0D74
2704 DepthMode depth_mode; ///< 0x0D7C
2705 std::array<f32, 4> clear_color; ///< 0x0D80
2706 f32 clear_depth; ///< 0x0D90
2707 u32 shader_cache_icache_prefetch; ///< 0x0D94
2708 u32 force_transition_to_beta; ///< 0x0D98
2709 u32 reduce_colour_thresholds; ///< 0x0D9C
2710 s32 clear_stencil; ///< 0x0DA0
2711 InvalidateShaderCacheNoWFI invalidate_shader_cache_no_wfi; ///< 0x0DA4
2712 ZCullSerialization zcull_serialization; ///< 0x0DA8
2713 PolygonMode polygon_mode_front; ///< 0x0DAC
2714 PolygonMode polygon_mode_back; ///< 0x0DB0
2715 u32 polygon_smooth; ///< 0x0DB4
2716 u32 zeta_mark_clean_ieee; ///< 0x0DB8
2717 ZCullDirFormat zcull_dir_format; ///< 0x0DBC
2718 u32 polygon_offset_point_enable; ///< 0x0DC0
2719 u32 polygon_offset_line_enable; ///< 0x0DC4
2720 u32 polygon_offset_fill_enable; ///< 0x0DC8
2721 u32 patch_vertices; ///< 0x0DCC
2722 IteratedBlend iterated_blend; ///< 0x0DD0
2723 ZCullCriterion zcull_criteria; ///< 0x0DD8
2724 INSERT_PADDING_BYTES_NOINIT(0x4);
2725 u32 fragment_barrier; ///< 0x0DE0
2726 u32 sm_timeout; ///< 0x0DE4
2727 u32 primitive_restart_array; ///< 0x0DE8
2728 INSERT_PADDING_BYTES_NOINIT(0x4);
2729 LoadIteratedBlend load_iterated_blend; ///< 0x0DF0
2730 u32 window_offset_x; ///< 0x0DF8
2731 u32 window_offset_y; ///< 0x0DFC
2732 std::array<ScissorTest, NumViewports> scissor_test; ///< 0x0E00
2733 INSERT_PADDING_BYTES_NOINIT(0x10);
2734 u32 select_texture_headers; ///< 0x0F10
2735 VPCPerf vpc_perf; ///< 0x0F14
2736 u32 pm_local_trigger; ///< 0x0F18
2737 u32 post_z_pixel_imask; ///< 0x0F1C
2738 INSERT_PADDING_BYTES_NOINIT(0x20);
2739 ConstantColorRendering const_color_rendering; ///< 0x0F40
2740 StencilFunc stencil_back_func; ///< 0x0F54
2741 INSERT_PADDING_BYTES_NOINIT(0x24);
2742 VertexStreamSubstitute vertex_stream_substitute; ///< 0x0F84
2743 u32 line_mode_clip_generated_edge_do_not_draw; ///< 0x0F8C
2744 u32 color_mask_common; ///< 0x0F90
2745 INSERT_PADDING_BYTES_NOINIT(0x4);
2746 VTGWarpWatermarks vtg_warp_watermarks; ///< 0x0F98
2747 f32 depth_bounds[2]; ///< 0x0F9C
2748 SampleMask::Target sample_mask_target; ///< 0x0FA4
2749 u32 color_target_mrt_enable; ///< 0x0FAC
2750 NonMultisampledZ non_multisampled_z; ///< 0x0FB0
2751 TIRMode tir_mode; ///< 0x0FB4
2752 AntiAliasRaster anti_alias_raster; ///< 0x0FB8
2753 SampleMask::Pos sample_mask_pos; ///< 0x0FBC
2754 SurfaceClipIDMemory surface_clip_id_memory; ///< 0x0FCC
2755 TIRModulation tir_modulation; ///< 0x0FD4
2756 u32 blend_control_allow_float_pixel_kills; ///< 0x0FDC
2757 Zeta zeta; ///< 0x0FE0
2758 SurfaceClip surface_clip; ///< 0x0FF4
2759 u32 tiled_cache_treat_heavy_as_light; ///< 0x0FFC
2760 L2CacheVAFRequests l2_cache_vaf; ///< 0x1000
2761 ViewportMulticast viewport_multicast; ///< 0x1004
2762 u32 tessellation_cut_height; ///< 0x1008
2763 u32 max_gs_instances_per_task; ///< 0x100C
2764 u32 max_gs_output_vertices_per_task; ///< 0x1010
2765 u32 reserved_sw_method0; ///< 0x1014
2766 u32 gs_output_cb_storage_multiplier; ///< 0x1018
2767 u32 beta_cb_storage_constant; ///< 0x101C
2768 u32 ti_output_cb_storage_multiplier; ///< 0x1020
2769 u32 alpha_cb_storage_constraint; ///< 0x1024
2770 u32 reserved_sw_method1; ///< 0x1028
2771 u32 reserved_sw_method2; ///< 0x102C
2772 std::array<TIRModulationCoeff, 5> tir_modulation_coeff; ///< 0x1030
2773 std::array<u32, 15> spare_nop; ///< 0x1044
2774 INSERT_PADDING_BYTES_NOINIT(0x30);
2775 std::array<u32, 7> reserved_sw_method3_to_7; ///< 0x10B0
2776 ReduceColorThreshold reduce_color_thresholds_unorm8; ///< 0x10CC
2777 std::array<u32, 4> reserved_sw_method10_to_13; ///< 0x10D0
2778 ReduceColorThreshold reduce_color_thresholds_unorm10; ///< 0x10E0
2779 ReduceColorThreshold reduce_color_thresholds_unorm16; ///< 0x10E4
2780 ReduceColorThreshold reduce_color_thresholds_fp11; ///< 0x10E8
2781 ReduceColorThreshold reduce_color_thresholds_fp16; ///< 0x10EC
2782 ReduceColorThreshold reduce_color_thresholds_srgb8; ///< 0x10F0
2783 u32 unbind_all_constant_buffers; ///< 0x10F4
2784 ClearControl clear_control; ///< 0x10F8
2785 L2CacheRopNonInterlockedReads l2_cache_rop_non_interlocked_reads; ///< 0x10FC
2786 u32 reserved_sw_method14; ///< 0x1100
2787 u32 reserved_sw_method15; ///< 0x1104
2788 INSERT_PADDING_BYTES_NOINIT(0x4);
2789 u32 no_operation_data_high; ///< 0x110C
2790 u32 depth_bias_control; ///< 0x1110
2791 u32 pm_trigger_end; ///< 0x1114
2792 u32 vertex_id_base; ///< 0x1118
2793 u32 stencil_compression_enabled; ///< 0x111C
2794 VertexOutputAttributeSkipMasks vertex_output_attribute_skip_masks; ///< 0x1120
2795 TIRControl tir_control; ///< 0x1130
2796 u32 mutable_method_treat_mutable_as_heavy; ///< 0x1134
2797 u32 post_ps_use_pre_ps_coverage; ///< 0x1138
2798 FillViaTriangleMode fill_via_triangle_mode; ///< 0x113C
2799 u32 blend_per_format_snorm8_unorm16_snorm16_enabled; ///< 0x1140
2800 u32 flush_pending_writes_sm_gloal_store; ///< 0x1144
2801 INSERT_PADDING_BYTES_NOINIT(0x18);
2802 std::array<VertexAttribute, NumVertexAttributes> vertex_attrib_format; ///< 0x1160
2803 std::array<MsaaSampleLocation, 4> multisample_sample_locations; ///< 0x11E0
2804 u32 offset_render_target_index_by_viewport_index; ///< 0x11F0
2805 u32 force_heavy_method_sync; ///< 0x11F4
2806 MultisampleCoverageToColor multisample_coverage_to_color; ///< 0x11F8
2807 DecompressZetaSurface decompress_zeta_surface; ///< 0x11FC
2808 INSERT_PADDING_BYTES_NOINIT(0x8);
2809 ZetaSparse zeta_sparse; ///< 0x1208
2810 u32 invalidate_sampler_cache; ///< 0x120C
2811 u32 invalidate_texture_header_cache; ///< 0x1210
2812 VertexArray vertex_array_instance_first; ///< 0x1214
2813 VertexArray vertex_array_instance_subsequent; ///< 0x1218
2814 RtControl rt_control; ///< 0x121C
2815 CompressionThresholdSamples compression_threshold_samples; ///< 0x1220
2816 PixelShaderInterlockControl ps_interlock_control; ///< 0x1224
2817 ZetaSize zeta_size; ///< 0x1228
2818 SamplerBinding sampler_binding; ///< 0x1234
2819 INSERT_PADDING_BYTES_NOINIT(0x4);
2820 u32 draw_auto_byte_count; ///< 0x123C
2821 std::array<u32, 8> post_vtg_shader_attrib_skip_mask; ///< 0x1240
2822 PsTicketDispenserValue ps_ticket_dispenser_value; ///< 0x1260
2823 INSERT_PADDING_BYTES_NOINIT(0x1C);
2824 u32 circular_buffer_size; ///< 0x1280
2825 RegisterWatermarks vtg_register_watermarks; ///< 0x1284
2826 InvalidateTextureDataCacheNoWfi invalidate_texture_cache_no_wfi; ///< 0x1288
2827 INSERT_PADDING_BYTES_NOINIT(0x4);
2828 L2CacheRopNonInterlockedReads l2_cache_rop_interlocked_reads; ///< 0x1290
2829 INSERT_PADDING_BYTES_NOINIT(0x10);
2830 u32 primitive_restart_topology_change_index; ///< 0x12A4
2831 INSERT_PADDING_BYTES_NOINIT(0x20);
2832 ZCullRegionEnable zcull_region_enable; ///< 0x12C8
2833 u32 depth_test_enable; ///< 0x12CC
2834 FillMode fill_mode; ///< 0x12D0
2835 ShadeMode shade_mode; ///< 0x12D4
2836 L2CacheRopNonInterlockedReads l2_cache_rop_non_interlocked_writes; ///< 0x12D8
2837 L2CacheRopNonInterlockedReads l2_cache_rop_interlocked_writes; ///< 0x12DC
2838 AlphaToCoverageDither alpha_to_coverage_dither; ///< 0x12E0
2839 u32 blend_per_target_enabled; ///< 0x12E4
2840 u32 depth_write_enabled; ///< 0x12E8
2841 u32 alpha_test_enabled; ///< 0x12EC
2842 INSERT_PADDING_BYTES_NOINIT(0x10);
2843 InlineIndex4x8Align inline_index_4x8_align; ///< 0x1300
2844 InlineIndex4x8Index inline_index_4x8_index; ///< 0x1304
2845 D3DCullMode d3d_cull_mode; ///< 0x1308
2846 ComparisonOp depth_test_func; ///< 0x130C
2847 f32 alpha_test_ref; ///< 0x1310
2848 ComparisonOp alpha_test_func; ///< 0x1314
2849 u32 draw_auto_stride; ///< 0x1318
2850 BlendColor blend_color; ///< 0x131C
2851 INSERT_PADDING_BYTES_NOINIT(0x4);
2852 InvalidateCacheLines invalidate_sampler_cache_lines; ///< 0x1330
2853 InvalidateCacheLines invalidate_texture_header_cache_lines; ///< 0x1334
2854 InvalidateCacheLines invalidate_texture_data_cache_lines; ///< 0x1338
2855 Blend blend; ///< 0x133C
2856 u32 stencil_enable; ///< 0x1380
2857 StencilOp stencil_front_op; ///< 0x1384
2858 StencilFunc stencil_front_func; ///< 0x1394
2859 INSERT_PADDING_BYTES_NOINIT(0x4);
2860 u32 draw_auto_start_byte_count; ///< 0x13A4
2861 PsSaturate frag_color_clamp; ///< 0x13A8
2862 WindowOrigin window_origin; ///< 0x13AC
2863 f32 line_width_smooth; ///< 0x13B0
2864 f32 line_width_aliased; ///< 0x13B4
2865 INSERT_PADDING_BYTES_NOINIT(0x60);
2866 u32 line_override_multisample; ///< 0x1418
2867 INSERT_PADDING_BYTES_NOINIT(0x4);
2868 u32 alpha_hysteresis_rounds; ///< 0x1420
2869 InvalidateCacheLines invalidate_sampler_cache_no_wfi; ///< 0x1424
2870 InvalidateCacheLines invalidate_texture_header_cache_no_wfi; ///< 0x1428
2871 INSERT_PADDING_BYTES_NOINIT(0x8);
2872 u32 global_base_vertex_index; ///< 0x1434
2873 u32 global_base_instance_index; ///< 0x1438
2874 INSERT_PADDING_BYTES_NOINIT(0x14);
2875 RegisterWatermarks ps_warp_watermarks; ///< 0x1450
2876 RegisterWatermarks ps_regster_watermarks; ///< 0x1454
2877 INSERT_PADDING_BYTES_NOINIT(0xC);
2878 u32 store_zcull; ///< 0x1464
2879 INSERT_PADDING_BYTES_NOINIT(0x18);
2880 std::array<IteratedBlendConstants, NumRenderTargets>
2881 iterated_blend_constants; ///< 0x1480
2882 u32 load_zcull; ///< 0x1500
2883 u32 surface_clip_id_height; ///< 0x1504
2884 Window surface_clip_id_clear_rect; ///< 0x1508
2885 UserClip::Enable user_clip_enable; ///< 0x1510
2886 u32 zpass_pixel_count_enable; ///< 0x1514
2887 f32 point_size; ///< 0x1518
2888 u32 zcull_stats_enable; ///< 0x151C
2889 u32 point_sprite_enable; ///< 0x1520
2890 INSERT_PADDING_BYTES_NOINIT(0x4);
2891 u32 shader_exceptions_enable; ///< 0x1528
2892 INSERT_PADDING_BYTES_NOINIT(0x4);
2893 ClearReport clear_report_value; ///< 0x1530
2894 u32 anti_alias_enable; ///< 0x1534
2895 u32 zeta_enable; ///< 0x1538
2896 AntiAliasAlphaControl anti_alias_alpha_control; ///< 0x153C
2897 INSERT_PADDING_BYTES_NOINIT(0x10);
2898 RenderEnable render_enable; ///< 0x1550
2899 TexSampler tex_sampler; ///< 0x155C
2900 INSERT_PADDING_BYTES_NOINIT(0x4);
2901 f32 slope_scale_depth_bias; ///< 0x156C
2902 u32 line_anti_alias_enable; ///< 0x1570
2903 TexHeader tex_header; ///< 0x1574
2904 INSERT_PADDING_BYTES_NOINIT(0x10);
2905 u32 active_zcull_region_id; ///< 0x1590
2906 u32 stencil_two_side_enable; ///< 0x1594
2907 StencilOp stencil_back_op; ///< 0x1598
2908 INSERT_PADDING_BYTES_NOINIT(0x10);
2909 u32 framebuffer_srgb; ///< 0x15B8
2910 f32 depth_bias; ///< 0x15BC
2911 INSERT_PADDING_BYTES_NOINIT(0x8);
2912 ZCullRegionFormat zcull_region_format; ///< 0x15C8
2913 RtLayer rt_layer; ///< 0x15CC
2914 Tegra::Texture::MsaaMode anti_alias_samples_mode; ///< 0x15D0
2915 INSERT_PADDING_BYTES_NOINIT(0x10);
2916 u32 edge_flag; ///< 0x15E4
2917 u32 draw_inline_index; ///< 0x15E8
2918 InlineIndex2x16 inline_index_2x16; ///< 0x15EC
2919 VertexGlobalBaseOffset vertex_global_base_offset; ///< 0x15F4
2920 ZCullRegionPixelOffset zcull_region_pixel_offset; ///< 0x15FC
2921 PointSprite point_sprite; ///< 0x1604
2922 ProgramRegion program_region; ///< 0x1608
2923 DefaultAttributes default_attributes; ///< 0x1610
2924 Draw draw; ///< 0x1614
2925 VertexIdCopy vertex_id_copy; ///< 0x161C
2926 u32 add_to_primitive_id; ///< 0x1620
2927 u32 load_to_primitive_id; ///< 0x1624
2928 INSERT_PADDING_BYTES_NOINIT(0x4);
2929 ShaderBasedCull shader_based_cull; ///< 0x162C
2930 INSERT_PADDING_BYTES_NOINIT(0x8);
2931 ClassVersion class_version; ///< 0x1638
2932 INSERT_PADDING_BYTES_NOINIT(0x8);
2933 PrimitiveRestart primitive_restart; ///< 0x1644
2934 OutputVertexId output_vertex_id; ///< 0x164C
2935 INSERT_PADDING_BYTES_NOINIT(0x8);
2936 u32 anti_alias_point_enable; ///< 0x1658
2937 PointCenterMode point_center_mode; ///< 0x165C
2938 INSERT_PADDING_BYTES_NOINIT(0x8);
2939 LineSmoothParams line_smooth_params; ///< 0x1668
2940 u32 line_stipple_enable; ///< 0x166C
2941 std::array<LineSmoothEdgeTable, 4> line_smooth_edge_table; ///< 0x1670
2942 LineStippleParams line_stipple_params; ///< 0x1680
2943 ProvokingVertex provoking_vertex; ///< 0x1684
2944 u32 two_sided_light_enabled; ///< 0x1688
2945 u32 polygon_stipple_enabled; ///< 0x168C
2946 ShaderControl shader_control; ///< 0x1690
2947 INSERT_PADDING_BYTES_NOINIT(0xC);
2948 ClassVersion class_version_check; ///< 0x16A0
2949 SphVersion sph_version; ///< 0x16A4
2950 SphVersion sph_version_check; ///< 0x16A8
2951 INSERT_PADDING_BYTES_NOINIT(0x8);
2952 AlphaToCoverageOverride alpha_to_coverage_override; ///< 0x16B4
2953 INSERT_PADDING_BYTES_NOINIT(0x48);
2954 std::array<u32, 32> polygon_stipple_pattern; ///< 0x1700
2955 INSERT_PADDING_BYTES_NOINIT(0x10);
2956 AamVersion aam_version; ///< 0x1790
2957 AamVersion aam_version_check; ///< 0x1794
2958 INSERT_PADDING_BYTES_NOINIT(0x4);
2959 u32 zeta_layer_offset; ///< 0x179C
2960 INSERT_PADDING_BYTES_NOINIT(0x28);
2961 IndexBuffer index_buffer; ///< 0x17C8
2962 IndexBufferSmall index_buffer32_first; ///< 0x17E4
2963 IndexBufferSmall index_buffer16_first; ///< 0x17E8
2964 IndexBufferSmall index_buffer8_first; ///< 0x17EC
2965 IndexBufferSmall index_buffer32_subsequent; ///< 0x17F0
2966 IndexBufferSmall index_buffer16_subsequent; ///< 0x17F4
2967 IndexBufferSmall index_buffer8_subsequent; ///< 0x17F8
2968 INSERT_PADDING_BYTES_NOINIT(0x80);
2969 f32 depth_bias_clamp; ///< 0x187C
2970 VertexStreamInstances vertex_stream_instances; ///< 0x1880
2971 INSERT_PADDING_BYTES_NOINIT(0x10);
2972 AttributePointSize point_size_attribute; ///< 0x1910
2973 INSERT_PADDING_BYTES_NOINIT(0x4);
2974 u32 gl_cull_test_enabled; ///< 0x1918
2975 FrontFace gl_front_face; ///< 0x191C
2976 CullFace gl_cull_face; ///< 0x1920
2977 Viewport::PixelCenter viewport_pixel_center; ///< 0x1924
2978 INSERT_PADDING_BYTES_NOINIT(0x4);
2979 u32 viewport_scale_offset_enbled; ///< 0x192C
2980 INSERT_PADDING_BYTES_NOINIT(0xC);
2981 ViewportClipControl viewport_clip_control; ///< 0x193C
2982 UserClip::Op user_clip_op; ///< 0x1940
2983 RenderEnable::Override render_enable_override; ///< 0x1944
2984 PrimitiveTopologyControl primitive_topology_control; ///< 0x1948
2985 WindowClip window_clip_enable; ///< 0x194C
2986 INSERT_PADDING_BYTES_NOINIT(0x4);
2987 InvalidateZCull invalidate_zcull; ///< 0x1958
2988 INSERT_PADDING_BYTES_NOINIT(0xC);
2989 ZCull zcull; ///< 0x1968
2990 PrimitiveTopologyOverride topology_override; ///< 0x1970
2991 INSERT_PADDING_BYTES_NOINIT(0x4);
2992 u32 zcull_sync; ///< 0x1978
2993 u32 clip_id_test_enable; ///< 0x197C
2994 u32 surface_clip_id_width; ///< 0x1980
2995 u32 clip_id; ///< 0x1984
2996 INSERT_PADDING_BYTES_NOINIT(0x34);
2997 u32 depth_bounds_enable; ///< 0x19BC
2998 u32 blend_float_zero_times_anything_is_zero; ///< 0x19C0
2999 LogicOp logic_op; ///< 0x19C4
3000 u32 z_compression_enable; ///< 0x19CC
3001 ClearSurface clear_surface; ///< 0x19D0
3002 u32 clear_clip_id_surface; ///< 0x19D4
3003 INSERT_PADDING_BYTES_NOINIT(0x8);
3004 std::array<u32, NumRenderTargets> color_compression_enable; ///< 0x19E0
3005 std::array<ColorMask, NumRenderTargets> color_mask; ///< 0x1A00
3006 INSERT_PADDING_BYTES_NOINIT(0xC);
3007 u32 pipe_nop; ///< 0x1A2C
3008 std::array<u32, 4> spare; ///< 0x1A30
3009 INSERT_PADDING_BYTES_NOINIT(0xC0);
3010 ReportSemaphore report_semaphore; ///< 0x1B00
3011 INSERT_PADDING_BYTES_NOINIT(0xF0);
3012 std::array<VertexStream, NumVertexArrays> vertex_streams; ///< 0x1C00
3013 BlendPerTarget blend_per_target[NumRenderTargets]; ///< 0x1E00
3014 std::array<VertexStreamLimit, NumVertexArrays> vertex_stream_limits; ///< 0x1F00
3015 std::array<Pipeline, MaxShaderProgram> pipelines; ///< 0x2000
3016 INSERT_PADDING_BYTES_NOINIT(0x180);
3017 u32 falcon[32]; ///< 0x2300
3018 ConstantBuffer const_buffer; ///< 0x2380
3019 INSERT_PADDING_BYTES_NOINIT(0x30);
3020 BindGroup bind_groups[MaxShaderStage]; ///< 0x2400
3021 INSERT_PADDING_BYTES_NOINIT(0x160);
3022 u32 color_clamp_enable; ///< 0x2600
3023 INSERT_PADDING_BYTES_NOINIT(0x4);
3024 u32 bindless_texture_const_buffer_slot; ///< 0x2608
3025 u32 trap_handler; ///< 0x260C
3026 INSERT_PADDING_BYTES_NOINIT(0x1F0);
3027 std::array<std::array<StreamOutLayout, 32>, NumTransformFeedbackBuffers>
3028 stream_out_layout; ///< 0x2800
3029 INSERT_PADDING_BYTES_NOINIT(0x93C);
3030 ShaderPerformance shader_performance; ///< 0x333C
3031 INSERT_PADDING_BYTES_NOINIT(0x18);
3032 std::array<u32, 0x100> shadow_scratch; ///< 0x3400
1422 }; 3033 };
1423 std::array<u32, NUM_REGS> reg_array; 3034 std::array<u32, NUM_REGS> reg_array;
1424 }; 3035 };
1425 }; 3036 };
3037 // clang-format on
1426 3038
1427 Regs regs{}; 3039 Regs regs{};
1428 3040
@@ -1591,147 +3203,346 @@ private:
1591}; 3203};
1592 3204
1593#define ASSERT_REG_POSITION(field_name, position) \ 3205#define ASSERT_REG_POSITION(field_name, position) \
1594 static_assert(offsetof(Maxwell3D::Regs, field_name) == position * 4, \ 3206 static_assert(offsetof(Maxwell3D::Regs, field_name) == position, \
1595 "Field " #field_name " has invalid position") 3207 "Field " #field_name " has invalid position")
1596 3208
1597ASSERT_REG_POSITION(wait_for_idle, 0x44); 3209ASSERT_REG_POSITION(object_id, 0x0000);
1598ASSERT_REG_POSITION(macros, 0x45); 3210ASSERT_REG_POSITION(nop, 0x0100);
1599ASSERT_REG_POSITION(shadow_ram_control, 0x49); 3211ASSERT_REG_POSITION(notify, 0x0104);
1600ASSERT_REG_POSITION(upload, 0x60); 3212ASSERT_REG_POSITION(wait_for_idle, 0x0110);
1601ASSERT_REG_POSITION(exec_upload, 0x6C); 3213ASSERT_REG_POSITION(load_mme, 0x0114);
1602ASSERT_REG_POSITION(data_upload, 0x6D); 3214ASSERT_REG_POSITION(shadow_ram_control, 0x0124);
1603ASSERT_REG_POSITION(force_early_fragment_tests, 0x84); 3215ASSERT_REG_POSITION(peer, 0x0128);
1604ASSERT_REG_POSITION(sync_info, 0xB2); 3216ASSERT_REG_POSITION(global_render, 0x0130);
1605ASSERT_REG_POSITION(tess_mode, 0xC8); 3217ASSERT_REG_POSITION(go_idle, 0x013C);
1606ASSERT_REG_POSITION(tess_level_outer, 0xC9); 3218ASSERT_REG_POSITION(trigger, 0x0140);
1607ASSERT_REG_POSITION(tess_level_inner, 0xCD); 3219ASSERT_REG_POSITION(trigger_wfi, 0x0144);
1608ASSERT_REG_POSITION(rasterize_enable, 0xDF); 3220ASSERT_REG_POSITION(instrumentation_method_header, 0x0150);
1609ASSERT_REG_POSITION(tfb_bindings, 0xE0); 3221ASSERT_REG_POSITION(instrumentation_method_data, 0x0154);
1610ASSERT_REG_POSITION(tfb_layouts, 0x1C0); 3222ASSERT_REG_POSITION(upload, 0x0180);
1611ASSERT_REG_POSITION(tfb_enabled, 0x1D1); 3223ASSERT_REG_POSITION(launch_dma, 0x01B0);
1612ASSERT_REG_POSITION(rt, 0x200); 3224ASSERT_REG_POSITION(inline_data, 0x01B4);
1613ASSERT_REG_POSITION(viewport_transform, 0x280); 3225ASSERT_REG_POSITION(i2m, 0x01DC);
1614ASSERT_REG_POSITION(viewports, 0x300); 3226ASSERT_REG_POSITION(run_ds_now, 0x0200);
1615ASSERT_REG_POSITION(vertex_buffer, 0x35D); 3227ASSERT_REG_POSITION(opportunistic_early_z, 0x0204);
1616ASSERT_REG_POSITION(depth_mode, 0x35F); 3228ASSERT_REG_POSITION(aliased_line_width_enabled, 0x020C);
1617ASSERT_REG_POSITION(clear_color[0], 0x360); 3229ASSERT_REG_POSITION(mandated_early_z, 0x0210);
1618ASSERT_REG_POSITION(clear_depth, 0x364); 3230ASSERT_REG_POSITION(gs_dm_fifo, 0x0214);
1619ASSERT_REG_POSITION(clear_stencil, 0x368); 3231ASSERT_REG_POSITION(l2_cache_control, 0x0218);
1620ASSERT_REG_POSITION(polygon_mode_front, 0x36B); 3232ASSERT_REG_POSITION(invalidate_shader_cache, 0x021C);
1621ASSERT_REG_POSITION(polygon_mode_back, 0x36C); 3233ASSERT_REG_POSITION(sync_info, 0x02C8);
1622ASSERT_REG_POSITION(polygon_offset_point_enable, 0x370); 3234ASSERT_REG_POSITION(prim_circular_buffer_throttle, 0x02D0);
1623ASSERT_REG_POSITION(polygon_offset_line_enable, 0x371); 3235ASSERT_REG_POSITION(flush_invalidate_rop_mini_cache, 0x02D4);
1624ASSERT_REG_POSITION(polygon_offset_fill_enable, 0x372); 3236ASSERT_REG_POSITION(surface_clip_block_id, 0x02D8);
1625ASSERT_REG_POSITION(patch_vertices, 0x373); 3237ASSERT_REG_POSITION(alpha_circular_buffer_size, 0x02DC);
1626ASSERT_REG_POSITION(fragment_barrier, 0x378); 3238ASSERT_REG_POSITION(decompress_surface, 0x02E0);
1627ASSERT_REG_POSITION(scissor_test, 0x380); 3239ASSERT_REG_POSITION(zcull_rop_bypass, 0x02E4);
1628ASSERT_REG_POSITION(stencil_back_func_ref, 0x3D5); 3240ASSERT_REG_POSITION(zcull_subregion, 0x02E8);
1629ASSERT_REG_POSITION(stencil_back_mask, 0x3D6); 3241ASSERT_REG_POSITION(raster_bounding_box, 0x02EC);
1630ASSERT_REG_POSITION(stencil_back_func_mask, 0x3D7); 3242ASSERT_REG_POSITION(peer_semaphore_release, 0x02F0);
1631ASSERT_REG_POSITION(invalidate_texture_data_cache, 0x3DD); 3243ASSERT_REG_POSITION(iterated_blend_optimization, 0x02F4);
1632ASSERT_REG_POSITION(tiled_cache_barrier, 0x3DF); 3244ASSERT_REG_POSITION(zcull_subregion_allocation, 0x02F8);
1633ASSERT_REG_POSITION(color_mask_common, 0x3E4); 3245ASSERT_REG_POSITION(zcull_subregion_algorithm, 0x02FC);
1634ASSERT_REG_POSITION(depth_bounds, 0x3E7); 3246ASSERT_REG_POSITION(ps_output_sample_mask_usage, 0x0300);
1635ASSERT_REG_POSITION(rt_separate_frag_data, 0x3EB); 3247ASSERT_REG_POSITION(draw_zero_index, 0x0304);
1636ASSERT_REG_POSITION(multisample_raster_enable, 0x3ED); 3248ASSERT_REG_POSITION(l1_configuration, 0x0308);
1637ASSERT_REG_POSITION(multisample_raster_samples, 0x3EE); 3249ASSERT_REG_POSITION(render_enable_control_load_const_buffer, 0x030C);
1638ASSERT_REG_POSITION(multisample_sample_mask, 0x3EF); 3250ASSERT_REG_POSITION(spa_version, 0x0310);
1639ASSERT_REG_POSITION(zeta, 0x3F8); 3251ASSERT_REG_POSITION(ieee_clean_update, 0x0314);
1640ASSERT_REG_POSITION(render_area, 0x3FD); 3252ASSERT_REG_POSITION(snap_grid, 0x0318);
1641ASSERT_REG_POSITION(clear_flags, 0x43E); 3253ASSERT_REG_POSITION(tessellation, 0x0320);
1642ASSERT_REG_POSITION(fill_rectangle, 0x44F); 3254ASSERT_REG_POSITION(sub_tiling_perf, 0x0360);
1643ASSERT_REG_POSITION(conservative_raster_enable, 0x452); 3255ASSERT_REG_POSITION(zcull_subregion_report, 0x036C);
1644ASSERT_REG_POSITION(vertex_attrib_format, 0x458); 3256ASSERT_REG_POSITION(balanced_primitive_workload, 0x0374);
1645ASSERT_REG_POSITION(multisample_sample_locations, 0x478); 3257ASSERT_REG_POSITION(max_patches_per_batch, 0x0378);
1646ASSERT_REG_POSITION(multisample_coverage_to_color, 0x47E); 3258ASSERT_REG_POSITION(rasterize_enable, 0x037C);
1647ASSERT_REG_POSITION(rt_control, 0x487); 3259ASSERT_REG_POSITION(transform_feedback, 0x0380);
1648ASSERT_REG_POSITION(zeta_width, 0x48a); 3260ASSERT_REG_POSITION(transform_feedback.controls, 0x0700);
1649ASSERT_REG_POSITION(zeta_height, 0x48b); 3261ASSERT_REG_POSITION(raster_input, 0x0740);
1650ASSERT_REG_POSITION(zeta_depth, 0x48c); 3262ASSERT_REG_POSITION(transform_feedback_enabled, 0x0744);
1651ASSERT_REG_POSITION(sampler_index, 0x48D); 3263ASSERT_REG_POSITION(primitive_restart_topology_change_enable, 0x0748);
1652ASSERT_REG_POSITION(gp_passthrough_mask, 0x490); 3264ASSERT_REG_POSITION(alpha_fraction, 0x074C);
1653ASSERT_REG_POSITION(depth_test_enable, 0x4B3); 3265ASSERT_REG_POSITION(hybrid_aa_control, 0x0754);
1654ASSERT_REG_POSITION(independent_blend_enable, 0x4B9); 3266ASSERT_REG_POSITION(shader_local_memory, 0x077C);
1655ASSERT_REG_POSITION(depth_write_enabled, 0x4BA); 3267ASSERT_REG_POSITION(color_zero_bandwidth_clear, 0x07A4);
1656ASSERT_REG_POSITION(alpha_test_enabled, 0x4BB); 3268ASSERT_REG_POSITION(z_zero_bandwidth_clear, 0x07A8);
1657ASSERT_REG_POSITION(d3d_cull_mode, 0x4C2); 3269ASSERT_REG_POSITION(isbe_save_restore_program_offset, 0x07AC);
1658ASSERT_REG_POSITION(depth_test_func, 0x4C3); 3270ASSERT_REG_POSITION(zcull_region, 0x07C0);
1659ASSERT_REG_POSITION(alpha_test_ref, 0x4C4); 3271ASSERT_REG_POSITION(zeta_read_only, 0x07F8);
1660ASSERT_REG_POSITION(alpha_test_func, 0x4C5); 3272ASSERT_REG_POSITION(rt, 0x0800);
1661ASSERT_REG_POSITION(draw_tfb_stride, 0x4C6); 3273ASSERT_REG_POSITION(viewport_transform, 0x0A00);
1662ASSERT_REG_POSITION(blend_color, 0x4C7); 3274ASSERT_REG_POSITION(viewports, 0x0C00);
1663ASSERT_REG_POSITION(blend, 0x4CF); 3275ASSERT_REG_POSITION(windows, 0x0D00);
1664ASSERT_REG_POSITION(stencil_enable, 0x4E0); 3276ASSERT_REG_POSITION(clip_id_extent, 0x0D40);
1665ASSERT_REG_POSITION(stencil_front_op_fail, 0x4E1); 3277ASSERT_REG_POSITION(max_geometry_instances_per_task, 0x0D60);
1666ASSERT_REG_POSITION(stencil_front_op_zfail, 0x4E2); 3278ASSERT_REG_POSITION(visible_call_limit, 0x0D64);
1667ASSERT_REG_POSITION(stencil_front_op_zpass, 0x4E3); 3279ASSERT_REG_POSITION(statistics_count, 0x0D68);
1668ASSERT_REG_POSITION(stencil_front_func_func, 0x4E4); 3280ASSERT_REG_POSITION(clear_rect, 0x0D6C);
1669ASSERT_REG_POSITION(stencil_front_func_ref, 0x4E5); 3281ASSERT_REG_POSITION(vertex_buffer, 0x0D74);
1670ASSERT_REG_POSITION(stencil_front_func_mask, 0x4E6); 3282ASSERT_REG_POSITION(depth_mode, 0x0D7C);
1671ASSERT_REG_POSITION(stencil_front_mask, 0x4E7); 3283ASSERT_REG_POSITION(clear_color, 0x0D80);
1672ASSERT_REG_POSITION(frag_color_clamp, 0x4EA); 3284ASSERT_REG_POSITION(clear_depth, 0x0D90);
1673ASSERT_REG_POSITION(screen_y_control, 0x4EB); 3285ASSERT_REG_POSITION(shader_cache_icache_prefetch, 0x0D94);
1674ASSERT_REG_POSITION(line_width_smooth, 0x4EC); 3286ASSERT_REG_POSITION(force_transition_to_beta, 0x0D98);
1675ASSERT_REG_POSITION(line_width_aliased, 0x4ED); 3287ASSERT_REG_POSITION(reduce_colour_thresholds, 0x0D9C);
1676ASSERT_REG_POSITION(invalidate_sampler_cache_no_wfi, 0x509); 3288ASSERT_REG_POSITION(clear_stencil, 0x0DA0);
1677ASSERT_REG_POSITION(invalidate_texture_header_cache_no_wfi, 0x50A); 3289ASSERT_REG_POSITION(invalidate_shader_cache_no_wfi, 0x0DA4);
1678ASSERT_REG_POSITION(vb_element_base, 0x50D); 3290ASSERT_REG_POSITION(zcull_serialization, 0x0DA8);
1679ASSERT_REG_POSITION(vb_base_instance, 0x50E); 3291ASSERT_REG_POSITION(polygon_mode_front, 0x0DAC);
1680ASSERT_REG_POSITION(clip_distance_enabled, 0x544); 3292ASSERT_REG_POSITION(polygon_mode_back, 0x0DB0);
1681ASSERT_REG_POSITION(samplecnt_enable, 0x545); 3293ASSERT_REG_POSITION(polygon_smooth, 0x0DB4);
1682ASSERT_REG_POSITION(point_size, 0x546); 3294ASSERT_REG_POSITION(zeta_mark_clean_ieee, 0x0DB8);
1683ASSERT_REG_POSITION(point_sprite_enable, 0x548); 3295ASSERT_REG_POSITION(zcull_dir_format, 0x0DBC);
1684ASSERT_REG_POSITION(counter_reset, 0x54C); 3296ASSERT_REG_POSITION(polygon_offset_point_enable, 0x0DC0);
1685ASSERT_REG_POSITION(multisample_enable, 0x54D); 3297ASSERT_REG_POSITION(polygon_offset_line_enable, 0x0DC4);
1686ASSERT_REG_POSITION(zeta_enable, 0x54E); 3298ASSERT_REG_POSITION(polygon_offset_fill_enable, 0x0DC8);
1687ASSERT_REG_POSITION(multisample_control, 0x54F); 3299ASSERT_REG_POSITION(patch_vertices, 0x0DCC);
1688ASSERT_REG_POSITION(condition, 0x554); 3300ASSERT_REG_POSITION(iterated_blend, 0x0DD0);
1689ASSERT_REG_POSITION(tsc, 0x557); 3301ASSERT_REG_POSITION(zcull_criteria, 0x0DD8);
1690ASSERT_REG_POSITION(polygon_offset_factor, 0x55B); 3302ASSERT_REG_POSITION(fragment_barrier, 0x0DE0);
1691ASSERT_REG_POSITION(line_smooth_enable, 0x55C); 3303ASSERT_REG_POSITION(sm_timeout, 0x0DE4);
1692ASSERT_REG_POSITION(tic, 0x55D); 3304ASSERT_REG_POSITION(primitive_restart_array, 0x0DE8);
1693ASSERT_REG_POSITION(stencil_two_side_enable, 0x565); 3305ASSERT_REG_POSITION(load_iterated_blend, 0x0DF0);
1694ASSERT_REG_POSITION(stencil_back_op_fail, 0x566); 3306ASSERT_REG_POSITION(window_offset_x, 0x0DF8);
1695ASSERT_REG_POSITION(stencil_back_op_zfail, 0x567); 3307ASSERT_REG_POSITION(window_offset_y, 0x0DFC);
1696ASSERT_REG_POSITION(stencil_back_op_zpass, 0x568); 3308ASSERT_REG_POSITION(scissor_test, 0x0E00);
1697ASSERT_REG_POSITION(stencil_back_func_func, 0x569); 3309ASSERT_REG_POSITION(select_texture_headers, 0x0F10);
1698ASSERT_REG_POSITION(framebuffer_srgb, 0x56E); 3310ASSERT_REG_POSITION(vpc_perf, 0x0F14);
1699ASSERT_REG_POSITION(polygon_offset_units, 0x56F); 3311ASSERT_REG_POSITION(pm_local_trigger, 0x0F18);
1700ASSERT_REG_POSITION(multisample_mode, 0x574); 3312ASSERT_REG_POSITION(post_z_pixel_imask, 0x0F1C);
1701ASSERT_REG_POSITION(point_coord_replace, 0x581); 3313ASSERT_REG_POSITION(const_color_rendering, 0x0F40);
1702ASSERT_REG_POSITION(code_address, 0x582); 3314ASSERT_REG_POSITION(stencil_back_func, 0x0F54);
1703ASSERT_REG_POSITION(draw, 0x585); 3315ASSERT_REG_POSITION(vertex_stream_substitute, 0x0F84);
1704ASSERT_REG_POSITION(primitive_restart, 0x591); 3316ASSERT_REG_POSITION(line_mode_clip_generated_edge_do_not_draw, 0x0F8C);
1705ASSERT_REG_POSITION(provoking_vertex_last, 0x5A1); 3317ASSERT_REG_POSITION(color_mask_common, 0x0F90);
1706ASSERT_REG_POSITION(index_array, 0x5F2); 3318ASSERT_REG_POSITION(vtg_warp_watermarks, 0x0F98);
1707ASSERT_REG_POSITION(small_index, 0x5F9); 3319ASSERT_REG_POSITION(depth_bounds, 0x0F9C);
1708ASSERT_REG_POSITION(polygon_offset_clamp, 0x61F); 3320ASSERT_REG_POSITION(sample_mask_target, 0x0FA4);
1709ASSERT_REG_POSITION(instanced_arrays, 0x620); 3321ASSERT_REG_POSITION(color_target_mrt_enable, 0x0FAC);
1710ASSERT_REG_POSITION(vp_point_size, 0x644); 3322ASSERT_REG_POSITION(non_multisampled_z, 0x0FB0);
1711ASSERT_REG_POSITION(cull_test_enabled, 0x646); 3323ASSERT_REG_POSITION(tir_mode, 0x0FB4);
1712ASSERT_REG_POSITION(front_face, 0x647); 3324ASSERT_REG_POSITION(anti_alias_raster, 0x0FB8);
1713ASSERT_REG_POSITION(cull_face, 0x648); 3325ASSERT_REG_POSITION(sample_mask_pos, 0x0FBC);
1714ASSERT_REG_POSITION(pixel_center_integer, 0x649); 3326ASSERT_REG_POSITION(surface_clip_id_memory, 0x0FCC);
1715ASSERT_REG_POSITION(viewport_transform_enabled, 0x64B); 3327ASSERT_REG_POSITION(tir_modulation, 0x0FD4);
1716ASSERT_REG_POSITION(view_volume_clip_control, 0x64F); 3328ASSERT_REG_POSITION(blend_control_allow_float_pixel_kills, 0x0FDC);
1717ASSERT_REG_POSITION(topology_override, 0x65C); 3329ASSERT_REG_POSITION(zeta, 0x0FE0);
1718ASSERT_REG_POSITION(depth_bounds_enable, 0x66F); 3330ASSERT_REG_POSITION(surface_clip, 0x0FF4);
1719ASSERT_REG_POSITION(logic_op, 0x671); 3331ASSERT_REG_POSITION(tiled_cache_treat_heavy_as_light, 0x0FFC);
1720ASSERT_REG_POSITION(clear_buffers, 0x674); 3332ASSERT_REG_POSITION(l2_cache_vaf, 0x1000);
1721ASSERT_REG_POSITION(color_mask, 0x680); 3333ASSERT_REG_POSITION(viewport_multicast, 0x1004);
1722ASSERT_REG_POSITION(query, 0x6C0); 3334ASSERT_REG_POSITION(tessellation_cut_height, 0x1008);
1723ASSERT_REG_POSITION(vertex_array[0], 0x700); 3335ASSERT_REG_POSITION(max_gs_instances_per_task, 0x100C);
1724ASSERT_REG_POSITION(independent_blend, 0x780); 3336ASSERT_REG_POSITION(max_gs_output_vertices_per_task, 0x1010);
1725ASSERT_REG_POSITION(vertex_array_limit[0], 0x7C0); 3337ASSERT_REG_POSITION(reserved_sw_method0, 0x1014);
1726ASSERT_REG_POSITION(shader_config[0], 0x800); 3338ASSERT_REG_POSITION(gs_output_cb_storage_multiplier, 0x1018);
1727ASSERT_REG_POSITION(firmware, 0x8C0); 3339ASSERT_REG_POSITION(beta_cb_storage_constant, 0x101C);
1728ASSERT_REG_POSITION(const_buffer, 0x8E0); 3340ASSERT_REG_POSITION(ti_output_cb_storage_multiplier, 0x1020);
1729ASSERT_REG_POSITION(cb_bind[0], 0x904); 3341ASSERT_REG_POSITION(alpha_cb_storage_constraint, 0x1024);
1730ASSERT_REG_POSITION(tex_cb_index, 0x982); 3342ASSERT_REG_POSITION(reserved_sw_method1, 0x1028);
1731ASSERT_REG_POSITION(tfb_varying_locs, 0xA00); 3343ASSERT_REG_POSITION(reserved_sw_method2, 0x102C);
1732ASSERT_REG_POSITION(ssbo_info, 0xD18); 3344ASSERT_REG_POSITION(tir_modulation_coeff, 0x1030);
1733ASSERT_REG_POSITION(tex_info_buffers.address[0], 0xD2A); 3345ASSERT_REG_POSITION(spare_nop, 0x1044);
1734ASSERT_REG_POSITION(tex_info_buffers.size[0], 0xD2F); 3346ASSERT_REG_POSITION(reserved_sw_method3_to_7, 0x10B0);
3347ASSERT_REG_POSITION(reduce_color_thresholds_unorm8, 0x10CC);
3348ASSERT_REG_POSITION(reserved_sw_method10_to_13, 0x10D0);
3349ASSERT_REG_POSITION(reduce_color_thresholds_unorm10, 0x10E0);
3350ASSERT_REG_POSITION(reduce_color_thresholds_unorm16, 0x10E4);
3351ASSERT_REG_POSITION(reduce_color_thresholds_fp11, 0x10E8);
3352ASSERT_REG_POSITION(reduce_color_thresholds_fp16, 0x10EC);
3353ASSERT_REG_POSITION(reduce_color_thresholds_srgb8, 0x10F0);
3354ASSERT_REG_POSITION(unbind_all_constant_buffers, 0x10F4);
3355ASSERT_REG_POSITION(clear_control, 0x10F8);
3356ASSERT_REG_POSITION(l2_cache_rop_non_interlocked_reads, 0x10FC);
3357ASSERT_REG_POSITION(reserved_sw_method14, 0x1100);
3358ASSERT_REG_POSITION(reserved_sw_method15, 0x1104);
3359ASSERT_REG_POSITION(no_operation_data_high, 0x110C);
3360ASSERT_REG_POSITION(depth_bias_control, 0x1110);
3361ASSERT_REG_POSITION(pm_trigger_end, 0x1114);
3362ASSERT_REG_POSITION(vertex_id_base, 0x1118);
3363ASSERT_REG_POSITION(stencil_compression_enabled, 0x111C);
3364ASSERT_REG_POSITION(vertex_output_attribute_skip_masks, 0x1120);
3365ASSERT_REG_POSITION(tir_control, 0x1130);
3366ASSERT_REG_POSITION(mutable_method_treat_mutable_as_heavy, 0x1134);
3367ASSERT_REG_POSITION(post_ps_use_pre_ps_coverage, 0x1138);
3368ASSERT_REG_POSITION(fill_via_triangle_mode, 0x113C);
3369ASSERT_REG_POSITION(blend_per_format_snorm8_unorm16_snorm16_enabled, 0x1140);
3370ASSERT_REG_POSITION(flush_pending_writes_sm_gloal_store, 0x1144);
3371ASSERT_REG_POSITION(vertex_attrib_format, 0x1160);
3372ASSERT_REG_POSITION(multisample_sample_locations, 0x11E0);
3373ASSERT_REG_POSITION(offset_render_target_index_by_viewport_index, 0x11F0);
3374ASSERT_REG_POSITION(force_heavy_method_sync, 0x11F4);
3375ASSERT_REG_POSITION(multisample_coverage_to_color, 0x11F8);
3376ASSERT_REG_POSITION(decompress_zeta_surface, 0x11FC);
3377ASSERT_REG_POSITION(zeta_sparse, 0x1208);
3378ASSERT_REG_POSITION(invalidate_sampler_cache, 0x120C);
3379ASSERT_REG_POSITION(invalidate_texture_header_cache, 0x1210);
3380ASSERT_REG_POSITION(vertex_array_instance_first, 0x1214);
3381ASSERT_REG_POSITION(vertex_array_instance_subsequent, 0x1218);
3382ASSERT_REG_POSITION(rt_control, 0x121C);
3383ASSERT_REG_POSITION(compression_threshold_samples, 0x1220);
3384ASSERT_REG_POSITION(ps_interlock_control, 0x1224);
3385ASSERT_REG_POSITION(zeta_size, 0x1228);
3386ASSERT_REG_POSITION(sampler_binding, 0x1234);
3387ASSERT_REG_POSITION(draw_auto_byte_count, 0x123C);
3388ASSERT_REG_POSITION(post_vtg_shader_attrib_skip_mask, 0x1240);
3389ASSERT_REG_POSITION(ps_ticket_dispenser_value, 0x1260);
3390ASSERT_REG_POSITION(circular_buffer_size, 0x1280);
3391ASSERT_REG_POSITION(vtg_register_watermarks, 0x1284);
3392ASSERT_REG_POSITION(invalidate_texture_cache_no_wfi, 0x1288);
3393ASSERT_REG_POSITION(l2_cache_rop_interlocked_reads, 0x1290);
3394ASSERT_REG_POSITION(primitive_restart_topology_change_index, 0x12A4);
3395ASSERT_REG_POSITION(zcull_region_enable, 0x12C8);
3396ASSERT_REG_POSITION(depth_test_enable, 0x12CC);
3397ASSERT_REG_POSITION(fill_mode, 0x12D0);
3398ASSERT_REG_POSITION(shade_mode, 0x12D4);
3399ASSERT_REG_POSITION(l2_cache_rop_non_interlocked_writes, 0x12D8);
3400ASSERT_REG_POSITION(l2_cache_rop_interlocked_writes, 0x12DC);
3401ASSERT_REG_POSITION(alpha_to_coverage_dither, 0x12E0);
3402ASSERT_REG_POSITION(blend_per_target_enabled, 0x12E4);
3403ASSERT_REG_POSITION(depth_write_enabled, 0x12E8);
3404ASSERT_REG_POSITION(alpha_test_enabled, 0x12EC);
3405ASSERT_REG_POSITION(inline_index_4x8_align, 0x1300);
3406ASSERT_REG_POSITION(inline_index_4x8_index, 0x1304);
3407ASSERT_REG_POSITION(d3d_cull_mode, 0x1308);
3408ASSERT_REG_POSITION(depth_test_func, 0x130C);
3409ASSERT_REG_POSITION(alpha_test_ref, 0x1310);
3410ASSERT_REG_POSITION(alpha_test_func, 0x1314);
3411ASSERT_REG_POSITION(draw_auto_stride, 0x1318);
3412ASSERT_REG_POSITION(blend_color, 0x131C);
3413ASSERT_REG_POSITION(invalidate_sampler_cache_lines, 0x1330);
3414ASSERT_REG_POSITION(invalidate_texture_header_cache_lines, 0x1334);
3415ASSERT_REG_POSITION(invalidate_texture_data_cache_lines, 0x1338);
3416ASSERT_REG_POSITION(blend, 0x133C);
3417ASSERT_REG_POSITION(stencil_enable, 0x1380);
3418ASSERT_REG_POSITION(stencil_front_op, 0x1384);
3419ASSERT_REG_POSITION(stencil_front_func, 0x1394);
3420ASSERT_REG_POSITION(draw_auto_start_byte_count, 0x13A4);
3421ASSERT_REG_POSITION(frag_color_clamp, 0x13A8);
3422ASSERT_REG_POSITION(window_origin, 0x13AC);
3423ASSERT_REG_POSITION(line_width_smooth, 0x13B0);
3424ASSERT_REG_POSITION(line_width_aliased, 0x13B4);
3425ASSERT_REG_POSITION(line_override_multisample, 0x1418);
3426ASSERT_REG_POSITION(alpha_hysteresis_rounds, 0x1420);
3427ASSERT_REG_POSITION(invalidate_sampler_cache_no_wfi, 0x1424);
3428ASSERT_REG_POSITION(invalidate_texture_header_cache_no_wfi, 0x1428);
3429ASSERT_REG_POSITION(global_base_vertex_index, 0x1434);
3430ASSERT_REG_POSITION(global_base_instance_index, 0x1438);
3431ASSERT_REG_POSITION(ps_warp_watermarks, 0x1450);
3432ASSERT_REG_POSITION(ps_regster_watermarks, 0x1454);
3433ASSERT_REG_POSITION(store_zcull, 0x1464);
3434ASSERT_REG_POSITION(iterated_blend_constants, 0x1480);
3435ASSERT_REG_POSITION(load_zcull, 0x1500);
3436ASSERT_REG_POSITION(surface_clip_id_height, 0x1504);
3437ASSERT_REG_POSITION(surface_clip_id_clear_rect, 0x1508);
3438ASSERT_REG_POSITION(user_clip_enable, 0x1510);
3439ASSERT_REG_POSITION(zpass_pixel_count_enable, 0x1514);
3440ASSERT_REG_POSITION(point_size, 0x1518);
3441ASSERT_REG_POSITION(zcull_stats_enable, 0x151C);
3442ASSERT_REG_POSITION(point_sprite_enable, 0x1520);
3443ASSERT_REG_POSITION(shader_exceptions_enable, 0x1528);
3444ASSERT_REG_POSITION(clear_report_value, 0x1530);
3445ASSERT_REG_POSITION(anti_alias_enable, 0x1534);
3446ASSERT_REG_POSITION(zeta_enable, 0x1538);
3447ASSERT_REG_POSITION(anti_alias_alpha_control, 0x153C);
3448ASSERT_REG_POSITION(render_enable, 0x1550);
3449ASSERT_REG_POSITION(tex_sampler, 0x155C);
3450ASSERT_REG_POSITION(slope_scale_depth_bias, 0x156C);
3451ASSERT_REG_POSITION(line_anti_alias_enable, 0x1570);
3452ASSERT_REG_POSITION(tex_header, 0x1574);
3453ASSERT_REG_POSITION(active_zcull_region_id, 0x1590);
3454ASSERT_REG_POSITION(stencil_two_side_enable, 0x1594);
3455ASSERT_REG_POSITION(stencil_back_op, 0x1598);
3456ASSERT_REG_POSITION(framebuffer_srgb, 0x15B8);
3457ASSERT_REG_POSITION(depth_bias, 0x15BC);
3458ASSERT_REG_POSITION(zcull_region_format, 0x15C8);
3459ASSERT_REG_POSITION(rt_layer, 0x15CC);
3460ASSERT_REG_POSITION(anti_alias_samples_mode, 0x15D0);
3461ASSERT_REG_POSITION(edge_flag, 0x15E4);
3462ASSERT_REG_POSITION(draw_inline_index, 0x15E8);
3463ASSERT_REG_POSITION(inline_index_2x16, 0x15EC);
3464ASSERT_REG_POSITION(vertex_global_base_offset, 0x15F4);
3465ASSERT_REG_POSITION(zcull_region_pixel_offset, 0x15FC);
3466ASSERT_REG_POSITION(point_sprite, 0x1604);
3467ASSERT_REG_POSITION(program_region, 0x1608);
3468ASSERT_REG_POSITION(default_attributes, 0x1610);
3469ASSERT_REG_POSITION(draw, 0x1614);
3470ASSERT_REG_POSITION(vertex_id_copy, 0x161C);
3471ASSERT_REG_POSITION(add_to_primitive_id, 0x1620);
3472ASSERT_REG_POSITION(load_to_primitive_id, 0x1624);
3473ASSERT_REG_POSITION(shader_based_cull, 0x162C);
3474ASSERT_REG_POSITION(class_version, 0x1638);
3475ASSERT_REG_POSITION(primitive_restart, 0x1644);
3476ASSERT_REG_POSITION(output_vertex_id, 0x164C);
3477ASSERT_REG_POSITION(anti_alias_point_enable, 0x1658);
3478ASSERT_REG_POSITION(point_center_mode, 0x165C);
3479ASSERT_REG_POSITION(line_smooth_params, 0x1668);
3480ASSERT_REG_POSITION(line_stipple_enable, 0x166C);
3481ASSERT_REG_POSITION(line_smooth_edge_table, 0x1670);
3482ASSERT_REG_POSITION(line_stipple_params, 0x1680);
3483ASSERT_REG_POSITION(provoking_vertex, 0x1684);
3484ASSERT_REG_POSITION(two_sided_light_enabled, 0x1688);
3485ASSERT_REG_POSITION(polygon_stipple_enabled, 0x168C);
3486ASSERT_REG_POSITION(shader_control, 0x1690);
3487ASSERT_REG_POSITION(class_version_check, 0x16A0);
3488ASSERT_REG_POSITION(sph_version, 0x16A4);
3489ASSERT_REG_POSITION(sph_version_check, 0x16A8);
3490ASSERT_REG_POSITION(alpha_to_coverage_override, 0x16B4);
3491ASSERT_REG_POSITION(polygon_stipple_pattern, 0x1700);
3492ASSERT_REG_POSITION(aam_version, 0x1790);
3493ASSERT_REG_POSITION(aam_version_check, 0x1794);
3494ASSERT_REG_POSITION(zeta_layer_offset, 0x179C);
3495ASSERT_REG_POSITION(index_buffer, 0x17C8);
3496ASSERT_REG_POSITION(index_buffer32_first, 0x17E4);
3497ASSERT_REG_POSITION(index_buffer16_first, 0x17E8);
3498ASSERT_REG_POSITION(index_buffer8_first, 0x17EC);
3499ASSERT_REG_POSITION(index_buffer32_subsequent, 0x17F0);
3500ASSERT_REG_POSITION(index_buffer16_subsequent, 0x17F4);
3501ASSERT_REG_POSITION(index_buffer8_subsequent, 0x17F8);
3502ASSERT_REG_POSITION(depth_bias_clamp, 0x187C);
3503ASSERT_REG_POSITION(vertex_stream_instances, 0x1880);
3504ASSERT_REG_POSITION(point_size_attribute, 0x1910);
3505ASSERT_REG_POSITION(gl_cull_test_enabled, 0x1918);
3506ASSERT_REG_POSITION(gl_front_face, 0x191C);
3507ASSERT_REG_POSITION(gl_cull_face, 0x1920);
3508ASSERT_REG_POSITION(viewport_pixel_center, 0x1924);
3509ASSERT_REG_POSITION(viewport_scale_offset_enbled, 0x192C);
3510ASSERT_REG_POSITION(viewport_clip_control, 0x193C);
3511ASSERT_REG_POSITION(user_clip_op, 0x1940);
3512ASSERT_REG_POSITION(render_enable_override, 0x1944);
3513ASSERT_REG_POSITION(primitive_topology_control, 0x1948);
3514ASSERT_REG_POSITION(window_clip_enable, 0x194C);
3515ASSERT_REG_POSITION(invalidate_zcull, 0x1958);
3516ASSERT_REG_POSITION(zcull, 0x1968);
3517ASSERT_REG_POSITION(topology_override, 0x1970);
3518ASSERT_REG_POSITION(zcull_sync, 0x1978);
3519ASSERT_REG_POSITION(clip_id_test_enable, 0x197C);
3520ASSERT_REG_POSITION(surface_clip_id_width, 0x1980);
3521ASSERT_REG_POSITION(clip_id, 0x1984);
3522ASSERT_REG_POSITION(depth_bounds_enable, 0x19BC);
3523ASSERT_REG_POSITION(blend_float_zero_times_anything_is_zero, 0x19C0);
3524ASSERT_REG_POSITION(logic_op, 0x19C4);
3525ASSERT_REG_POSITION(z_compression_enable, 0x19CC);
3526ASSERT_REG_POSITION(clear_surface, 0x19D0);
3527ASSERT_REG_POSITION(clear_clip_id_surface, 0x19D4);
3528ASSERT_REG_POSITION(color_compression_enable, 0x19E0);
3529ASSERT_REG_POSITION(color_mask, 0x1A00);
3530ASSERT_REG_POSITION(pipe_nop, 0x1A2C);
3531ASSERT_REG_POSITION(spare, 0x1A30);
3532ASSERT_REG_POSITION(report_semaphore, 0x1B00);
3533ASSERT_REG_POSITION(vertex_streams, 0x1C00);
3534ASSERT_REG_POSITION(blend_per_target, 0x1E00);
3535ASSERT_REG_POSITION(vertex_stream_limits, 0x1F00);
3536ASSERT_REG_POSITION(pipelines, 0x2000);
3537ASSERT_REG_POSITION(falcon, 0x2300);
3538ASSERT_REG_POSITION(const_buffer, 0x2380);
3539ASSERT_REG_POSITION(bind_groups, 0x2400);
3540ASSERT_REG_POSITION(color_clamp_enable, 0x2600);
3541ASSERT_REG_POSITION(bindless_texture_const_buffer_slot, 0x2608);
3542ASSERT_REG_POSITION(trap_handler, 0x260C);
3543ASSERT_REG_POSITION(stream_out_layout, 0x2800);
3544ASSERT_REG_POSITION(shader_performance, 0x333C);
3545ASSERT_REG_POSITION(shadow_scratch, 0x3400);
1735 3546
1736#undef ASSERT_REG_POSITION 3547#undef ASSERT_REG_POSITION
1737 3548
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h
index 0a4a8b14f..d0709dc69 100644
--- a/src/video_core/gpu.h
+++ b/src/video_core/gpu.h
@@ -24,11 +24,15 @@ namespace Tegra {
24class DmaPusher; 24class DmaPusher;
25struct CommandList; 25struct CommandList;
26 26
27// TODO: Implement the commented ones
27enum class RenderTargetFormat : u32 { 28enum class RenderTargetFormat : u32 {
28 NONE = 0x0, 29 NONE = 0x0,
29 R32B32G32A32_FLOAT = 0xC0, 30 R32B32G32A32_FLOAT = 0xC0,
30 R32G32B32A32_SINT = 0xC1, 31 R32G32B32A32_SINT = 0xC1,
31 R32G32B32A32_UINT = 0xC2, 32 R32G32B32A32_UINT = 0xC2,
33 // R32G32B32X32_FLOAT = 0xC3,
34 // R32G32B32X32_SINT = 0xC4,
35 // R32G32B32X32_UINT = 0xC5,
32 R16G16B16A16_UNORM = 0xC6, 36 R16G16B16A16_UNORM = 0xC6,
33 R16G16B16A16_SNORM = 0xC7, 37 R16G16B16A16_SNORM = 0xC7,
34 R16G16B16A16_SINT = 0xC8, 38 R16G16B16A16_SINT = 0xC8,
@@ -38,8 +42,8 @@ enum class RenderTargetFormat : u32 {
38 R32G32_SINT = 0xCC, 42 R32G32_SINT = 0xCC,
39 R32G32_UINT = 0xCD, 43 R32G32_UINT = 0xCD,
40 R16G16B16X16_FLOAT = 0xCE, 44 R16G16B16X16_FLOAT = 0xCE,
41 B8G8R8A8_UNORM = 0xCF, 45 A8R8G8B8_UNORM = 0xCF,
42 B8G8R8A8_SRGB = 0xD0, 46 A8R8G8B8_SRGB = 0xD0,
43 A2B10G10R10_UNORM = 0xD1, 47 A2B10G10R10_UNORM = 0xD1,
44 A2B10G10R10_UINT = 0xD2, 48 A2B10G10R10_UINT = 0xD2,
45 A8B8G8R8_UNORM = 0xD5, 49 A8B8G8R8_UNORM = 0xD5,
@@ -52,10 +56,13 @@ enum class RenderTargetFormat : u32 {
52 R16G16_SINT = 0xDC, 56 R16G16_SINT = 0xDC,
53 R16G16_UINT = 0xDD, 57 R16G16_UINT = 0xDD,
54 R16G16_FLOAT = 0xDE, 58 R16G16_FLOAT = 0xDE,
59 // A2R10G10B10_UNORM = 0xDF,
55 B10G11R11_FLOAT = 0xE0, 60 B10G11R11_FLOAT = 0xE0,
56 R32_SINT = 0xE3, 61 R32_SINT = 0xE3,
57 R32_UINT = 0xE4, 62 R32_UINT = 0xE4,
58 R32_FLOAT = 0xE5, 63 R32_FLOAT = 0xE5,
64 // X8R8G8B8_UNORM = 0xE6,
65 // X8R8G8B8_SRGB = 0xE7,
59 R5G6B5_UNORM = 0xE8, 66 R5G6B5_UNORM = 0xE8,
60 A1R5G5B5_UNORM = 0xE9, 67 A1R5G5B5_UNORM = 0xE9,
61 R8G8_UNORM = 0xEA, 68 R8G8_UNORM = 0xEA,
@@ -71,17 +78,42 @@ enum class RenderTargetFormat : u32 {
71 R8_SNORM = 0xF4, 78 R8_SNORM = 0xF4,
72 R8_SINT = 0xF5, 79 R8_SINT = 0xF5,
73 R8_UINT = 0xF6, 80 R8_UINT = 0xF6,
81
82 /*
83 A8_UNORM = 0xF7,
84 X1R5G5B5_UNORM = 0xF8,
85 X8B8G8R8_UNORM = 0xF9,
86 X8B8G8R8_SRGB = 0xFA,
87 Z1R5G5B5_UNORM = 0xFB,
88 O1R5G5B5_UNORM = 0xFC,
89 Z8R8G8B8_UNORM = 0xFD,
90 O8R8G8B8_UNORM = 0xFE,
91 R32_UNORM = 0xFF,
92 A16_UNORM = 0x40,
93 A16_FLOAT = 0x41,
94 A32_FLOAT = 0x42,
95 A8R8_UNORM = 0x43,
96 R16A16_UNORM = 0x44,
97 R16A16_FLOAT = 0x45,
98 R32A32_FLOAT = 0x46,
99 B8G8R8A8_UNORM = 0x47,
100 */
74}; 101};
75 102
76enum class DepthFormat : u32 { 103enum class DepthFormat : u32 {
77 D32_FLOAT = 0xA, 104 Z32_FLOAT = 0xA,
78 D16_UNORM = 0x13, 105 Z16_UNORM = 0x13,
79 S8_UINT_Z24_UNORM = 0x14, 106 Z24_UNORM_S8_UINT = 0x14,
80 D24X8_UNORM = 0x15, 107 X8Z24_UNORM = 0x15,
81 D24S8_UNORM = 0x16, 108 S8Z24_UNORM = 0x16,
82 S8_UINT = 0x17, 109 S8_UINT = 0x17,
83 D24C8_UNORM = 0x18, 110 V8Z24_UNORM = 0x18,
84 D32_FLOAT_S8X24_UINT = 0x19, 111 Z32_FLOAT_X24S8_UINT = 0x19,
112 /*
113 X8Z24_UNORM_X16V8S8_UINT = 0x1D,
114 Z32_FLOAT_X16V8X8_UINT = 0x1E,
115 Z32_FLOAT_X16V8S8_UINT = 0x1F,
116 */
85}; 117};
86 118
87namespace Engines { 119namespace Engines {
diff --git a/src/video_core/macro/macro_hle.cpp b/src/video_core/macro/macro_hle.cpp
index cabe8dcbf..8a8adbb42 100644
--- a/src/video_core/macro/macro_hle.cpp
+++ b/src/video_core/macro/macro_hle.cpp
@@ -21,16 +21,16 @@ void HLE_771BB18C62444DA0(Engines::Maxwell3D& maxwell3d, const std::vector<u32>&
21 21
22 maxwell3d.regs.draw.topology.Assign( 22 maxwell3d.regs.draw.topology.Assign(
23 static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[0] & 0x3ffffff)); 23 static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[0] & 0x3ffffff));
24 maxwell3d.regs.vb_base_instance = parameters[5]; 24 maxwell3d.regs.global_base_instance_index = parameters[5];
25 maxwell3d.mme_draw.instance_count = instance_count; 25 maxwell3d.mme_draw.instance_count = instance_count;
26 maxwell3d.regs.vb_element_base = parameters[3]; 26 maxwell3d.regs.global_base_vertex_index = parameters[3];
27 maxwell3d.regs.index_array.count = parameters[1]; 27 maxwell3d.regs.index_buffer.count = parameters[1];
28 maxwell3d.regs.index_array.first = parameters[4]; 28 maxwell3d.regs.index_buffer.first = parameters[4];
29 29
30 if (maxwell3d.ShouldExecute()) { 30 if (maxwell3d.ShouldExecute()) {
31 maxwell3d.Rasterizer().Draw(true, true); 31 maxwell3d.Rasterizer().Draw(true, true);
32 } 32 }
33 maxwell3d.regs.index_array.count = 0; 33 maxwell3d.regs.index_buffer.count = 0;
34 maxwell3d.mme_draw.instance_count = 0; 34 maxwell3d.mme_draw.instance_count = 0;
35 maxwell3d.mme_draw.current_mode = Engines::Maxwell3D::MMEDrawMode::Undefined; 35 maxwell3d.mme_draw.current_mode = Engines::Maxwell3D::MMEDrawMode::Undefined;
36} 36}
@@ -40,7 +40,7 @@ void HLE_0D61FC9FAAC9FCAD(Engines::Maxwell3D& maxwell3d, const std::vector<u32>&
40 40
41 maxwell3d.regs.vertex_buffer.first = parameters[3]; 41 maxwell3d.regs.vertex_buffer.first = parameters[3];
42 maxwell3d.regs.vertex_buffer.count = parameters[1]; 42 maxwell3d.regs.vertex_buffer.count = parameters[1];
43 maxwell3d.regs.vb_base_instance = parameters[4]; 43 maxwell3d.regs.global_base_instance_index = parameters[4];
44 maxwell3d.regs.draw.topology.Assign( 44 maxwell3d.regs.draw.topology.Assign(
45 static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[0])); 45 static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[0]));
46 maxwell3d.mme_draw.instance_count = count; 46 maxwell3d.mme_draw.instance_count = count;
@@ -57,12 +57,12 @@ void HLE_0217920100488FF7(Engines::Maxwell3D& maxwell3d, const std::vector<u32>&
57 const u32 instance_count = (maxwell3d.GetRegisterValue(0xD1B) & parameters[2]); 57 const u32 instance_count = (maxwell3d.GetRegisterValue(0xD1B) & parameters[2]);
58 const u32 element_base = parameters[4]; 58 const u32 element_base = parameters[4];
59 const u32 base_instance = parameters[5]; 59 const u32 base_instance = parameters[5];
60 maxwell3d.regs.index_array.first = parameters[3]; 60 maxwell3d.regs.index_buffer.first = parameters[3];
61 maxwell3d.regs.reg_array[0x446] = element_base; // vertex id base? 61 maxwell3d.regs.vertex_id_base = element_base;
62 maxwell3d.regs.index_array.count = parameters[1]; 62 maxwell3d.regs.index_buffer.count = parameters[1];
63 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; 63 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
64 maxwell3d.regs.vb_element_base = element_base; 64 maxwell3d.regs.global_base_vertex_index = element_base;
65 maxwell3d.regs.vb_base_instance = base_instance; 65 maxwell3d.regs.global_base_instance_index = base_instance;
66 maxwell3d.mme_draw.instance_count = instance_count; 66 maxwell3d.mme_draw.instance_count = instance_count;
67 maxwell3d.CallMethodFromMME(0x8e3, 0x640); 67 maxwell3d.CallMethodFromMME(0x8e3, 0x640);
68 maxwell3d.CallMethodFromMME(0x8e4, element_base); 68 maxwell3d.CallMethodFromMME(0x8e4, element_base);
@@ -72,10 +72,10 @@ void HLE_0217920100488FF7(Engines::Maxwell3D& maxwell3d, const std::vector<u32>&
72 if (maxwell3d.ShouldExecute()) { 72 if (maxwell3d.ShouldExecute()) {
73 maxwell3d.Rasterizer().Draw(true, true); 73 maxwell3d.Rasterizer().Draw(true, true);
74 } 74 }
75 maxwell3d.regs.reg_array[0x446] = 0x0; // vertex id base? 75 maxwell3d.regs.vertex_id_base = 0x0;
76 maxwell3d.regs.index_array.count = 0; 76 maxwell3d.regs.index_buffer.count = 0;
77 maxwell3d.regs.vb_element_base = 0x0; 77 maxwell3d.regs.global_base_vertex_index = 0x0;
78 maxwell3d.regs.vb_base_instance = 0x0; 78 maxwell3d.regs.global_base_instance_index = 0x0;
79 maxwell3d.mme_draw.instance_count = 0; 79 maxwell3d.mme_draw.instance_count = 0;
80 maxwell3d.CallMethodFromMME(0x8e3, 0x640); 80 maxwell3d.CallMethodFromMME(0x8e3, 0x640);
81 maxwell3d.CallMethodFromMME(0x8e4, 0x0); 81 maxwell3d.CallMethodFromMME(0x8e4, 0x0);
@@ -87,10 +87,10 @@ void HLE_0217920100488FF7(Engines::Maxwell3D& maxwell3d, const std::vector<u32>&
87void HLE_3F5E74B9C9A50164(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& parameters) { 87void HLE_3F5E74B9C9A50164(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& parameters) {
88 SCOPE_EXIT({ 88 SCOPE_EXIT({
89 // Clean everything. 89 // Clean everything.
90 maxwell3d.regs.reg_array[0x446] = 0x0; // vertex id base? 90 maxwell3d.regs.vertex_id_base = 0x0;
91 maxwell3d.regs.index_array.count = 0; 91 maxwell3d.regs.index_buffer.count = 0;
92 maxwell3d.regs.vb_element_base = 0x0; 92 maxwell3d.regs.global_base_vertex_index = 0x0;
93 maxwell3d.regs.vb_base_instance = 0x0; 93 maxwell3d.regs.global_base_instance_index = 0x0;
94 maxwell3d.mme_draw.instance_count = 0; 94 maxwell3d.mme_draw.instance_count = 0;
95 maxwell3d.CallMethodFromMME(0x8e3, 0x640); 95 maxwell3d.CallMethodFromMME(0x8e3, 0x640);
96 maxwell3d.CallMethodFromMME(0x8e4, 0x0); 96 maxwell3d.CallMethodFromMME(0x8e4, 0x0);
@@ -122,11 +122,11 @@ void HLE_3F5E74B9C9A50164(Engines::Maxwell3D& maxwell3d, const std::vector<u32>&
122 const u32 first_index = parameters[base + 2]; 122 const u32 first_index = parameters[base + 2];
123 const u32 base_vertex = parameters[base + 3]; 123 const u32 base_vertex = parameters[base + 3];
124 const u32 base_instance = parameters[base + 4]; 124 const u32 base_instance = parameters[base + 4];
125 maxwell3d.regs.index_array.first = first_index; 125 maxwell3d.regs.index_buffer.first = first_index;
126 maxwell3d.regs.reg_array[0x446] = base_vertex; 126 maxwell3d.regs.vertex_id_base = base_vertex;
127 maxwell3d.regs.index_array.count = num_vertices; 127 maxwell3d.regs.index_buffer.count = num_vertices;
128 maxwell3d.regs.vb_element_base = base_vertex; 128 maxwell3d.regs.global_base_vertex_index = base_vertex;
129 maxwell3d.regs.vb_base_instance = base_instance; 129 maxwell3d.regs.global_base_instance_index = base_instance;
130 maxwell3d.mme_draw.instance_count = instance_count; 130 maxwell3d.mme_draw.instance_count = instance_count;
131 maxwell3d.CallMethodFromMME(0x8e3, 0x640); 131 maxwell3d.CallMethodFromMME(0x8e3, 0x640);
132 maxwell3d.CallMethodFromMME(0x8e4, base_vertex); 132 maxwell3d.CallMethodFromMME(0x8e4, base_vertex);
diff --git a/src/video_core/query_cache.h b/src/video_core/query_cache.h
index b0ebe71b7..00ce53e3e 100644
--- a/src/video_core/query_cache.h
+++ b/src/video_core/query_cache.h
@@ -137,7 +137,7 @@ public:
137 std::unique_lock lock{mutex}; 137 std::unique_lock lock{mutex};
138 if (maxwell3d) { 138 if (maxwell3d) {
139 const auto& regs = maxwell3d->regs; 139 const auto& regs = maxwell3d->regs;
140 Stream(VideoCore::QueryType::SamplesPassed).Update(regs.samplecnt_enable); 140 Stream(VideoCore::QueryType::SamplesPassed).Update(regs.zpass_pixel_count_enable);
141 } 141 }
142 } 142 }
143 143
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
index 41493a7da..1d20a79ec 100644
--- a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
+++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
@@ -73,8 +73,8 @@ GLenum AssemblyStage(size_t stage_index) {
73/// @param location Hardware location 73/// @param location Hardware location
74/// @return Pair of ARB_transform_feedback3 token stream first and third arguments 74/// @return Pair of ARB_transform_feedback3 token stream first and third arguments
75/// @note Read https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_transform_feedback3.txt 75/// @note Read https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_transform_feedback3.txt
76std::pair<GLint, GLint> TransformFeedbackEnum(u8 location) { 76std::pair<GLint, GLint> TransformFeedbackEnum(u32 location) {
77 const u8 index = location / 4; 77 const auto index = location / 4;
78 if (index >= 8 && index <= 39) { 78 if (index >= 8 && index <= 39) {
79 return {GL_GENERIC_ATTRIB_NV, index - 8}; 79 return {GL_GENERIC_ATTRIB_NV, index - 8};
80 } 80 }
@@ -286,7 +286,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
286 buffer_cache.runtime.SetEnableStorageBuffers(use_storage_buffers); 286 buffer_cache.runtime.SetEnableStorageBuffers(use_storage_buffers);
287 287
288 const auto& regs{maxwell3d->regs}; 288 const auto& regs{maxwell3d->regs};
289 const bool via_header_index{regs.sampler_index == Maxwell::SamplerIndex::ViaHeaderIndex}; 289 const bool via_header_index{regs.sampler_binding == Maxwell::SamplerBinding::ViaHeaderBinding};
290 const auto config_stage{[&](size_t stage) LAMBDA_FORCEINLINE { 290 const auto config_stage{[&](size_t stage) LAMBDA_FORCEINLINE {
291 const Shader::Info& info{stage_infos[stage]}; 291 const Shader::Info& info{stage_infos[stage]};
292 buffer_cache.UnbindGraphicsStorageBuffers(stage); 292 buffer_cache.UnbindGraphicsStorageBuffers(stage);
@@ -557,10 +557,25 @@ void GraphicsPipeline::GenerateTransformFeedbackState() {
557 ++current_stream; 557 ++current_stream;
558 558
559 const auto& locations = key.xfb_state.varyings[feedback]; 559 const auto& locations = key.xfb_state.varyings[feedback];
560 std::optional<u8> current_index; 560 std::optional<u32> current_index;
561 for (u32 offset = 0; offset < layout.varying_count; ++offset) { 561 for (u32 offset = 0; offset < layout.varying_count; ++offset) {
562 const u8 location = locations[offset]; 562 const auto get_attribute = [&locations](u32 index) -> u32 {
563 const u8 index = location / 4; 563 switch (index % 4) {
564 case 0:
565 return locations[index / 4].attribute0.Value();
566 case 1:
567 return locations[index / 4].attribute1.Value();
568 case 2:
569 return locations[index / 4].attribute2.Value();
570 case 3:
571 return locations[index / 4].attribute3.Value();
572 }
573 UNREACHABLE();
574 return 0;
575 };
576
577 const auto attribute{get_attribute(offset)};
578 const auto index = attribute / 4U;
564 579
565 if (current_index == index) { 580 if (current_index == index) {
566 // Increase number of components of the previous attachment 581 // Increase number of components of the previous attachment
@@ -569,7 +584,7 @@ void GraphicsPipeline::GenerateTransformFeedbackState() {
569 } 584 }
570 current_index = index; 585 current_index = index;
571 586
572 std::tie(cursor[0], cursor[2]) = TransformFeedbackEnum(location); 587 std::tie(cursor[0], cursor[2]) = TransformFeedbackEnum(attribute);
573 cursor[1] = 1; 588 cursor[1] = 1;
574 cursor += XFB_ENTRY_STRIDE; 589 cursor += XFB_ENTRY_STRIDE;
575 } 590 }
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.h b/src/video_core/renderer_opengl/gl_graphics_pipeline.h
index a0f0e63cb..ea53ddb46 100644
--- a/src/video_core/renderer_opengl/gl_graphics_pipeline.h
+++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.h
@@ -37,8 +37,8 @@ struct GraphicsPipelineKey {
37 BitField<0, 1, u32> xfb_enabled; 37 BitField<0, 1, u32> xfb_enabled;
38 BitField<1, 1, u32> early_z; 38 BitField<1, 1, u32> early_z;
39 BitField<2, 4, Maxwell::PrimitiveTopology> gs_input_topology; 39 BitField<2, 4, Maxwell::PrimitiveTopology> gs_input_topology;
40 BitField<6, 2, Maxwell::TessellationPrimitive> tessellation_primitive; 40 BitField<6, 2, Maxwell::Tessellation::DomainType> tessellation_primitive;
41 BitField<8, 2, Maxwell::TessellationSpacing> tessellation_spacing; 41 BitField<8, 2, Maxwell::Tessellation::Spacing> tessellation_spacing;
42 BitField<10, 1, u32> tessellation_clockwise; 42 BitField<10, 1, u32> tessellation_clockwise;
43 }; 43 };
44 std::array<u32, 3> padding; 44 std::array<u32, 3> padding;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index c2d80605d..cce00cea8 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -87,7 +87,7 @@ void RasterizerOpenGL::SyncVertexFormats() {
87 } 87 }
88 flags[Dirty::VertexFormat0 + index] = false; 88 flags[Dirty::VertexFormat0 + index] = false;
89 89
90 const auto attrib = maxwell3d->regs.vertex_attrib_format[index]; 90 const auto& attrib = maxwell3d->regs.vertex_attrib_format[index];
91 const auto gl_index = static_cast<GLuint>(index); 91 const auto gl_index = static_cast<GLuint>(index);
92 92
93 // Disable constant attributes. 93 // Disable constant attributes.
@@ -97,8 +97,8 @@ void RasterizerOpenGL::SyncVertexFormats() {
97 } 97 }
98 glEnableVertexAttribArray(gl_index); 98 glEnableVertexAttribArray(gl_index);
99 99
100 if (attrib.type == Maxwell::VertexAttribute::Type::SignedInt || 100 if (attrib.type == Maxwell::VertexAttribute::Type::SInt ||
101 attrib.type == Maxwell::VertexAttribute::Type::UnsignedInt) { 101 attrib.type == Maxwell::VertexAttribute::Type::UInt) {
102 glVertexAttribIFormat(gl_index, attrib.ComponentCount(), 102 glVertexAttribIFormat(gl_index, attrib.ComponentCount(),
103 MaxwellToGL::VertexFormat(attrib), attrib.offset); 103 MaxwellToGL::VertexFormat(attrib), attrib.offset);
104 } else { 104 } else {
@@ -125,8 +125,8 @@ void RasterizerOpenGL::SyncVertexInstances() {
125 flags[Dirty::VertexInstance0 + index] = false; 125 flags[Dirty::VertexInstance0 + index] = false;
126 126
127 const auto gl_index = static_cast<GLuint>(index); 127 const auto gl_index = static_cast<GLuint>(index);
128 const bool instancing_enabled = regs.instanced_arrays.IsInstancingEnabled(gl_index); 128 const bool instancing_enabled = regs.vertex_stream_instances.IsInstancingEnabled(gl_index);
129 const GLuint divisor = instancing_enabled ? regs.vertex_array[index].divisor : 0; 129 const GLuint divisor = instancing_enabled ? regs.vertex_streams[index].frequency : 0;
130 glVertexBindingDivisor(gl_index, divisor); 130 glVertexBindingDivisor(gl_index, divisor);
131 } 131 }
132} 132}
@@ -147,27 +147,27 @@ void RasterizerOpenGL::Clear() {
147 bool use_depth{}; 147 bool use_depth{};
148 bool use_stencil{}; 148 bool use_stencil{};
149 149
150 if (regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B || 150 if (regs.clear_surface.R || regs.clear_surface.G || regs.clear_surface.B ||
151 regs.clear_buffers.A) { 151 regs.clear_surface.A) {
152 use_color = true; 152 use_color = true;
153 153
154 const GLuint index = regs.clear_buffers.RT; 154 const GLuint index = regs.clear_surface.RT;
155 state_tracker.NotifyColorMask(index); 155 state_tracker.NotifyColorMask(index);
156 glColorMaski(index, regs.clear_buffers.R != 0, regs.clear_buffers.G != 0, 156 glColorMaski(index, regs.clear_surface.R != 0, regs.clear_surface.G != 0,
157 regs.clear_buffers.B != 0, regs.clear_buffers.A != 0); 157 regs.clear_surface.B != 0, regs.clear_surface.A != 0);
158 158
159 // TODO(Rodrigo): Determine if clamping is used on clears 159 // TODO(Rodrigo): Determine if clamping is used on clears
160 SyncFragmentColorClampState(); 160 SyncFragmentColorClampState();
161 SyncFramebufferSRGB(); 161 SyncFramebufferSRGB();
162 } 162 }
163 if (regs.clear_buffers.Z) { 163 if (regs.clear_surface.Z) {
164 ASSERT_MSG(regs.zeta_enable != 0, "Tried to clear Z but buffer is not enabled!"); 164 ASSERT_MSG(regs.zeta_enable != 0, "Tried to clear Z but buffer is not enabled!");
165 use_depth = true; 165 use_depth = true;
166 166
167 state_tracker.NotifyDepthMask(); 167 state_tracker.NotifyDepthMask();
168 glDepthMask(GL_TRUE); 168 glDepthMask(GL_TRUE);
169 } 169 }
170 if (regs.clear_buffers.S) { 170 if (regs.clear_surface.S) {
171 ASSERT_MSG(regs.zeta_enable, "Tried to clear stencil but buffer is not enabled!"); 171 ASSERT_MSG(regs.zeta_enable, "Tried to clear stencil but buffer is not enabled!");
172 use_stencil = true; 172 use_stencil = true;
173 } 173 }
@@ -184,16 +184,16 @@ void RasterizerOpenGL::Clear() {
184 texture_cache.UpdateRenderTargets(true); 184 texture_cache.UpdateRenderTargets(true);
185 state_tracker.BindFramebuffer(texture_cache.GetFramebuffer()->Handle()); 185 state_tracker.BindFramebuffer(texture_cache.GetFramebuffer()->Handle());
186 SyncViewport(); 186 SyncViewport();
187 if (regs.clear_flags.scissor) { 187 if (regs.clear_control.use_scissor) {
188 SyncScissorTest(); 188 SyncScissorTest();
189 } else { 189 } else {
190 state_tracker.NotifyScissor0(); 190 state_tracker.NotifyScissor0();
191 glDisablei(GL_SCISSOR_TEST, 0); 191 glDisablei(GL_SCISSOR_TEST, 0);
192 } 192 }
193 UNIMPLEMENTED_IF(regs.clear_flags.viewport); 193 UNIMPLEMENTED_IF(regs.clear_control.use_viewport_clip0);
194 194
195 if (use_color) { 195 if (use_color) {
196 glClearBufferfv(GL_COLOR, regs.clear_buffers.RT, regs.clear_color); 196 glClearBufferfv(GL_COLOR, regs.clear_surface.RT, regs.clear_color.data());
197 } 197 }
198 if (use_depth && use_stencil) { 198 if (use_depth && use_stencil) {
199 glClearBufferfi(GL_DEPTH_STENCIL, 0, regs.clear_depth, regs.clear_stencil); 199 glClearBufferfi(GL_DEPTH_STENCIL, 0, regs.clear_depth, regs.clear_stencil);
@@ -227,14 +227,14 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
227 const GLenum primitive_mode = MaxwellToGL::PrimitiveTopology(maxwell3d->regs.draw.topology); 227 const GLenum primitive_mode = MaxwellToGL::PrimitiveTopology(maxwell3d->regs.draw.topology);
228 BeginTransformFeedback(pipeline, primitive_mode); 228 BeginTransformFeedback(pipeline, primitive_mode);
229 229
230 const GLuint base_instance = static_cast<GLuint>(maxwell3d->regs.vb_base_instance); 230 const GLuint base_instance = static_cast<GLuint>(maxwell3d->regs.global_base_instance_index);
231 const GLsizei num_instances = 231 const GLsizei num_instances =
232 static_cast<GLsizei>(is_instanced ? maxwell3d->mme_draw.instance_count : 1); 232 static_cast<GLsizei>(is_instanced ? maxwell3d->mme_draw.instance_count : 1);
233 if (is_indexed) { 233 if (is_indexed) {
234 const GLint base_vertex = static_cast<GLint>(maxwell3d->regs.vb_element_base); 234 const GLint base_vertex = static_cast<GLint>(maxwell3d->regs.global_base_vertex_index);
235 const GLsizei num_vertices = static_cast<GLsizei>(maxwell3d->regs.index_array.count); 235 const GLsizei num_vertices = static_cast<GLsizei>(maxwell3d->regs.index_buffer.count);
236 const GLvoid* const offset = buffer_cache_runtime.IndexOffset(); 236 const GLvoid* const offset = buffer_cache_runtime.IndexOffset();
237 const GLenum format = MaxwellToGL::IndexFormat(maxwell3d->regs.index_array.format); 237 const GLenum format = MaxwellToGL::IndexFormat(maxwell3d->regs.index_buffer.format);
238 if (num_instances == 1 && base_instance == 0 && base_vertex == 0) { 238 if (num_instances == 1 && base_instance == 0 && base_vertex == 0) {
239 glDrawElements(primitive_mode, num_vertices, format, offset); 239 glDrawElements(primitive_mode, num_vertices, format, offset);
240 } else if (num_instances == 1 && base_instance == 0) { 240 } else if (num_instances == 1 && base_instance == 0) {
@@ -555,9 +555,9 @@ void RasterizerOpenGL::SyncViewport() {
555 if (dirty_viewport || dirty_clip_control || flags[Dirty::FrontFace]) { 555 if (dirty_viewport || dirty_clip_control || flags[Dirty::FrontFace]) {
556 flags[Dirty::FrontFace] = false; 556 flags[Dirty::FrontFace] = false;
557 557
558 GLenum mode = MaxwellToGL::FrontFace(regs.front_face); 558 GLenum mode = MaxwellToGL::FrontFace(regs.gl_front_face);
559 bool flip_faces = true; 559 bool flip_faces = true;
560 if (regs.screen_y_control.triangle_rast_flip != 0) { 560 if (regs.window_origin.flip_y != 0) {
561 flip_faces = !flip_faces; 561 flip_faces = !flip_faces;
562 } 562 }
563 if (regs.viewport_transform[0].scale_y < 0.0f) { 563 if (regs.viewport_transform[0].scale_y < 0.0f) {
@@ -582,14 +582,15 @@ void RasterizerOpenGL::SyncViewport() {
582 if (regs.viewport_transform[0].scale_y < 0.0f) { 582 if (regs.viewport_transform[0].scale_y < 0.0f) {
583 flip_y = !flip_y; 583 flip_y = !flip_y;
584 } 584 }
585 if (regs.screen_y_control.y_negate != 0) { 585 const bool lower_left{regs.window_origin.mode != Maxwell::WindowOrigin::Mode::UpperLeft};
586 if (lower_left) {
586 flip_y = !flip_y; 587 flip_y = !flip_y;
587 } 588 }
588 const bool is_zero_to_one = regs.depth_mode == Maxwell::DepthMode::ZeroToOne; 589 const bool is_zero_to_one = regs.depth_mode == Maxwell::DepthMode::ZeroToOne;
589 const GLenum origin = flip_y ? GL_UPPER_LEFT : GL_LOWER_LEFT; 590 const GLenum origin = flip_y ? GL_UPPER_LEFT : GL_LOWER_LEFT;
590 const GLenum depth = is_zero_to_one ? GL_ZERO_TO_ONE : GL_NEGATIVE_ONE_TO_ONE; 591 const GLenum depth = is_zero_to_one ? GL_ZERO_TO_ONE : GL_NEGATIVE_ONE_TO_ONE;
591 state_tracker.ClipControl(origin, depth); 592 state_tracker.ClipControl(origin, depth);
592 state_tracker.SetYNegate(regs.screen_y_control.y_negate != 0); 593 state_tracker.SetYNegate(lower_left);
593 } 594 }
594 const bool is_rescaling{texture_cache.IsRescaling()}; 595 const bool is_rescaling{texture_cache.IsRescaling()};
595 const float scale = is_rescaling ? Settings::values.resolution_info.up_factor : 1.0f; 596 const float scale = is_rescaling ? Settings::values.resolution_info.up_factor : 1.0f;
@@ -657,7 +658,8 @@ void RasterizerOpenGL::SyncDepthClamp() {
657 } 658 }
658 flags[Dirty::DepthClampEnabled] = false; 659 flags[Dirty::DepthClampEnabled] = false;
659 660
660 oglEnable(GL_DEPTH_CLAMP, maxwell3d->regs.view_volume_clip_control.depth_clamp_disabled == 0); 661 oglEnable(GL_DEPTH_CLAMP, maxwell3d->regs.viewport_clip_control.geometry_clip !=
662 Maxwell::ViewportClipControl::GeometryClip::Passthrough);
661} 663}
662 664
663void RasterizerOpenGL::SyncClipEnabled(u32 clip_mask) { 665void RasterizerOpenGL::SyncClipEnabled(u32 clip_mask) {
@@ -667,7 +669,7 @@ void RasterizerOpenGL::SyncClipEnabled(u32 clip_mask) {
667 } 669 }
668 flags[Dirty::ClipDistances] = false; 670 flags[Dirty::ClipDistances] = false;
669 671
670 clip_mask &= maxwell3d->regs.clip_distance_enabled; 672 clip_mask &= maxwell3d->regs.user_clip_enable.raw;
671 if (clip_mask == last_clip_distance_mask) { 673 if (clip_mask == last_clip_distance_mask) {
672 return; 674 return;
673 } 675 }
@@ -689,9 +691,9 @@ void RasterizerOpenGL::SyncCullMode() {
689 if (flags[Dirty::CullTest]) { 691 if (flags[Dirty::CullTest]) {
690 flags[Dirty::CullTest] = false; 692 flags[Dirty::CullTest] = false;
691 693
692 if (regs.cull_test_enabled) { 694 if (regs.gl_cull_test_enabled) {
693 glEnable(GL_CULL_FACE); 695 glEnable(GL_CULL_FACE);
694 glCullFace(MaxwellToGL::CullFace(regs.cull_face)); 696 glCullFace(MaxwellToGL::CullFace(regs.gl_cull_face));
695 } else { 697 } else {
696 glDisable(GL_CULL_FACE); 698 glDisable(GL_CULL_FACE);
697 } 699 }
@@ -743,20 +745,20 @@ void RasterizerOpenGL::SyncStencilTestState() {
743 const auto& regs = maxwell3d->regs; 745 const auto& regs = maxwell3d->regs;
744 oglEnable(GL_STENCIL_TEST, regs.stencil_enable); 746 oglEnable(GL_STENCIL_TEST, regs.stencil_enable);
745 747
746 glStencilFuncSeparate(GL_FRONT, MaxwellToGL::ComparisonOp(regs.stencil_front_func_func), 748 glStencilFuncSeparate(GL_FRONT, MaxwellToGL::ComparisonOp(regs.stencil_front_op.func),
747 regs.stencil_front_func_ref, regs.stencil_front_func_mask); 749 regs.stencil_front_func.ref, regs.stencil_front_func.func_mask);
748 glStencilOpSeparate(GL_FRONT, MaxwellToGL::StencilOp(regs.stencil_front_op_fail), 750 glStencilOpSeparate(GL_FRONT, MaxwellToGL::StencilOp(regs.stencil_front_op.fail),
749 MaxwellToGL::StencilOp(regs.stencil_front_op_zfail), 751 MaxwellToGL::StencilOp(regs.stencil_front_op.zfail),
750 MaxwellToGL::StencilOp(regs.stencil_front_op_zpass)); 752 MaxwellToGL::StencilOp(regs.stencil_front_op.zpass));
751 glStencilMaskSeparate(GL_FRONT, regs.stencil_front_mask); 753 glStencilMaskSeparate(GL_FRONT, regs.stencil_front_func.mask);
752 754
753 if (regs.stencil_two_side_enable) { 755 if (regs.stencil_two_side_enable) {
754 glStencilFuncSeparate(GL_BACK, MaxwellToGL::ComparisonOp(regs.stencil_back_func_func), 756 glStencilFuncSeparate(GL_BACK, MaxwellToGL::ComparisonOp(regs.stencil_back_op.func),
755 regs.stencil_back_func_ref, regs.stencil_back_func_mask); 757 regs.stencil_back_func.ref, regs.stencil_back_func.mask);
756 glStencilOpSeparate(GL_BACK, MaxwellToGL::StencilOp(regs.stencil_back_op_fail), 758 glStencilOpSeparate(GL_BACK, MaxwellToGL::StencilOp(regs.stencil_back_op.fail),
757 MaxwellToGL::StencilOp(regs.stencil_back_op_zfail), 759 MaxwellToGL::StencilOp(regs.stencil_back_op.zfail),
758 MaxwellToGL::StencilOp(regs.stencil_back_op_zpass)); 760 MaxwellToGL::StencilOp(regs.stencil_back_op.zpass));
759 glStencilMaskSeparate(GL_BACK, regs.stencil_back_mask); 761 glStencilMaskSeparate(GL_BACK, regs.stencil_back_func.mask);
760 } else { 762 } else {
761 glStencilFuncSeparate(GL_BACK, GL_ALWAYS, 0, 0xFFFFFFFF); 763 glStencilFuncSeparate(GL_BACK, GL_ALWAYS, 0, 0xFFFFFFFF);
762 glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_KEEP); 764 glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_KEEP);
@@ -782,7 +784,7 @@ void RasterizerOpenGL::SyncPolygonModes() {
782 flags[Dirty::PolygonModes] = false; 784 flags[Dirty::PolygonModes] = false;
783 785
784 const auto& regs = maxwell3d->regs; 786 const auto& regs = maxwell3d->regs;
785 if (regs.fill_rectangle) { 787 if (regs.fill_via_triangle_mode != Maxwell::FillViaTriangleMode::Disabled) {
786 if (!GLAD_GL_NV_fill_rectangle) { 788 if (!GLAD_GL_NV_fill_rectangle) {
787 LOG_ERROR(Render_OpenGL, "GL_NV_fill_rectangle used and not supported"); 789 LOG_ERROR(Render_OpenGL, "GL_NV_fill_rectangle used and not supported");
788 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 790 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
@@ -855,8 +857,8 @@ void RasterizerOpenGL::SyncMultiSampleState() {
855 flags[Dirty::MultisampleControl] = false; 857 flags[Dirty::MultisampleControl] = false;
856 858
857 const auto& regs = maxwell3d->regs; 859 const auto& regs = maxwell3d->regs;
858 oglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE, regs.multisample_control.alpha_to_coverage); 860 oglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE, regs.anti_alias_alpha_control.alpha_to_coverage);
859 oglEnable(GL_SAMPLE_ALPHA_TO_ONE, regs.multisample_control.alpha_to_one); 861 oglEnable(GL_SAMPLE_ALPHA_TO_ONE, regs.anti_alias_alpha_control.alpha_to_one);
860} 862}
861 863
862void RasterizerOpenGL::SyncFragmentColorClampState() { 864void RasterizerOpenGL::SyncFragmentColorClampState() {
@@ -866,7 +868,8 @@ void RasterizerOpenGL::SyncFragmentColorClampState() {
866 } 868 }
867 flags[Dirty::FragmentClampColor] = false; 869 flags[Dirty::FragmentClampColor] = false;
868 870
869 glClampColor(GL_CLAMP_FRAGMENT_COLOR, maxwell3d->regs.frag_color_clamp ? GL_TRUE : GL_FALSE); 871 glClampColor(GL_CLAMP_FRAGMENT_COLOR,
872 maxwell3d->regs.frag_color_clamp.AnyEnabled() ? GL_TRUE : GL_FALSE);
870} 873}
871 874
872void RasterizerOpenGL::SyncBlendState() { 875void RasterizerOpenGL::SyncBlendState() {
@@ -886,18 +889,18 @@ void RasterizerOpenGL::SyncBlendState() {
886 } 889 }
887 flags[Dirty::BlendStates] = false; 890 flags[Dirty::BlendStates] = false;
888 891
889 if (!regs.independent_blend_enable) { 892 if (!regs.blend_per_target_enabled) {
890 if (!regs.blend.enable[0]) { 893 if (!regs.blend.enable[0]) {
891 glDisable(GL_BLEND); 894 glDisable(GL_BLEND);
892 return; 895 return;
893 } 896 }
894 glEnable(GL_BLEND); 897 glEnable(GL_BLEND);
895 glBlendFuncSeparate(MaxwellToGL::BlendFunc(regs.blend.factor_source_rgb), 898 glBlendFuncSeparate(MaxwellToGL::BlendFunc(regs.blend.color_source),
896 MaxwellToGL::BlendFunc(regs.blend.factor_dest_rgb), 899 MaxwellToGL::BlendFunc(regs.blend.color_dest),
897 MaxwellToGL::BlendFunc(regs.blend.factor_source_a), 900 MaxwellToGL::BlendFunc(regs.blend.alpha_source),
898 MaxwellToGL::BlendFunc(regs.blend.factor_dest_a)); 901 MaxwellToGL::BlendFunc(regs.blend.alpha_dest));
899 glBlendEquationSeparate(MaxwellToGL::BlendEquation(regs.blend.equation_rgb), 902 glBlendEquationSeparate(MaxwellToGL::BlendEquation(regs.blend.color_op),
900 MaxwellToGL::BlendEquation(regs.blend.equation_a)); 903 MaxwellToGL::BlendEquation(regs.blend.alpha_op));
901 return; 904 return;
902 } 905 }
903 906
@@ -916,14 +919,13 @@ void RasterizerOpenGL::SyncBlendState() {
916 } 919 }
917 glEnablei(GL_BLEND, static_cast<GLuint>(i)); 920 glEnablei(GL_BLEND, static_cast<GLuint>(i));
918 921
919 const auto& src = regs.independent_blend[i]; 922 const auto& src = regs.blend_per_target[i];
920 glBlendFuncSeparatei(static_cast<GLuint>(i), MaxwellToGL::BlendFunc(src.factor_source_rgb), 923 glBlendFuncSeparatei(static_cast<GLuint>(i), MaxwellToGL::BlendFunc(src.color_source),
921 MaxwellToGL::BlendFunc(src.factor_dest_rgb), 924 MaxwellToGL::BlendFunc(src.color_dest),
922 MaxwellToGL::BlendFunc(src.factor_source_a), 925 MaxwellToGL::BlendFunc(src.alpha_source),
923 MaxwellToGL::BlendFunc(src.factor_dest_a)); 926 MaxwellToGL::BlendFunc(src.alpha_dest));
924 glBlendEquationSeparatei(static_cast<GLuint>(i), 927 glBlendEquationSeparatei(static_cast<GLuint>(i), MaxwellToGL::BlendEquation(src.color_op),
925 MaxwellToGL::BlendEquation(src.equation_rgb), 928 MaxwellToGL::BlendEquation(src.alpha_op));
926 MaxwellToGL::BlendEquation(src.equation_a));
927 } 929 }
928} 930}
929 931
@@ -937,7 +939,7 @@ void RasterizerOpenGL::SyncLogicOpState() {
937 const auto& regs = maxwell3d->regs; 939 const auto& regs = maxwell3d->regs;
938 if (regs.logic_op.enable) { 940 if (regs.logic_op.enable) {
939 glEnable(GL_COLOR_LOGIC_OP); 941 glEnable(GL_COLOR_LOGIC_OP);
940 glLogicOp(MaxwellToGL::LogicOp(regs.logic_op.operation)); 942 glLogicOp(MaxwellToGL::LogicOp(regs.logic_op.op));
941 } else { 943 } else {
942 glDisable(GL_COLOR_LOGIC_OP); 944 glDisable(GL_COLOR_LOGIC_OP);
943 } 945 }
@@ -996,7 +998,7 @@ void RasterizerOpenGL::SyncPointState() {
996 flags[Dirty::PointSize] = false; 998 flags[Dirty::PointSize] = false;
997 999
998 oglEnable(GL_POINT_SPRITE, maxwell3d->regs.point_sprite_enable); 1000 oglEnable(GL_POINT_SPRITE, maxwell3d->regs.point_sprite_enable);
999 oglEnable(GL_PROGRAM_POINT_SIZE, maxwell3d->regs.vp_point_size.enable); 1001 oglEnable(GL_PROGRAM_POINT_SIZE, maxwell3d->regs.point_size_attribute.enabled);
1000 const bool is_rescaling{texture_cache.IsRescaling()}; 1002 const bool is_rescaling{texture_cache.IsRescaling()};
1001 const float scale = is_rescaling ? Settings::values.resolution_info.up_factor : 1.0f; 1003 const float scale = is_rescaling ? Settings::values.resolution_info.up_factor : 1.0f;
1002 glPointSize(std::max(1.0f, maxwell3d->regs.point_size * scale)); 1004 glPointSize(std::max(1.0f, maxwell3d->regs.point_size * scale));
@@ -1010,8 +1012,8 @@ void RasterizerOpenGL::SyncLineState() {
1010 flags[Dirty::LineWidth] = false; 1012 flags[Dirty::LineWidth] = false;
1011 1013
1012 const auto& regs = maxwell3d->regs; 1014 const auto& regs = maxwell3d->regs;
1013 oglEnable(GL_LINE_SMOOTH, regs.line_smooth_enable); 1015 oglEnable(GL_LINE_SMOOTH, regs.line_anti_alias_enable);
1014 glLineWidth(regs.line_smooth_enable ? regs.line_width_smooth : regs.line_width_aliased); 1016 glLineWidth(regs.line_anti_alias_enable ? regs.line_width_smooth : regs.line_width_aliased);
1015} 1017}
1016 1018
1017void RasterizerOpenGL::SyncPolygonOffset() { 1019void RasterizerOpenGL::SyncPolygonOffset() {
@@ -1029,8 +1031,8 @@ void RasterizerOpenGL::SyncPolygonOffset() {
1029 if (regs.polygon_offset_fill_enable || regs.polygon_offset_line_enable || 1031 if (regs.polygon_offset_fill_enable || regs.polygon_offset_line_enable ||
1030 regs.polygon_offset_point_enable) { 1032 regs.polygon_offset_point_enable) {
1031 // Hardware divides polygon offset units by two 1033 // Hardware divides polygon offset units by two
1032 glPolygonOffsetClamp(regs.polygon_offset_factor, regs.polygon_offset_units / 2.0f, 1034 glPolygonOffsetClamp(regs.slope_scale_depth_bias, regs.depth_bias / 2.0f,
1033 regs.polygon_offset_clamp); 1035 regs.depth_bias_clamp);
1034 } 1036 }
1035} 1037}
1036 1038
@@ -1062,14 +1064,14 @@ void RasterizerOpenGL::SyncFramebufferSRGB() {
1062 1064
1063void RasterizerOpenGL::BeginTransformFeedback(GraphicsPipeline* program, GLenum primitive_mode) { 1065void RasterizerOpenGL::BeginTransformFeedback(GraphicsPipeline* program, GLenum primitive_mode) {
1064 const auto& regs = maxwell3d->regs; 1066 const auto& regs = maxwell3d->regs;
1065 if (regs.tfb_enabled == 0) { 1067 if (regs.transform_feedback_enabled == 0) {
1066 return; 1068 return;
1067 } 1069 }
1068 program->ConfigureTransformFeedback(); 1070 program->ConfigureTransformFeedback();
1069 1071
1070 UNIMPLEMENTED_IF(regs.IsShaderConfigEnabled(Maxwell::ShaderProgram::TesselationControl) || 1072 UNIMPLEMENTED_IF(regs.IsShaderConfigEnabled(Maxwell::ShaderType::TessellationInit) ||
1071 regs.IsShaderConfigEnabled(Maxwell::ShaderProgram::TesselationEval) || 1073 regs.IsShaderConfigEnabled(Maxwell::ShaderType::Tessellation) ||
1072 regs.IsShaderConfigEnabled(Maxwell::ShaderProgram::Geometry)); 1074 regs.IsShaderConfigEnabled(Maxwell::ShaderType::Geometry));
1073 UNIMPLEMENTED_IF(primitive_mode != GL_POINTS); 1075 UNIMPLEMENTED_IF(primitive_mode != GL_POINTS);
1074 1076
1075 // We may have to call BeginTransformFeedbackNV here since they seem to call different 1077 // We may have to call BeginTransformFeedbackNV here since they seem to call different
@@ -1080,7 +1082,7 @@ void RasterizerOpenGL::BeginTransformFeedback(GraphicsPipeline* program, GLenum
1080} 1082}
1081 1083
1082void RasterizerOpenGL::EndTransformFeedback() { 1084void RasterizerOpenGL::EndTransformFeedback() {
1083 if (maxwell3d->regs.tfb_enabled != 0) { 1085 if (maxwell3d->regs.transform_feedback_enabled != 0) {
1084 glEndTransformFeedback(); 1086 glEndTransformFeedback();
1085 } 1087 }
1086} 1088}
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index 5a29a41d2..6bdb0b645 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -78,11 +78,11 @@ Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key,
78 info.tess_clockwise = key.tessellation_clockwise != 0; 78 info.tess_clockwise = key.tessellation_clockwise != 0;
79 info.tess_primitive = [&key] { 79 info.tess_primitive = [&key] {
80 switch (key.tessellation_primitive) { 80 switch (key.tessellation_primitive) {
81 case Maxwell::TessellationPrimitive::Isolines: 81 case Maxwell::Tessellation::DomainType::Isolines:
82 return Shader::TessPrimitive::Isolines; 82 return Shader::TessPrimitive::Isolines;
83 case Maxwell::TessellationPrimitive::Triangles: 83 case Maxwell::Tessellation::DomainType::Triangles:
84 return Shader::TessPrimitive::Triangles; 84 return Shader::TessPrimitive::Triangles;
85 case Maxwell::TessellationPrimitive::Quads: 85 case Maxwell::Tessellation::DomainType::Quads:
86 return Shader::TessPrimitive::Quads; 86 return Shader::TessPrimitive::Quads;
87 } 87 }
88 ASSERT(false); 88 ASSERT(false);
@@ -90,11 +90,11 @@ Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key,
90 }(); 90 }();
91 info.tess_spacing = [&] { 91 info.tess_spacing = [&] {
92 switch (key.tessellation_spacing) { 92 switch (key.tessellation_spacing) {
93 case Maxwell::TessellationSpacing::Equal: 93 case Maxwell::Tessellation::Spacing::Integer:
94 return Shader::TessSpacing::Equal; 94 return Shader::TessSpacing::Equal;
95 case Maxwell::TessellationSpacing::FractionalOdd: 95 case Maxwell::Tessellation::Spacing::FractionalOdd:
96 return Shader::TessSpacing::FractionalOdd; 96 return Shader::TessSpacing::FractionalOdd;
97 case Maxwell::TessellationSpacing::FractionalEven: 97 case Maxwell::Tessellation::Spacing::FractionalEven:
98 return Shader::TessSpacing::FractionalEven; 98 return Shader::TessSpacing::FractionalEven;
99 } 99 }
100 ASSERT(false); 100 ASSERT(false);
@@ -139,14 +139,15 @@ Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key,
139} 139}
140 140
141void SetXfbState(VideoCommon::TransformFeedbackState& state, const Maxwell& regs) { 141void SetXfbState(VideoCommon::TransformFeedbackState& state, const Maxwell& regs) {
142 std::ranges::transform(regs.tfb_layouts, state.layouts.begin(), [](const auto& layout) { 142 std::ranges::transform(regs.transform_feedback.controls, state.layouts.begin(),
143 return VideoCommon::TransformFeedbackState::Layout{ 143 [](const auto& layout) {
144 .stream = layout.stream, 144 return VideoCommon::TransformFeedbackState::Layout{
145 .varying_count = layout.varying_count, 145 .stream = layout.stream,
146 .stride = layout.stride, 146 .varying_count = layout.varying_count,
147 }; 147 .stride = layout.stride,
148 }); 148 };
149 state.varyings = regs.tfb_varying_locs; 149 });
150 state.varyings = regs.stream_out_layout;
150} 151}
151} // Anonymous namespace 152} // Anonymous namespace
152 153
@@ -309,14 +310,16 @@ GraphicsPipeline* ShaderCache::CurrentGraphicsPipeline() {
309 } 310 }
310 const auto& regs{maxwell3d->regs}; 311 const auto& regs{maxwell3d->regs};
311 graphics_key.raw = 0; 312 graphics_key.raw = 0;
312 graphics_key.early_z.Assign(regs.force_early_fragment_tests != 0 ? 1 : 0); 313 graphics_key.early_z.Assign(regs.mandated_early_z != 0 ? 1 : 0);
313 graphics_key.gs_input_topology.Assign(graphics_key.unique_hashes[4] != 0 314 graphics_key.gs_input_topology.Assign(graphics_key.unique_hashes[4] != 0
314 ? regs.draw.topology.Value() 315 ? regs.draw.topology.Value()
315 : Maxwell::PrimitiveTopology{}); 316 : Maxwell::PrimitiveTopology{});
316 graphics_key.tessellation_primitive.Assign(regs.tess_mode.prim.Value()); 317 graphics_key.tessellation_primitive.Assign(regs.tessellation.params.domain_type.Value());
317 graphics_key.tessellation_spacing.Assign(regs.tess_mode.spacing.Value()); 318 graphics_key.tessellation_spacing.Assign(regs.tessellation.params.spacing.Value());
318 graphics_key.tessellation_clockwise.Assign(regs.tess_mode.cw.Value()); 319 graphics_key.tessellation_clockwise.Assign(
319 graphics_key.xfb_enabled.Assign(regs.tfb_enabled != 0 ? 1 : 0); 320 regs.tessellation.params.output_primitives.Value() !=
321 Maxwell::Tessellation::OutputPrimitves::Triangles_CCW);
322 graphics_key.xfb_enabled.Assign(regs.transform_feedback_enabled != 0 ? 1 : 0);
320 if (graphics_key.xfb_enabled) { 323 if (graphics_key.xfb_enabled) {
321 SetXfbState(graphics_key.xfb_state, regs); 324 SetXfbState(graphics_key.xfb_state, regs);
322 } 325 }
@@ -354,7 +357,7 @@ GraphicsPipeline* ShaderCache::BuiltPipeline(GraphicsPipeline* pipeline) const n
354 // If games are using a small index count, we can assume these are full screen quads. 357 // If games are using a small index count, we can assume these are full screen quads.
355 // Usually these shaders are only used once for building textures so we can assume they 358 // Usually these shaders are only used once for building textures so we can assume they
356 // can't be built async 359 // can't be built async
357 if (maxwell3d->regs.index_array.count <= 6 || maxwell3d->regs.vertex_buffer.count <= 6) { 360 if (maxwell3d->regs.index_buffer.count <= 6 || maxwell3d->regs.vertex_buffer.count <= 6) {
358 return pipeline; 361 return pipeline;
359 } 362 }
360 return nullptr; 363 return nullptr;
diff --git a/src/video_core/renderer_opengl/gl_state_tracker.cpp b/src/video_core/renderer_opengl/gl_state_tracker.cpp
index a8f3a0f57..e2c709aac 100644
--- a/src/video_core/renderer_opengl/gl_state_tracker.cpp
+++ b/src/video_core/renderer_opengl/gl_state_tracker.cpp
@@ -38,12 +38,12 @@ void SetupDirtyColorMasks(Tables& tables) {
38void SetupDirtyVertexInstances(Tables& tables) { 38void SetupDirtyVertexInstances(Tables& tables) {
39 static constexpr std::size_t instance_base_offset = 3; 39 static constexpr std::size_t instance_base_offset = 3;
40 for (std::size_t i = 0; i < Regs::NumVertexArrays; ++i) { 40 for (std::size_t i = 0; i < Regs::NumVertexArrays; ++i) {
41 const std::size_t array_offset = OFF(vertex_array) + i * NUM(vertex_array[0]); 41 const std::size_t array_offset = OFF(vertex_streams) + i * NUM(vertex_streams[0]);
42 const std::size_t instance_array_offset = array_offset + instance_base_offset; 42 const std::size_t instance_array_offset = array_offset + instance_base_offset;
43 tables[0][instance_array_offset] = static_cast<u8>(VertexInstance0 + i); 43 tables[0][instance_array_offset] = static_cast<u8>(VertexInstance0 + i);
44 tables[1][instance_array_offset] = VertexInstances; 44 tables[1][instance_array_offset] = VertexInstances;
45 45
46 const std::size_t instance_offset = OFF(instanced_arrays) + i; 46 const std::size_t instance_offset = OFF(vertex_stream_instances) + i;
47 tables[0][instance_offset] = static_cast<u8>(VertexInstance0 + i); 47 tables[0][instance_offset] = static_cast<u8>(VertexInstance0 + i);
48 tables[1][instance_offset] = VertexInstances; 48 tables[1][instance_offset] = VertexInstances;
49 } 49 }
@@ -70,8 +70,8 @@ void SetupDirtyViewports(Tables& tables) {
70 FillBlock(tables[1], OFF(viewport_transform), NUM(viewport_transform), Viewports); 70 FillBlock(tables[1], OFF(viewport_transform), NUM(viewport_transform), Viewports);
71 FillBlock(tables[1], OFF(viewports), NUM(viewports), Viewports); 71 FillBlock(tables[1], OFF(viewports), NUM(viewports), Viewports);
72 72
73 tables[0][OFF(viewport_transform_enabled)] = ViewportTransform; 73 tables[0][OFF(viewport_scale_offset_enbled)] = ViewportTransform;
74 tables[1][OFF(viewport_transform_enabled)] = Viewports; 74 tables[1][OFF(viewport_scale_offset_enbled)] = Viewports;
75} 75}
76 76
77void SetupDirtyScissors(Tables& tables) { 77void SetupDirtyScissors(Tables& tables) {
@@ -88,7 +88,7 @@ void SetupDirtyPolygonModes(Tables& tables) {
88 88
89 tables[1][OFF(polygon_mode_front)] = PolygonModes; 89 tables[1][OFF(polygon_mode_front)] = PolygonModes;
90 tables[1][OFF(polygon_mode_back)] = PolygonModes; 90 tables[1][OFF(polygon_mode_back)] = PolygonModes;
91 tables[0][OFF(fill_rectangle)] = PolygonModes; 91 tables[0][OFF(fill_via_triangle_mode)] = PolygonModes;
92} 92}
93 93
94void SetupDirtyDepthTest(Tables& tables) { 94void SetupDirtyDepthTest(Tables& tables) {
@@ -100,12 +100,14 @@ void SetupDirtyDepthTest(Tables& tables) {
100 100
101void SetupDirtyStencilTest(Tables& tables) { 101void SetupDirtyStencilTest(Tables& tables) {
102 static constexpr std::array offsets = { 102 static constexpr std::array offsets = {
103 OFF(stencil_enable), OFF(stencil_front_func_func), OFF(stencil_front_func_ref), 103 OFF(stencil_enable), OFF(stencil_front_op.func),
104 OFF(stencil_front_func_mask), OFF(stencil_front_op_fail), OFF(stencil_front_op_zfail), 104 OFF(stencil_front_func.ref), OFF(stencil_front_func.func_mask),
105 OFF(stencil_front_op_zpass), OFF(stencil_front_mask), OFF(stencil_two_side_enable), 105 OFF(stencil_front_op.fail), OFF(stencil_front_op.zfail),
106 OFF(stencil_back_func_func), OFF(stencil_back_func_ref), OFF(stencil_back_func_mask), 106 OFF(stencil_front_op.zpass), OFF(stencil_front_func.mask),
107 OFF(stencil_back_op_fail), OFF(stencil_back_op_zfail), OFF(stencil_back_op_zpass), 107 OFF(stencil_two_side_enable), OFF(stencil_back_op.func),
108 OFF(stencil_back_mask)}; 108 OFF(stencil_back_func.ref), OFF(stencil_back_func.func_mask),
109 OFF(stencil_back_op.fail), OFF(stencil_back_op.zfail),
110 OFF(stencil_back_op.zpass), OFF(stencil_back_func.mask)};
109 for (const auto offset : offsets) { 111 for (const auto offset : offsets) {
110 tables[0][offset] = StencilTest; 112 tables[0][offset] = StencilTest;
111 } 113 }
@@ -121,15 +123,15 @@ void SetupDirtyAlphaTest(Tables& tables) {
121void SetupDirtyBlend(Tables& tables) { 123void SetupDirtyBlend(Tables& tables) {
122 FillBlock(tables[0], OFF(blend_color), NUM(blend_color), BlendColor); 124 FillBlock(tables[0], OFF(blend_color), NUM(blend_color), BlendColor);
123 125
124 tables[0][OFF(independent_blend_enable)] = BlendIndependentEnabled; 126 tables[0][OFF(blend_per_target_enabled)] = BlendIndependentEnabled;
125 127
126 for (std::size_t i = 0; i < Regs::NumRenderTargets; ++i) { 128 for (std::size_t i = 0; i < Regs::NumRenderTargets; ++i) {
127 const std::size_t offset = OFF(independent_blend) + i * NUM(independent_blend[0]); 129 const std::size_t offset = OFF(blend_per_target) + i * NUM(blend_per_target[0]);
128 FillBlock(tables[0], offset, NUM(independent_blend[0]), BlendState0 + i); 130 FillBlock(tables[0], offset, NUM(blend_per_target[0]), BlendState0 + i);
129 131
130 tables[0][OFF(blend.enable) + i] = static_cast<u8>(BlendState0 + i); 132 tables[0][OFF(blend.enable) + i] = static_cast<u8>(BlendState0 + i);
131 } 133 }
132 FillBlock(tables[1], OFF(independent_blend), NUM(independent_blend), BlendStates); 134 FillBlock(tables[1], OFF(blend_per_target), NUM(blend_per_target), BlendStates);
133 FillBlock(tables[1], OFF(blend), NUM(blend), BlendStates); 135 FillBlock(tables[1], OFF(blend), NUM(blend), BlendStates);
134} 136}
135 137
@@ -142,13 +144,14 @@ void SetupDirtyPolygonOffset(Tables& tables) {
142 table[OFF(polygon_offset_fill_enable)] = PolygonOffset; 144 table[OFF(polygon_offset_fill_enable)] = PolygonOffset;
143 table[OFF(polygon_offset_line_enable)] = PolygonOffset; 145 table[OFF(polygon_offset_line_enable)] = PolygonOffset;
144 table[OFF(polygon_offset_point_enable)] = PolygonOffset; 146 table[OFF(polygon_offset_point_enable)] = PolygonOffset;
145 table[OFF(polygon_offset_factor)] = PolygonOffset; 147 table[OFF(slope_scale_depth_bias)] = PolygonOffset;
146 table[OFF(polygon_offset_units)] = PolygonOffset; 148 table[OFF(depth_bias)] = PolygonOffset;
147 table[OFF(polygon_offset_clamp)] = PolygonOffset; 149 table[OFF(depth_bias_clamp)] = PolygonOffset;
148} 150}
149 151
150void SetupDirtyMultisampleControl(Tables& tables) { 152void SetupDirtyMultisampleControl(Tables& tables) {
151 FillBlock(tables[0], OFF(multisample_control), NUM(multisample_control), MultisampleControl); 153 FillBlock(tables[0], OFF(anti_alias_alpha_control), NUM(anti_alias_alpha_control),
154 MultisampleControl);
152} 155}
153 156
154void SetupDirtyRasterizeEnable(Tables& tables) { 157void SetupDirtyRasterizeEnable(Tables& tables) {
@@ -168,7 +171,7 @@ void SetupDirtyFragmentClampColor(Tables& tables) {
168} 171}
169 172
170void SetupDirtyPointSize(Tables& tables) { 173void SetupDirtyPointSize(Tables& tables) {
171 tables[0][OFF(vp_point_size)] = PointSize; 174 tables[0][OFF(point_size_attribute)] = PointSize;
172 tables[0][OFF(point_size)] = PointSize; 175 tables[0][OFF(point_size)] = PointSize;
173 tables[0][OFF(point_sprite_enable)] = PointSize; 176 tables[0][OFF(point_sprite_enable)] = PointSize;
174} 177}
@@ -176,28 +179,28 @@ void SetupDirtyPointSize(Tables& tables) {
176void SetupDirtyLineWidth(Tables& tables) { 179void SetupDirtyLineWidth(Tables& tables) {
177 tables[0][OFF(line_width_smooth)] = LineWidth; 180 tables[0][OFF(line_width_smooth)] = LineWidth;
178 tables[0][OFF(line_width_aliased)] = LineWidth; 181 tables[0][OFF(line_width_aliased)] = LineWidth;
179 tables[0][OFF(line_smooth_enable)] = LineWidth; 182 tables[0][OFF(line_anti_alias_enable)] = LineWidth;
180} 183}
181 184
182void SetupDirtyClipControl(Tables& tables) { 185void SetupDirtyClipControl(Tables& tables) {
183 auto& table = tables[0]; 186 auto& table = tables[0];
184 table[OFF(screen_y_control)] = ClipControl; 187 table[OFF(window_origin)] = ClipControl;
185 table[OFF(depth_mode)] = ClipControl; 188 table[OFF(depth_mode)] = ClipControl;
186} 189}
187 190
188void SetupDirtyDepthClampEnabled(Tables& tables) { 191void SetupDirtyDepthClampEnabled(Tables& tables) {
189 tables[0][OFF(view_volume_clip_control)] = DepthClampEnabled; 192 tables[0][OFF(viewport_clip_control)] = DepthClampEnabled;
190} 193}
191 194
192void SetupDirtyMisc(Tables& tables) { 195void SetupDirtyMisc(Tables& tables) {
193 auto& table = tables[0]; 196 auto& table = tables[0];
194 197
195 table[OFF(clip_distance_enabled)] = ClipDistances; 198 table[OFF(user_clip_enable)] = ClipDistances;
196 199
197 table[OFF(front_face)] = FrontFace; 200 table[OFF(gl_front_face)] = FrontFace;
198 201
199 table[OFF(cull_test_enabled)] = CullTest; 202 table[OFF(gl_cull_test_enabled)] = CullTest;
200 table[OFF(cull_face)] = CullTest; 203 table[OFF(gl_cull_face)] = CullTest;
201} 204}
202 205
203} // Anonymous namespace 206} // Anonymous namespace
diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h
index 004421236..e14f9b2db 100644
--- a/src/video_core/renderer_opengl/maxwell_to_gl.h
+++ b/src/video_core/renderer_opengl/maxwell_to_gl.h
@@ -126,51 +126,60 @@ inline const FormatTuple& GetFormatTuple(VideoCore::Surface::PixelFormat pixel_f
126 126
127inline GLenum VertexFormat(Maxwell::VertexAttribute attrib) { 127inline GLenum VertexFormat(Maxwell::VertexAttribute attrib) {
128 switch (attrib.type) { 128 switch (attrib.type) {
129 case Maxwell::VertexAttribute::Type::UnsignedNorm: 129 case Maxwell::VertexAttribute::Type::UnusedEnumDoNotUseBecauseItWillGoAway:
130 case Maxwell::VertexAttribute::Type::UnsignedScaled: 130 ASSERT_MSG(false, "Invalid vertex attribute type!");
131 case Maxwell::VertexAttribute::Type::UnsignedInt: 131 break;
132 case Maxwell::VertexAttribute::Type::UNorm:
133 case Maxwell::VertexAttribute::Type::UScaled:
134 case Maxwell::VertexAttribute::Type::UInt:
132 switch (attrib.size) { 135 switch (attrib.size) {
133 case Maxwell::VertexAttribute::Size::Size_8: 136 case Maxwell::VertexAttribute::Size::Size_R8:
134 case Maxwell::VertexAttribute::Size::Size_8_8: 137 case Maxwell::VertexAttribute::Size::Size_A8:
135 case Maxwell::VertexAttribute::Size::Size_8_8_8: 138 case Maxwell::VertexAttribute::Size::Size_R8_G8:
136 case Maxwell::VertexAttribute::Size::Size_8_8_8_8: 139 case Maxwell::VertexAttribute::Size::Size_G8_R8:
140 case Maxwell::VertexAttribute::Size::Size_R8_G8_B8:
141 case Maxwell::VertexAttribute::Size::Size_R8_G8_B8_A8:
142 case Maxwell::VertexAttribute::Size::Size_X8_B8_G8_R8:
137 return GL_UNSIGNED_BYTE; 143 return GL_UNSIGNED_BYTE;
138 case Maxwell::VertexAttribute::Size::Size_16: 144 case Maxwell::VertexAttribute::Size::Size_R16:
139 case Maxwell::VertexAttribute::Size::Size_16_16: 145 case Maxwell::VertexAttribute::Size::Size_R16_G16:
140 case Maxwell::VertexAttribute::Size::Size_16_16_16: 146 case Maxwell::VertexAttribute::Size::Size_R16_G16_B16:
141 case Maxwell::VertexAttribute::Size::Size_16_16_16_16: 147 case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16:
142 return GL_UNSIGNED_SHORT; 148 return GL_UNSIGNED_SHORT;
143 case Maxwell::VertexAttribute::Size::Size_32: 149 case Maxwell::VertexAttribute::Size::Size_R32:
144 case Maxwell::VertexAttribute::Size::Size_32_32: 150 case Maxwell::VertexAttribute::Size::Size_R32_G32:
145 case Maxwell::VertexAttribute::Size::Size_32_32_32: 151 case Maxwell::VertexAttribute::Size::Size_R32_G32_B32:
146 case Maxwell::VertexAttribute::Size::Size_32_32_32_32: 152 case Maxwell::VertexAttribute::Size::Size_R32_G32_B32_A32:
147 return GL_UNSIGNED_INT; 153 return GL_UNSIGNED_INT;
148 case Maxwell::VertexAttribute::Size::Size_10_10_10_2: 154 case Maxwell::VertexAttribute::Size::Size_A2_B10_G10_R10:
149 return GL_UNSIGNED_INT_2_10_10_10_REV; 155 return GL_UNSIGNED_INT_2_10_10_10_REV;
150 default: 156 default:
151 break; 157 break;
152 } 158 }
153 break; 159 break;
154 case Maxwell::VertexAttribute::Type::SignedNorm: 160 case Maxwell::VertexAttribute::Type::SNorm:
155 case Maxwell::VertexAttribute::Type::SignedScaled: 161 case Maxwell::VertexAttribute::Type::SScaled:
156 case Maxwell::VertexAttribute::Type::SignedInt: 162 case Maxwell::VertexAttribute::Type::SInt:
157 switch (attrib.size) { 163 switch (attrib.size) {
158 case Maxwell::VertexAttribute::Size::Size_8: 164 case Maxwell::VertexAttribute::Size::Size_R8:
159 case Maxwell::VertexAttribute::Size::Size_8_8: 165 case Maxwell::VertexAttribute::Size::Size_A8:
160 case Maxwell::VertexAttribute::Size::Size_8_8_8: 166 case Maxwell::VertexAttribute::Size::Size_R8_G8:
161 case Maxwell::VertexAttribute::Size::Size_8_8_8_8: 167 case Maxwell::VertexAttribute::Size::Size_G8_R8:
168 case Maxwell::VertexAttribute::Size::Size_R8_G8_B8:
169 case Maxwell::VertexAttribute::Size::Size_R8_G8_B8_A8:
170 case Maxwell::VertexAttribute::Size::Size_X8_B8_G8_R8:
162 return GL_BYTE; 171 return GL_BYTE;
163 case Maxwell::VertexAttribute::Size::Size_16: 172 case Maxwell::VertexAttribute::Size::Size_R16:
164 case Maxwell::VertexAttribute::Size::Size_16_16: 173 case Maxwell::VertexAttribute::Size::Size_R16_G16:
165 case Maxwell::VertexAttribute::Size::Size_16_16_16: 174 case Maxwell::VertexAttribute::Size::Size_R16_G16_B16:
166 case Maxwell::VertexAttribute::Size::Size_16_16_16_16: 175 case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16:
167 return GL_SHORT; 176 return GL_SHORT;
168 case Maxwell::VertexAttribute::Size::Size_32: 177 case Maxwell::VertexAttribute::Size::Size_R32:
169 case Maxwell::VertexAttribute::Size::Size_32_32: 178 case Maxwell::VertexAttribute::Size::Size_R32_G32:
170 case Maxwell::VertexAttribute::Size::Size_32_32_32: 179 case Maxwell::VertexAttribute::Size::Size_R32_G32_B32:
171 case Maxwell::VertexAttribute::Size::Size_32_32_32_32: 180 case Maxwell::VertexAttribute::Size::Size_R32_G32_B32_A32:
172 return GL_INT; 181 return GL_INT;
173 case Maxwell::VertexAttribute::Size::Size_10_10_10_2: 182 case Maxwell::VertexAttribute::Size::Size_A2_B10_G10_R10:
174 return GL_INT_2_10_10_10_REV; 183 return GL_INT_2_10_10_10_REV;
175 default: 184 default:
176 break; 185 break;
@@ -178,17 +187,17 @@ inline GLenum VertexFormat(Maxwell::VertexAttribute attrib) {
178 break; 187 break;
179 case Maxwell::VertexAttribute::Type::Float: 188 case Maxwell::VertexAttribute::Type::Float:
180 switch (attrib.size) { 189 switch (attrib.size) {
181 case Maxwell::VertexAttribute::Size::Size_16: 190 case Maxwell::VertexAttribute::Size::Size_R16:
182 case Maxwell::VertexAttribute::Size::Size_16_16: 191 case Maxwell::VertexAttribute::Size::Size_R16_G16:
183 case Maxwell::VertexAttribute::Size::Size_16_16_16: 192 case Maxwell::VertexAttribute::Size::Size_R16_G16_B16:
184 case Maxwell::VertexAttribute::Size::Size_16_16_16_16: 193 case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16:
185 return GL_HALF_FLOAT; 194 return GL_HALF_FLOAT;
186 case Maxwell::VertexAttribute::Size::Size_32: 195 case Maxwell::VertexAttribute::Size::Size_R32:
187 case Maxwell::VertexAttribute::Size::Size_32_32: 196 case Maxwell::VertexAttribute::Size::Size_R32_G32:
188 case Maxwell::VertexAttribute::Size::Size_32_32_32: 197 case Maxwell::VertexAttribute::Size::Size_R32_G32_B32:
189 case Maxwell::VertexAttribute::Size::Size_32_32_32_32: 198 case Maxwell::VertexAttribute::Size::Size_R32_G32_B32_A32:
190 return GL_FLOAT; 199 return GL_FLOAT;
191 case Maxwell::VertexAttribute::Size::Size_11_11_10: 200 case Maxwell::VertexAttribute::Size::Size_B10_G11_R11:
192 return GL_UNSIGNED_INT_10F_11F_11F_REV; 201 return GL_UNSIGNED_INT_10F_11F_11F_REV;
193 default: 202 default:
194 break; 203 break;
@@ -335,20 +344,20 @@ inline GLenum DepthCompareFunc(Tegra::Texture::DepthCompareFunc func) {
335 344
336inline GLenum BlendEquation(Maxwell::Blend::Equation equation) { 345inline GLenum BlendEquation(Maxwell::Blend::Equation equation) {
337 switch (equation) { 346 switch (equation) {
338 case Maxwell::Blend::Equation::Add: 347 case Maxwell::Blend::Equation::Add_D3D:
339 case Maxwell::Blend::Equation::AddGL: 348 case Maxwell::Blend::Equation::Add_GL:
340 return GL_FUNC_ADD; 349 return GL_FUNC_ADD;
341 case Maxwell::Blend::Equation::Subtract: 350 case Maxwell::Blend::Equation::Subtract_D3D:
342 case Maxwell::Blend::Equation::SubtractGL: 351 case Maxwell::Blend::Equation::Subtract_GL:
343 return GL_FUNC_SUBTRACT; 352 return GL_FUNC_SUBTRACT;
344 case Maxwell::Blend::Equation::ReverseSubtract: 353 case Maxwell::Blend::Equation::ReverseSubtract_D3D:
345 case Maxwell::Blend::Equation::ReverseSubtractGL: 354 case Maxwell::Blend::Equation::ReverseSubtract_GL:
346 return GL_FUNC_REVERSE_SUBTRACT; 355 return GL_FUNC_REVERSE_SUBTRACT;
347 case Maxwell::Blend::Equation::Min: 356 case Maxwell::Blend::Equation::Min_D3D:
348 case Maxwell::Blend::Equation::MinGL: 357 case Maxwell::Blend::Equation::Min_GL:
349 return GL_MIN; 358 return GL_MIN;
350 case Maxwell::Blend::Equation::Max: 359 case Maxwell::Blend::Equation::Max_D3D:
351 case Maxwell::Blend::Equation::MaxGL: 360 case Maxwell::Blend::Equation::Max_GL:
352 return GL_MAX; 361 return GL_MAX;
353 } 362 }
354 UNIMPLEMENTED_MSG("Unimplemented blend equation={}", equation); 363 UNIMPLEMENTED_MSG("Unimplemented blend equation={}", equation);
@@ -357,62 +366,62 @@ inline GLenum BlendEquation(Maxwell::Blend::Equation equation) {
357 366
358inline GLenum BlendFunc(Maxwell::Blend::Factor factor) { 367inline GLenum BlendFunc(Maxwell::Blend::Factor factor) {
359 switch (factor) { 368 switch (factor) {
360 case Maxwell::Blend::Factor::Zero: 369 case Maxwell::Blend::Factor::Zero_D3D:
361 case Maxwell::Blend::Factor::ZeroGL: 370 case Maxwell::Blend::Factor::Zero_GL:
362 return GL_ZERO; 371 return GL_ZERO;
363 case Maxwell::Blend::Factor::One: 372 case Maxwell::Blend::Factor::One_D3D:
364 case Maxwell::Blend::Factor::OneGL: 373 case Maxwell::Blend::Factor::One_GL:
365 return GL_ONE; 374 return GL_ONE;
366 case Maxwell::Blend::Factor::SourceColor: 375 case Maxwell::Blend::Factor::SourceColor_D3D:
367 case Maxwell::Blend::Factor::SourceColorGL: 376 case Maxwell::Blend::Factor::SourceColor_GL:
368 return GL_SRC_COLOR; 377 return GL_SRC_COLOR;
369 case Maxwell::Blend::Factor::OneMinusSourceColor: 378 case Maxwell::Blend::Factor::OneMinusSourceColor_D3D:
370 case Maxwell::Blend::Factor::OneMinusSourceColorGL: 379 case Maxwell::Blend::Factor::OneMinusSourceColor_GL:
371 return GL_ONE_MINUS_SRC_COLOR; 380 return GL_ONE_MINUS_SRC_COLOR;
372 case Maxwell::Blend::Factor::SourceAlpha: 381 case Maxwell::Blend::Factor::SourceAlpha_D3D:
373 case Maxwell::Blend::Factor::SourceAlphaGL: 382 case Maxwell::Blend::Factor::SourceAlpha_GL:
374 return GL_SRC_ALPHA; 383 return GL_SRC_ALPHA;
375 case Maxwell::Blend::Factor::OneMinusSourceAlpha: 384 case Maxwell::Blend::Factor::OneMinusSourceAlpha_D3D:
376 case Maxwell::Blend::Factor::OneMinusSourceAlphaGL: 385 case Maxwell::Blend::Factor::OneMinusSourceAlpha_GL:
377 return GL_ONE_MINUS_SRC_ALPHA; 386 return GL_ONE_MINUS_SRC_ALPHA;
378 case Maxwell::Blend::Factor::DestAlpha: 387 case Maxwell::Blend::Factor::DestAlpha_D3D:
379 case Maxwell::Blend::Factor::DestAlphaGL: 388 case Maxwell::Blend::Factor::DestAlpha_GL:
380 return GL_DST_ALPHA; 389 return GL_DST_ALPHA;
381 case Maxwell::Blend::Factor::OneMinusDestAlpha: 390 case Maxwell::Blend::Factor::OneMinusDestAlpha_D3D:
382 case Maxwell::Blend::Factor::OneMinusDestAlphaGL: 391 case Maxwell::Blend::Factor::OneMinusDestAlpha_GL:
383 return GL_ONE_MINUS_DST_ALPHA; 392 return GL_ONE_MINUS_DST_ALPHA;
384 case Maxwell::Blend::Factor::DestColor: 393 case Maxwell::Blend::Factor::DestColor_D3D:
385 case Maxwell::Blend::Factor::DestColorGL: 394 case Maxwell::Blend::Factor::DestColor_GL:
386 return GL_DST_COLOR; 395 return GL_DST_COLOR;
387 case Maxwell::Blend::Factor::OneMinusDestColor: 396 case Maxwell::Blend::Factor::OneMinusDestColor_D3D:
388 case Maxwell::Blend::Factor::OneMinusDestColorGL: 397 case Maxwell::Blend::Factor::OneMinusDestColor_GL:
389 return GL_ONE_MINUS_DST_COLOR; 398 return GL_ONE_MINUS_DST_COLOR;
390 case Maxwell::Blend::Factor::SourceAlphaSaturate: 399 case Maxwell::Blend::Factor::SourceAlphaSaturate_D3D:
391 case Maxwell::Blend::Factor::SourceAlphaSaturateGL: 400 case Maxwell::Blend::Factor::SourceAlphaSaturate_GL:
392 return GL_SRC_ALPHA_SATURATE; 401 return GL_SRC_ALPHA_SATURATE;
393 case Maxwell::Blend::Factor::Source1Color: 402 case Maxwell::Blend::Factor::Source1Color_D3D:
394 case Maxwell::Blend::Factor::Source1ColorGL: 403 case Maxwell::Blend::Factor::Source1Color_GL:
395 return GL_SRC1_COLOR; 404 return GL_SRC1_COLOR;
396 case Maxwell::Blend::Factor::OneMinusSource1Color: 405 case Maxwell::Blend::Factor::OneMinusSource1Color_D3D:
397 case Maxwell::Blend::Factor::OneMinusSource1ColorGL: 406 case Maxwell::Blend::Factor::OneMinusSource1Color_GL:
398 return GL_ONE_MINUS_SRC1_COLOR; 407 return GL_ONE_MINUS_SRC1_COLOR;
399 case Maxwell::Blend::Factor::Source1Alpha: 408 case Maxwell::Blend::Factor::Source1Alpha_D3D:
400 case Maxwell::Blend::Factor::Source1AlphaGL: 409 case Maxwell::Blend::Factor::Source1Alpha_GL:
401 return GL_SRC1_ALPHA; 410 return GL_SRC1_ALPHA;
402 case Maxwell::Blend::Factor::OneMinusSource1Alpha: 411 case Maxwell::Blend::Factor::OneMinusSource1Alpha_D3D:
403 case Maxwell::Blend::Factor::OneMinusSource1AlphaGL: 412 case Maxwell::Blend::Factor::OneMinusSource1Alpha_GL:
404 return GL_ONE_MINUS_SRC1_ALPHA; 413 return GL_ONE_MINUS_SRC1_ALPHA;
405 case Maxwell::Blend::Factor::ConstantColor: 414 case Maxwell::Blend::Factor::BlendFactor_D3D:
406 case Maxwell::Blend::Factor::ConstantColorGL: 415 case Maxwell::Blend::Factor::ConstantColor_GL:
407 return GL_CONSTANT_COLOR; 416 return GL_CONSTANT_COLOR;
408 case Maxwell::Blend::Factor::OneMinusConstantColor: 417 case Maxwell::Blend::Factor::OneMinusBlendFactor_D3D:
409 case Maxwell::Blend::Factor::OneMinusConstantColorGL: 418 case Maxwell::Blend::Factor::OneMinusConstantColor_GL:
410 return GL_ONE_MINUS_CONSTANT_COLOR; 419 return GL_ONE_MINUS_CONSTANT_COLOR;
411 case Maxwell::Blend::Factor::ConstantAlpha: 420 case Maxwell::Blend::Factor::BothSourceAlpha_D3D:
412 case Maxwell::Blend::Factor::ConstantAlphaGL: 421 case Maxwell::Blend::Factor::ConstantAlpha_GL:
413 return GL_CONSTANT_ALPHA; 422 return GL_CONSTANT_ALPHA;
414 case Maxwell::Blend::Factor::OneMinusConstantAlpha: 423 case Maxwell::Blend::Factor::OneMinusBothSourceAlpha_D3D:
415 case Maxwell::Blend::Factor::OneMinusConstantAlphaGL: 424 case Maxwell::Blend::Factor::OneMinusConstantAlpha_GL:
416 return GL_ONE_MINUS_CONSTANT_ALPHA; 425 return GL_ONE_MINUS_CONSTANT_ALPHA;
417 } 426 }
418 UNIMPLEMENTED_MSG("Unimplemented blend factor={}", factor); 427 UNIMPLEMENTED_MSG("Unimplemented blend factor={}", factor);
@@ -421,60 +430,60 @@ inline GLenum BlendFunc(Maxwell::Blend::Factor factor) {
421 430
422inline GLenum ComparisonOp(Maxwell::ComparisonOp comparison) { 431inline GLenum ComparisonOp(Maxwell::ComparisonOp comparison) {
423 switch (comparison) { 432 switch (comparison) {
424 case Maxwell::ComparisonOp::Never: 433 case Maxwell::ComparisonOp::Never_D3D:
425 case Maxwell::ComparisonOp::NeverOld: 434 case Maxwell::ComparisonOp::Never_GL:
426 return GL_NEVER; 435 return GL_NEVER;
427 case Maxwell::ComparisonOp::Less: 436 case Maxwell::ComparisonOp::Less_D3D:
428 case Maxwell::ComparisonOp::LessOld: 437 case Maxwell::ComparisonOp::Less_GL:
429 return GL_LESS; 438 return GL_LESS;
430 case Maxwell::ComparisonOp::Equal: 439 case Maxwell::ComparisonOp::Equal_D3D:
431 case Maxwell::ComparisonOp::EqualOld: 440 case Maxwell::ComparisonOp::Equal_GL:
432 return GL_EQUAL; 441 return GL_EQUAL;
433 case Maxwell::ComparisonOp::LessEqual: 442 case Maxwell::ComparisonOp::LessEqual_D3D:
434 case Maxwell::ComparisonOp::LessEqualOld: 443 case Maxwell::ComparisonOp::LessEqual_GL:
435 return GL_LEQUAL; 444 return GL_LEQUAL;
436 case Maxwell::ComparisonOp::Greater: 445 case Maxwell::ComparisonOp::Greater_D3D:
437 case Maxwell::ComparisonOp::GreaterOld: 446 case Maxwell::ComparisonOp::Greater_GL:
438 return GL_GREATER; 447 return GL_GREATER;
439 case Maxwell::ComparisonOp::NotEqual: 448 case Maxwell::ComparisonOp::NotEqual_D3D:
440 case Maxwell::ComparisonOp::NotEqualOld: 449 case Maxwell::ComparisonOp::NotEqual_GL:
441 return GL_NOTEQUAL; 450 return GL_NOTEQUAL;
442 case Maxwell::ComparisonOp::GreaterEqual: 451 case Maxwell::ComparisonOp::GreaterEqual_D3D:
443 case Maxwell::ComparisonOp::GreaterEqualOld: 452 case Maxwell::ComparisonOp::GreaterEqual_GL:
444 return GL_GEQUAL; 453 return GL_GEQUAL;
445 case Maxwell::ComparisonOp::Always: 454 case Maxwell::ComparisonOp::Always_D3D:
446 case Maxwell::ComparisonOp::AlwaysOld: 455 case Maxwell::ComparisonOp::Always_GL:
447 return GL_ALWAYS; 456 return GL_ALWAYS;
448 } 457 }
449 UNIMPLEMENTED_MSG("Unimplemented comparison op={}", comparison); 458 UNIMPLEMENTED_MSG("Unimplemented comparison op={}", comparison);
450 return GL_ALWAYS; 459 return GL_ALWAYS;
451} 460}
452 461
453inline GLenum StencilOp(Maxwell::StencilOp stencil) { 462inline GLenum StencilOp(Maxwell::StencilOp::Op stencil) {
454 switch (stencil) { 463 switch (stencil) {
455 case Maxwell::StencilOp::Keep: 464 case Maxwell::StencilOp::Op::Keep_D3D:
456 case Maxwell::StencilOp::KeepOGL: 465 case Maxwell::StencilOp::Op::Keep_GL:
457 return GL_KEEP; 466 return GL_KEEP;
458 case Maxwell::StencilOp::Zero: 467 case Maxwell::StencilOp::Op::Zero_D3D:
459 case Maxwell::StencilOp::ZeroOGL: 468 case Maxwell::StencilOp::Op::Zero_GL:
460 return GL_ZERO; 469 return GL_ZERO;
461 case Maxwell::StencilOp::Replace: 470 case Maxwell::StencilOp::Op::Replace_D3D:
462 case Maxwell::StencilOp::ReplaceOGL: 471 case Maxwell::StencilOp::Op::Replace_GL:
463 return GL_REPLACE; 472 return GL_REPLACE;
464 case Maxwell::StencilOp::Incr: 473 case Maxwell::StencilOp::Op::IncrSaturate_D3D:
465 case Maxwell::StencilOp::IncrOGL: 474 case Maxwell::StencilOp::Op::IncrSaturate_GL:
466 return GL_INCR; 475 return GL_INCR;
467 case Maxwell::StencilOp::Decr: 476 case Maxwell::StencilOp::Op::DecrSaturate_D3D:
468 case Maxwell::StencilOp::DecrOGL: 477 case Maxwell::StencilOp::Op::DecrSaturate_GL:
469 return GL_DECR; 478 return GL_DECR;
470 case Maxwell::StencilOp::Invert: 479 case Maxwell::StencilOp::Op::Invert_D3D:
471 case Maxwell::StencilOp::InvertOGL: 480 case Maxwell::StencilOp::Op::Invert_GL:
472 return GL_INVERT; 481 return GL_INVERT;
473 case Maxwell::StencilOp::IncrWrap: 482 case Maxwell::StencilOp::Op::Incr_D3D:
474 case Maxwell::StencilOp::IncrWrapOGL: 483 case Maxwell::StencilOp::Op::Incr_GL:
475 return GL_INCR_WRAP; 484 return GL_INCR_WRAP;
476 case Maxwell::StencilOp::DecrWrap: 485 case Maxwell::StencilOp::Op::Decr_D3D:
477 case Maxwell::StencilOp::DecrWrapOGL: 486 case Maxwell::StencilOp::Op::Decr_GL:
478 return GL_DECR_WRAP; 487 return GL_DECR_WRAP;
479 } 488 }
480 UNIMPLEMENTED_MSG("Unimplemented stencil op={}", stencil); 489 UNIMPLEMENTED_MSG("Unimplemented stencil op={}", stencil);
@@ -505,39 +514,39 @@ inline GLenum CullFace(Maxwell::CullFace cull_face) {
505 return GL_BACK; 514 return GL_BACK;
506} 515}
507 516
508inline GLenum LogicOp(Maxwell::LogicOperation operation) { 517inline GLenum LogicOp(Maxwell::LogicOp::Op operation) {
509 switch (operation) { 518 switch (operation) {
510 case Maxwell::LogicOperation::Clear: 519 case Maxwell::LogicOp::Op::Clear:
511 return GL_CLEAR; 520 return GL_CLEAR;
512 case Maxwell::LogicOperation::And: 521 case Maxwell::LogicOp::Op::And:
513 return GL_AND; 522 return GL_AND;
514 case Maxwell::LogicOperation::AndReverse: 523 case Maxwell::LogicOp::Op::AndReverse:
515 return GL_AND_REVERSE; 524 return GL_AND_REVERSE;
516 case Maxwell::LogicOperation::Copy: 525 case Maxwell::LogicOp::Op::Copy:
517 return GL_COPY; 526 return GL_COPY;
518 case Maxwell::LogicOperation::AndInverted: 527 case Maxwell::LogicOp::Op::AndInverted:
519 return GL_AND_INVERTED; 528 return GL_AND_INVERTED;
520 case Maxwell::LogicOperation::NoOp: 529 case Maxwell::LogicOp::Op::NoOp:
521 return GL_NOOP; 530 return GL_NOOP;
522 case Maxwell::LogicOperation::Xor: 531 case Maxwell::LogicOp::Op::Xor:
523 return GL_XOR; 532 return GL_XOR;
524 case Maxwell::LogicOperation::Or: 533 case Maxwell::LogicOp::Op::Or:
525 return GL_OR; 534 return GL_OR;
526 case Maxwell::LogicOperation::Nor: 535 case Maxwell::LogicOp::Op::Nor:
527 return GL_NOR; 536 return GL_NOR;
528 case Maxwell::LogicOperation::Equiv: 537 case Maxwell::LogicOp::Op::Equiv:
529 return GL_EQUIV; 538 return GL_EQUIV;
530 case Maxwell::LogicOperation::Invert: 539 case Maxwell::LogicOp::Op::Invert:
531 return GL_INVERT; 540 return GL_INVERT;
532 case Maxwell::LogicOperation::OrReverse: 541 case Maxwell::LogicOp::Op::OrReverse:
533 return GL_OR_REVERSE; 542 return GL_OR_REVERSE;
534 case Maxwell::LogicOperation::CopyInverted: 543 case Maxwell::LogicOp::Op::CopyInverted:
535 return GL_COPY_INVERTED; 544 return GL_COPY_INVERTED;
536 case Maxwell::LogicOperation::OrInverted: 545 case Maxwell::LogicOp::Op::OrInverted:
537 return GL_OR_INVERTED; 546 return GL_OR_INVERTED;
538 case Maxwell::LogicOperation::Nand: 547 case Maxwell::LogicOp::Op::Nand:
539 return GL_NAND; 548 return GL_NAND;
540 case Maxwell::LogicOperation::Set: 549 case Maxwell::LogicOp::Op::Set:
541 return GL_SET; 550 return GL_SET;
542 } 551 }
543 UNIMPLEMENTED_MSG("Unimplemented logic operation={}", operation); 552 UNIMPLEMENTED_MSG("Unimplemented logic operation={}", operation);
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
index 733b454de..eb7c22fd5 100644
--- a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
+++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
@@ -34,14 +34,15 @@ constexpr std::array POLYGON_OFFSET_ENABLE_LUT = {
34}; 34};
35 35
36void RefreshXfbState(VideoCommon::TransformFeedbackState& state, const Maxwell& regs) { 36void RefreshXfbState(VideoCommon::TransformFeedbackState& state, const Maxwell& regs) {
37 std::ranges::transform(regs.tfb_layouts, state.layouts.begin(), [](const auto& layout) { 37 std::ranges::transform(regs.transform_feedback.controls, state.layouts.begin(),
38 return VideoCommon::TransformFeedbackState::Layout{ 38 [](const auto& layout) {
39 .stream = layout.stream, 39 return VideoCommon::TransformFeedbackState::Layout{
40 .varying_count = layout.varying_count, 40 .stream = layout.stream,
41 .stride = layout.stride, 41 .varying_count = layout.varying_count,
42 }; 42 .stride = layout.stride,
43 }); 43 };
44 state.varyings = regs.tfb_varying_locs; 44 });
45 state.varyings = regs.stream_out_layout;
45} 46}
46} // Anonymous namespace 47} // Anonymous namespace
47 48
@@ -58,33 +59,34 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d,
58 raw1 = 0; 59 raw1 = 0;
59 extended_dynamic_state.Assign(has_extended_dynamic_state ? 1 : 0); 60 extended_dynamic_state.Assign(has_extended_dynamic_state ? 1 : 0);
60 dynamic_vertex_input.Assign(has_dynamic_vertex_input ? 1 : 0); 61 dynamic_vertex_input.Assign(has_dynamic_vertex_input ? 1 : 0);
61 xfb_enabled.Assign(regs.tfb_enabled != 0); 62 xfb_enabled.Assign(regs.transform_feedback_enabled != 0);
62 primitive_restart_enable.Assign(regs.primitive_restart.enabled != 0 ? 1 : 0); 63 primitive_restart_enable.Assign(regs.primitive_restart.enabled != 0 ? 1 : 0);
63 depth_bias_enable.Assign(enabled_lut[POLYGON_OFFSET_ENABLE_LUT[topology_index]] != 0 ? 1 : 0); 64 depth_bias_enable.Assign(enabled_lut[POLYGON_OFFSET_ENABLE_LUT[topology_index]] != 0 ? 1 : 0);
64 depth_clamp_disabled.Assign(regs.view_volume_clip_control.depth_clamp_disabled.Value()); 65 depth_clamp_disabled.Assign(regs.viewport_clip_control.geometry_clip ==
66 Maxwell::ViewportClipControl::GeometryClip::Passthrough);
65 ndc_minus_one_to_one.Assign(regs.depth_mode == Maxwell::DepthMode::MinusOneToOne ? 1 : 0); 67 ndc_minus_one_to_one.Assign(regs.depth_mode == Maxwell::DepthMode::MinusOneToOne ? 1 : 0);
66 polygon_mode.Assign(PackPolygonMode(regs.polygon_mode_front)); 68 polygon_mode.Assign(PackPolygonMode(regs.polygon_mode_front));
67 patch_control_points_minus_one.Assign(regs.patch_vertices - 1); 69 patch_control_points_minus_one.Assign(regs.patch_vertices - 1);
68 tessellation_primitive.Assign(static_cast<u32>(regs.tess_mode.prim.Value())); 70 tessellation_primitive.Assign(static_cast<u32>(regs.tessellation.params.domain_type.Value()));
69 tessellation_spacing.Assign(static_cast<u32>(regs.tess_mode.spacing.Value())); 71 tessellation_spacing.Assign(static_cast<u32>(regs.tessellation.params.spacing.Value()));
70 tessellation_clockwise.Assign(regs.tess_mode.cw.Value()); 72 tessellation_clockwise.Assign(regs.tessellation.params.output_primitives.Value() !=
73 Maxwell::Tessellation::OutputPrimitves::Triangles_CCW);
71 logic_op_enable.Assign(regs.logic_op.enable != 0 ? 1 : 0); 74 logic_op_enable.Assign(regs.logic_op.enable != 0 ? 1 : 0);
72 logic_op.Assign(PackLogicOp(regs.logic_op.operation)); 75 logic_op.Assign(PackLogicOp(regs.logic_op.op));
73 topology.Assign(regs.draw.topology); 76 topology.Assign(regs.draw.topology);
74 msaa_mode.Assign(regs.multisample_mode); 77 msaa_mode.Assign(regs.anti_alias_samples_mode);
75 78
76 raw2 = 0; 79 raw2 = 0;
77 rasterize_enable.Assign(regs.rasterize_enable != 0 ? 1 : 0); 80 rasterize_enable.Assign(regs.rasterize_enable != 0 ? 1 : 0);
78 const auto test_func = 81 const auto test_func =
79 regs.alpha_test_enabled != 0 ? regs.alpha_test_func : Maxwell::ComparisonOp::Always; 82 regs.alpha_test_enabled != 0 ? regs.alpha_test_func : Maxwell::ComparisonOp::Always_GL;
80 alpha_test_func.Assign(PackComparisonOp(test_func)); 83 alpha_test_func.Assign(PackComparisonOp(test_func));
81 early_z.Assign(regs.force_early_fragment_tests != 0 ? 1 : 0); 84 early_z.Assign(regs.mandated_early_z != 0 ? 1 : 0);
82 depth_enabled.Assign(regs.zeta_enable != 0 ? 1 : 0); 85 depth_enabled.Assign(regs.zeta_enable != 0 ? 1 : 0);
83 depth_format.Assign(static_cast<u32>(regs.zeta.format)); 86 depth_format.Assign(static_cast<u32>(regs.zeta.format));
84 y_negate.Assign(regs.screen_y_control.y_negate != 0 ? 1 : 0); 87 y_negate.Assign(regs.window_origin.mode != Maxwell::WindowOrigin::Mode::UpperLeft ? 1 : 0);
85 provoking_vertex_last.Assign(regs.provoking_vertex_last != 0 ? 1 : 0); 88 provoking_vertex_last.Assign(regs.provoking_vertex == Maxwell::ProvokingVertex::Last ? 1 : 0);
86 conservative_raster_enable.Assign(regs.conservative_raster_enable != 0 ? 1 : 0); 89 smooth_lines.Assign(regs.line_anti_alias_enable != 0 ? 1 : 0);
87 smooth_lines.Assign(regs.line_smooth_enable != 0 ? 1 : 0);
88 90
89 for (size_t i = 0; i < regs.rt.size(); ++i) { 91 for (size_t i = 0; i < regs.rt.size(); ++i) {
90 color_formats[i] = static_cast<u8>(regs.rt[i].format); 92 color_formats[i] = static_cast<u8>(regs.rt[i].format);
@@ -116,8 +118,8 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d,
116 maxwell3d.dirty.flags[Dirty::VertexInput] = false; 118 maxwell3d.dirty.flags[Dirty::VertexInput] = false;
117 enabled_divisors = 0; 119 enabled_divisors = 0;
118 for (size_t index = 0; index < Maxwell::NumVertexArrays; ++index) { 120 for (size_t index = 0; index < Maxwell::NumVertexArrays; ++index) {
119 const bool is_enabled = regs.instanced_arrays.IsInstancingEnabled(index); 121 const bool is_enabled = regs.vertex_stream_instances.IsInstancingEnabled(index);
120 binding_divisors[index] = is_enabled ? regs.vertex_array[index].divisor : 0; 122 binding_divisors[index] = is_enabled ? regs.vertex_streams[index].frequency : 0;
121 enabled_divisors |= (is_enabled ? u64{1} : 0) << index; 123 enabled_divisors |= (is_enabled ? u64{1} : 0) << index;
122 } 124 }
123 for (size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) { 125 for (size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) {
@@ -164,17 +166,17 @@ void FixedPipelineState::BlendingAttachment::Refresh(const Maxwell& regs, size_t
164 166
165 // TODO: C++20 Use templated lambda to deduplicate code 167 // TODO: C++20 Use templated lambda to deduplicate code
166 168
167 if (!regs.independent_blend_enable) { 169 if (!regs.blend_per_target_enabled) {
168 const auto& src = regs.blend; 170 if (!regs.blend.enable[index]) {
169 if (!src.enable[index]) {
170 return; 171 return;
171 } 172 }
172 equation_rgb.Assign(PackBlendEquation(src.equation_rgb)); 173 const auto& src = regs.blend;
173 equation_a.Assign(PackBlendEquation(src.equation_a)); 174 equation_rgb.Assign(PackBlendEquation(src.color_op));
174 factor_source_rgb.Assign(PackBlendFactor(src.factor_source_rgb)); 175 equation_a.Assign(PackBlendEquation(src.alpha_op));
175 factor_dest_rgb.Assign(PackBlendFactor(src.factor_dest_rgb)); 176 factor_source_rgb.Assign(PackBlendFactor(src.color_source));
176 factor_source_a.Assign(PackBlendFactor(src.factor_source_a)); 177 factor_dest_rgb.Assign(PackBlendFactor(src.color_dest));
177 factor_dest_a.Assign(PackBlendFactor(src.factor_dest_a)); 178 factor_source_a.Assign(PackBlendFactor(src.alpha_source));
179 factor_dest_a.Assign(PackBlendFactor(src.alpha_dest));
178 enable.Assign(1); 180 enable.Assign(1);
179 return; 181 return;
180 } 182 }
@@ -182,34 +184,34 @@ void FixedPipelineState::BlendingAttachment::Refresh(const Maxwell& regs, size_t
182 if (!regs.blend.enable[index]) { 184 if (!regs.blend.enable[index]) {
183 return; 185 return;
184 } 186 }
185 const auto& src = regs.independent_blend[index]; 187 const auto& src = regs.blend_per_target[index];
186 equation_rgb.Assign(PackBlendEquation(src.equation_rgb)); 188 equation_rgb.Assign(PackBlendEquation(src.color_op));
187 equation_a.Assign(PackBlendEquation(src.equation_a)); 189 equation_a.Assign(PackBlendEquation(src.alpha_op));
188 factor_source_rgb.Assign(PackBlendFactor(src.factor_source_rgb)); 190 factor_source_rgb.Assign(PackBlendFactor(src.color_source));
189 factor_dest_rgb.Assign(PackBlendFactor(src.factor_dest_rgb)); 191 factor_dest_rgb.Assign(PackBlendFactor(src.color_dest));
190 factor_source_a.Assign(PackBlendFactor(src.factor_source_a)); 192 factor_source_a.Assign(PackBlendFactor(src.alpha_source));
191 factor_dest_a.Assign(PackBlendFactor(src.factor_dest_a)); 193 factor_dest_a.Assign(PackBlendFactor(src.alpha_dest));
192 enable.Assign(1); 194 enable.Assign(1);
193} 195}
194 196
195void FixedPipelineState::DynamicState::Refresh(const Maxwell& regs) { 197void FixedPipelineState::DynamicState::Refresh(const Maxwell& regs) {
196 u32 packed_front_face = PackFrontFace(regs.front_face); 198 u32 packed_front_face = PackFrontFace(regs.gl_front_face);
197 if (regs.screen_y_control.triangle_rast_flip != 0) { 199 if (regs.window_origin.flip_y != 0) {
198 // Flip front face 200 // Flip front face
199 packed_front_face = 1 - packed_front_face; 201 packed_front_face = 1 - packed_front_face;
200 } 202 }
201 203
202 raw1 = 0; 204 raw1 = 0;
203 raw2 = 0; 205 raw2 = 0;
204 front.action_stencil_fail.Assign(PackStencilOp(regs.stencil_front_op_fail)); 206 front.action_stencil_fail.Assign(PackStencilOp(regs.stencil_front_op.fail));
205 front.action_depth_fail.Assign(PackStencilOp(regs.stencil_front_op_zfail)); 207 front.action_depth_fail.Assign(PackStencilOp(regs.stencil_front_op.zfail));
206 front.action_depth_pass.Assign(PackStencilOp(regs.stencil_front_op_zpass)); 208 front.action_depth_pass.Assign(PackStencilOp(regs.stencil_front_op.zpass));
207 front.test_func.Assign(PackComparisonOp(regs.stencil_front_func_func)); 209 front.test_func.Assign(PackComparisonOp(regs.stencil_front_op.func));
208 if (regs.stencil_two_side_enable) { 210 if (regs.stencil_two_side_enable) {
209 back.action_stencil_fail.Assign(PackStencilOp(regs.stencil_back_op_fail)); 211 back.action_stencil_fail.Assign(PackStencilOp(regs.stencil_back_op.fail));
210 back.action_depth_fail.Assign(PackStencilOp(regs.stencil_back_op_zfail)); 212 back.action_depth_fail.Assign(PackStencilOp(regs.stencil_back_op.zfail));
211 back.action_depth_pass.Assign(PackStencilOp(regs.stencil_back_op_zpass)); 213 back.action_depth_pass.Assign(PackStencilOp(regs.stencil_back_op.zpass));
212 back.test_func.Assign(PackComparisonOp(regs.stencil_back_func_func)); 214 back.test_func.Assign(PackComparisonOp(regs.stencil_back_op.func));
213 } else { 215 } else {
214 back.action_stencil_fail.Assign(front.action_stencil_fail); 216 back.action_stencil_fail.Assign(front.action_stencil_fail);
215 back.action_depth_fail.Assign(front.action_depth_fail); 217 back.action_depth_fail.Assign(front.action_depth_fail);
@@ -222,9 +224,9 @@ void FixedPipelineState::DynamicState::Refresh(const Maxwell& regs) {
222 depth_test_enable.Assign(regs.depth_test_enable); 224 depth_test_enable.Assign(regs.depth_test_enable);
223 front_face.Assign(packed_front_face); 225 front_face.Assign(packed_front_face);
224 depth_test_func.Assign(PackComparisonOp(regs.depth_test_func)); 226 depth_test_func.Assign(PackComparisonOp(regs.depth_test_func));
225 cull_face.Assign(PackCullFace(regs.cull_face)); 227 cull_face.Assign(PackCullFace(regs.gl_cull_face));
226 cull_enable.Assign(regs.cull_test_enabled != 0 ? 1 : 0); 228 cull_enable.Assign(regs.gl_cull_test_enabled != 0 ? 1 : 0);
227 std::ranges::transform(regs.vertex_array, vertex_strides.begin(), [](const auto& array) { 229 std::ranges::transform(regs.vertex_streams, vertex_strides.begin(), [](const auto& array) {
228 return static_cast<u16>(array.stride.Value()); 230 return static_cast<u16>(array.stride.Value());
229 }); 231 });
230} 232}
@@ -251,41 +253,42 @@ Maxwell::ComparisonOp FixedPipelineState::UnpackComparisonOp(u32 packed) noexcep
251 return static_cast<Maxwell::ComparisonOp>(packed + 1); 253 return static_cast<Maxwell::ComparisonOp>(packed + 1);
252} 254}
253 255
254u32 FixedPipelineState::PackStencilOp(Maxwell::StencilOp op) noexcept { 256u32 FixedPipelineState::PackStencilOp(Maxwell::StencilOp::Op op) noexcept {
255 switch (op) { 257 switch (op) {
256 case Maxwell::StencilOp::Keep: 258 case Maxwell::StencilOp::Op::Keep_D3D:
257 case Maxwell::StencilOp::KeepOGL: 259 case Maxwell::StencilOp::Op::Keep_GL:
258 return 0; 260 return 0;
259 case Maxwell::StencilOp::Zero: 261 case Maxwell::StencilOp::Op::Zero_D3D:
260 case Maxwell::StencilOp::ZeroOGL: 262 case Maxwell::StencilOp::Op::Zero_GL:
261 return 1; 263 return 1;
262 case Maxwell::StencilOp::Replace: 264 case Maxwell::StencilOp::Op::Replace_D3D:
263 case Maxwell::StencilOp::ReplaceOGL: 265 case Maxwell::StencilOp::Op::Replace_GL:
264 return 2; 266 return 2;
265 case Maxwell::StencilOp::Incr: 267 case Maxwell::StencilOp::Op::IncrSaturate_D3D:
266 case Maxwell::StencilOp::IncrOGL: 268 case Maxwell::StencilOp::Op::IncrSaturate_GL:
267 return 3; 269 return 3;
268 case Maxwell::StencilOp::Decr: 270 case Maxwell::StencilOp::Op::DecrSaturate_D3D:
269 case Maxwell::StencilOp::DecrOGL: 271 case Maxwell::StencilOp::Op::DecrSaturate_GL:
270 return 4; 272 return 4;
271 case Maxwell::StencilOp::Invert: 273 case Maxwell::StencilOp::Op::Invert_D3D:
272 case Maxwell::StencilOp::InvertOGL: 274 case Maxwell::StencilOp::Op::Invert_GL:
273 return 5; 275 return 5;
274 case Maxwell::StencilOp::IncrWrap: 276 case Maxwell::StencilOp::Op::Incr_D3D:
275 case Maxwell::StencilOp::IncrWrapOGL: 277 case Maxwell::StencilOp::Op::Incr_GL:
276 return 6; 278 return 6;
277 case Maxwell::StencilOp::DecrWrap: 279 case Maxwell::StencilOp::Op::Decr_D3D:
278 case Maxwell::StencilOp::DecrWrapOGL: 280 case Maxwell::StencilOp::Op::Decr_GL:
279 return 7; 281 return 7;
280 } 282 }
281 return 0; 283 return 0;
282} 284}
283 285
284Maxwell::StencilOp FixedPipelineState::UnpackStencilOp(u32 packed) noexcept { 286Maxwell::StencilOp::Op FixedPipelineState::UnpackStencilOp(u32 packed) noexcept {
285 static constexpr std::array LUT = {Maxwell::StencilOp::Keep, Maxwell::StencilOp::Zero, 287 static constexpr std::array LUT = {
286 Maxwell::StencilOp::Replace, Maxwell::StencilOp::Incr, 288 Maxwell::StencilOp::Op::Keep_D3D, Maxwell::StencilOp::Op::Zero_D3D,
287 Maxwell::StencilOp::Decr, Maxwell::StencilOp::Invert, 289 Maxwell::StencilOp::Op::Replace_D3D, Maxwell::StencilOp::Op::IncrSaturate_D3D,
288 Maxwell::StencilOp::IncrWrap, Maxwell::StencilOp::DecrWrap}; 290 Maxwell::StencilOp::Op::DecrSaturate_D3D, Maxwell::StencilOp::Op::Invert_D3D,
291 Maxwell::StencilOp::Op::Incr_D3D, Maxwell::StencilOp::Op::Decr_D3D};
289 return LUT[packed]; 292 return LUT[packed];
290} 293}
291 294
@@ -318,30 +321,30 @@ Maxwell::PolygonMode FixedPipelineState::UnpackPolygonMode(u32 packed) noexcept
318 return static_cast<Maxwell::PolygonMode>(packed + 0x1B00); 321 return static_cast<Maxwell::PolygonMode>(packed + 0x1B00);
319} 322}
320 323
321u32 FixedPipelineState::PackLogicOp(Maxwell::LogicOperation op) noexcept { 324u32 FixedPipelineState::PackLogicOp(Maxwell::LogicOp::Op op) noexcept {
322 return static_cast<u32>(op) - 0x1500; 325 return static_cast<u32>(op) - 0x1500;
323} 326}
324 327
325Maxwell::LogicOperation FixedPipelineState::UnpackLogicOp(u32 packed) noexcept { 328Maxwell::LogicOp::Op FixedPipelineState::UnpackLogicOp(u32 packed) noexcept {
326 return static_cast<Maxwell::LogicOperation>(packed + 0x1500); 329 return static_cast<Maxwell::LogicOp::Op>(packed + 0x1500);
327} 330}
328 331
329u32 FixedPipelineState::PackBlendEquation(Maxwell::Blend::Equation equation) noexcept { 332u32 FixedPipelineState::PackBlendEquation(Maxwell::Blend::Equation equation) noexcept {
330 switch (equation) { 333 switch (equation) {
331 case Maxwell::Blend::Equation::Add: 334 case Maxwell::Blend::Equation::Add_D3D:
332 case Maxwell::Blend::Equation::AddGL: 335 case Maxwell::Blend::Equation::Add_GL:
333 return 0; 336 return 0;
334 case Maxwell::Blend::Equation::Subtract: 337 case Maxwell::Blend::Equation::Subtract_D3D:
335 case Maxwell::Blend::Equation::SubtractGL: 338 case Maxwell::Blend::Equation::Subtract_GL:
336 return 1; 339 return 1;
337 case Maxwell::Blend::Equation::ReverseSubtract: 340 case Maxwell::Blend::Equation::ReverseSubtract_D3D:
338 case Maxwell::Blend::Equation::ReverseSubtractGL: 341 case Maxwell::Blend::Equation::ReverseSubtract_GL:
339 return 2; 342 return 2;
340 case Maxwell::Blend::Equation::Min: 343 case Maxwell::Blend::Equation::Min_D3D:
341 case Maxwell::Blend::Equation::MinGL: 344 case Maxwell::Blend::Equation::Min_GL:
342 return 3; 345 return 3;
343 case Maxwell::Blend::Equation::Max: 346 case Maxwell::Blend::Equation::Max_D3D:
344 case Maxwell::Blend::Equation::MaxGL: 347 case Maxwell::Blend::Equation::Max_GL:
345 return 4; 348 return 4;
346 } 349 }
347 return 0; 350 return 0;
@@ -349,97 +352,99 @@ u32 FixedPipelineState::PackBlendEquation(Maxwell::Blend::Equation equation) noe
349 352
350Maxwell::Blend::Equation FixedPipelineState::UnpackBlendEquation(u32 packed) noexcept { 353Maxwell::Blend::Equation FixedPipelineState::UnpackBlendEquation(u32 packed) noexcept {
351 static constexpr std::array LUT = { 354 static constexpr std::array LUT = {
352 Maxwell::Blend::Equation::Add, Maxwell::Blend::Equation::Subtract, 355 Maxwell::Blend::Equation::Add_D3D, Maxwell::Blend::Equation::Subtract_D3D,
353 Maxwell::Blend::Equation::ReverseSubtract, Maxwell::Blend::Equation::Min, 356 Maxwell::Blend::Equation::ReverseSubtract_D3D, Maxwell::Blend::Equation::Min_D3D,
354 Maxwell::Blend::Equation::Max}; 357 Maxwell::Blend::Equation::Max_D3D};
355 return LUT[packed]; 358 return LUT[packed];
356} 359}
357 360
358u32 FixedPipelineState::PackBlendFactor(Maxwell::Blend::Factor factor) noexcept { 361u32 FixedPipelineState::PackBlendFactor(Maxwell::Blend::Factor factor) noexcept {
359 switch (factor) { 362 switch (factor) {
360 case Maxwell::Blend::Factor::Zero: 363 case Maxwell::Blend::Factor::Zero_D3D:
361 case Maxwell::Blend::Factor::ZeroGL: 364 case Maxwell::Blend::Factor::Zero_GL:
362 return 0; 365 return 0;
363 case Maxwell::Blend::Factor::One: 366 case Maxwell::Blend::Factor::One_D3D:
364 case Maxwell::Blend::Factor::OneGL: 367 case Maxwell::Blend::Factor::One_GL:
365 return 1; 368 return 1;
366 case Maxwell::Blend::Factor::SourceColor: 369 case Maxwell::Blend::Factor::SourceColor_D3D:
367 case Maxwell::Blend::Factor::SourceColorGL: 370 case Maxwell::Blend::Factor::SourceColor_GL:
368 return 2; 371 return 2;
369 case Maxwell::Blend::Factor::OneMinusSourceColor: 372 case Maxwell::Blend::Factor::OneMinusSourceColor_D3D:
370 case Maxwell::Blend::Factor::OneMinusSourceColorGL: 373 case Maxwell::Blend::Factor::OneMinusSourceColor_GL:
371 return 3; 374 return 3;
372 case Maxwell::Blend::Factor::SourceAlpha: 375 case Maxwell::Blend::Factor::SourceAlpha_D3D:
373 case Maxwell::Blend::Factor::SourceAlphaGL: 376 case Maxwell::Blend::Factor::SourceAlpha_GL:
374 return 4; 377 return 4;
375 case Maxwell::Blend::Factor::OneMinusSourceAlpha: 378 case Maxwell::Blend::Factor::OneMinusSourceAlpha_D3D:
376 case Maxwell::Blend::Factor::OneMinusSourceAlphaGL: 379 case Maxwell::Blend::Factor::OneMinusSourceAlpha_GL:
377 return 5; 380 return 5;
378 case Maxwell::Blend::Factor::DestAlpha: 381 case Maxwell::Blend::Factor::DestAlpha_D3D:
379 case Maxwell::Blend::Factor::DestAlphaGL: 382 case Maxwell::Blend::Factor::DestAlpha_GL:
380 return 6; 383 return 6;
381 case Maxwell::Blend::Factor::OneMinusDestAlpha: 384 case Maxwell::Blend::Factor::OneMinusDestAlpha_D3D:
382 case Maxwell::Blend::Factor::OneMinusDestAlphaGL: 385 case Maxwell::Blend::Factor::OneMinusDestAlpha_GL:
383 return 7; 386 return 7;
384 case Maxwell::Blend::Factor::DestColor: 387 case Maxwell::Blend::Factor::DestColor_D3D:
385 case Maxwell::Blend::Factor::DestColorGL: 388 case Maxwell::Blend::Factor::DestColor_GL:
386 return 8; 389 return 8;
387 case Maxwell::Blend::Factor::OneMinusDestColor: 390 case Maxwell::Blend::Factor::OneMinusDestColor_D3D:
388 case Maxwell::Blend::Factor::OneMinusDestColorGL: 391 case Maxwell::Blend::Factor::OneMinusDestColor_GL:
389 return 9; 392 return 9;
390 case Maxwell::Blend::Factor::SourceAlphaSaturate: 393 case Maxwell::Blend::Factor::SourceAlphaSaturate_D3D:
391 case Maxwell::Blend::Factor::SourceAlphaSaturateGL: 394 case Maxwell::Blend::Factor::SourceAlphaSaturate_GL:
392 return 10; 395 return 10;
393 case Maxwell::Blend::Factor::Source1Color: 396 case Maxwell::Blend::Factor::Source1Color_D3D:
394 case Maxwell::Blend::Factor::Source1ColorGL: 397 case Maxwell::Blend::Factor::Source1Color_GL:
395 return 11; 398 return 11;
396 case Maxwell::Blend::Factor::OneMinusSource1Color: 399 case Maxwell::Blend::Factor::OneMinusSource1Color_D3D:
397 case Maxwell::Blend::Factor::OneMinusSource1ColorGL: 400 case Maxwell::Blend::Factor::OneMinusSource1Color_GL:
398 return 12; 401 return 12;
399 case Maxwell::Blend::Factor::Source1Alpha: 402 case Maxwell::Blend::Factor::Source1Alpha_D3D:
400 case Maxwell::Blend::Factor::Source1AlphaGL: 403 case Maxwell::Blend::Factor::Source1Alpha_GL:
401 return 13; 404 return 13;
402 case Maxwell::Blend::Factor::OneMinusSource1Alpha: 405 case Maxwell::Blend::Factor::OneMinusSource1Alpha_D3D:
403 case Maxwell::Blend::Factor::OneMinusSource1AlphaGL: 406 case Maxwell::Blend::Factor::OneMinusSource1Alpha_GL:
404 return 14; 407 return 14;
405 case Maxwell::Blend::Factor::ConstantColor: 408 case Maxwell::Blend::Factor::BlendFactor_D3D:
406 case Maxwell::Blend::Factor::ConstantColorGL: 409 case Maxwell::Blend::Factor::ConstantColor_GL:
407 return 15; 410 return 15;
408 case Maxwell::Blend::Factor::OneMinusConstantColor: 411 case Maxwell::Blend::Factor::OneMinusBlendFactor_D3D:
409 case Maxwell::Blend::Factor::OneMinusConstantColorGL: 412 case Maxwell::Blend::Factor::OneMinusConstantColor_GL:
410 return 16; 413 return 16;
411 case Maxwell::Blend::Factor::ConstantAlpha: 414 case Maxwell::Blend::Factor::BothSourceAlpha_D3D:
412 case Maxwell::Blend::Factor::ConstantAlphaGL: 415 case Maxwell::Blend::Factor::ConstantAlpha_GL:
413 return 17; 416 return 17;
414 case Maxwell::Blend::Factor::OneMinusConstantAlpha: 417 case Maxwell::Blend::Factor::OneMinusBothSourceAlpha_D3D:
415 case Maxwell::Blend::Factor::OneMinusConstantAlphaGL: 418 case Maxwell::Blend::Factor::OneMinusConstantAlpha_GL:
416 return 18; 419 return 18;
417 } 420 }
421 UNIMPLEMENTED_MSG("Unknown blend factor {}", static_cast<u32>(factor));
418 return 0; 422 return 0;
419} 423}
420 424
421Maxwell::Blend::Factor FixedPipelineState::UnpackBlendFactor(u32 packed) noexcept { 425Maxwell::Blend::Factor FixedPipelineState::UnpackBlendFactor(u32 packed) noexcept {
422 static constexpr std::array LUT = { 426 static constexpr std::array LUT = {
423 Maxwell::Blend::Factor::Zero, 427 Maxwell::Blend::Factor::Zero_D3D,
424 Maxwell::Blend::Factor::One, 428 Maxwell::Blend::Factor::One_D3D,
425 Maxwell::Blend::Factor::SourceColor, 429 Maxwell::Blend::Factor::SourceColor_D3D,
426 Maxwell::Blend::Factor::OneMinusSourceColor, 430 Maxwell::Blend::Factor::OneMinusSourceColor_D3D,
427 Maxwell::Blend::Factor::SourceAlpha, 431 Maxwell::Blend::Factor::SourceAlpha_D3D,
428 Maxwell::Blend::Factor::OneMinusSourceAlpha, 432 Maxwell::Blend::Factor::OneMinusSourceAlpha_D3D,
429 Maxwell::Blend::Factor::DestAlpha, 433 Maxwell::Blend::Factor::DestAlpha_D3D,
430 Maxwell::Blend::Factor::OneMinusDestAlpha, 434 Maxwell::Blend::Factor::OneMinusDestAlpha_D3D,
431 Maxwell::Blend::Factor::DestColor, 435 Maxwell::Blend::Factor::DestColor_D3D,
432 Maxwell::Blend::Factor::OneMinusDestColor, 436 Maxwell::Blend::Factor::OneMinusDestColor_D3D,
433 Maxwell::Blend::Factor::SourceAlphaSaturate, 437 Maxwell::Blend::Factor::SourceAlphaSaturate_D3D,
434 Maxwell::Blend::Factor::Source1Color, 438 Maxwell::Blend::Factor::Source1Color_D3D,
435 Maxwell::Blend::Factor::OneMinusSource1Color, 439 Maxwell::Blend::Factor::OneMinusSource1Color_D3D,
436 Maxwell::Blend::Factor::Source1Alpha, 440 Maxwell::Blend::Factor::Source1Alpha_D3D,
437 Maxwell::Blend::Factor::OneMinusSource1Alpha, 441 Maxwell::Blend::Factor::OneMinusSource1Alpha_D3D,
438 Maxwell::Blend::Factor::ConstantColor, 442 Maxwell::Blend::Factor::BlendFactor_D3D,
439 Maxwell::Blend::Factor::OneMinusConstantColor, 443 Maxwell::Blend::Factor::OneMinusBlendFactor_D3D,
440 Maxwell::Blend::Factor::ConstantAlpha, 444 Maxwell::Blend::Factor::BothSourceAlpha_D3D,
441 Maxwell::Blend::Factor::OneMinusConstantAlpha, 445 Maxwell::Blend::Factor::OneMinusBothSourceAlpha_D3D,
442 }; 446 };
447 ASSERT(packed < LUT.size());
443 return LUT[packed]; 448 return LUT[packed];
444} 449}
445 450
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.h b/src/video_core/renderer_vulkan/fixed_pipeline_state.h
index 9d60756e5..43441209c 100644
--- a/src/video_core/renderer_vulkan/fixed_pipeline_state.h
+++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.h
@@ -21,8 +21,8 @@ struct FixedPipelineState {
21 static u32 PackComparisonOp(Maxwell::ComparisonOp op) noexcept; 21 static u32 PackComparisonOp(Maxwell::ComparisonOp op) noexcept;
22 static Maxwell::ComparisonOp UnpackComparisonOp(u32 packed) noexcept; 22 static Maxwell::ComparisonOp UnpackComparisonOp(u32 packed) noexcept;
23 23
24 static u32 PackStencilOp(Maxwell::StencilOp op) noexcept; 24 static u32 PackStencilOp(Maxwell::StencilOp::Op op) noexcept;
25 static Maxwell::StencilOp UnpackStencilOp(u32 packed) noexcept; 25 static Maxwell::StencilOp::Op UnpackStencilOp(u32 packed) noexcept;
26 26
27 static u32 PackCullFace(Maxwell::CullFace cull) noexcept; 27 static u32 PackCullFace(Maxwell::CullFace cull) noexcept;
28 static Maxwell::CullFace UnpackCullFace(u32 packed) noexcept; 28 static Maxwell::CullFace UnpackCullFace(u32 packed) noexcept;
@@ -33,8 +33,8 @@ struct FixedPipelineState {
33 static u32 PackPolygonMode(Maxwell::PolygonMode mode) noexcept; 33 static u32 PackPolygonMode(Maxwell::PolygonMode mode) noexcept;
34 static Maxwell::PolygonMode UnpackPolygonMode(u32 packed) noexcept; 34 static Maxwell::PolygonMode UnpackPolygonMode(u32 packed) noexcept;
35 35
36 static u32 PackLogicOp(Maxwell::LogicOperation op) noexcept; 36 static u32 PackLogicOp(Maxwell::LogicOp::Op op) noexcept;
37 static Maxwell::LogicOperation UnpackLogicOp(u32 packed) noexcept; 37 static Maxwell::LogicOp::Op UnpackLogicOp(u32 packed) noexcept;
38 38
39 static u32 PackBlendEquation(Maxwell::Blend::Equation equation) noexcept; 39 static u32 PackBlendEquation(Maxwell::Blend::Equation equation) noexcept;
40 static Maxwell::Blend::Equation UnpackBlendEquation(u32 packed) noexcept; 40 static Maxwell::Blend::Equation UnpackBlendEquation(u32 packed) noexcept;
@@ -113,15 +113,15 @@ struct FixedPipelineState {
113 BitField<Position + 6, 3, u32> action_depth_pass; 113 BitField<Position + 6, 3, u32> action_depth_pass;
114 BitField<Position + 9, 3, u32> test_func; 114 BitField<Position + 9, 3, u32> test_func;
115 115
116 Maxwell::StencilOp ActionStencilFail() const noexcept { 116 Maxwell::StencilOp::Op ActionStencilFail() const noexcept {
117 return UnpackStencilOp(action_stencil_fail); 117 return UnpackStencilOp(action_stencil_fail);
118 } 118 }
119 119
120 Maxwell::StencilOp ActionDepthFail() const noexcept { 120 Maxwell::StencilOp::Op ActionDepthFail() const noexcept {
121 return UnpackStencilOp(action_depth_fail); 121 return UnpackStencilOp(action_depth_fail);
122 } 122 }
123 123
124 Maxwell::StencilOp ActionDepthPass() const noexcept { 124 Maxwell::StencilOp::Op ActionDepthPass() const noexcept {
125 return UnpackStencilOp(action_depth_pass); 125 return UnpackStencilOp(action_depth_pass);
126 } 126 }
127 127
@@ -193,7 +193,6 @@ struct FixedPipelineState {
193 BitField<6, 5, u32> depth_format; 193 BitField<6, 5, u32> depth_format;
194 BitField<11, 1, u32> y_negate; 194 BitField<11, 1, u32> y_negate;
195 BitField<12, 1, u32> provoking_vertex_last; 195 BitField<12, 1, u32> provoking_vertex_last;
196 BitField<13, 1, u32> conservative_raster_enable;
197 BitField<14, 1, u32> smooth_lines; 196 BitField<14, 1, u32> smooth_lines;
198 }; 197 };
199 std::array<u8, Maxwell::NumRenderTargets> color_formats; 198 std::array<u8, Maxwell::NumRenderTargets> color_formats;
diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
index e7104d377..5c156087b 100644
--- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
+++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
@@ -323,161 +323,182 @@ VkFormat VertexFormat(const Device& device, Maxwell::VertexAttribute::Type type,
323 Maxwell::VertexAttribute::Size size) { 323 Maxwell::VertexAttribute::Size size) {
324 const VkFormat format{([&]() { 324 const VkFormat format{([&]() {
325 switch (type) { 325 switch (type) {
326 case Maxwell::VertexAttribute::Type::UnsignedNorm: 326 case Maxwell::VertexAttribute::Type::UnusedEnumDoNotUseBecauseItWillGoAway:
327 ASSERT_MSG(false, "Invalid vertex attribute type!");
328 break;
329 case Maxwell::VertexAttribute::Type::UNorm:
327 switch (size) { 330 switch (size) {
328 case Maxwell::VertexAttribute::Size::Size_8: 331 case Maxwell::VertexAttribute::Size::Size_R8:
332 case Maxwell::VertexAttribute::Size::Size_A8:
329 return VK_FORMAT_R8_UNORM; 333 return VK_FORMAT_R8_UNORM;
330 case Maxwell::VertexAttribute::Size::Size_8_8: 334 case Maxwell::VertexAttribute::Size::Size_R8_G8:
335 case Maxwell::VertexAttribute::Size::Size_G8_R8:
331 return VK_FORMAT_R8G8_UNORM; 336 return VK_FORMAT_R8G8_UNORM;
332 case Maxwell::VertexAttribute::Size::Size_8_8_8: 337 case Maxwell::VertexAttribute::Size::Size_R8_G8_B8:
333 return VK_FORMAT_R8G8B8_UNORM; 338 return VK_FORMAT_R8G8B8_UNORM;
334 case Maxwell::VertexAttribute::Size::Size_8_8_8_8: 339 case Maxwell::VertexAttribute::Size::Size_R8_G8_B8_A8:
340 case Maxwell::VertexAttribute::Size::Size_X8_B8_G8_R8:
335 return VK_FORMAT_R8G8B8A8_UNORM; 341 return VK_FORMAT_R8G8B8A8_UNORM;
336 case Maxwell::VertexAttribute::Size::Size_16: 342 case Maxwell::VertexAttribute::Size::Size_R16:
337 return VK_FORMAT_R16_UNORM; 343 return VK_FORMAT_R16_UNORM;
338 case Maxwell::VertexAttribute::Size::Size_16_16: 344 case Maxwell::VertexAttribute::Size::Size_R16_G16:
339 return VK_FORMAT_R16G16_UNORM; 345 return VK_FORMAT_R16G16_UNORM;
340 case Maxwell::VertexAttribute::Size::Size_16_16_16: 346 case Maxwell::VertexAttribute::Size::Size_R16_G16_B16:
341 return VK_FORMAT_R16G16B16_UNORM; 347 return VK_FORMAT_R16G16B16_UNORM;
342 case Maxwell::VertexAttribute::Size::Size_16_16_16_16: 348 case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16:
343 return VK_FORMAT_R16G16B16A16_UNORM; 349 return VK_FORMAT_R16G16B16A16_UNORM;
344 case Maxwell::VertexAttribute::Size::Size_10_10_10_2: 350 case Maxwell::VertexAttribute::Size::Size_A2_B10_G10_R10:
345 return VK_FORMAT_A2B10G10R10_UNORM_PACK32; 351 return VK_FORMAT_A2B10G10R10_UNORM_PACK32;
346 default: 352 default:
347 break; 353 break;
348 } 354 }
349 break; 355 break;
350 case Maxwell::VertexAttribute::Type::SignedNorm: 356 case Maxwell::VertexAttribute::Type::SNorm:
351 switch (size) { 357 switch (size) {
352 case Maxwell::VertexAttribute::Size::Size_8: 358 case Maxwell::VertexAttribute::Size::Size_R8:
359 case Maxwell::VertexAttribute::Size::Size_A8:
353 return VK_FORMAT_R8_SNORM; 360 return VK_FORMAT_R8_SNORM;
354 case Maxwell::VertexAttribute::Size::Size_8_8: 361 case Maxwell::VertexAttribute::Size::Size_R8_G8:
362 case Maxwell::VertexAttribute::Size::Size_G8_R8:
355 return VK_FORMAT_R8G8_SNORM; 363 return VK_FORMAT_R8G8_SNORM;
356 case Maxwell::VertexAttribute::Size::Size_8_8_8: 364 case Maxwell::VertexAttribute::Size::Size_R8_G8_B8:
357 return VK_FORMAT_R8G8B8_SNORM; 365 return VK_FORMAT_R8G8B8_SNORM;
358 case Maxwell::VertexAttribute::Size::Size_8_8_8_8: 366 case Maxwell::VertexAttribute::Size::Size_R8_G8_B8_A8:
367 case Maxwell::VertexAttribute::Size::Size_X8_B8_G8_R8:
359 return VK_FORMAT_R8G8B8A8_SNORM; 368 return VK_FORMAT_R8G8B8A8_SNORM;
360 case Maxwell::VertexAttribute::Size::Size_16: 369 case Maxwell::VertexAttribute::Size::Size_R16:
361 return VK_FORMAT_R16_SNORM; 370 return VK_FORMAT_R16_SNORM;
362 case Maxwell::VertexAttribute::Size::Size_16_16: 371 case Maxwell::VertexAttribute::Size::Size_R16_G16:
363 return VK_FORMAT_R16G16_SNORM; 372 return VK_FORMAT_R16G16_SNORM;
364 case Maxwell::VertexAttribute::Size::Size_16_16_16: 373 case Maxwell::VertexAttribute::Size::Size_R16_G16_B16:
365 return VK_FORMAT_R16G16B16_SNORM; 374 return VK_FORMAT_R16G16B16_SNORM;
366 case Maxwell::VertexAttribute::Size::Size_16_16_16_16: 375 case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16:
367 return VK_FORMAT_R16G16B16A16_SNORM; 376 return VK_FORMAT_R16G16B16A16_SNORM;
368 case Maxwell::VertexAttribute::Size::Size_10_10_10_2: 377 case Maxwell::VertexAttribute::Size::Size_A2_B10_G10_R10:
369 return VK_FORMAT_A2B10G10R10_SNORM_PACK32; 378 return VK_FORMAT_A2B10G10R10_SNORM_PACK32;
370 default: 379 default:
371 break; 380 break;
372 } 381 }
373 break; 382 break;
374 case Maxwell::VertexAttribute::Type::UnsignedScaled: 383 case Maxwell::VertexAttribute::Type::UScaled:
375 switch (size) { 384 switch (size) {
376 case Maxwell::VertexAttribute::Size::Size_8: 385 case Maxwell::VertexAttribute::Size::Size_R8:
386 case Maxwell::VertexAttribute::Size::Size_A8:
377 return VK_FORMAT_R8_USCALED; 387 return VK_FORMAT_R8_USCALED;
378 case Maxwell::VertexAttribute::Size::Size_8_8: 388 case Maxwell::VertexAttribute::Size::Size_R8_G8:
389 case Maxwell::VertexAttribute::Size::Size_G8_R8:
379 return VK_FORMAT_R8G8_USCALED; 390 return VK_FORMAT_R8G8_USCALED;
380 case Maxwell::VertexAttribute::Size::Size_8_8_8: 391 case Maxwell::VertexAttribute::Size::Size_R8_G8_B8:
381 return VK_FORMAT_R8G8B8_USCALED; 392 return VK_FORMAT_R8G8B8_USCALED;
382 case Maxwell::VertexAttribute::Size::Size_8_8_8_8: 393 case Maxwell::VertexAttribute::Size::Size_R8_G8_B8_A8:
394 case Maxwell::VertexAttribute::Size::Size_X8_B8_G8_R8:
383 return VK_FORMAT_R8G8B8A8_USCALED; 395 return VK_FORMAT_R8G8B8A8_USCALED;
384 case Maxwell::VertexAttribute::Size::Size_16: 396 case Maxwell::VertexAttribute::Size::Size_R16:
385 return VK_FORMAT_R16_USCALED; 397 return VK_FORMAT_R16_USCALED;
386 case Maxwell::VertexAttribute::Size::Size_16_16: 398 case Maxwell::VertexAttribute::Size::Size_R16_G16:
387 return VK_FORMAT_R16G16_USCALED; 399 return VK_FORMAT_R16G16_USCALED;
388 case Maxwell::VertexAttribute::Size::Size_16_16_16: 400 case Maxwell::VertexAttribute::Size::Size_R16_G16_B16:
389 return VK_FORMAT_R16G16B16_USCALED; 401 return VK_FORMAT_R16G16B16_USCALED;
390 case Maxwell::VertexAttribute::Size::Size_16_16_16_16: 402 case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16:
391 return VK_FORMAT_R16G16B16A16_USCALED; 403 return VK_FORMAT_R16G16B16A16_USCALED;
392 case Maxwell::VertexAttribute::Size::Size_10_10_10_2: 404 case Maxwell::VertexAttribute::Size::Size_A2_B10_G10_R10:
393 return VK_FORMAT_A2B10G10R10_USCALED_PACK32; 405 return VK_FORMAT_A2B10G10R10_USCALED_PACK32;
394 default: 406 default:
395 break; 407 break;
396 } 408 }
397 break; 409 break;
398 case Maxwell::VertexAttribute::Type::SignedScaled: 410 case Maxwell::VertexAttribute::Type::SScaled:
399 switch (size) { 411 switch (size) {
400 case Maxwell::VertexAttribute::Size::Size_8: 412 case Maxwell::VertexAttribute::Size::Size_R8:
413 case Maxwell::VertexAttribute::Size::Size_A8:
401 return VK_FORMAT_R8_SSCALED; 414 return VK_FORMAT_R8_SSCALED;
402 case Maxwell::VertexAttribute::Size::Size_8_8: 415 case Maxwell::VertexAttribute::Size::Size_R8_G8:
416 case Maxwell::VertexAttribute::Size::Size_G8_R8:
403 return VK_FORMAT_R8G8_SSCALED; 417 return VK_FORMAT_R8G8_SSCALED;
404 case Maxwell::VertexAttribute::Size::Size_8_8_8: 418 case Maxwell::VertexAttribute::Size::Size_R8_G8_B8:
405 return VK_FORMAT_R8G8B8_SSCALED; 419 return VK_FORMAT_R8G8B8_SSCALED;
406 case Maxwell::VertexAttribute::Size::Size_8_8_8_8: 420 case Maxwell::VertexAttribute::Size::Size_R8_G8_B8_A8:
421 case Maxwell::VertexAttribute::Size::Size_X8_B8_G8_R8:
407 return VK_FORMAT_R8G8B8A8_SSCALED; 422 return VK_FORMAT_R8G8B8A8_SSCALED;
408 case Maxwell::VertexAttribute::Size::Size_16: 423 case Maxwell::VertexAttribute::Size::Size_R16:
409 return VK_FORMAT_R16_SSCALED; 424 return VK_FORMAT_R16_SSCALED;
410 case Maxwell::VertexAttribute::Size::Size_16_16: 425 case Maxwell::VertexAttribute::Size::Size_R16_G16:
411 return VK_FORMAT_R16G16_SSCALED; 426 return VK_FORMAT_R16G16_SSCALED;
412 case Maxwell::VertexAttribute::Size::Size_16_16_16: 427 case Maxwell::VertexAttribute::Size::Size_R16_G16_B16:
413 return VK_FORMAT_R16G16B16_SSCALED; 428 return VK_FORMAT_R16G16B16_SSCALED;
414 case Maxwell::VertexAttribute::Size::Size_16_16_16_16: 429 case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16:
415 return VK_FORMAT_R16G16B16A16_SSCALED; 430 return VK_FORMAT_R16G16B16A16_SSCALED;
416 case Maxwell::VertexAttribute::Size::Size_10_10_10_2: 431 case Maxwell::VertexAttribute::Size::Size_A2_B10_G10_R10:
417 return VK_FORMAT_A2B10G10R10_SSCALED_PACK32; 432 return VK_FORMAT_A2B10G10R10_SSCALED_PACK32;
418 default: 433 default:
419 break; 434 break;
420 } 435 }
421 break; 436 break;
422 case Maxwell::VertexAttribute::Type::UnsignedInt: 437 case Maxwell::VertexAttribute::Type::UInt:
423 switch (size) { 438 switch (size) {
424 case Maxwell::VertexAttribute::Size::Size_8: 439 case Maxwell::VertexAttribute::Size::Size_R8:
440 case Maxwell::VertexAttribute::Size::Size_A8:
425 return VK_FORMAT_R8_UINT; 441 return VK_FORMAT_R8_UINT;
426 case Maxwell::VertexAttribute::Size::Size_8_8: 442 case Maxwell::VertexAttribute::Size::Size_R8_G8:
443 case Maxwell::VertexAttribute::Size::Size_G8_R8:
427 return VK_FORMAT_R8G8_UINT; 444 return VK_FORMAT_R8G8_UINT;
428 case Maxwell::VertexAttribute::Size::Size_8_8_8: 445 case Maxwell::VertexAttribute::Size::Size_R8_G8_B8:
429 return VK_FORMAT_R8G8B8_UINT; 446 return VK_FORMAT_R8G8B8_UINT;
430 case Maxwell::VertexAttribute::Size::Size_8_8_8_8: 447 case Maxwell::VertexAttribute::Size::Size_R8_G8_B8_A8:
448 case Maxwell::VertexAttribute::Size::Size_X8_B8_G8_R8:
431 return VK_FORMAT_R8G8B8A8_UINT; 449 return VK_FORMAT_R8G8B8A8_UINT;
432 case Maxwell::VertexAttribute::Size::Size_16: 450 case Maxwell::VertexAttribute::Size::Size_R16:
433 return VK_FORMAT_R16_UINT; 451 return VK_FORMAT_R16_UINT;
434 case Maxwell::VertexAttribute::Size::Size_16_16: 452 case Maxwell::VertexAttribute::Size::Size_R16_G16:
435 return VK_FORMAT_R16G16_UINT; 453 return VK_FORMAT_R16G16_UINT;
436 case Maxwell::VertexAttribute::Size::Size_16_16_16: 454 case Maxwell::VertexAttribute::Size::Size_R16_G16_B16:
437 return VK_FORMAT_R16G16B16_UINT; 455 return VK_FORMAT_R16G16B16_UINT;
438 case Maxwell::VertexAttribute::Size::Size_16_16_16_16: 456 case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16:
439 return VK_FORMAT_R16G16B16A16_UINT; 457 return VK_FORMAT_R16G16B16A16_UINT;
440 case Maxwell::VertexAttribute::Size::Size_32: 458 case Maxwell::VertexAttribute::Size::Size_R32:
441 return VK_FORMAT_R32_UINT; 459 return VK_FORMAT_R32_UINT;
442 case Maxwell::VertexAttribute::Size::Size_32_32: 460 case Maxwell::VertexAttribute::Size::Size_R32_G32:
443 return VK_FORMAT_R32G32_UINT; 461 return VK_FORMAT_R32G32_UINT;
444 case Maxwell::VertexAttribute::Size::Size_32_32_32: 462 case Maxwell::VertexAttribute::Size::Size_R32_G32_B32:
445 return VK_FORMAT_R32G32B32_UINT; 463 return VK_FORMAT_R32G32B32_UINT;
446 case Maxwell::VertexAttribute::Size::Size_32_32_32_32: 464 case Maxwell::VertexAttribute::Size::Size_R32_G32_B32_A32:
447 return VK_FORMAT_R32G32B32A32_UINT; 465 return VK_FORMAT_R32G32B32A32_UINT;
448 case Maxwell::VertexAttribute::Size::Size_10_10_10_2: 466 case Maxwell::VertexAttribute::Size::Size_A2_B10_G10_R10:
449 return VK_FORMAT_A2B10G10R10_UINT_PACK32; 467 return VK_FORMAT_A2B10G10R10_UINT_PACK32;
450 default: 468 default:
451 break; 469 break;
452 } 470 }
453 break; 471 break;
454 case Maxwell::VertexAttribute::Type::SignedInt: 472 case Maxwell::VertexAttribute::Type::SInt:
455 switch (size) { 473 switch (size) {
456 case Maxwell::VertexAttribute::Size::Size_8: 474 case Maxwell::VertexAttribute::Size::Size_R8:
475 case Maxwell::VertexAttribute::Size::Size_A8:
457 return VK_FORMAT_R8_SINT; 476 return VK_FORMAT_R8_SINT;
458 case Maxwell::VertexAttribute::Size::Size_8_8: 477 case Maxwell::VertexAttribute::Size::Size_R8_G8:
478 case Maxwell::VertexAttribute::Size::Size_G8_R8:
459 return VK_FORMAT_R8G8_SINT; 479 return VK_FORMAT_R8G8_SINT;
460 case Maxwell::VertexAttribute::Size::Size_8_8_8: 480 case Maxwell::VertexAttribute::Size::Size_R8_G8_B8:
461 return VK_FORMAT_R8G8B8_SINT; 481 return VK_FORMAT_R8G8B8_SINT;
462 case Maxwell::VertexAttribute::Size::Size_8_8_8_8: 482 case Maxwell::VertexAttribute::Size::Size_R8_G8_B8_A8:
483 case Maxwell::VertexAttribute::Size::Size_X8_B8_G8_R8:
463 return VK_FORMAT_R8G8B8A8_SINT; 484 return VK_FORMAT_R8G8B8A8_SINT;
464 case Maxwell::VertexAttribute::Size::Size_16: 485 case Maxwell::VertexAttribute::Size::Size_R16:
465 return VK_FORMAT_R16_SINT; 486 return VK_FORMAT_R16_SINT;
466 case Maxwell::VertexAttribute::Size::Size_16_16: 487 case Maxwell::VertexAttribute::Size::Size_R16_G16:
467 return VK_FORMAT_R16G16_SINT; 488 return VK_FORMAT_R16G16_SINT;
468 case Maxwell::VertexAttribute::Size::Size_16_16_16: 489 case Maxwell::VertexAttribute::Size::Size_R16_G16_B16:
469 return VK_FORMAT_R16G16B16_SINT; 490 return VK_FORMAT_R16G16B16_SINT;
470 case Maxwell::VertexAttribute::Size::Size_16_16_16_16: 491 case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16:
471 return VK_FORMAT_R16G16B16A16_SINT; 492 return VK_FORMAT_R16G16B16A16_SINT;
472 case Maxwell::VertexAttribute::Size::Size_32: 493 case Maxwell::VertexAttribute::Size::Size_R32:
473 return VK_FORMAT_R32_SINT; 494 return VK_FORMAT_R32_SINT;
474 case Maxwell::VertexAttribute::Size::Size_32_32: 495 case Maxwell::VertexAttribute::Size::Size_R32_G32:
475 return VK_FORMAT_R32G32_SINT; 496 return VK_FORMAT_R32G32_SINT;
476 case Maxwell::VertexAttribute::Size::Size_32_32_32: 497 case Maxwell::VertexAttribute::Size::Size_R32_G32_B32:
477 return VK_FORMAT_R32G32B32_SINT; 498 return VK_FORMAT_R32G32B32_SINT;
478 case Maxwell::VertexAttribute::Size::Size_32_32_32_32: 499 case Maxwell::VertexAttribute::Size::Size_R32_G32_B32_A32:
479 return VK_FORMAT_R32G32B32A32_SINT; 500 return VK_FORMAT_R32G32B32A32_SINT;
480 case Maxwell::VertexAttribute::Size::Size_10_10_10_2: 501 case Maxwell::VertexAttribute::Size::Size_A2_B10_G10_R10:
481 return VK_FORMAT_A2B10G10R10_SINT_PACK32; 502 return VK_FORMAT_A2B10G10R10_SINT_PACK32;
482 default: 503 default:
483 break; 504 break;
@@ -485,23 +506,23 @@ VkFormat VertexFormat(const Device& device, Maxwell::VertexAttribute::Type type,
485 break; 506 break;
486 case Maxwell::VertexAttribute::Type::Float: 507 case Maxwell::VertexAttribute::Type::Float:
487 switch (size) { 508 switch (size) {
488 case Maxwell::VertexAttribute::Size::Size_16: 509 case Maxwell::VertexAttribute::Size::Size_R16:
489 return VK_FORMAT_R16_SFLOAT; 510 return VK_FORMAT_R16_SFLOAT;
490 case Maxwell::VertexAttribute::Size::Size_16_16: 511 case Maxwell::VertexAttribute::Size::Size_R16_G16:
491 return VK_FORMAT_R16G16_SFLOAT; 512 return VK_FORMAT_R16G16_SFLOAT;
492 case Maxwell::VertexAttribute::Size::Size_16_16_16: 513 case Maxwell::VertexAttribute::Size::Size_R16_G16_B16:
493 return VK_FORMAT_R16G16B16_SFLOAT; 514 return VK_FORMAT_R16G16B16_SFLOAT;
494 case Maxwell::VertexAttribute::Size::Size_16_16_16_16: 515 case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16:
495 return VK_FORMAT_R16G16B16A16_SFLOAT; 516 return VK_FORMAT_R16G16B16A16_SFLOAT;
496 case Maxwell::VertexAttribute::Size::Size_32: 517 case Maxwell::VertexAttribute::Size::Size_R32:
497 return VK_FORMAT_R32_SFLOAT; 518 return VK_FORMAT_R32_SFLOAT;
498 case Maxwell::VertexAttribute::Size::Size_32_32: 519 case Maxwell::VertexAttribute::Size::Size_R32_G32:
499 return VK_FORMAT_R32G32_SFLOAT; 520 return VK_FORMAT_R32G32_SFLOAT;
500 case Maxwell::VertexAttribute::Size::Size_32_32_32: 521 case Maxwell::VertexAttribute::Size::Size_R32_G32_B32:
501 return VK_FORMAT_R32G32B32_SFLOAT; 522 return VK_FORMAT_R32G32B32_SFLOAT;
502 case Maxwell::VertexAttribute::Size::Size_32_32_32_32: 523 case Maxwell::VertexAttribute::Size::Size_R32_G32_B32_A32:
503 return VK_FORMAT_R32G32B32A32_SFLOAT; 524 return VK_FORMAT_R32G32B32A32_SFLOAT;
504 case Maxwell::VertexAttribute::Size::Size_11_11_10: 525 case Maxwell::VertexAttribute::Size::Size_B10_G11_R11:
505 return VK_FORMAT_B10G11R11_UFLOAT_PACK32; 526 return VK_FORMAT_B10G11R11_UFLOAT_PACK32;
506 default: 527 default:
507 break; 528 break;
@@ -521,29 +542,29 @@ VkFormat VertexFormat(const Device& device, Maxwell::VertexAttribute::Type type,
521 542
522VkCompareOp ComparisonOp(Maxwell::ComparisonOp comparison) { 543VkCompareOp ComparisonOp(Maxwell::ComparisonOp comparison) {
523 switch (comparison) { 544 switch (comparison) {
524 case Maxwell::ComparisonOp::Never: 545 case Maxwell::ComparisonOp::Never_D3D:
525 case Maxwell::ComparisonOp::NeverOld: 546 case Maxwell::ComparisonOp::Never_GL:
526 return VK_COMPARE_OP_NEVER; 547 return VK_COMPARE_OP_NEVER;
527 case Maxwell::ComparisonOp::Less: 548 case Maxwell::ComparisonOp::Less_D3D:
528 case Maxwell::ComparisonOp::LessOld: 549 case Maxwell::ComparisonOp::Less_GL:
529 return VK_COMPARE_OP_LESS; 550 return VK_COMPARE_OP_LESS;
530 case Maxwell::ComparisonOp::Equal: 551 case Maxwell::ComparisonOp::Equal_D3D:
531 case Maxwell::ComparisonOp::EqualOld: 552 case Maxwell::ComparisonOp::Equal_GL:
532 return VK_COMPARE_OP_EQUAL; 553 return VK_COMPARE_OP_EQUAL;
533 case Maxwell::ComparisonOp::LessEqual: 554 case Maxwell::ComparisonOp::LessEqual_D3D:
534 case Maxwell::ComparisonOp::LessEqualOld: 555 case Maxwell::ComparisonOp::LessEqual_GL:
535 return VK_COMPARE_OP_LESS_OR_EQUAL; 556 return VK_COMPARE_OP_LESS_OR_EQUAL;
536 case Maxwell::ComparisonOp::Greater: 557 case Maxwell::ComparisonOp::Greater_D3D:
537 case Maxwell::ComparisonOp::GreaterOld: 558 case Maxwell::ComparisonOp::Greater_GL:
538 return VK_COMPARE_OP_GREATER; 559 return VK_COMPARE_OP_GREATER;
539 case Maxwell::ComparisonOp::NotEqual: 560 case Maxwell::ComparisonOp::NotEqual_D3D:
540 case Maxwell::ComparisonOp::NotEqualOld: 561 case Maxwell::ComparisonOp::NotEqual_GL:
541 return VK_COMPARE_OP_NOT_EQUAL; 562 return VK_COMPARE_OP_NOT_EQUAL;
542 case Maxwell::ComparisonOp::GreaterEqual: 563 case Maxwell::ComparisonOp::GreaterEqual_D3D:
543 case Maxwell::ComparisonOp::GreaterEqualOld: 564 case Maxwell::ComparisonOp::GreaterEqual_GL:
544 return VK_COMPARE_OP_GREATER_OR_EQUAL; 565 return VK_COMPARE_OP_GREATER_OR_EQUAL;
545 case Maxwell::ComparisonOp::Always: 566 case Maxwell::ComparisonOp::Always_D3D:
546 case Maxwell::ComparisonOp::AlwaysOld: 567 case Maxwell::ComparisonOp::Always_GL:
547 return VK_COMPARE_OP_ALWAYS; 568 return VK_COMPARE_OP_ALWAYS;
548 } 569 }
549 UNIMPLEMENTED_MSG("Unimplemented comparison op={}", comparison); 570 UNIMPLEMENTED_MSG("Unimplemented comparison op={}", comparison);
@@ -563,31 +584,31 @@ VkIndexType IndexFormat(Maxwell::IndexFormat index_format) {
563 return {}; 584 return {};
564} 585}
565 586
566VkStencilOp StencilOp(Maxwell::StencilOp stencil_op) { 587VkStencilOp StencilOp(Maxwell::StencilOp::Op stencil_op) {
567 switch (stencil_op) { 588 switch (stencil_op) {
568 case Maxwell::StencilOp::Keep: 589 case Maxwell::StencilOp::Op::Keep_D3D:
569 case Maxwell::StencilOp::KeepOGL: 590 case Maxwell::StencilOp::Op::Keep_GL:
570 return VK_STENCIL_OP_KEEP; 591 return VK_STENCIL_OP_KEEP;
571 case Maxwell::StencilOp::Zero: 592 case Maxwell::StencilOp::Op::Zero_D3D:
572 case Maxwell::StencilOp::ZeroOGL: 593 case Maxwell::StencilOp::Op::Zero_GL:
573 return VK_STENCIL_OP_ZERO; 594 return VK_STENCIL_OP_ZERO;
574 case Maxwell::StencilOp::Replace: 595 case Maxwell::StencilOp::Op::Replace_D3D:
575 case Maxwell::StencilOp::ReplaceOGL: 596 case Maxwell::StencilOp::Op::Replace_GL:
576 return VK_STENCIL_OP_REPLACE; 597 return VK_STENCIL_OP_REPLACE;
577 case Maxwell::StencilOp::Incr: 598 case Maxwell::StencilOp::Op::IncrSaturate_D3D:
578 case Maxwell::StencilOp::IncrOGL: 599 case Maxwell::StencilOp::Op::IncrSaturate_GL:
579 return VK_STENCIL_OP_INCREMENT_AND_CLAMP; 600 return VK_STENCIL_OP_INCREMENT_AND_CLAMP;
580 case Maxwell::StencilOp::Decr: 601 case Maxwell::StencilOp::Op::DecrSaturate_D3D:
581 case Maxwell::StencilOp::DecrOGL: 602 case Maxwell::StencilOp::Op::DecrSaturate_GL:
582 return VK_STENCIL_OP_DECREMENT_AND_CLAMP; 603 return VK_STENCIL_OP_DECREMENT_AND_CLAMP;
583 case Maxwell::StencilOp::Invert: 604 case Maxwell::StencilOp::Op::Invert_D3D:
584 case Maxwell::StencilOp::InvertOGL: 605 case Maxwell::StencilOp::Op::Invert_GL:
585 return VK_STENCIL_OP_INVERT; 606 return VK_STENCIL_OP_INVERT;
586 case Maxwell::StencilOp::IncrWrap: 607 case Maxwell::StencilOp::Op::Incr_D3D:
587 case Maxwell::StencilOp::IncrWrapOGL: 608 case Maxwell::StencilOp::Op::Incr_GL:
588 return VK_STENCIL_OP_INCREMENT_AND_WRAP; 609 return VK_STENCIL_OP_INCREMENT_AND_WRAP;
589 case Maxwell::StencilOp::DecrWrap: 610 case Maxwell::StencilOp::Op::Decr_D3D:
590 case Maxwell::StencilOp::DecrWrapOGL: 611 case Maxwell::StencilOp::Op::Decr_GL:
591 return VK_STENCIL_OP_DECREMENT_AND_WRAP; 612 return VK_STENCIL_OP_DECREMENT_AND_WRAP;
592 } 613 }
593 UNIMPLEMENTED_MSG("Unimplemented stencil op={}", stencil_op); 614 UNIMPLEMENTED_MSG("Unimplemented stencil op={}", stencil_op);
@@ -596,20 +617,20 @@ VkStencilOp StencilOp(Maxwell::StencilOp stencil_op) {
596 617
597VkBlendOp BlendEquation(Maxwell::Blend::Equation equation) { 618VkBlendOp BlendEquation(Maxwell::Blend::Equation equation) {
598 switch (equation) { 619 switch (equation) {
599 case Maxwell::Blend::Equation::Add: 620 case Maxwell::Blend::Equation::Add_D3D:
600 case Maxwell::Blend::Equation::AddGL: 621 case Maxwell::Blend::Equation::Add_GL:
601 return VK_BLEND_OP_ADD; 622 return VK_BLEND_OP_ADD;
602 case Maxwell::Blend::Equation::Subtract: 623 case Maxwell::Blend::Equation::Subtract_D3D:
603 case Maxwell::Blend::Equation::SubtractGL: 624 case Maxwell::Blend::Equation::Subtract_GL:
604 return VK_BLEND_OP_SUBTRACT; 625 return VK_BLEND_OP_SUBTRACT;
605 case Maxwell::Blend::Equation::ReverseSubtract: 626 case Maxwell::Blend::Equation::ReverseSubtract_D3D:
606 case Maxwell::Blend::Equation::ReverseSubtractGL: 627 case Maxwell::Blend::Equation::ReverseSubtract_GL:
607 return VK_BLEND_OP_REVERSE_SUBTRACT; 628 return VK_BLEND_OP_REVERSE_SUBTRACT;
608 case Maxwell::Blend::Equation::Min: 629 case Maxwell::Blend::Equation::Min_D3D:
609 case Maxwell::Blend::Equation::MinGL: 630 case Maxwell::Blend::Equation::Min_GL:
610 return VK_BLEND_OP_MIN; 631 return VK_BLEND_OP_MIN;
611 case Maxwell::Blend::Equation::Max: 632 case Maxwell::Blend::Equation::Max_D3D:
612 case Maxwell::Blend::Equation::MaxGL: 633 case Maxwell::Blend::Equation::Max_GL:
613 return VK_BLEND_OP_MAX; 634 return VK_BLEND_OP_MAX;
614 } 635 }
615 UNIMPLEMENTED_MSG("Unimplemented blend equation={}", equation); 636 UNIMPLEMENTED_MSG("Unimplemented blend equation={}", equation);
@@ -618,62 +639,62 @@ VkBlendOp BlendEquation(Maxwell::Blend::Equation equation) {
618 639
619VkBlendFactor BlendFactor(Maxwell::Blend::Factor factor) { 640VkBlendFactor BlendFactor(Maxwell::Blend::Factor factor) {
620 switch (factor) { 641 switch (factor) {
621 case Maxwell::Blend::Factor::Zero: 642 case Maxwell::Blend::Factor::Zero_D3D:
622 case Maxwell::Blend::Factor::ZeroGL: 643 case Maxwell::Blend::Factor::Zero_GL:
623 return VK_BLEND_FACTOR_ZERO; 644 return VK_BLEND_FACTOR_ZERO;
624 case Maxwell::Blend::Factor::One: 645 case Maxwell::Blend::Factor::One_D3D:
625 case Maxwell::Blend::Factor::OneGL: 646 case Maxwell::Blend::Factor::One_GL:
626 return VK_BLEND_FACTOR_ONE; 647 return VK_BLEND_FACTOR_ONE;
627 case Maxwell::Blend::Factor::SourceColor: 648 case Maxwell::Blend::Factor::SourceColor_D3D:
628 case Maxwell::Blend::Factor::SourceColorGL: 649 case Maxwell::Blend::Factor::SourceColor_GL:
629 return VK_BLEND_FACTOR_SRC_COLOR; 650 return VK_BLEND_FACTOR_SRC_COLOR;
630 case Maxwell::Blend::Factor::OneMinusSourceColor: 651 case Maxwell::Blend::Factor::OneMinusSourceColor_D3D:
631 case Maxwell::Blend::Factor::OneMinusSourceColorGL: 652 case Maxwell::Blend::Factor::OneMinusSourceColor_GL:
632 return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR; 653 return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
633 case Maxwell::Blend::Factor::SourceAlpha: 654 case Maxwell::Blend::Factor::SourceAlpha_D3D:
634 case Maxwell::Blend::Factor::SourceAlphaGL: 655 case Maxwell::Blend::Factor::SourceAlpha_GL:
635 return VK_BLEND_FACTOR_SRC_ALPHA; 656 return VK_BLEND_FACTOR_SRC_ALPHA;
636 case Maxwell::Blend::Factor::OneMinusSourceAlpha: 657 case Maxwell::Blend::Factor::OneMinusSourceAlpha_D3D:
637 case Maxwell::Blend::Factor::OneMinusSourceAlphaGL: 658 case Maxwell::Blend::Factor::OneMinusSourceAlpha_GL:
638 return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; 659 return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
639 case Maxwell::Blend::Factor::DestAlpha: 660 case Maxwell::Blend::Factor::DestAlpha_D3D:
640 case Maxwell::Blend::Factor::DestAlphaGL: 661 case Maxwell::Blend::Factor::DestAlpha_GL:
641 return VK_BLEND_FACTOR_DST_ALPHA; 662 return VK_BLEND_FACTOR_DST_ALPHA;
642 case Maxwell::Blend::Factor::OneMinusDestAlpha: 663 case Maxwell::Blend::Factor::OneMinusDestAlpha_D3D:
643 case Maxwell::Blend::Factor::OneMinusDestAlphaGL: 664 case Maxwell::Blend::Factor::OneMinusDestAlpha_GL:
644 return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA; 665 return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
645 case Maxwell::Blend::Factor::DestColor: 666 case Maxwell::Blend::Factor::DestColor_D3D:
646 case Maxwell::Blend::Factor::DestColorGL: 667 case Maxwell::Blend::Factor::DestColor_GL:
647 return VK_BLEND_FACTOR_DST_COLOR; 668 return VK_BLEND_FACTOR_DST_COLOR;
648 case Maxwell::Blend::Factor::OneMinusDestColor: 669 case Maxwell::Blend::Factor::OneMinusDestColor_D3D:
649 case Maxwell::Blend::Factor::OneMinusDestColorGL: 670 case Maxwell::Blend::Factor::OneMinusDestColor_GL:
650 return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR; 671 return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
651 case Maxwell::Blend::Factor::SourceAlphaSaturate: 672 case Maxwell::Blend::Factor::SourceAlphaSaturate_D3D:
652 case Maxwell::Blend::Factor::SourceAlphaSaturateGL: 673 case Maxwell::Blend::Factor::SourceAlphaSaturate_GL:
653 return VK_BLEND_FACTOR_SRC_ALPHA_SATURATE; 674 return VK_BLEND_FACTOR_SRC_ALPHA_SATURATE;
654 case Maxwell::Blend::Factor::Source1Color: 675 case Maxwell::Blend::Factor::Source1Color_D3D:
655 case Maxwell::Blend::Factor::Source1ColorGL: 676 case Maxwell::Blend::Factor::Source1Color_GL:
656 return VK_BLEND_FACTOR_SRC1_COLOR; 677 return VK_BLEND_FACTOR_SRC1_COLOR;
657 case Maxwell::Blend::Factor::OneMinusSource1Color: 678 case Maxwell::Blend::Factor::OneMinusSource1Color_D3D:
658 case Maxwell::Blend::Factor::OneMinusSource1ColorGL: 679 case Maxwell::Blend::Factor::OneMinusSource1Color_GL:
659 return VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR; 680 return VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR;
660 case Maxwell::Blend::Factor::Source1Alpha: 681 case Maxwell::Blend::Factor::Source1Alpha_D3D:
661 case Maxwell::Blend::Factor::Source1AlphaGL: 682 case Maxwell::Blend::Factor::Source1Alpha_GL:
662 return VK_BLEND_FACTOR_SRC1_ALPHA; 683 return VK_BLEND_FACTOR_SRC1_ALPHA;
663 case Maxwell::Blend::Factor::OneMinusSource1Alpha: 684 case Maxwell::Blend::Factor::OneMinusSource1Alpha_D3D:
664 case Maxwell::Blend::Factor::OneMinusSource1AlphaGL: 685 case Maxwell::Blend::Factor::OneMinusSource1Alpha_GL:
665 return VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA; 686 return VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA;
666 case Maxwell::Blend::Factor::ConstantColor: 687 case Maxwell::Blend::Factor::BlendFactor_D3D:
667 case Maxwell::Blend::Factor::ConstantColorGL: 688 case Maxwell::Blend::Factor::ConstantColor_GL:
668 return VK_BLEND_FACTOR_CONSTANT_COLOR; 689 return VK_BLEND_FACTOR_CONSTANT_COLOR;
669 case Maxwell::Blend::Factor::OneMinusConstantColor: 690 case Maxwell::Blend::Factor::OneMinusBlendFactor_D3D:
670 case Maxwell::Blend::Factor::OneMinusConstantColorGL: 691 case Maxwell::Blend::Factor::OneMinusConstantColor_GL:
671 return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR; 692 return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR;
672 case Maxwell::Blend::Factor::ConstantAlpha: 693 case Maxwell::Blend::Factor::BothSourceAlpha_D3D:
673 case Maxwell::Blend::Factor::ConstantAlphaGL: 694 case Maxwell::Blend::Factor::ConstantAlpha_GL:
674 return VK_BLEND_FACTOR_CONSTANT_ALPHA; 695 return VK_BLEND_FACTOR_CONSTANT_ALPHA;
675 case Maxwell::Blend::Factor::OneMinusConstantAlpha: 696 case Maxwell::Blend::Factor::OneMinusBothSourceAlpha_D3D:
676 case Maxwell::Blend::Factor::OneMinusConstantAlphaGL: 697 case Maxwell::Blend::Factor::OneMinusConstantAlpha_GL:
677 return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA; 698 return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA;
678 } 699 }
679 UNIMPLEMENTED_MSG("Unimplemented blend factor={}", factor); 700 UNIMPLEMENTED_MSG("Unimplemented blend factor={}", factor);
diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.h b/src/video_core/renderer_vulkan/maxwell_to_vk.h
index 356d46292..6f65502d6 100644
--- a/src/video_core/renderer_vulkan/maxwell_to_vk.h
+++ b/src/video_core/renderer_vulkan/maxwell_to_vk.h
@@ -55,7 +55,7 @@ VkCompareOp ComparisonOp(Maxwell::ComparisonOp comparison);
55 55
56VkIndexType IndexFormat(Maxwell::IndexFormat index_format); 56VkIndexType IndexFormat(Maxwell::IndexFormat index_format);
57 57
58VkStencilOp StencilOp(Maxwell::StencilOp stencil_op); 58VkStencilOp StencilOp(Maxwell::StencilOp::Op stencil_op);
59 59
60VkBlendOp BlendEquation(Maxwell::Blend::Equation equation); 60VkBlendOp BlendEquation(Maxwell::Blend::Equation equation);
61 61
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
index f47786f48..c3f66c8a3 100644
--- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
+++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
@@ -288,7 +288,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
288 buffer_cache.SetUniformBuffersState(enabled_uniform_buffer_masks, &uniform_buffer_sizes); 288 buffer_cache.SetUniformBuffersState(enabled_uniform_buffer_masks, &uniform_buffer_sizes);
289 289
290 const auto& regs{maxwell3d->regs}; 290 const auto& regs{maxwell3d->regs};
291 const bool via_header_index{regs.sampler_index == Maxwell::SamplerIndex::ViaHeaderIndex}; 291 const bool via_header_index{regs.sampler_binding == Maxwell::SamplerBinding::ViaHeaderBinding};
292 const auto config_stage{[&](size_t stage) LAMBDA_FORCEINLINE { 292 const auto config_stage{[&](size_t stage) LAMBDA_FORCEINLINE {
293 const Shader::Info& info{stage_infos[stage]}; 293 const Shader::Info& info{stage_infos[stage]};
294 buffer_cache.UnbindGraphicsStorageBuffers(stage); 294 buffer_cache.UnbindGraphicsStorageBuffers(stage);
@@ -664,15 +664,6 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
664 .lineStippleFactor = 0, 664 .lineStippleFactor = 0,
665 .lineStipplePattern = 0, 665 .lineStipplePattern = 0,
666 }; 666 };
667 VkPipelineRasterizationConservativeStateCreateInfoEXT conservative_raster{
668 .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT,
669 .pNext = nullptr,
670 .flags = 0,
671 .conservativeRasterizationMode = key.state.conservative_raster_enable != 0
672 ? VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT
673 : VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT,
674 .extraPrimitiveOverestimationSize = 0.0f,
675 };
676 VkPipelineRasterizationProvokingVertexStateCreateInfoEXT provoking_vertex{ 667 VkPipelineRasterizationProvokingVertexStateCreateInfoEXT provoking_vertex{
677 .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT, 668 .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT,
678 .pNext = nullptr, 669 .pNext = nullptr,
@@ -683,9 +674,6 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
683 if (IsLine(input_assembly_topology) && device.IsExtLineRasterizationSupported()) { 674 if (IsLine(input_assembly_topology) && device.IsExtLineRasterizationSupported()) {
684 line_state.pNext = std::exchange(rasterization_ci.pNext, &line_state); 675 line_state.pNext = std::exchange(rasterization_ci.pNext, &line_state);
685 } 676 }
686 if (device.IsExtConservativeRasterizationSupported()) {
687 conservative_raster.pNext = std::exchange(rasterization_ci.pNext, &conservative_raster);
688 }
689 if (device.IsExtProvokingVertexSupported()) { 677 if (device.IsExtProvokingVertexSupported()) {
690 provoking_vertex.pNext = std::exchange(rasterization_ci.pNext, &provoking_vertex); 678 provoking_vertex.pNext = std::exchange(rasterization_ci.pNext, &provoking_vertex);
691 } 679 }
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index 732e7b6f2..20f1d6584 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -62,29 +62,29 @@ auto MakeSpan(Container& container) {
62 62
63Shader::CompareFunction MaxwellToCompareFunction(Maxwell::ComparisonOp comparison) { 63Shader::CompareFunction MaxwellToCompareFunction(Maxwell::ComparisonOp comparison) {
64 switch (comparison) { 64 switch (comparison) {
65 case Maxwell::ComparisonOp::Never: 65 case Maxwell::ComparisonOp::Never_D3D:
66 case Maxwell::ComparisonOp::NeverOld: 66 case Maxwell::ComparisonOp::Never_GL:
67 return Shader::CompareFunction::Never; 67 return Shader::CompareFunction::Never;
68 case Maxwell::ComparisonOp::Less: 68 case Maxwell::ComparisonOp::Less_D3D:
69 case Maxwell::ComparisonOp::LessOld: 69 case Maxwell::ComparisonOp::Less_GL:
70 return Shader::CompareFunction::Less; 70 return Shader::CompareFunction::Less;
71 case Maxwell::ComparisonOp::Equal: 71 case Maxwell::ComparisonOp::Equal_D3D:
72 case Maxwell::ComparisonOp::EqualOld: 72 case Maxwell::ComparisonOp::Equal_GL:
73 return Shader::CompareFunction::Equal; 73 return Shader::CompareFunction::Equal;
74 case Maxwell::ComparisonOp::LessEqual: 74 case Maxwell::ComparisonOp::LessEqual_D3D:
75 case Maxwell::ComparisonOp::LessEqualOld: 75 case Maxwell::ComparisonOp::LessEqual_GL:
76 return Shader::CompareFunction::LessThanEqual; 76 return Shader::CompareFunction::LessThanEqual;
77 case Maxwell::ComparisonOp::Greater: 77 case Maxwell::ComparisonOp::Greater_D3D:
78 case Maxwell::ComparisonOp::GreaterOld: 78 case Maxwell::ComparisonOp::Greater_GL:
79 return Shader::CompareFunction::Greater; 79 return Shader::CompareFunction::Greater;
80 case Maxwell::ComparisonOp::NotEqual: 80 case Maxwell::ComparisonOp::NotEqual_D3D:
81 case Maxwell::ComparisonOp::NotEqualOld: 81 case Maxwell::ComparisonOp::NotEqual_GL:
82 return Shader::CompareFunction::NotEqual; 82 return Shader::CompareFunction::NotEqual;
83 case Maxwell::ComparisonOp::GreaterEqual: 83 case Maxwell::ComparisonOp::GreaterEqual_D3D:
84 case Maxwell::ComparisonOp::GreaterEqualOld: 84 case Maxwell::ComparisonOp::GreaterEqual_GL:
85 return Shader::CompareFunction::GreaterThanEqual; 85 return Shader::CompareFunction::GreaterThanEqual;
86 case Maxwell::ComparisonOp::Always: 86 case Maxwell::ComparisonOp::Always_D3D:
87 case Maxwell::ComparisonOp::AlwaysOld: 87 case Maxwell::ComparisonOp::Always_GL:
88 return Shader::CompareFunction::Always; 88 return Shader::CompareFunction::Always;
89 } 89 }
90 UNIMPLEMENTED_MSG("Unimplemented comparison op={}", comparison); 90 UNIMPLEMENTED_MSG("Unimplemented comparison op={}", comparison);
@@ -96,15 +96,18 @@ Shader::AttributeType CastAttributeType(const FixedPipelineState::VertexAttribut
96 return Shader::AttributeType::Disabled; 96 return Shader::AttributeType::Disabled;
97 } 97 }
98 switch (attr.Type()) { 98 switch (attr.Type()) {
99 case Maxwell::VertexAttribute::Type::SignedNorm: 99 case Maxwell::VertexAttribute::Type::UnusedEnumDoNotUseBecauseItWillGoAway:
100 case Maxwell::VertexAttribute::Type::UnsignedNorm: 100 ASSERT_MSG(false, "Invalid vertex attribute type!");
101 case Maxwell::VertexAttribute::Type::UnsignedScaled: 101 return Shader::AttributeType::Disabled;
102 case Maxwell::VertexAttribute::Type::SignedScaled: 102 case Maxwell::VertexAttribute::Type::SNorm:
103 case Maxwell::VertexAttribute::Type::UNorm:
104 case Maxwell::VertexAttribute::Type::UScaled:
105 case Maxwell::VertexAttribute::Type::SScaled:
103 case Maxwell::VertexAttribute::Type::Float: 106 case Maxwell::VertexAttribute::Type::Float:
104 return Shader::AttributeType::Float; 107 return Shader::AttributeType::Float;
105 case Maxwell::VertexAttribute::Type::SignedInt: 108 case Maxwell::VertexAttribute::Type::SInt:
106 return Shader::AttributeType::SignedInt; 109 return Shader::AttributeType::SignedInt;
107 case Maxwell::VertexAttribute::Type::UnsignedInt: 110 case Maxwell::VertexAttribute::Type::UInt:
108 return Shader::AttributeType::UnsignedInt; 111 return Shader::AttributeType::UnsignedInt;
109 } 112 }
110 return Shader::AttributeType::Float; 113 return Shader::AttributeType::Float;
@@ -162,16 +165,14 @@ Shader::RuntimeInfo MakeRuntimeInfo(std::span<const Shader::IR::Program> program
162 } 165 }
163 break; 166 break;
164 case Shader::Stage::TessellationEval: 167 case Shader::Stage::TessellationEval:
165 // We have to flip tessellation clockwise for some reason...
166 info.tess_clockwise = key.state.tessellation_clockwise == 0;
167 info.tess_primitive = [&key] { 168 info.tess_primitive = [&key] {
168 const u32 raw{key.state.tessellation_primitive.Value()}; 169 const u32 raw{key.state.tessellation_primitive.Value()};
169 switch (static_cast<Maxwell::TessellationPrimitive>(raw)) { 170 switch (static_cast<Maxwell::Tessellation::DomainType>(raw)) {
170 case Maxwell::TessellationPrimitive::Isolines: 171 case Maxwell::Tessellation::DomainType::Isolines:
171 return Shader::TessPrimitive::Isolines; 172 return Shader::TessPrimitive::Isolines;
172 case Maxwell::TessellationPrimitive::Triangles: 173 case Maxwell::Tessellation::DomainType::Triangles:
173 return Shader::TessPrimitive::Triangles; 174 return Shader::TessPrimitive::Triangles;
174 case Maxwell::TessellationPrimitive::Quads: 175 case Maxwell::Tessellation::DomainType::Quads:
175 return Shader::TessPrimitive::Quads; 176 return Shader::TessPrimitive::Quads;
176 } 177 }
177 ASSERT(false); 178 ASSERT(false);
@@ -179,12 +180,12 @@ Shader::RuntimeInfo MakeRuntimeInfo(std::span<const Shader::IR::Program> program
179 }(); 180 }();
180 info.tess_spacing = [&] { 181 info.tess_spacing = [&] {
181 const u32 raw{key.state.tessellation_spacing}; 182 const u32 raw{key.state.tessellation_spacing};
182 switch (static_cast<Maxwell::TessellationSpacing>(raw)) { 183 switch (static_cast<Maxwell::Tessellation::Spacing>(raw)) {
183 case Maxwell::TessellationSpacing::Equal: 184 case Maxwell::Tessellation::Spacing::Integer:
184 return Shader::TessSpacing::Equal; 185 return Shader::TessSpacing::Equal;
185 case Maxwell::TessellationSpacing::FractionalOdd: 186 case Maxwell::Tessellation::Spacing::FractionalOdd:
186 return Shader::TessSpacing::FractionalOdd; 187 return Shader::TessSpacing::FractionalOdd;
187 case Maxwell::TessellationSpacing::FractionalEven: 188 case Maxwell::Tessellation::Spacing::FractionalEven:
188 return Shader::TessSpacing::FractionalEven; 189 return Shader::TessSpacing::FractionalEven;
189 } 190 }
190 ASSERT(false); 191 ASSERT(false);
@@ -490,7 +491,7 @@ GraphicsPipeline* PipelineCache::BuiltPipeline(GraphicsPipeline* pipeline) const
490 // If games are using a small index count, we can assume these are full screen quads. 491 // If games are using a small index count, we can assume these are full screen quads.
491 // Usually these shaders are only used once for building textures so we can assume they 492 // Usually these shaders are only used once for building textures so we can assume they
492 // can't be built async 493 // can't be built async
493 if (maxwell3d->regs.index_array.count <= 6 || maxwell3d->regs.vertex_buffer.count <= 6) { 494 if (maxwell3d->regs.index_buffer.count <= 6 || maxwell3d->regs.vertex_buffer.count <= 6) {
494 return pipeline; 495 return pipeline;
495 } 496 }
496 return nullptr; 497 return nullptr;
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index acfd5da7d..892cd94a3 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -70,7 +70,7 @@ VkViewport GetViewportState(const Device& device, const Maxwell& regs, size_t in
70 const float width = conv(src.scale_x * 2.0f); 70 const float width = conv(src.scale_x * 2.0f);
71 float y = conv(src.translate_y - src.scale_y); 71 float y = conv(src.translate_y - src.scale_y);
72 float height = conv(src.scale_y * 2.0f); 72 float height = conv(src.scale_y * 2.0f);
73 bool y_negate = regs.screen_y_control.y_negate; 73 bool y_negate = regs.window_origin.mode != Maxwell::WindowOrigin::Mode::UpperLeft;
74 74
75 if (!device.IsNvViewportSwizzleSupported()) { 75 if (!device.IsNvViewportSwizzleSupported()) {
76 y_negate = y_negate != (src.swizzle.y == Maxwell::ViewportSwizzle::NegativeY); 76 y_negate = y_negate != (src.swizzle.y == Maxwell::ViewportSwizzle::NegativeY);
@@ -130,11 +130,11 @@ VkRect2D GetScissorState(const Maxwell& regs, size_t index, u32 up_scale = 1, u3
130DrawParams MakeDrawParams(const Maxwell& regs, u32 num_instances, bool is_instanced, 130DrawParams MakeDrawParams(const Maxwell& regs, u32 num_instances, bool is_instanced,
131 bool is_indexed) { 131 bool is_indexed) {
132 DrawParams params{ 132 DrawParams params{
133 .base_instance = regs.vb_base_instance, 133 .base_instance = regs.global_base_instance_index,
134 .num_instances = is_instanced ? num_instances : 1, 134 .num_instances = is_instanced ? num_instances : 1,
135 .base_vertex = is_indexed ? regs.vb_element_base : regs.vertex_buffer.first, 135 .base_vertex = is_indexed ? regs.global_base_vertex_index : regs.vertex_buffer.first,
136 .num_vertices = is_indexed ? regs.index_array.count : regs.vertex_buffer.count, 136 .num_vertices = is_indexed ? regs.index_buffer.count : regs.vertex_buffer.count,
137 .first_index = is_indexed ? regs.index_array.first : 0, 137 .first_index = is_indexed ? regs.index_buffer.first : 0,
138 .is_indexed = is_indexed, 138 .is_indexed = is_indexed,
139 }; 139 };
140 if (regs.draw.topology == Maxwell::PrimitiveTopology::Quads) { 140 if (regs.draw.topology == Maxwell::PrimitiveTopology::Quads) {
@@ -225,10 +225,10 @@ void RasterizerVulkan::Clear() {
225 query_cache.UpdateCounters(); 225 query_cache.UpdateCounters();
226 226
227 auto& regs = maxwell3d->regs; 227 auto& regs = maxwell3d->regs;
228 const bool use_color = regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B || 228 const bool use_color = regs.clear_surface.R || regs.clear_surface.G || regs.clear_surface.B ||
229 regs.clear_buffers.A; 229 regs.clear_surface.A;
230 const bool use_depth = regs.clear_buffers.Z; 230 const bool use_depth = regs.clear_surface.Z;
231 const bool use_stencil = regs.clear_buffers.S; 231 const bool use_stencil = regs.clear_surface.S;
232 if (!use_color && !use_depth && !use_stencil) { 232 if (!use_color && !use_depth && !use_stencil) {
233 return; 233 return;
234 } 234 }
@@ -254,9 +254,9 @@ void RasterizerVulkan::Clear() {
254 default_scissor.extent.height = std::numeric_limits<s32>::max(); 254 default_scissor.extent.height = std::numeric_limits<s32>::max();
255 255
256 VkClearRect clear_rect{ 256 VkClearRect clear_rect{
257 .rect = regs.clear_flags.scissor ? GetScissorState(regs, 0, up_scale, down_shift) 257 .rect = regs.clear_control.use_scissor ? GetScissorState(regs, 0, up_scale, down_shift)
258 : default_scissor, 258 : default_scissor,
259 .baseArrayLayer = regs.clear_buffers.layer, 259 .baseArrayLayer = regs.clear_surface.layer,
260 .layerCount = 1, 260 .layerCount = 1,
261 }; 261 };
262 if (clear_rect.rect.extent.width == 0 || clear_rect.rect.extent.height == 0) { 262 if (clear_rect.rect.extent.width == 0 || clear_rect.rect.extent.height == 0) {
@@ -267,7 +267,7 @@ void RasterizerVulkan::Clear() {
267 .height = std::min(clear_rect.rect.extent.height, render_area.height), 267 .height = std::min(clear_rect.rect.extent.height, render_area.height),
268 }; 268 };
269 269
270 const u32 color_attachment = regs.clear_buffers.RT; 270 const u32 color_attachment = regs.clear_surface.RT;
271 if (use_color && framebuffer->HasAspectColorBit(color_attachment)) { 271 if (use_color && framebuffer->HasAspectColorBit(color_attachment)) {
272 VkClearValue clear_value; 272 VkClearValue clear_value;
273 bool is_integer = false; 273 bool is_integer = false;
@@ -289,7 +289,8 @@ void RasterizerVulkan::Clear() {
289 break; 289 break;
290 } 290 }
291 if (!is_integer) { 291 if (!is_integer) {
292 std::memcpy(clear_value.color.float32, regs.clear_color, sizeof(regs.clear_color)); 292 std::memcpy(clear_value.color.float32, regs.clear_color.data(),
293 regs.clear_color.size() * sizeof(f32));
293 } else if (!is_signed) { 294 } else if (!is_signed) {
294 for (size_t i = 0; i < 4; i++) { 295 for (size_t i = 0; i < 4; i++) {
295 clear_value.color.uint32[i] = static_cast<u32>( 296 clear_value.color.uint32[i] = static_cast<u32>(
@@ -648,23 +649,23 @@ void RasterizerVulkan::UpdateDynamicStates() {
648 649
649void RasterizerVulkan::BeginTransformFeedback() { 650void RasterizerVulkan::BeginTransformFeedback() {
650 const auto& regs = maxwell3d->regs; 651 const auto& regs = maxwell3d->regs;
651 if (regs.tfb_enabled == 0) { 652 if (regs.transform_feedback_enabled == 0) {
652 return; 653 return;
653 } 654 }
654 if (!device.IsExtTransformFeedbackSupported()) { 655 if (!device.IsExtTransformFeedbackSupported()) {
655 LOG_ERROR(Render_Vulkan, "Transform feedbacks used but not supported"); 656 LOG_ERROR(Render_Vulkan, "Transform feedbacks used but not supported");
656 return; 657 return;
657 } 658 }
658 UNIMPLEMENTED_IF(regs.IsShaderConfigEnabled(Maxwell::ShaderProgram::TesselationControl) || 659 UNIMPLEMENTED_IF(regs.IsShaderConfigEnabled(Maxwell::ShaderType::TessellationInit) ||
659 regs.IsShaderConfigEnabled(Maxwell::ShaderProgram::TesselationEval) || 660 regs.IsShaderConfigEnabled(Maxwell::ShaderType::Tessellation) ||
660 regs.IsShaderConfigEnabled(Maxwell::ShaderProgram::Geometry)); 661 regs.IsShaderConfigEnabled(Maxwell::ShaderType::Geometry));
661 scheduler.Record( 662 scheduler.Record(
662 [](vk::CommandBuffer cmdbuf) { cmdbuf.BeginTransformFeedbackEXT(0, 0, nullptr, nullptr); }); 663 [](vk::CommandBuffer cmdbuf) { cmdbuf.BeginTransformFeedbackEXT(0, 0, nullptr, nullptr); });
663} 664}
664 665
665void RasterizerVulkan::EndTransformFeedback() { 666void RasterizerVulkan::EndTransformFeedback() {
666 const auto& regs = maxwell3d->regs; 667 const auto& regs = maxwell3d->regs;
667 if (regs.tfb_enabled == 0) { 668 if (regs.transform_feedback_enabled == 0) {
668 return; 669 return;
669 } 670 }
670 if (!device.IsExtTransformFeedbackSupported()) { 671 if (!device.IsExtTransformFeedbackSupported()) {
@@ -728,11 +729,11 @@ void RasterizerVulkan::UpdateDepthBias(Tegra::Engines::Maxwell3D::Regs& regs) {
728 if (!state_tracker.TouchDepthBias()) { 729 if (!state_tracker.TouchDepthBias()) {
729 return; 730 return;
730 } 731 }
731 float units = regs.polygon_offset_units / 2.0f; 732 float units = regs.depth_bias / 2.0f;
732 const bool is_d24 = regs.zeta.format == Tegra::DepthFormat::S8_UINT_Z24_UNORM || 733 const bool is_d24 = regs.zeta.format == Tegra::DepthFormat::Z24_UNORM_S8_UINT ||
733 regs.zeta.format == Tegra::DepthFormat::D24X8_UNORM || 734 regs.zeta.format == Tegra::DepthFormat::X8Z24_UNORM ||
734 regs.zeta.format == Tegra::DepthFormat::D24S8_UNORM || 735 regs.zeta.format == Tegra::DepthFormat::S8Z24_UNORM ||
735 regs.zeta.format == Tegra::DepthFormat::D24C8_UNORM; 736 regs.zeta.format == Tegra::DepthFormat::V8Z24_UNORM;
736 if (is_d24 && !device.SupportsD24DepthBuffer()) { 737 if (is_d24 && !device.SupportsD24DepthBuffer()) {
737 // the base formulas can be obtained from here: 738 // the base formulas can be obtained from here:
738 // https://docs.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-output-merger-stage-depth-bias 739 // https://docs.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-output-merger-stage-depth-bias
@@ -740,8 +741,8 @@ void RasterizerVulkan::UpdateDepthBias(Tegra::Engines::Maxwell3D::Regs& regs) {
740 static_cast<double>(1ULL << (32 - 24)) / (static_cast<double>(0x1.ep+127)); 741 static_cast<double>(1ULL << (32 - 24)) / (static_cast<double>(0x1.ep+127));
741 units = static_cast<float>(static_cast<double>(units) * rescale_factor); 742 units = static_cast<float>(static_cast<double>(units) * rescale_factor);
742 } 743 }
743 scheduler.Record([constant = units, clamp = regs.polygon_offset_clamp, 744 scheduler.Record([constant = units, clamp = regs.depth_bias_clamp,
744 factor = regs.polygon_offset_factor](vk::CommandBuffer cmdbuf) { 745 factor = regs.slope_scale_depth_bias](vk::CommandBuffer cmdbuf) {
745 cmdbuf.SetDepthBias(constant, clamp, factor); 746 cmdbuf.SetDepthBias(constant, clamp, factor);
746 }); 747 });
747} 748}
@@ -771,10 +772,11 @@ void RasterizerVulkan::UpdateStencilFaces(Tegra::Engines::Maxwell3D::Regs& regs)
771 if (regs.stencil_two_side_enable) { 772 if (regs.stencil_two_side_enable) {
772 // Separate values per face 773 // Separate values per face
773 scheduler.Record( 774 scheduler.Record(
774 [front_ref = regs.stencil_front_func_ref, front_write_mask = regs.stencil_front_mask, 775 [front_ref = regs.stencil_front_func.ref,
775 front_test_mask = regs.stencil_front_func_mask, back_ref = regs.stencil_back_func_ref, 776 front_write_mask = regs.stencil_front_func.mask,
776 back_write_mask = regs.stencil_back_mask, 777 front_test_mask = regs.stencil_front_func.func_mask,
777 back_test_mask = regs.stencil_back_func_mask](vk::CommandBuffer cmdbuf) { 778 back_ref = regs.stencil_back_func.ref, back_write_mask = regs.stencil_back_func.mask,
779 back_test_mask = regs.stencil_back_func.func_mask](vk::CommandBuffer cmdbuf) {
778 // Front face 780 // Front face
779 cmdbuf.SetStencilReference(VK_STENCIL_FACE_FRONT_BIT, front_ref); 781 cmdbuf.SetStencilReference(VK_STENCIL_FACE_FRONT_BIT, front_ref);
780 cmdbuf.SetStencilWriteMask(VK_STENCIL_FACE_FRONT_BIT, front_write_mask); 782 cmdbuf.SetStencilWriteMask(VK_STENCIL_FACE_FRONT_BIT, front_write_mask);
@@ -787,8 +789,9 @@ void RasterizerVulkan::UpdateStencilFaces(Tegra::Engines::Maxwell3D::Regs& regs)
787 }); 789 });
788 } else { 790 } else {
789 // Front face defines both faces 791 // Front face defines both faces
790 scheduler.Record([ref = regs.stencil_front_func_ref, write_mask = regs.stencil_front_mask, 792 scheduler.Record([ref = regs.stencil_front_func.ref,
791 test_mask = regs.stencil_front_func_mask](vk::CommandBuffer cmdbuf) { 793 write_mask = regs.stencil_front_func.mask,
794 test_mask = regs.stencil_front_func.func_mask](vk::CommandBuffer cmdbuf) {
792 cmdbuf.SetStencilReference(VK_STENCIL_FACE_FRONT_AND_BACK, ref); 795 cmdbuf.SetStencilReference(VK_STENCIL_FACE_FRONT_AND_BACK, ref);
793 cmdbuf.SetStencilWriteMask(VK_STENCIL_FACE_FRONT_AND_BACK, write_mask); 796 cmdbuf.SetStencilWriteMask(VK_STENCIL_FACE_FRONT_AND_BACK, write_mask);
794 cmdbuf.SetStencilCompareMask(VK_STENCIL_FACE_FRONT_AND_BACK, test_mask); 797 cmdbuf.SetStencilCompareMask(VK_STENCIL_FACE_FRONT_AND_BACK, test_mask);
@@ -800,7 +803,8 @@ void RasterizerVulkan::UpdateLineWidth(Tegra::Engines::Maxwell3D::Regs& regs) {
800 if (!state_tracker.TouchLineWidth()) { 803 if (!state_tracker.TouchLineWidth()) {
801 return; 804 return;
802 } 805 }
803 const float width = regs.line_smooth_enable ? regs.line_width_smooth : regs.line_width_aliased; 806 const float width =
807 regs.line_anti_alias_enable ? regs.line_width_smooth : regs.line_width_aliased;
804 scheduler.Record([width](vk::CommandBuffer cmdbuf) { cmdbuf.SetLineWidth(width); }); 808 scheduler.Record([width](vk::CommandBuffer cmdbuf) { cmdbuf.SetLineWidth(width); });
805} 809}
806 810
@@ -808,10 +812,10 @@ void RasterizerVulkan::UpdateCullMode(Tegra::Engines::Maxwell3D::Regs& regs) {
808 if (!state_tracker.TouchCullMode()) { 812 if (!state_tracker.TouchCullMode()) {
809 return; 813 return;
810 } 814 }
811 scheduler.Record( 815 scheduler.Record([enabled = regs.gl_cull_test_enabled,
812 [enabled = regs.cull_test_enabled, cull_face = regs.cull_face](vk::CommandBuffer cmdbuf) { 816 cull_face = regs.gl_cull_face](vk::CommandBuffer cmdbuf) {
813 cmdbuf.SetCullModeEXT(enabled ? MaxwellToVK::CullFace(cull_face) : VK_CULL_MODE_NONE); 817 cmdbuf.SetCullModeEXT(enabled ? MaxwellToVK::CullFace(cull_face) : VK_CULL_MODE_NONE);
814 }); 818 });
815} 819}
816 820
817void RasterizerVulkan::UpdateDepthBoundsTestEnable(Tegra::Engines::Maxwell3D::Regs& regs) { 821void RasterizerVulkan::UpdateDepthBoundsTestEnable(Tegra::Engines::Maxwell3D::Regs& regs) {
@@ -860,8 +864,8 @@ void RasterizerVulkan::UpdateFrontFace(Tegra::Engines::Maxwell3D::Regs& regs) {
860 return; 864 return;
861 } 865 }
862 866
863 VkFrontFace front_face = MaxwellToVK::FrontFace(regs.front_face); 867 VkFrontFace front_face = MaxwellToVK::FrontFace(regs.gl_front_face);
864 if (regs.screen_y_control.triangle_rast_flip != 0) { 868 if (regs.window_origin.flip_y != 0) {
865 front_face = front_face == VK_FRONT_FACE_CLOCKWISE ? VK_FRONT_FACE_COUNTER_CLOCKWISE 869 front_face = front_face == VK_FRONT_FACE_CLOCKWISE ? VK_FRONT_FACE_COUNTER_CLOCKWISE
866 : VK_FRONT_FACE_CLOCKWISE; 870 : VK_FRONT_FACE_CLOCKWISE;
867 } 871 }
@@ -873,16 +877,16 @@ void RasterizerVulkan::UpdateStencilOp(Tegra::Engines::Maxwell3D::Regs& regs) {
873 if (!state_tracker.TouchStencilOp()) { 877 if (!state_tracker.TouchStencilOp()) {
874 return; 878 return;
875 } 879 }
876 const Maxwell::StencilOp fail = regs.stencil_front_op_fail; 880 const Maxwell::StencilOp::Op fail = regs.stencil_front_op.fail;
877 const Maxwell::StencilOp zfail = regs.stencil_front_op_zfail; 881 const Maxwell::StencilOp::Op zfail = regs.stencil_front_op.zfail;
878 const Maxwell::StencilOp zpass = regs.stencil_front_op_zpass; 882 const Maxwell::StencilOp::Op zpass = regs.stencil_front_op.zpass;
879 const Maxwell::ComparisonOp compare = regs.stencil_front_func_func; 883 const Maxwell::ComparisonOp compare = regs.stencil_front_op.func;
880 if (regs.stencil_two_side_enable) { 884 if (regs.stencil_two_side_enable) {
881 // Separate stencil op per face 885 // Separate stencil op per face
882 const Maxwell::StencilOp back_fail = regs.stencil_back_op_fail; 886 const Maxwell::StencilOp::Op back_fail = regs.stencil_back_op.fail;
883 const Maxwell::StencilOp back_zfail = regs.stencil_back_op_zfail; 887 const Maxwell::StencilOp::Op back_zfail = regs.stencil_back_op.zfail;
884 const Maxwell::StencilOp back_zpass = regs.stencil_back_op_zpass; 888 const Maxwell::StencilOp::Op back_zpass = regs.stencil_back_op.zpass;
885 const Maxwell::ComparisonOp back_compare = regs.stencil_back_func_func; 889 const Maxwell::ComparisonOp back_compare = regs.stencil_back_op.func;
886 scheduler.Record([fail, zfail, zpass, compare, back_fail, back_zfail, back_zpass, 890 scheduler.Record([fail, zfail, zpass, compare, back_fail, back_zfail, back_zpass,
887 back_compare](vk::CommandBuffer cmdbuf) { 891 back_compare](vk::CommandBuffer cmdbuf) {
888 cmdbuf.SetStencilOpEXT(VK_STENCIL_FACE_FRONT_BIT, MaxwellToVK::StencilOp(fail), 892 cmdbuf.SetStencilOpEXT(VK_STENCIL_FACE_FRONT_BIT, MaxwellToVK::StencilOp(fail),
@@ -954,15 +958,15 @@ void RasterizerVulkan::UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs)
954 dirty[Dirty::VertexBinding0 + index] = false; 958 dirty[Dirty::VertexBinding0 + index] = false;
955 959
956 const u32 binding{static_cast<u32>(index)}; 960 const u32 binding{static_cast<u32>(index)};
957 const auto& input_binding{regs.vertex_array[binding]}; 961 const auto& input_binding{regs.vertex_streams[binding]};
958 const bool is_instanced{regs.instanced_arrays.IsInstancingEnabled(binding)}; 962 const bool is_instanced{regs.vertex_stream_instances.IsInstancingEnabled(binding)};
959 bindings.push_back({ 963 bindings.push_back({
960 .sType = VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT, 964 .sType = VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT,
961 .pNext = nullptr, 965 .pNext = nullptr,
962 .binding = binding, 966 .binding = binding,
963 .stride = input_binding.stride, 967 .stride = input_binding.stride,
964 .inputRate = is_instanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX, 968 .inputRate = is_instanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX,
965 .divisor = is_instanced ? input_binding.divisor : 1, 969 .divisor = is_instanced ? input_binding.frequency : 1,
966 }); 970 });
967 } 971 }
968 scheduler.Record([bindings, attributes](vk::CommandBuffer cmdbuf) { 972 scheduler.Record([bindings, attributes](vk::CommandBuffer cmdbuf) {
diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.cpp b/src/video_core/renderer_vulkan/vk_state_tracker.cpp
index f234e1a31..ed98c8370 100644
--- a/src/video_core/renderer_vulkan/vk_state_tracker.cpp
+++ b/src/video_core/renderer_vulkan/vk_state_tracker.cpp
@@ -51,8 +51,8 @@ Flags MakeInvalidationFlags() {
51void SetupDirtyViewports(Tables& tables) { 51void SetupDirtyViewports(Tables& tables) {
52 FillBlock(tables[0], OFF(viewport_transform), NUM(viewport_transform), Viewports); 52 FillBlock(tables[0], OFF(viewport_transform), NUM(viewport_transform), Viewports);
53 FillBlock(tables[0], OFF(viewports), NUM(viewports), Viewports); 53 FillBlock(tables[0], OFF(viewports), NUM(viewports), Viewports);
54 tables[0][OFF(viewport_transform_enabled)] = Viewports; 54 tables[0][OFF(viewport_scale_offset_enbled)] = Viewports;
55 tables[1][OFF(screen_y_control)] = Viewports; 55 tables[1][OFF(window_origin)] = Viewports;
56} 56}
57 57
58void SetupDirtyScissors(Tables& tables) { 58void SetupDirtyScissors(Tables& tables) {
@@ -61,9 +61,9 @@ void SetupDirtyScissors(Tables& tables) {
61 61
62void SetupDirtyDepthBias(Tables& tables) { 62void SetupDirtyDepthBias(Tables& tables) {
63 auto& table = tables[0]; 63 auto& table = tables[0];
64 table[OFF(polygon_offset_units)] = DepthBias; 64 table[OFF(depth_bias)] = DepthBias;
65 table[OFF(polygon_offset_clamp)] = DepthBias; 65 table[OFF(depth_bias_clamp)] = DepthBias;
66 table[OFF(polygon_offset_factor)] = DepthBias; 66 table[OFF(slope_scale_depth_bias)] = DepthBias;
67} 67}
68 68
69void SetupDirtyBlendConstants(Tables& tables) { 69void SetupDirtyBlendConstants(Tables& tables) {
@@ -77,12 +77,12 @@ void SetupDirtyDepthBounds(Tables& tables) {
77void SetupDirtyStencilProperties(Tables& tables) { 77void SetupDirtyStencilProperties(Tables& tables) {
78 auto& table = tables[0]; 78 auto& table = tables[0];
79 table[OFF(stencil_two_side_enable)] = StencilProperties; 79 table[OFF(stencil_two_side_enable)] = StencilProperties;
80 table[OFF(stencil_front_func_ref)] = StencilProperties; 80 table[OFF(stencil_front_func.ref)] = StencilProperties;
81 table[OFF(stencil_front_mask)] = StencilProperties; 81 table[OFF(stencil_front_func.mask)] = StencilProperties;
82 table[OFF(stencil_front_func_mask)] = StencilProperties; 82 table[OFF(stencil_front_func.func_mask)] = StencilProperties;
83 table[OFF(stencil_back_func_ref)] = StencilProperties; 83 table[OFF(stencil_back_func.ref)] = StencilProperties;
84 table[OFF(stencil_back_mask)] = StencilProperties; 84 table[OFF(stencil_back_func.mask)] = StencilProperties;
85 table[OFF(stencil_back_func_mask)] = StencilProperties; 85 table[OFF(stencil_back_func.func_mask)] = StencilProperties;
86} 86}
87 87
88void SetupDirtyLineWidth(Tables& tables) { 88void SetupDirtyLineWidth(Tables& tables) {
@@ -92,8 +92,8 @@ void SetupDirtyLineWidth(Tables& tables) {
92 92
93void SetupDirtyCullMode(Tables& tables) { 93void SetupDirtyCullMode(Tables& tables) {
94 auto& table = tables[0]; 94 auto& table = tables[0];
95 table[OFF(cull_face)] = CullMode; 95 table[OFF(gl_cull_face)] = CullMode;
96 table[OFF(cull_test_enabled)] = CullMode; 96 table[OFF(gl_cull_test_enabled)] = CullMode;
97} 97}
98 98
99void SetupDirtyDepthBoundsEnable(Tables& tables) { 99void SetupDirtyDepthBoundsEnable(Tables& tables) {
@@ -114,20 +114,20 @@ void SetupDirtyDepthCompareOp(Tables& tables) {
114 114
115void SetupDirtyFrontFace(Tables& tables) { 115void SetupDirtyFrontFace(Tables& tables) {
116 auto& table = tables[0]; 116 auto& table = tables[0];
117 table[OFF(front_face)] = FrontFace; 117 table[OFF(gl_front_face)] = FrontFace;
118 table[OFF(screen_y_control)] = FrontFace; 118 table[OFF(window_origin)] = FrontFace;
119} 119}
120 120
121void SetupDirtyStencilOp(Tables& tables) { 121void SetupDirtyStencilOp(Tables& tables) {
122 auto& table = tables[0]; 122 auto& table = tables[0];
123 table[OFF(stencil_front_op_fail)] = StencilOp; 123 table[OFF(stencil_front_op.fail)] = StencilOp;
124 table[OFF(stencil_front_op_zfail)] = StencilOp; 124 table[OFF(stencil_front_op.zfail)] = StencilOp;
125 table[OFF(stencil_front_op_zpass)] = StencilOp; 125 table[OFF(stencil_front_op.zpass)] = StencilOp;
126 table[OFF(stencil_front_func_func)] = StencilOp; 126 table[OFF(stencil_front_op.func)] = StencilOp;
127 table[OFF(stencil_back_op_fail)] = StencilOp; 127 table[OFF(stencil_back_op.fail)] = StencilOp;
128 table[OFF(stencil_back_op_zfail)] = StencilOp; 128 table[OFF(stencil_back_op.zfail)] = StencilOp;
129 table[OFF(stencil_back_op_zpass)] = StencilOp; 129 table[OFF(stencil_back_op.zpass)] = StencilOp;
130 table[OFF(stencil_back_func_func)] = StencilOp; 130 table[OFF(stencil_back_op.func)] = StencilOp;
131 131
132 // Table 0 is used by StencilProperties 132 // Table 0 is used by StencilProperties
133 tables[1][OFF(stencil_two_side_enable)] = StencilOp; 133 tables[1][OFF(stencil_two_side_enable)] = StencilOp;
@@ -139,10 +139,10 @@ void SetupDirtyStencilTestEnable(Tables& tables) {
139 139
140void SetupDirtyBlending(Tables& tables) { 140void SetupDirtyBlending(Tables& tables) {
141 tables[0][OFF(color_mask_common)] = Blending; 141 tables[0][OFF(color_mask_common)] = Blending;
142 tables[0][OFF(independent_blend_enable)] = Blending; 142 tables[0][OFF(blend_per_target_enabled)] = Blending;
143 FillBlock(tables[0], OFF(color_mask), NUM(color_mask), Blending); 143 FillBlock(tables[0], OFF(color_mask), NUM(color_mask), Blending);
144 FillBlock(tables[0], OFF(blend), NUM(blend), Blending); 144 FillBlock(tables[0], OFF(blend), NUM(blend), Blending);
145 FillBlock(tables[0], OFF(independent_blend), NUM(independent_blend), Blending); 145 FillBlock(tables[0], OFF(blend_per_target), NUM(blend_per_target), Blending);
146} 146}
147 147
148void SetupDirtyViewportSwizzles(Tables& tables) { 148void SetupDirtyViewportSwizzles(Tables& tables) {
@@ -166,10 +166,10 @@ void SetupDirtyVertexBindings(Tables& tables) {
166 static constexpr size_t divisor_offset = 3; 166 static constexpr size_t divisor_offset = 3;
167 for (size_t i = 0; i < Regs::NumVertexArrays; ++i) { 167 for (size_t i = 0; i < Regs::NumVertexArrays; ++i) {
168 const u8 flag = static_cast<u8>(VertexBinding0 + i); 168 const u8 flag = static_cast<u8>(VertexBinding0 + i);
169 tables[0][OFF(instanced_arrays) + i] = VertexInput; 169 tables[0][OFF(vertex_stream_instances) + i] = VertexInput;
170 tables[1][OFF(instanced_arrays) + i] = flag; 170 tables[1][OFF(vertex_stream_instances) + i] = flag;
171 tables[0][OFF(vertex_array) + i * NUM(vertex_array[0]) + divisor_offset] = VertexInput; 171 tables[0][OFF(vertex_streams) + i * NUM(vertex_streams[0]) + divisor_offset] = VertexInput;
172 tables[1][OFF(vertex_array) + i * NUM(vertex_array[0]) + divisor_offset] = flag; 172 tables[1][OFF(vertex_streams) + i * NUM(vertex_streams[0]) + divisor_offset] = flag;
173 } 173 }
174} 174}
175} // Anonymous namespace 175} // Anonymous namespace
diff --git a/src/video_core/shader_cache.cpp b/src/video_core/shader_cache.cpp
index f53066579..d9482371b 100644
--- a/src/video_core/shader_cache.cpp
+++ b/src/video_core/shader_cache.cpp
@@ -43,14 +43,14 @@ bool ShaderCache::RefreshStages(std::array<u64, 6>& unique_hashes) {
43 } 43 }
44 dirty[VideoCommon::Dirty::Shaders] = false; 44 dirty[VideoCommon::Dirty::Shaders] = false;
45 45
46 const GPUVAddr base_addr{maxwell3d->regs.code_address.CodeAddress()}; 46 const GPUVAddr base_addr{maxwell3d->regs.program_region.Address()};
47 for (size_t index = 0; index < Tegra::Engines::Maxwell3D::Regs::MaxShaderProgram; ++index) { 47 for (size_t index = 0; index < Tegra::Engines::Maxwell3D::Regs::MaxShaderProgram; ++index) {
48 if (!maxwell3d->regs.IsShaderConfigEnabled(index)) { 48 if (!maxwell3d->regs.IsShaderConfigEnabled(index)) {
49 unique_hashes[index] = 0; 49 unique_hashes[index] = 0;
50 continue; 50 continue;
51 } 51 }
52 const auto& shader_config{maxwell3d->regs.shader_config[index]}; 52 const auto& shader_config{maxwell3d->regs.pipelines[index]};
53 const auto program{static_cast<Tegra::Engines::Maxwell3D::Regs::ShaderProgram>(index)}; 53 const auto program{static_cast<Tegra::Engines::Maxwell3D::Regs::ShaderType>(index)};
54 const GPUVAddr shader_addr{base_addr + shader_config.offset}; 54 const GPUVAddr shader_addr{base_addr + shader_config.offset};
55 const std::optional<VAddr> cpu_shader_addr{gpu_memory->GpuToCpuAddress(shader_addr)}; 55 const std::optional<VAddr> cpu_shader_addr{gpu_memory->GpuToCpuAddress(shader_addr)};
56 if (!cpu_shader_addr) { 56 if (!cpu_shader_addr) {
@@ -90,14 +90,14 @@ const ShaderInfo* ShaderCache::ComputeShader() {
90void ShaderCache::GetGraphicsEnvironments(GraphicsEnvironments& result, 90void ShaderCache::GetGraphicsEnvironments(GraphicsEnvironments& result,
91 const std::array<u64, NUM_PROGRAMS>& unique_hashes) { 91 const std::array<u64, NUM_PROGRAMS>& unique_hashes) {
92 size_t env_index{}; 92 size_t env_index{};
93 const GPUVAddr base_addr{maxwell3d->regs.code_address.CodeAddress()}; 93 const GPUVAddr base_addr{maxwell3d->regs.program_region.Address()};
94 for (size_t index = 0; index < NUM_PROGRAMS; ++index) { 94 for (size_t index = 0; index < NUM_PROGRAMS; ++index) {
95 if (unique_hashes[index] == 0) { 95 if (unique_hashes[index] == 0) {
96 continue; 96 continue;
97 } 97 }
98 const auto program{static_cast<Tegra::Engines::Maxwell3D::Regs::ShaderProgram>(index)}; 98 const auto program{static_cast<Tegra::Engines::Maxwell3D::Regs::ShaderType>(index)};
99 auto& env{result.envs[index]}; 99 auto& env{result.envs[index]};
100 const u32 start_address{maxwell3d->regs.shader_config[index].offset}; 100 const u32 start_address{maxwell3d->regs.pipelines[index].offset};
101 env = GraphicsEnvironment{*maxwell3d, *gpu_memory, program, base_addr, start_address}; 101 env = GraphicsEnvironment{*maxwell3d, *gpu_memory, program, base_addr, start_address};
102 env.SetCachedSize(shader_infos[index]->size_bytes); 102 env.SetCachedSize(shader_infos[index]->size_bytes);
103 result.env_ptrs[env_index++] = &env; 103 result.env_ptrs[env_index++] = &env;
diff --git a/src/video_core/shader_environment.cpp b/src/video_core/shader_environment.cpp
index 5f7625947..fbabb3219 100644
--- a/src/video_core/shader_environment.cpp
+++ b/src/video_core/shader_environment.cpp
@@ -250,34 +250,34 @@ Shader::TextureType GenericEnvironment::ReadTextureTypeImpl(GPUVAddr tic_addr, u
250 250
251GraphicsEnvironment::GraphicsEnvironment(Tegra::Engines::Maxwell3D& maxwell3d_, 251GraphicsEnvironment::GraphicsEnvironment(Tegra::Engines::Maxwell3D& maxwell3d_,
252 Tegra::MemoryManager& gpu_memory_, 252 Tegra::MemoryManager& gpu_memory_,
253 Maxwell::ShaderProgram program, GPUVAddr program_base_, 253 Maxwell::ShaderType program, GPUVAddr program_base_,
254 u32 start_address_) 254 u32 start_address_)
255 : GenericEnvironment{gpu_memory_, program_base_, start_address_}, maxwell3d{&maxwell3d_} { 255 : GenericEnvironment{gpu_memory_, program_base_, start_address_}, maxwell3d{&maxwell3d_} {
256 gpu_memory->ReadBlock(program_base + start_address, &sph, sizeof(sph)); 256 gpu_memory->ReadBlock(program_base + start_address, &sph, sizeof(sph));
257 initial_offset = sizeof(sph); 257 initial_offset = sizeof(sph);
258 gp_passthrough_mask = maxwell3d->regs.gp_passthrough_mask; 258 gp_passthrough_mask = maxwell3d->regs.post_vtg_shader_attrib_skip_mask;
259 switch (program) { 259 switch (program) {
260 case Maxwell::ShaderProgram::VertexA: 260 case Maxwell::ShaderType::VertexA:
261 stage = Shader::Stage::VertexA; 261 stage = Shader::Stage::VertexA;
262 stage_index = 0; 262 stage_index = 0;
263 break; 263 break;
264 case Maxwell::ShaderProgram::VertexB: 264 case Maxwell::ShaderType::VertexB:
265 stage = Shader::Stage::VertexB; 265 stage = Shader::Stage::VertexB;
266 stage_index = 0; 266 stage_index = 0;
267 break; 267 break;
268 case Maxwell::ShaderProgram::TesselationControl: 268 case Maxwell::ShaderType::TessellationInit:
269 stage = Shader::Stage::TessellationControl; 269 stage = Shader::Stage::TessellationControl;
270 stage_index = 1; 270 stage_index = 1;
271 break; 271 break;
272 case Maxwell::ShaderProgram::TesselationEval: 272 case Maxwell::ShaderType::Tessellation:
273 stage = Shader::Stage::TessellationEval; 273 stage = Shader::Stage::TessellationEval;
274 stage_index = 2; 274 stage_index = 2;
275 break; 275 break;
276 case Maxwell::ShaderProgram::Geometry: 276 case Maxwell::ShaderType::Geometry:
277 stage = Shader::Stage::Geometry; 277 stage = Shader::Stage::Geometry;
278 stage_index = 3; 278 stage_index = 3;
279 break; 279 break;
280 case Maxwell::ShaderProgram::Fragment: 280 case Maxwell::ShaderType::Pixel:
281 stage = Shader::Stage::Fragment; 281 stage = Shader::Stage::Fragment;
282 stage_index = 4; 282 stage_index = 4;
283 break; 283 break;
@@ -288,7 +288,7 @@ GraphicsEnvironment::GraphicsEnvironment(Tegra::Engines::Maxwell3D& maxwell3d_,
288 const u64 local_size{sph.LocalMemorySize()}; 288 const u64 local_size{sph.LocalMemorySize()};
289 ASSERT(local_size <= std::numeric_limits<u32>::max()); 289 ASSERT(local_size <= std::numeric_limits<u32>::max());
290 local_memory_size = static_cast<u32>(local_size) + sph.common3.shader_local_memory_crs_size; 290 local_memory_size = static_cast<u32>(local_size) + sph.common3.shader_local_memory_crs_size;
291 texture_bound = maxwell3d->regs.tex_cb_index; 291 texture_bound = maxwell3d->regs.bindless_texture_const_buffer_slot;
292} 292}
293 293
294u32 GraphicsEnvironment::ReadCbufValue(u32 cbuf_index, u32 cbuf_offset) { 294u32 GraphicsEnvironment::ReadCbufValue(u32 cbuf_index, u32 cbuf_offset) {
@@ -304,8 +304,9 @@ u32 GraphicsEnvironment::ReadCbufValue(u32 cbuf_index, u32 cbuf_offset) {
304 304
305Shader::TextureType GraphicsEnvironment::ReadTextureType(u32 handle) { 305Shader::TextureType GraphicsEnvironment::ReadTextureType(u32 handle) {
306 const auto& regs{maxwell3d->regs}; 306 const auto& regs{maxwell3d->regs};
307 const bool via_header_index{regs.sampler_index == Maxwell::SamplerIndex::ViaHeaderIndex}; 307 const bool via_header_index{regs.sampler_binding == Maxwell::SamplerBinding::ViaHeaderBinding};
308 return ReadTextureTypeImpl(regs.tic.Address(), regs.tic.limit, via_header_index, handle); 308 return ReadTextureTypeImpl(regs.tex_header.Address(), regs.tex_header.limit, via_header_index,
309 handle);
309} 310}
310 311
311ComputeEnvironment::ComputeEnvironment(Tegra::Engines::KeplerCompute& kepler_compute_, 312ComputeEnvironment::ComputeEnvironment(Tegra::Engines::KeplerCompute& kepler_compute_,
diff --git a/src/video_core/shader_environment.h b/src/video_core/shader_environment.h
index 5a145f33a..8b3b8e9f5 100644
--- a/src/video_core/shader_environment.h
+++ b/src/video_core/shader_environment.h
@@ -93,7 +93,7 @@ public:
93 explicit GraphicsEnvironment() = default; 93 explicit GraphicsEnvironment() = default;
94 explicit GraphicsEnvironment(Tegra::Engines::Maxwell3D& maxwell3d_, 94 explicit GraphicsEnvironment(Tegra::Engines::Maxwell3D& maxwell3d_,
95 Tegra::MemoryManager& gpu_memory_, 95 Tegra::MemoryManager& gpu_memory_,
96 Tegra::Engines::Maxwell3D::Regs::ShaderProgram program, 96 Tegra::Engines::Maxwell3D::Regs::ShaderType program,
97 GPUVAddr program_base_, u32 start_address_); 97 GPUVAddr program_base_, u32 start_address_);
98 98
99 ~GraphicsEnvironment() override = default; 99 ~GraphicsEnvironment() override = default;
diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp
index a2bf08294..6bd133d10 100644
--- a/src/video_core/surface.cpp
+++ b/src/video_core/surface.cpp
@@ -73,17 +73,17 @@ bool SurfaceTargetIsArray(SurfaceTarget target) {
73 73
74PixelFormat PixelFormatFromDepthFormat(Tegra::DepthFormat format) { 74PixelFormat PixelFormatFromDepthFormat(Tegra::DepthFormat format) {
75 switch (format) { 75 switch (format) {
76 case Tegra::DepthFormat::S8_UINT_Z24_UNORM: 76 case Tegra::DepthFormat::Z24_UNORM_S8_UINT:
77 return PixelFormat::S8_UINT_D24_UNORM; 77 return PixelFormat::S8_UINT_D24_UNORM;
78 case Tegra::DepthFormat::D24S8_UNORM: 78 case Tegra::DepthFormat::S8Z24_UNORM:
79 return PixelFormat::D24_UNORM_S8_UINT; 79 return PixelFormat::D24_UNORM_S8_UINT;
80 case Tegra::DepthFormat::D32_FLOAT: 80 case Tegra::DepthFormat::Z32_FLOAT:
81 return PixelFormat::D32_FLOAT; 81 return PixelFormat::D32_FLOAT;
82 case Tegra::DepthFormat::D16_UNORM: 82 case Tegra::DepthFormat::Z16_UNORM:
83 return PixelFormat::D16_UNORM; 83 return PixelFormat::D16_UNORM;
84 case Tegra::DepthFormat::S8_UINT: 84 case Tegra::DepthFormat::S8_UINT:
85 return PixelFormat::S8_UINT; 85 return PixelFormat::S8_UINT;
86 case Tegra::DepthFormat::D32_FLOAT_S8X24_UINT: 86 case Tegra::DepthFormat::Z32_FLOAT_X24S8_UINT:
87 return PixelFormat::D32_FLOAT_S8_UINT; 87 return PixelFormat::D32_FLOAT_S8_UINT;
88 default: 88 default:
89 UNIMPLEMENTED_MSG("Unimplemented format={}", format); 89 UNIMPLEMENTED_MSG("Unimplemented format={}", format);
@@ -117,9 +117,9 @@ PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format)
117 return PixelFormat::R32G32_UINT; 117 return PixelFormat::R32G32_UINT;
118 case Tegra::RenderTargetFormat::R16G16B16X16_FLOAT: 118 case Tegra::RenderTargetFormat::R16G16B16X16_FLOAT:
119 return PixelFormat::R16G16B16X16_FLOAT; 119 return PixelFormat::R16G16B16X16_FLOAT;
120 case Tegra::RenderTargetFormat::B8G8R8A8_UNORM: 120 case Tegra::RenderTargetFormat::A8R8G8B8_UNORM:
121 return PixelFormat::B8G8R8A8_UNORM; 121 return PixelFormat::B8G8R8A8_UNORM;
122 case Tegra::RenderTargetFormat::B8G8R8A8_SRGB: 122 case Tegra::RenderTargetFormat::A8R8G8B8_SRGB:
123 return PixelFormat::B8G8R8A8_SRGB; 123 return PixelFormat::B8G8R8A8_SRGB;
124 case Tegra::RenderTargetFormat::A2B10G10R10_UNORM: 124 case Tegra::RenderTargetFormat::A2B10G10R10_UNORM:
125 return PixelFormat::A2B10G10R10_UNORM; 125 return PixelFormat::A2B10G10R10_UNORM;
diff --git a/src/video_core/texture_cache/image_info.cpp b/src/video_core/texture_cache/image_info.cpp
index 6c073ee57..852ec2519 100644
--- a/src/video_core/texture_cache/image_info.cpp
+++ b/src/video_core/texture_cache/image_info.cpp
@@ -1,6 +1,8 @@
1// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include <fmt/format.h>
5
4#include "common/assert.h" 6#include "common/assert.h"
5#include "video_core/surface.h" 7#include "video_core/surface.h"
6#include "video_core/texture_cache/format_lookup_table.h" 8#include "video_core/texture_cache/format_lookup_table.h"
@@ -12,6 +14,7 @@
12 14
13namespace VideoCommon { 15namespace VideoCommon {
14 16
17using Tegra::Engines::Maxwell3D;
15using Tegra::Texture::TextureType; 18using Tegra::Texture::TextureType;
16using Tegra::Texture::TICEntry; 19using Tegra::Texture::TICEntry;
17using VideoCore::Surface::PixelFormat; 20using VideoCore::Surface::PixelFormat;
@@ -107,12 +110,13 @@ ImageInfo::ImageInfo(const TICEntry& config) noexcept {
107 } 110 }
108} 111}
109 112
110ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs, size_t index) noexcept { 113ImageInfo::ImageInfo(const Maxwell3D::Regs& regs, size_t index) noexcept {
111 const auto& rt = regs.rt[index]; 114 const auto& rt = regs.rt[index];
112 format = VideoCore::Surface::PixelFormatFromRenderTargetFormat(rt.format); 115 format = VideoCore::Surface::PixelFormatFromRenderTargetFormat(rt.format);
113 rescaleable = false; 116 rescaleable = false;
114 if (rt.tile_mode.is_pitch_linear) { 117 if (rt.tile_mode.is_pitch_linear) {
115 ASSERT(rt.tile_mode.is_3d == 0); 118 ASSERT(rt.tile_mode.dim_control ==
119 Maxwell3D::Regs::TileMode::DimensionControl::DepthDefinesArray);
116 type = ImageType::Linear; 120 type = ImageType::Linear;
117 pitch = rt.width; 121 pitch = rt.width;
118 size = Extent3D{ 122 size = Extent3D{
@@ -124,15 +128,16 @@ ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs, size_t index)
124 } 128 }
125 size.width = rt.width; 129 size.width = rt.width;
126 size.height = rt.height; 130 size.height = rt.height;
127 layer_stride = rt.layer_stride * 4; 131 layer_stride = rt.array_pitch * 4;
128 maybe_unaligned_layer_stride = layer_stride; 132 maybe_unaligned_layer_stride = layer_stride;
129 num_samples = NumSamples(regs.multisample_mode); 133 num_samples = NumSamples(regs.anti_alias_samples_mode);
130 block = Extent3D{ 134 block = Extent3D{
131 .width = rt.tile_mode.block_width, 135 .width = rt.tile_mode.block_width,
132 .height = rt.tile_mode.block_height, 136 .height = rt.tile_mode.block_height,
133 .depth = rt.tile_mode.block_depth, 137 .depth = rt.tile_mode.block_depth,
134 }; 138 };
135 if (rt.tile_mode.is_3d) { 139 if (rt.tile_mode.dim_control ==
140 Maxwell3D::Regs::TileMode::DimensionControl::DepthDefinesDepth) {
136 type = ImageType::e3D; 141 type = ImageType::e3D;
137 size.depth = rt.depth; 142 size.depth = rt.depth;
138 } else { 143 } else {
@@ -146,31 +151,37 @@ ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs, size_t index)
146 151
147ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs) noexcept { 152ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs) noexcept {
148 format = VideoCore::Surface::PixelFormatFromDepthFormat(regs.zeta.format); 153 format = VideoCore::Surface::PixelFormatFromDepthFormat(regs.zeta.format);
149 size.width = regs.zeta_width; 154 size.width = regs.zeta_size.width;
150 size.height = regs.zeta_height; 155 size.height = regs.zeta_size.height;
151 rescaleable = false; 156 rescaleable = false;
152 resources.levels = 1; 157 resources.levels = 1;
153 layer_stride = regs.zeta.layer_stride * 4; 158 layer_stride = regs.zeta.array_pitch * 4;
154 maybe_unaligned_layer_stride = layer_stride; 159 maybe_unaligned_layer_stride = layer_stride;
155 num_samples = NumSamples(regs.multisample_mode); 160 num_samples = NumSamples(regs.anti_alias_samples_mode);
156 block = Extent3D{ 161 block = Extent3D{
157 .width = regs.zeta.tile_mode.block_width, 162 .width = regs.zeta.tile_mode.block_width,
158 .height = regs.zeta.tile_mode.block_height, 163 .height = regs.zeta.tile_mode.block_height,
159 .depth = regs.zeta.tile_mode.block_depth, 164 .depth = regs.zeta.tile_mode.block_depth,
160 }; 165 };
161 if (regs.zeta.tile_mode.is_pitch_linear) { 166 if (regs.zeta.tile_mode.is_pitch_linear) {
162 ASSERT(regs.zeta.tile_mode.is_3d == 0); 167 ASSERT(regs.zeta.tile_mode.dim_control ==
168 Maxwell3D::Regs::TileMode::DimensionControl::DepthDefinesArray);
163 type = ImageType::Linear; 169 type = ImageType::Linear;
164 pitch = size.width * BytesPerBlock(format); 170 pitch = size.width * BytesPerBlock(format);
165 } else if (regs.zeta.tile_mode.is_3d) { 171 } else if (regs.zeta.tile_mode.dim_control ==
172 Maxwell3D::Regs::TileMode::DimensionControl::DepthDefinesDepth) {
166 ASSERT(regs.zeta.tile_mode.is_pitch_linear == 0); 173 ASSERT(regs.zeta.tile_mode.is_pitch_linear == 0);
174 ASSERT(regs.zeta_size.dim_control ==
175 Maxwell3D::Regs::ZetaSize::DimensionControl::ArraySizeOne);
167 type = ImageType::e3D; 176 type = ImageType::e3D;
168 size.depth = regs.zeta_depth; 177 size.depth = regs.zeta_size.depth;
169 } else { 178 } else {
179 ASSERT(regs.zeta_size.dim_control ==
180 Maxwell3D::Regs::ZetaSize::DimensionControl::DepthDefinesArray);
170 rescaleable = block.depth == 0; 181 rescaleable = block.depth == 0;
171 downscaleable = size.height > 512; 182 downscaleable = size.height > 512;
172 type = ImageType::e2D; 183 type = ImageType::e2D;
173 resources.layers = regs.zeta_depth; 184 resources.layers = regs.zeta_size.depth;
174 } 185 }
175} 186}
176 187
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index eaf4a1c95..413baf730 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -189,15 +189,16 @@ typename P::Sampler* TextureCache<P>::GetComputeSampler(u32 index) {
189 189
190template <class P> 190template <class P>
191void TextureCache<P>::SynchronizeGraphicsDescriptors() { 191void TextureCache<P>::SynchronizeGraphicsDescriptors() {
192 using SamplerIndex = Tegra::Engines::Maxwell3D::Regs::SamplerIndex; 192 using SamplerBinding = Tegra::Engines::Maxwell3D::Regs::SamplerBinding;
193 const bool linked_tsc = maxwell3d->regs.sampler_index == SamplerIndex::ViaHeaderIndex; 193 const bool linked_tsc = maxwell3d->regs.sampler_binding == SamplerBinding::ViaHeaderBinding;
194 const u32 tic_limit = maxwell3d->regs.tic.limit; 194 const u32 tic_limit = maxwell3d->regs.tex_header.limit;
195 const u32 tsc_limit = linked_tsc ? tic_limit : maxwell3d->regs.tsc.limit; 195 const u32 tsc_limit = linked_tsc ? tic_limit : maxwell3d->regs.tex_sampler.limit;
196 if (channel_state->graphics_sampler_table.Synchornize(maxwell3d->regs.tsc.Address(), 196 if (channel_state->graphics_sampler_table.Synchornize(maxwell3d->regs.tex_sampler.Address(),
197 tsc_limit)) { 197 tsc_limit)) {
198 channel_state->graphics_sampler_ids.resize(tsc_limit + 1, CORRUPT_ID); 198 channel_state->graphics_sampler_ids.resize(tsc_limit + 1, CORRUPT_ID);
199 } 199 }
200 if (channel_state->graphics_image_table.Synchornize(maxwell3d->regs.tic.Address(), tic_limit)) { 200 if (channel_state->graphics_image_table.Synchornize(maxwell3d->regs.tex_header.Address(),
201 tic_limit)) {
201 channel_state->graphics_image_view_ids.resize(tic_limit + 1, CORRUPT_ID); 202 channel_state->graphics_image_view_ids.resize(tic_limit + 1, CORRUPT_ID);
202 } 203 }
203} 204}
@@ -352,8 +353,8 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) {
352 down_shift = Settings::values.resolution_info.down_shift; 353 down_shift = Settings::values.resolution_info.down_shift;
353 } 354 }
354 render_targets.size = Extent2D{ 355 render_targets.size = Extent2D{
355 (maxwell3d->regs.render_area.width * up_scale) >> down_shift, 356 (maxwell3d->regs.surface_clip.width * up_scale) >> down_shift,
356 (maxwell3d->regs.render_area.height * up_scale) >> down_shift, 357 (maxwell3d->regs.surface_clip.height * up_scale) >> down_shift,
357 }; 358 };
358 render_targets.is_rescaled = is_rescaling; 359 render_targets.is_rescaled = is_rescaling;
359 360
@@ -1980,7 +1981,7 @@ bool TextureCache<P>::IsFullClear(ImageViewId id) {
1980 // Images with multiple resources can't be cleared in a single call 1981 // Images with multiple resources can't be cleared in a single call
1981 return false; 1982 return false;
1982 } 1983 }
1983 if (regs.clear_flags.scissor == 0) { 1984 if (regs.clear_control.use_scissor == 0) {
1984 // If scissor testing is disabled, the clear is always full 1985 // If scissor testing is disabled, the clear is always full
1985 return true; 1986 return true;
1986 } 1987 }
diff --git a/src/video_core/transform_feedback.cpp b/src/video_core/transform_feedback.cpp
index 7e605981c..45071185a 100644
--- a/src/video_core/transform_feedback.cpp
+++ b/src/video_core/transform_feedback.cpp
@@ -15,51 +15,51 @@ namespace VideoCommon {
15std::vector<Shader::TransformFeedbackVarying> MakeTransformFeedbackVaryings( 15std::vector<Shader::TransformFeedbackVarying> MakeTransformFeedbackVaryings(
16 const TransformFeedbackState& state) { 16 const TransformFeedbackState& state) {
17 static constexpr std::array VECTORS{ 17 static constexpr std::array VECTORS{
18 28, // gl_Position 18 28U, // gl_Position
19 32, // Generic 0 19 32U, // Generic 0
20 36, // Generic 1 20 36U, // Generic 1
21 40, // Generic 2 21 40U, // Generic 2
22 44, // Generic 3 22 44U, // Generic 3
23 48, // Generic 4 23 48U, // Generic 4
24 52, // Generic 5 24 52U, // Generic 5
25 56, // Generic 6 25 56U, // Generic 6
26 60, // Generic 7 26 60U, // Generic 7
27 64, // Generic 8 27 64U, // Generic 8
28 68, // Generic 9 28 68U, // Generic 9
29 72, // Generic 10 29 72U, // Generic 10
30 76, // Generic 11 30 76U, // Generic 11
31 80, // Generic 12 31 80U, // Generic 12
32 84, // Generic 13 32 84U, // Generic 13
33 88, // Generic 14 33 88U, // Generic 14
34 92, // Generic 15 34 92U, // Generic 15
35 96, // Generic 16 35 96U, // Generic 16
36 100, // Generic 17 36 100U, // Generic 17
37 104, // Generic 18 37 104U, // Generic 18
38 108, // Generic 19 38 108U, // Generic 19
39 112, // Generic 20 39 112U, // Generic 20
40 116, // Generic 21 40 116U, // Generic 21
41 120, // Generic 22 41 120U, // Generic 22
42 124, // Generic 23 42 124U, // Generic 23
43 128, // Generic 24 43 128U, // Generic 24
44 132, // Generic 25 44 132U, // Generic 25
45 136, // Generic 26 45 136U, // Generic 26
46 140, // Generic 27 46 140U, // Generic 27
47 144, // Generic 28 47 144U, // Generic 28
48 148, // Generic 29 48 148U, // Generic 29
49 152, // Generic 30 49 152U, // Generic 30
50 156, // Generic 31 50 156U, // Generic 31
51 160, // gl_FrontColor 51 160U, // gl_FrontColor
52 164, // gl_FrontSecondaryColor 52 164U, // gl_FrontSecondaryColor
53 160, // gl_BackColor 53 160U, // gl_BackColor
54 164, // gl_BackSecondaryColor 54 164U, // gl_BackSecondaryColor
55 192, // gl_TexCoord[0] 55 192U, // gl_TexCoord[0]
56 196, // gl_TexCoord[1] 56 196U, // gl_TexCoord[1]
57 200, // gl_TexCoord[2] 57 200U, // gl_TexCoord[2]
58 204, // gl_TexCoord[3] 58 204U, // gl_TexCoord[3]
59 208, // gl_TexCoord[4] 59 208U, // gl_TexCoord[4]
60 212, // gl_TexCoord[5] 60 212U, // gl_TexCoord[5]
61 216, // gl_TexCoord[6] 61 216U, // gl_TexCoord[6]
62 220, // gl_TexCoord[7] 62 220U, // gl_TexCoord[7]
63 }; 63 };
64 std::vector<Shader::TransformFeedbackVarying> xfb(256); 64 std::vector<Shader::TransformFeedbackVarying> xfb(256);
65 for (size_t buffer = 0; buffer < state.layouts.size(); ++buffer) { 65 for (size_t buffer = 0; buffer < state.layouts.size(); ++buffer) {
@@ -68,8 +68,20 @@ std::vector<Shader::TransformFeedbackVarying> MakeTransformFeedbackVaryings(
68 const u32 varying_count = layout.varying_count; 68 const u32 varying_count = layout.varying_count;
69 u32 highest = 0; 69 u32 highest = 0;
70 for (u32 offset = 0; offset < varying_count; ++offset) { 70 for (u32 offset = 0; offset < varying_count; ++offset) {
71 const u32 base_offset = offset; 71 const auto get_attribute = [&locations](u32 index) -> u32 {
72 const u8 location = locations[offset]; 72 switch (index % 4) {
73 case 0:
74 return locations[index / 4].attribute0.Value();
75 case 1:
76 return locations[index / 4].attribute1.Value();
77 case 2:
78 return locations[index / 4].attribute2.Value();
79 case 3:
80 return locations[index / 4].attribute3.Value();
81 }
82 UNREACHABLE();
83 return 0;
84 };
73 85
74 UNIMPLEMENTED_IF_MSG(layout.stream != 0, "Stream is not zero: {}", layout.stream); 86 UNIMPLEMENTED_IF_MSG(layout.stream != 0, "Stream is not zero: {}", layout.stream);
75 Shader::TransformFeedbackVarying varying{ 87 Shader::TransformFeedbackVarying varying{
@@ -78,16 +90,18 @@ std::vector<Shader::TransformFeedbackVarying> MakeTransformFeedbackVaryings(
78 .offset = offset * 4, 90 .offset = offset * 4,
79 .components = 1, 91 .components = 1,
80 }; 92 };
81 if (std::ranges::find(VECTORS, Common::AlignDown(location, 4)) != VECTORS.end()) { 93 const u32 base_offset = offset;
82 UNIMPLEMENTED_IF_MSG(location % 4 != 0, "Unaligned TFB"); 94 const auto attribute{get_attribute(offset)};
95 if (std::ranges::find(VECTORS, Common::AlignDown(attribute, 4)) != VECTORS.end()) {
96 UNIMPLEMENTED_IF_MSG(attribute % 4 != 0, "Unaligned TFB {}", attribute);
83 97
84 const u8 base_index = location / 4; 98 const auto base_index = attribute / 4;
85 while (offset + 1 < varying_count && base_index == locations[offset + 1] / 4) { 99 while (offset + 1 < varying_count && base_index == get_attribute(offset + 1) / 4) {
86 ++offset; 100 ++offset;
87 ++varying.components; 101 ++varying.components;
88 } 102 }
89 } 103 }
90 xfb[location] = varying; 104 xfb[attribute] = varying;
91 highest = std::max(highest, (base_offset + varying.components) * 4); 105 highest = std::max(highest, (base_offset + varying.components) * 4);
92 } 106 }
93 UNIMPLEMENTED_IF(highest != layout.stride); 107 UNIMPLEMENTED_IF(highest != layout.stride);
diff --git a/src/video_core/transform_feedback.h b/src/video_core/transform_feedback.h
index a519adb59..d13eb16c3 100644
--- a/src/video_core/transform_feedback.h
+++ b/src/video_core/transform_feedback.h
@@ -19,7 +19,8 @@ struct TransformFeedbackState {
19 u32 stride; 19 u32 stride;
20 }; 20 };
21 std::array<Layout, Tegra::Engines::Maxwell3D::Regs::NumTransformFeedbackBuffers> layouts; 21 std::array<Layout, Tegra::Engines::Maxwell3D::Regs::NumTransformFeedbackBuffers> layouts;
22 std::array<std::array<u8, 128>, Tegra::Engines::Maxwell3D::Regs::NumTransformFeedbackBuffers> 22 std::array<std::array<Tegra::Engines::Maxwell3D::Regs::StreamOutLayout, 32>,
23 Tegra::Engines::Maxwell3D::Regs::NumTransformFeedbackBuffers>
23 varyings; 24 varyings;
24}; 25};
25 26