summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2023-01-03 10:01:25 -0500
committerGravatar Fernando Sahmkow2023-01-04 14:39:42 -0500
commita0c697124ced080f58866825e2e323e8682bbd7f (patch)
tree73830fc46134be10d7feffc3da11aa9f0ea58ffb /src
parentTexture Cache: Implement async texture downloads. (diff)
downloadyuzu-a0c697124ced080f58866825e2e323e8682bbd7f.tar.gz
yuzu-a0c697124ced080f58866825e2e323e8682bbd7f.tar.xz
yuzu-a0c697124ced080f58866825e2e323e8682bbd7f.zip
Video_core: Address feedback
Diffstat (limited to 'src')
-rw-r--r--src/common/range_map.h6
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp18
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp6
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp4
-rw-r--r--src/shader_recompiler/backend/spirv/spirv_emit_context.cpp3
-rw-r--r--src/shader_recompiler/backend/spirv/spirv_emit_context.h1
-rw-r--r--src/shader_recompiler/frontend/ir/attribute.cpp2
-rw-r--r--src/shader_recompiler/frontend/ir/attribute.h1
-rw-r--r--src/shader_recompiler/ir_opt/constant_propagation_pass.cpp3
-rw-r--r--src/shader_recompiler/shader_info.h1
-rw-r--r--src/video_core/engines/draw_manager.cpp13
-rw-r--r--src/video_core/engines/draw_manager.h2
-rw-r--r--src/video_core/engines/maxwell_3d.cpp13
-rw-r--r--src/video_core/engines/maxwell_3d.h30
-rw-r--r--src/video_core/macro/macro.cpp2
-rw-r--r--src/video_core/macro/macro_hle.cpp356
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp18
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp27
-rw-r--r--src/video_core/renderer_vulkan/vk_state_tracker.cpp2
-rw-r--r--src/video_core/shader_environment.cpp8
20 files changed, 346 insertions, 170 deletions
diff --git a/src/common/range_map.h b/src/common/range_map.h
index 051e713a7..79c7ef547 100644
--- a/src/common/range_map.h
+++ b/src/common/range_map.h
@@ -60,7 +60,7 @@ private:
60 using ConstIteratorType = typename MapType::const_iterator; 60 using ConstIteratorType = typename MapType::const_iterator;
61 61
62 size_t ContinousSizeInternal(KeyT address) const { 62 size_t ContinousSizeInternal(KeyT address) const {
63 const auto it = GetFirstElemnentBeforeOrOn(address); 63 const auto it = GetFirstElementBeforeOrOn(address);
64 if (it == container.end() || it->second == null_value) { 64 if (it == container.end() || it->second == null_value) {
65 return 0; 65 return 0;
66 } 66 }
@@ -72,14 +72,14 @@ private:
72 } 72 }
73 73
74 ValueT GetValueInternal(KeyT address) const { 74 ValueT GetValueInternal(KeyT address) const {
75 const auto it = GetFirstElemnentBeforeOrOn(address); 75 const auto it = GetFirstElementBeforeOrOn(address);
76 if (it == container.end()) { 76 if (it == container.end()) {
77 return null_value; 77 return null_value;
78 } 78 }
79 return it->second; 79 return it->second;
80 } 80 }
81 81
82 ConstIteratorType GetFirstElemnentBeforeOrOn(KeyT address) const { 82 ConstIteratorType GetFirstElementBeforeOrOn(KeyT address) const {
83 auto it = container.lower_bound(address); 83 auto it = container.lower_bound(address);
84 if (it == container.begin()) { 84 if (it == container.begin()) {
85 return it; 85 return it;
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp
index f0bd84ab2..c7d7d5fef 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp
@@ -137,6 +137,15 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr, Scal
137 case IR::Attribute::VertexId: 137 case IR::Attribute::VertexId:
138 ctx.Add("MOV.F {}.x,{}.id;", inst, ctx.attrib_name); 138 ctx.Add("MOV.F {}.x,{}.id;", inst, ctx.attrib_name);
139 break; 139 break;
140 case IR::Attribute::BaseInstance:
141 ctx.Add("MOV.F {}.x,{}.baseInstance;", inst, ctx.attrib_name);
142 break;
143 case IR::Attribute::BaseVertex:
144 ctx.Add("MOV.F {}.x,{}.baseVertex;", inst, ctx.attrib_name);
145 break;
146 case IR::Attribute::DrawID:
147 ctx.Add("MOV.F {}.x,{}.draw.id;", inst, ctx.attrib_name);
148 break;
140 case IR::Attribute::FrontFace: 149 case IR::Attribute::FrontFace:
141 ctx.Add("CMP.F {}.x,{}.facing.x,0,-1;", inst, ctx.attrib_name); 150 ctx.Add("CMP.F {}.x,{}.facing.x,0,-1;", inst, ctx.attrib_name);
142 break; 151 break;
@@ -156,6 +165,15 @@ void EmitGetAttributeU32(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr, S
156 case IR::Attribute::VertexId: 165 case IR::Attribute::VertexId:
157 ctx.Add("MOV.S {}.x,{}.id;", inst, ctx.attrib_name); 166 ctx.Add("MOV.S {}.x,{}.id;", inst, ctx.attrib_name);
158 break; 167 break;
168 case IR::Attribute::BaseInstance:
169 ctx.Add("MOV.S {}.x,{}.baseInstance;", inst, ctx.attrib_name);
170 break;
171 case IR::Attribute::BaseVertex:
172 ctx.Add("MOV.S {}.x,{}.baseVertex;", inst, ctx.attrib_name);
173 break;
174 case IR::Attribute::DrawID:
175 ctx.Add("MOV.S {}.x,{}.draw.id;", inst, ctx.attrib_name);
176 break;
159 default: 177 default:
160 throw NotImplementedException("Get U32 attribute {}", attr); 178 throw NotImplementedException("Get U32 attribute {}", attr);
161 } 179 }
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp
index 25106da67..2e369ed72 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp
@@ -240,6 +240,9 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr,
240 case IR::Attribute::BaseVertex: 240 case IR::Attribute::BaseVertex:
241 ctx.AddF32("{}=itof(gl_BaseVertex);", inst); 241 ctx.AddF32("{}=itof(gl_BaseVertex);", inst);
242 break; 242 break;
243 case IR::Attribute::DrawID:
244 ctx.AddF32("{}=itof(gl_DrawID);", inst);
245 break;
243 default: 246 default:
244 throw NotImplementedException("Get attribute {}", attr); 247 throw NotImplementedException("Get attribute {}", attr);
245 } 248 }
@@ -262,6 +265,9 @@ void EmitGetAttributeU32(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr, s
262 case IR::Attribute::BaseVertex: 265 case IR::Attribute::BaseVertex:
263 ctx.AddU32("{}=uint(gl_BaseVertex);", inst); 266 ctx.AddU32("{}=uint(gl_BaseVertex);", inst);
264 break; 267 break;
268 case IR::Attribute::DrawID:
269 ctx.AddU32("{}=uint(gl_DrawID);", inst);
270 break;
265 default: 271 default:
266 throw NotImplementedException("Get U32 attribute {}", attr); 272 throw NotImplementedException("Get U32 attribute {}", attr);
267 } 273 }
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp
index e4802bf9e..db9c94ce8 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp
@@ -343,6 +343,8 @@ Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, Id vertex) {
343 return ctx.OpBitcast(ctx.F32[1], ctx.OpLoad(ctx.U32[1], ctx.base_instance)); 343 return ctx.OpBitcast(ctx.F32[1], ctx.OpLoad(ctx.U32[1], ctx.base_instance));
344 case IR::Attribute::BaseVertex: 344 case IR::Attribute::BaseVertex:
345 return ctx.OpBitcast(ctx.F32[1], ctx.OpLoad(ctx.U32[1], ctx.base_vertex)); 345 return ctx.OpBitcast(ctx.F32[1], ctx.OpLoad(ctx.U32[1], ctx.base_vertex));
346 case IR::Attribute::DrawID:
347 return ctx.OpBitcast(ctx.F32[1], ctx.OpLoad(ctx.U32[1], ctx.draw_index));
346 case IR::Attribute::FrontFace: 348 case IR::Attribute::FrontFace:
347 return ctx.OpSelect(ctx.F32[1], ctx.OpLoad(ctx.U1, ctx.front_face), 349 return ctx.OpSelect(ctx.F32[1], ctx.OpLoad(ctx.U1, ctx.front_face),
348 ctx.OpBitcast(ctx.F32[1], ctx.Const(std::numeric_limits<u32>::max())), 350 ctx.OpBitcast(ctx.F32[1], ctx.Const(std::numeric_limits<u32>::max())),
@@ -388,6 +390,8 @@ Id EmitGetAttributeU32(EmitContext& ctx, IR::Attribute attr, Id) {
388 return ctx.OpLoad(ctx.U32[1], ctx.base_instance); 390 return ctx.OpLoad(ctx.U32[1], ctx.base_instance);
389 case IR::Attribute::BaseVertex: 391 case IR::Attribute::BaseVertex:
390 return ctx.OpLoad(ctx.U32[1], ctx.base_vertex); 392 return ctx.OpLoad(ctx.U32[1], ctx.base_vertex);
393 case IR::Attribute::DrawID:
394 return ctx.OpLoad(ctx.U32[1], ctx.draw_index);
391 default: 395 default:
392 throw NotImplementedException("Read U32 attribute {}", attr); 396 throw NotImplementedException("Read U32 attribute {}", attr);
393 } 397 }
diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp
index 563a5fc49..ecb2db494 100644
--- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp
+++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp
@@ -1402,6 +1402,9 @@ void EmitContext::DefineInputs(const IR::Program& program) {
1402 } else if (loads[IR::Attribute::BaseVertex]) { 1402 } else if (loads[IR::Attribute::BaseVertex]) {
1403 base_vertex = DefineInput(*this, U32[1], true, spv::BuiltIn::BaseVertex); 1403 base_vertex = DefineInput(*this, U32[1], true, spv::BuiltIn::BaseVertex);
1404 } 1404 }
1405 if (loads[IR::Attribute::DrawID]) {
1406 draw_index = DefineInput(*this, U32[1], true, spv::BuiltIn::DrawIndex);
1407 }
1405 if (loads[IR::Attribute::FrontFace]) { 1408 if (loads[IR::Attribute::FrontFace]) {
1406 front_face = DefineInput(*this, U1, true, spv::BuiltIn::FrontFacing); 1409 front_face = DefineInput(*this, U1, true, spv::BuiltIn::FrontFacing);
1407 } 1410 }
diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.h b/src/shader_recompiler/backend/spirv/spirv_emit_context.h
index dde45b4bc..4414a5169 100644
--- a/src/shader_recompiler/backend/spirv/spirv_emit_context.h
+++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.h
@@ -218,6 +218,7 @@ public:
218 Id base_instance{}; 218 Id base_instance{};
219 Id vertex_id{}; 219 Id vertex_id{};
220 Id vertex_index{}; 220 Id vertex_index{};
221 Id draw_index{};
221 Id base_vertex{}; 222 Id base_vertex{};
222 Id front_face{}; 223 Id front_face{};
223 Id point_coord{}; 224 Id point_coord{};
diff --git a/src/shader_recompiler/frontend/ir/attribute.cpp b/src/shader_recompiler/frontend/ir/attribute.cpp
index 73e189a89..1bf9db935 100644
--- a/src/shader_recompiler/frontend/ir/attribute.cpp
+++ b/src/shader_recompiler/frontend/ir/attribute.cpp
@@ -450,6 +450,8 @@ std::string NameOf(Attribute attribute) {
450 return "BaseInstance"; 450 return "BaseInstance";
451 case Attribute::BaseVertex: 451 case Attribute::BaseVertex:
452 return "BaseVertex"; 452 return "BaseVertex";
453 case Attribute::DrawID:
454 return "DrawID";
453 } 455 }
454 return fmt::format("<reserved attribute {}>", static_cast<int>(attribute)); 456 return fmt::format("<reserved attribute {}>", static_cast<int>(attribute));
455} 457}
diff --git a/src/shader_recompiler/frontend/ir/attribute.h b/src/shader_recompiler/frontend/ir/attribute.h
index 364d8a912..5f039b6f6 100644
--- a/src/shader_recompiler/frontend/ir/attribute.h
+++ b/src/shader_recompiler/frontend/ir/attribute.h
@@ -223,6 +223,7 @@ enum class Attribute : u64 {
223 // Implementation attributes 223 // Implementation attributes
224 BaseInstance = 256, 224 BaseInstance = 256,
225 BaseVertex = 257, 225 BaseVertex = 257,
226 DrawID = 258,
226}; 227};
227 228
228constexpr size_t NUM_GENERICS = 32; 229constexpr size_t NUM_GENERICS = 32;
diff --git a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
index 5275b2c8b..4d81e9336 100644
--- a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
+++ b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
@@ -518,6 +518,7 @@ void FoldBitCast(IR::Inst& inst, IR::Opcode reverse) {
518 case IR::Attribute::VertexId: 518 case IR::Attribute::VertexId:
519 case IR::Attribute::BaseVertex: 519 case IR::Attribute::BaseVertex:
520 case IR::Attribute::BaseInstance: 520 case IR::Attribute::BaseInstance:
521 case IR::Attribute::DrawID:
521 break; 522 break;
522 default: 523 default:
523 return; 524 return;
@@ -665,6 +666,8 @@ void FoldConstBuffer(Environment& env, IR::Block& block, IR::Inst& inst) {
665 return IR::Attribute::BaseInstance; 666 return IR::Attribute::BaseInstance;
666 case ReplaceConstant::BaseVertex: 667 case ReplaceConstant::BaseVertex:
667 return IR::Attribute::BaseVertex; 668 return IR::Attribute::BaseVertex;
669 case ReplaceConstant::DrawID:
670 return IR::Attribute::DrawID;
668 default: 671 default:
669 throw NotImplementedException("Not implemented replacement variable {}", *replacement); 672 throw NotImplementedException("Not implemented replacement variable {}", *replacement);
670 } 673 }
diff --git a/src/shader_recompiler/shader_info.h b/src/shader_recompiler/shader_info.h
index ea0f48344..44236b6b1 100644
--- a/src/shader_recompiler/shader_info.h
+++ b/src/shader_recompiler/shader_info.h
@@ -19,6 +19,7 @@ namespace Shader {
19enum class ReplaceConstant : u32 { 19enum class ReplaceConstant : u32 {
20 BaseInstance, 20 BaseInstance,
21 BaseVertex, 21 BaseVertex,
22 DrawID,
22}; 23};
23 24
24enum class TextureType : u32 { 25enum class TextureType : u32 {
diff --git a/src/video_core/engines/draw_manager.cpp b/src/video_core/engines/draw_manager.cpp
index feea89c0e..2437121ce 100644
--- a/src/video_core/engines/draw_manager.cpp
+++ b/src/video_core/engines/draw_manager.cpp
@@ -94,7 +94,7 @@ void DrawManager::DrawIndex(PrimitiveTopology topology, u32 index_first, u32 ind
94void DrawManager::DrawArrayIndirect(PrimitiveTopology topology) { 94void DrawManager::DrawArrayIndirect(PrimitiveTopology topology) {
95 draw_state.topology = topology; 95 draw_state.topology = topology;
96 96
97 ProcessDrawIndirect(true); 97 ProcessDrawIndirect();
98} 98}
99 99
100void DrawManager::DrawIndexedIndirect(PrimitiveTopology topology, u32 index_first, 100void DrawManager::DrawIndexedIndirect(PrimitiveTopology topology, u32 index_first,
@@ -105,7 +105,7 @@ void DrawManager::DrawIndexedIndirect(PrimitiveTopology topology, u32 index_firs
105 draw_state.index_buffer.first = index_first; 105 draw_state.index_buffer.first = index_first;
106 draw_state.index_buffer.count = index_count; 106 draw_state.index_buffer.count = index_count;
107 107
108 ProcessDrawIndirect(true); 108 ProcessDrawIndirect();
109} 109}
110 110
111void DrawManager::SetInlineIndexBuffer(u32 index) { 111void DrawManager::SetInlineIndexBuffer(u32 index) {
@@ -216,9 +216,12 @@ void DrawManager::ProcessDraw(bool draw_indexed, u32 instance_count) {
216 } 216 }
217} 217}
218 218
219void DrawManager::ProcessDrawIndirect(bool draw_indexed) { 219void DrawManager::ProcessDrawIndirect() {
220 LOG_TRACE(HW_GPU, "called, topology={}, count={}", draw_state.topology, 220 LOG_TRACE(
221 draw_indexed ? draw_state.index_buffer.count : draw_state.vertex_buffer.count); 221 HW_GPU,
222 "called, topology={}, is_indexed={}, includes_count={}, buffer_size={}, max_draw_count={}",
223 draw_state.topology, indirect_state.is_indexed, indirect_state.include_count,
224 indirect_state.buffer_size, indirect_state.max_draw_counts);
222 225
223 UpdateTopology(); 226 UpdateTopology();
224 227
diff --git a/src/video_core/engines/draw_manager.h b/src/video_core/engines/draw_manager.h
index 49a4fca48..58d1b2d59 100644
--- a/src/video_core/engines/draw_manager.h
+++ b/src/video_core/engines/draw_manager.h
@@ -85,7 +85,7 @@ private:
85 85
86 void ProcessDraw(bool draw_indexed, u32 instance_count); 86 void ProcessDraw(bool draw_indexed, u32 instance_count);
87 87
88 void ProcessDrawIndirect(bool draw_indexed); 88 void ProcessDrawIndirect();
89 89
90 Maxwell3D* maxwell3d{}; 90 Maxwell3D* maxwell3d{};
91 State draw_state{}; 91 State draw_state{};
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 943a69935..fbfd1ddd2 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -220,9 +220,6 @@ void Maxwell3D::ProcessMacro(u32 method, const u32* base_start, u32 amount, bool
220} 220}
221 221
222void Maxwell3D::RefreshParametersImpl() { 222void Maxwell3D::RefreshParametersImpl() {
223 if (!Settings::IsGPULevelHigh()) {
224 return;
225 }
226 size_t current_index = 0; 223 size_t current_index = 0;
227 for (auto& segment : macro_segments) { 224 for (auto& segment : macro_segments) {
228 if (segment.first == 0) { 225 if (segment.first == 0) {
@@ -448,9 +445,11 @@ void Maxwell3D::CallMultiMethod(u32 method, const u32* base_start, u32 amount,
448 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 15: 445 case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 15:
449 ProcessCBMultiData(base_start, amount); 446 ProcessCBMultiData(base_start, amount);
450 break; 447 break;
451 case MAXWELL3D_REG_INDEX(inline_data): 448 case MAXWELL3D_REG_INDEX(inline_data): {
449 ASSERT(methods_pending == amount);
452 upload_state.ProcessData(base_start, amount); 450 upload_state.ProcessData(base_start, amount);
453 return; 451 return;
452 }
454 default: 453 default:
455 for (u32 i = 0; i < amount; i++) { 454 for (u32 i = 0; i < amount; i++) {
456 CallMethod(method, base_start[i], methods_pending - i <= 1); 455 CallMethod(method, base_start[i], methods_pending - i <= 1);
@@ -537,7 +536,7 @@ void Maxwell3D::ProcessQueryGet() {
537void Maxwell3D::ProcessQueryCondition() { 536void Maxwell3D::ProcessQueryCondition() {
538 const GPUVAddr condition_address{regs.render_enable.Address()}; 537 const GPUVAddr condition_address{regs.render_enable.Address()};
539 switch (regs.render_enable_override) { 538 switch (regs.render_enable_override) {
540 case Regs::RenderEnable::Override::AlwaysRender: { 539 case Regs::RenderEnable::Override::AlwaysRender:
541 execute_on = true; 540 execute_on = true;
542 break; 541 break;
543 case Regs::RenderEnable::Override::NeverRender: 542 case Regs::RenderEnable::Override::NeverRender:
@@ -586,7 +585,6 @@ void Maxwell3D::ProcessQueryCondition() {
586 break; 585 break;
587 } 586 }
588 } 587 }
589 }
590} 588}
591 589
592void Maxwell3D::ProcessCounterReset() { 590void Maxwell3D::ProcessCounterReset() {
@@ -685,7 +683,8 @@ u32 Maxwell3D::GetRegisterValue(u32 method) const {
685 return regs.reg_array[method]; 683 return regs.reg_array[method];
686} 684}
687 685
688void Maxwell3D::setHLEReplacementName(u32 bank, u32 offset, HLEReplaceName name) { 686void Maxwell3D::SetHLEReplacementAttributeType(u32 bank, u32 offset,
687 HLEReplacementAttributeType name) {
689 const u64 key = (static_cast<u64>(bank) << 32) | offset; 688 const u64 key = (static_cast<u64>(bank) << 32) | offset;
690 replace_table.emplace(key, name); 689 replace_table.emplace(key, name);
691} 690}
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index a2dff0350..0b2fd2928 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -1218,12 +1218,12 @@ public:
1218 1218
1219 struct Window { 1219 struct Window {
1220 union { 1220 union {
1221 u32 raw_1; 1221 u32 raw_x;
1222 BitField<0, 16, u32> x_min; 1222 BitField<0, 16, u32> x_min;
1223 BitField<16, 16, u32> x_max; 1223 BitField<16, 16, u32> x_max;
1224 }; 1224 };
1225 union { 1225 union {
1226 u32 raw_2; 1226 u32 raw_y;
1227 BitField<0, 16, u32> y_min; 1227 BitField<0, 16, u32> y_min;
1228 BitField<16, 16, u32> y_max; 1228 BitField<16, 16, u32> y_max;
1229 }; 1229 };
@@ -3031,14 +3031,15 @@ public:
3031 3031
3032 EngineHint engine_state{EngineHint::None}; 3032 EngineHint engine_state{EngineHint::None};
3033 3033
3034 enum class HLEReplaceName : u32 { 3034 enum class HLEReplacementAttributeType : u32 {
3035 BaseVertex = 0x0, 3035 BaseVertex = 0x0,
3036 BaseInstance = 0x1, 3036 BaseInstance = 0x1,
3037 DrawID = 0x2,
3037 }; 3038 };
3038 3039
3039 void setHLEReplacementName(u32 bank, u32 offset, HLEReplaceName name); 3040 void SetHLEReplacementAttributeType(u32 bank, u32 offset, HLEReplacementAttributeType name);
3040 3041
3041 std::unordered_map<u64, HLEReplaceName> replace_table; 3042 std::unordered_map<u64, HLEReplacementAttributeType> replace_table;
3042 3043
3043 static_assert(sizeof(Regs) == Regs::NUM_REGS * sizeof(u32), "Maxwell3D Regs has wrong size"); 3044 static_assert(sizeof(Regs) == Regs::NUM_REGS * sizeof(u32), "Maxwell3D Regs has wrong size");
3044 static_assert(std::is_trivially_copyable_v<Regs>, "Maxwell3D Regs must be trivially copyable"); 3045 static_assert(std::is_trivially_copyable_v<Regs>, "Maxwell3D Regs must be trivially copyable");
@@ -3087,9 +3088,7 @@ public:
3087 std::unique_ptr<DrawManager> draw_manager; 3088 std::unique_ptr<DrawManager> draw_manager;
3088 friend class DrawManager; 3089 friend class DrawManager;
3089 3090
3090 std::vector<u8> inline_index_draw_indexes; 3091 GPUVAddr GetMacroAddress(size_t index) const {
3091
3092 GPUVAddr getMacroAddress(size_t index) const {
3093 return macro_addresses[index]; 3092 return macro_addresses[index];
3094 } 3093 }
3095 3094
@@ -3100,7 +3099,7 @@ public:
3100 RefreshParametersImpl(); 3099 RefreshParametersImpl();
3101 } 3100 }
3102 3101
3103 bool AnyParametersDirty() { 3102 bool AnyParametersDirty() const {
3104 return current_macro_dirty; 3103 return current_macro_dirty;
3105 } 3104 }
3106 3105
@@ -3114,6 +3113,10 @@ public:
3114 /// Handles a write to the CB_BIND register. 3113 /// Handles a write to the CB_BIND register.
3115 void ProcessCBBind(size_t stage_index); 3114 void ProcessCBBind(size_t stage_index);
3116 3115
3116 /// Handles a write to the CB_DATA[i] register.
3117 void ProcessCBData(u32 value);
3118 void ProcessCBMultiData(const u32* start_base, u32 amount);
3119
3117private: 3120private:
3118 void InitializeRegisterDefaults(); 3121 void InitializeRegisterDefaults();
3119 3122
@@ -3165,10 +3168,6 @@ private:
3165 /// Handles writes to syncing register. 3168 /// Handles writes to syncing register.
3166 void ProcessSyncPoint(); 3169 void ProcessSyncPoint();
3167 3170
3168 /// Handles a write to the CB_DATA[i] register.
3169 void ProcessCBData(u32 value);
3170 void ProcessCBMultiData(const u32* start_base, u32 amount);
3171
3172 /// Returns a query's value or an empty object if the value will be deferred through a cache. 3171 /// Returns a query's value or an empty object if the value will be deferred through a cache.
3173 std::optional<u64> GetQueryResult(); 3172 std::optional<u64> GetQueryResult();
3174 3173
@@ -3196,11 +3195,6 @@ private:
3196 3195
3197 bool execute_on{true}; 3196 bool execute_on{true};
3198 3197
3199 std::array<bool, Regs::NUM_REGS> draw_command{};
3200 std::vector<u32> deferred_draw_method;
3201 enum class DrawMode : u32 { General = 0, Instance, InlineIndex };
3202 DrawMode draw_mode{DrawMode::General};
3203 bool draw_indexed{};
3204 std::vector<std::pair<GPUVAddr, size_t>> macro_segments; 3198 std::vector<std::pair<GPUVAddr, size_t>> macro_segments;
3205 std::vector<GPUVAddr> macro_addresses; 3199 std::vector<GPUVAddr> macro_addresses;
3206 bool current_macro_dirty{}; 3200 bool current_macro_dirty{};
diff --git a/src/video_core/macro/macro.cpp b/src/video_core/macro/macro.cpp
index 49c47dafe..a96e8648c 100644
--- a/src/video_core/macro/macro.cpp
+++ b/src/video_core/macro/macro.cpp
@@ -23,7 +23,7 @@
23#include "video_core/macro/macro_jit_x64.h" 23#include "video_core/macro/macro_jit_x64.h"
24#endif 24#endif
25 25
26MICROPROFILE_DEFINE(MacroHLE, "GPU", "Execute macro hle", MP_RGB(128, 192, 192)); 26MICROPROFILE_DEFINE(MacroHLE, "GPU", "Execute macro HLE", MP_RGB(128, 192, 192));
27 27
28namespace Tegra { 28namespace Tegra {
29 29
diff --git a/src/video_core/macro/macro_hle.cpp b/src/video_core/macro/macro_hle.cpp
index c08b4abb3..a5476e795 100644
--- a/src/video_core/macro/macro_hle.cpp
+++ b/src/video_core/macro/macro_hle.cpp
@@ -1,5 +1,5 @@
1// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-3.0-or-later
3 3
4#include <array> 4#include <array>
5#include <vector> 5#include <vector>
@@ -15,28 +15,28 @@
15 15
16namespace Tegra { 16namespace Tegra {
17 17
18using Maxwell = Engines::Maxwell3D; 18using Maxwell3D = Engines::Maxwell3D;
19 19
20namespace { 20namespace {
21 21
22bool IsTopologySafe(Maxwell::Regs::PrimitiveTopology topology) { 22bool IsTopologySafe(Maxwell3D::Regs::PrimitiveTopology topology) {
23 switch (topology) { 23 switch (topology) {
24 case Maxwell::Regs::PrimitiveTopology::Points: 24 case Maxwell3D::Regs::PrimitiveTopology::Points:
25 case Maxwell::Regs::PrimitiveTopology::Lines: 25 case Maxwell3D::Regs::PrimitiveTopology::Lines:
26 case Maxwell::Regs::PrimitiveTopology::LineLoop: 26 case Maxwell3D::Regs::PrimitiveTopology::LineLoop:
27 case Maxwell::Regs::PrimitiveTopology::LineStrip: 27 case Maxwell3D::Regs::PrimitiveTopology::LineStrip:
28 case Maxwell::Regs::PrimitiveTopology::Triangles: 28 case Maxwell3D::Regs::PrimitiveTopology::Triangles:
29 case Maxwell::Regs::PrimitiveTopology::TriangleStrip: 29 case Maxwell3D::Regs::PrimitiveTopology::TriangleStrip:
30 case Maxwell::Regs::PrimitiveTopology::TriangleFan: 30 case Maxwell3D::Regs::PrimitiveTopology::TriangleFan:
31 case Maxwell::Regs::PrimitiveTopology::LinesAdjacency: 31 case Maxwell3D::Regs::PrimitiveTopology::LinesAdjacency:
32 case Maxwell::Regs::PrimitiveTopology::LineStripAdjacency: 32 case Maxwell3D::Regs::PrimitiveTopology::LineStripAdjacency:
33 case Maxwell::Regs::PrimitiveTopology::TrianglesAdjacency: 33 case Maxwell3D::Regs::PrimitiveTopology::TrianglesAdjacency:
34 case Maxwell::Regs::PrimitiveTopology::TriangleStripAdjacency: 34 case Maxwell3D::Regs::PrimitiveTopology::TriangleStripAdjacency:
35 case Maxwell::Regs::PrimitiveTopology::Patches: 35 case Maxwell3D::Regs::PrimitiveTopology::Patches:
36 return true; 36 return true;
37 case Maxwell::Regs::PrimitiveTopology::Quads: 37 case Maxwell3D::Regs::PrimitiveTopology::Quads:
38 case Maxwell::Regs::PrimitiveTopology::QuadStrip: 38 case Maxwell3D::Regs::PrimitiveTopology::QuadStrip:
39 case Maxwell::Regs::PrimitiveTopology::Polygon: 39 case Maxwell3D::Regs::PrimitiveTopology::Polygon:
40 default: 40 default:
41 return false; 41 return false;
42 } 42 }
@@ -44,34 +44,55 @@ bool IsTopologySafe(Maxwell::Regs::PrimitiveTopology topology) {
44 44
45class HLEMacroImpl : public CachedMacro { 45class HLEMacroImpl : public CachedMacro {
46public: 46public:
47 explicit HLEMacroImpl(Engines::Maxwell3D& maxwell3d_) : maxwell3d{maxwell3d_} {} 47 explicit HLEMacroImpl(Maxwell3D& maxwell3d_) : maxwell3d{maxwell3d_} {}
48 48
49protected: 49protected:
50 Engines::Maxwell3D& maxwell3d; 50 Maxwell3D& maxwell3d;
51}; 51};
52 52
53class HLE_771BB18C62444DA0 final : public HLEMacroImpl { 53class HLE_DrawArrays final : public HLEMacroImpl {
54public: 54public:
55 explicit HLE_771BB18C62444DA0(Engines::Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {} 55 explicit HLE_DrawArrays(Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {}
56 56
57 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override { 57 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override {
58 maxwell3d.RefreshParameters(); 58 maxwell3d.RefreshParameters();
59 const u32 instance_count = parameters[2] & maxwell3d.GetRegisterValue(0xD1B); 59
60 auto topology = static_cast<Maxwell3D::Regs::PrimitiveTopology>(parameters[0]);
61 maxwell3d.draw_manager->DrawArray(topology, parameters[1], parameters[2],
62 maxwell3d.regs.global_base_instance_index, 1);
63 }
64};
65
66class HLE_DrawIndexed final : public HLEMacroImpl {
67public:
68 explicit HLE_DrawIndexed(Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {}
69
70 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override {
71 maxwell3d.RefreshParameters();
72 maxwell3d.regs.index_buffer.start_addr_high = parameters[1];
73 maxwell3d.regs.index_buffer.start_addr_low = parameters[2];
74 maxwell3d.regs.index_buffer.format =
75 static_cast<Engines::Maxwell3D::Regs::IndexFormat>(parameters[3]);
60 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; 76 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
61 maxwell3d.draw_manager->DrawIndex( 77
62 static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[0] & 78 auto topology = static_cast<Maxwell3D::Regs::PrimitiveTopology>(parameters[0]);
63 0x3ffffff), 79 maxwell3d.draw_manager->DrawIndex(topology, 0, parameters[4],
64 parameters[4], parameters[1], parameters[3], parameters[5], instance_count); 80 maxwell3d.regs.global_base_vertex_index,
81 maxwell3d.regs.global_base_instance_index, 1);
65 } 82 }
66}; 83};
67 84
85/*
86 * @note: these macros have two versions, a normal and extended version, with the extended version
87 * also assigning the base vertex/instance.
88 */
89template <bool extended>
68class HLE_DrawArraysIndirect final : public HLEMacroImpl { 90class HLE_DrawArraysIndirect final : public HLEMacroImpl {
69public: 91public:
70 explicit HLE_DrawArraysIndirect(Engines::Maxwell3D& maxwell3d_, bool extended_ = false) 92 explicit HLE_DrawArraysIndirect(Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {}
71 : HLEMacroImpl(maxwell3d_), extended(extended_) {}
72 93
73 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override { 94 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override {
74 auto topology = static_cast<Maxwell::Regs::PrimitiveTopology>(parameters[0]); 95 auto topology = static_cast<Maxwell3D::Regs::PrimitiveTopology>(parameters[0]);
75 if (!maxwell3d.AnyParametersDirty() || !IsTopologySafe(topology)) { 96 if (!maxwell3d.AnyParametersDirty() || !IsTopologySafe(topology)) {
76 Fallback(parameters); 97 Fallback(parameters);
77 return; 98 return;
@@ -81,20 +102,21 @@ public:
81 params.is_indexed = false; 102 params.is_indexed = false;
82 params.include_count = false; 103 params.include_count = false;
83 params.count_start_address = 0; 104 params.count_start_address = 0;
84 params.indirect_start_address = maxwell3d.getMacroAddress(1); 105 params.indirect_start_address = maxwell3d.GetMacroAddress(1);
85 params.buffer_size = 4 * sizeof(u32); 106 params.buffer_size = 4 * sizeof(u32);
86 params.max_draw_counts = 1; 107 params.max_draw_counts = 1;
87 params.stride = 0; 108 params.stride = 0;
88 109
89 if (extended) { 110 if constexpr (extended) {
90 maxwell3d.engine_state = Maxwell::EngineHint::OnHLEMacro; 111 maxwell3d.engine_state = Maxwell3D::EngineHint::OnHLEMacro;
91 maxwell3d.setHLEReplacementName(0, 0x640, Maxwell::HLEReplaceName::BaseInstance); 112 maxwell3d.SetHLEReplacementAttributeType(
113 0, 0x640, Maxwell3D::HLEReplacementAttributeType::BaseInstance);
92 } 114 }
93 115
94 maxwell3d.draw_manager->DrawArrayIndirect(topology); 116 maxwell3d.draw_manager->DrawArrayIndirect(topology);
95 117
96 if (extended) { 118 if constexpr (extended) {
97 maxwell3d.engine_state = Maxwell::EngineHint::None; 119 maxwell3d.engine_state = Maxwell3D::EngineHint::None;
98 maxwell3d.replace_table.clear(); 120 maxwell3d.replace_table.clear();
99 } 121 }
100 } 122 }
@@ -103,14 +125,14 @@ private:
103 void Fallback(const std::vector<u32>& parameters) { 125 void Fallback(const std::vector<u32>& parameters) {
104 SCOPE_EXIT({ 126 SCOPE_EXIT({
105 if (extended) { 127 if (extended) {
106 maxwell3d.engine_state = Maxwell::EngineHint::None; 128 maxwell3d.engine_state = Maxwell3D::EngineHint::None;
107 maxwell3d.replace_table.clear(); 129 maxwell3d.replace_table.clear();
108 } 130 }
109 }); 131 });
110 maxwell3d.RefreshParameters(); 132 maxwell3d.RefreshParameters();
111 const u32 instance_count = (maxwell3d.GetRegisterValue(0xD1B) & parameters[2]); 133 const u32 instance_count = (maxwell3d.GetRegisterValue(0xD1B) & parameters[2]);
112 134
113 auto topology = static_cast<Maxwell::Regs::PrimitiveTopology>(parameters[0]); 135 auto topology = static_cast<Maxwell3D::Regs::PrimitiveTopology>(parameters[0]);
114 const u32 vertex_first = parameters[3]; 136 const u32 vertex_first = parameters[3];
115 const u32 vertex_count = parameters[1]; 137 const u32 vertex_count = parameters[1];
116 138
@@ -122,31 +144,35 @@ private:
122 } 144 }
123 145
124 const u32 base_instance = parameters[4]; 146 const u32 base_instance = parameters[4];
125 if (extended) { 147 if constexpr (extended) {
126 maxwell3d.regs.global_base_instance_index = base_instance; 148 maxwell3d.regs.global_base_instance_index = base_instance;
127 maxwell3d.engine_state = Maxwell::EngineHint::OnHLEMacro; 149 maxwell3d.engine_state = Maxwell3D::EngineHint::OnHLEMacro;
128 maxwell3d.setHLEReplacementName(0, 0x640, Maxwell::HLEReplaceName::BaseInstance); 150 maxwell3d.SetHLEReplacementAttributeType(
151 0, 0x640, Maxwell3D::HLEReplacementAttributeType::BaseInstance);
129 } 152 }
130 153
131 maxwell3d.draw_manager->DrawArray(topology, vertex_first, vertex_count, base_instance, 154 maxwell3d.draw_manager->DrawArray(topology, vertex_first, vertex_count, base_instance,
132 instance_count); 155 instance_count);
133 156
134 if (extended) { 157 if constexpr (extended) {
135 maxwell3d.regs.global_base_instance_index = 0; 158 maxwell3d.regs.global_base_instance_index = 0;
136 maxwell3d.engine_state = Maxwell::EngineHint::None; 159 maxwell3d.engine_state = Maxwell3D::EngineHint::None;
137 maxwell3d.replace_table.clear(); 160 maxwell3d.replace_table.clear();
138 } 161 }
139 } 162 }
140
141 bool extended;
142}; 163};
143 164
165/*
166 * @note: these macros have two versions, a normal and extended version, with the extended version
167 * also assigning the base vertex/instance.
168 */
169template <bool extended>
144class HLE_DrawIndexedIndirect final : public HLEMacroImpl { 170class HLE_DrawIndexedIndirect final : public HLEMacroImpl {
145public: 171public:
146 explicit HLE_DrawIndexedIndirect(Engines::Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {} 172 explicit HLE_DrawIndexedIndirect(Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {}
147 173
148 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override { 174 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override {
149 auto topology = static_cast<Maxwell::Regs::PrimitiveTopology>(parameters[0]); 175 auto topology = static_cast<Maxwell3D::Regs::PrimitiveTopology>(parameters[0]);
150 if (!maxwell3d.AnyParametersDirty() || !IsTopologySafe(topology)) { 176 if (!maxwell3d.AnyParametersDirty() || !IsTopologySafe(topology)) {
151 Fallback(parameters); 177 Fallback(parameters);
152 return; 178 return;
@@ -159,24 +185,30 @@ public:
159 maxwell3d.regs.global_base_vertex_index = element_base; 185 maxwell3d.regs.global_base_vertex_index = element_base;
160 maxwell3d.regs.global_base_instance_index = base_instance; 186 maxwell3d.regs.global_base_instance_index = base_instance;
161 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; 187 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
162 maxwell3d.engine_state = Maxwell::EngineHint::OnHLEMacro; 188 if constexpr (extended) {
163 maxwell3d.setHLEReplacementName(0, 0x640, Maxwell::HLEReplaceName::BaseVertex); 189 maxwell3d.engine_state = Maxwell3D::EngineHint::OnHLEMacro;
164 maxwell3d.setHLEReplacementName(0, 0x644, Maxwell::HLEReplaceName::BaseInstance); 190 maxwell3d.SetHLEReplacementAttributeType(
191 0, 0x640, Maxwell3D::HLEReplacementAttributeType::BaseVertex);
192 maxwell3d.SetHLEReplacementAttributeType(
193 0, 0x644, Maxwell3D::HLEReplacementAttributeType::BaseInstance);
194 }
165 auto& params = maxwell3d.draw_manager->GetIndirectParams(); 195 auto& params = maxwell3d.draw_manager->GetIndirectParams();
166 params.is_indexed = true; 196 params.is_indexed = true;
167 params.include_count = false; 197 params.include_count = false;
168 params.count_start_address = 0; 198 params.count_start_address = 0;
169 params.indirect_start_address = maxwell3d.getMacroAddress(1); 199 params.indirect_start_address = maxwell3d.GetMacroAddress(1);
170 params.buffer_size = 5 * sizeof(u32); 200 params.buffer_size = 5 * sizeof(u32);
171 params.max_draw_counts = 1; 201 params.max_draw_counts = 1;
172 params.stride = 0; 202 params.stride = 0;
173 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; 203 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
174 maxwell3d.draw_manager->DrawIndexedIndirect(topology, 0, estimate); 204 maxwell3d.draw_manager->DrawIndexedIndirect(topology, 0, estimate);
175 maxwell3d.engine_state = Maxwell::EngineHint::None;
176 maxwell3d.replace_table.clear();
177 maxwell3d.regs.vertex_id_base = 0x0; 205 maxwell3d.regs.vertex_id_base = 0x0;
178 maxwell3d.regs.global_base_vertex_index = 0x0; 206 maxwell3d.regs.global_base_vertex_index = 0x0;
179 maxwell3d.regs.global_base_instance_index = 0x0; 207 maxwell3d.regs.global_base_instance_index = 0x0;
208 if constexpr (extended) {
209 maxwell3d.engine_state = Maxwell3D::EngineHint::None;
210 maxwell3d.replace_table.clear();
211 }
180 } 212 }
181 213
182private: 214private:
@@ -189,31 +221,37 @@ private:
189 maxwell3d.regs.global_base_vertex_index = element_base; 221 maxwell3d.regs.global_base_vertex_index = element_base;
190 maxwell3d.regs.global_base_instance_index = base_instance; 222 maxwell3d.regs.global_base_instance_index = base_instance;
191 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; 223 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
192 maxwell3d.engine_state = Maxwell::EngineHint::OnHLEMacro; 224 if constexpr (extended) {
193 maxwell3d.setHLEReplacementName(0, 0x640, Maxwell::HLEReplaceName::BaseVertex); 225 maxwell3d.engine_state = Maxwell3D::EngineHint::OnHLEMacro;
194 maxwell3d.setHLEReplacementName(0, 0x644, Maxwell::HLEReplaceName::BaseInstance); 226 maxwell3d.SetHLEReplacementAttributeType(
227 0, 0x640, Maxwell3D::HLEReplacementAttributeType::BaseVertex);
228 maxwell3d.SetHLEReplacementAttributeType(
229 0, 0x644, Maxwell3D::HLEReplacementAttributeType::BaseInstance);
230 }
195 231
196 maxwell3d.draw_manager->DrawIndex( 232 maxwell3d.draw_manager->DrawIndex(
197 static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[0]), 233 static_cast<Tegra::Maxwell3D::Regs::PrimitiveTopology>(parameters[0]), parameters[3],
198 parameters[3], parameters[1], element_base, base_instance, instance_count); 234 parameters[1], element_base, base_instance, instance_count);
199 235
200 maxwell3d.regs.vertex_id_base = 0x0; 236 maxwell3d.regs.vertex_id_base = 0x0;
201 maxwell3d.regs.global_base_vertex_index = 0x0; 237 maxwell3d.regs.global_base_vertex_index = 0x0;
202 maxwell3d.regs.global_base_instance_index = 0x0; 238 maxwell3d.regs.global_base_instance_index = 0x0;
203 maxwell3d.engine_state = Maxwell::EngineHint::None; 239 if constexpr (extended) {
204 maxwell3d.replace_table.clear(); 240 maxwell3d.engine_state = Maxwell3D::EngineHint::None;
241 maxwell3d.replace_table.clear();
242 }
205 } 243 }
206}; 244};
207 245
208class HLE_MultiLayerClear final : public HLEMacroImpl { 246class HLE_MultiLayerClear final : public HLEMacroImpl {
209public: 247public:
210 explicit HLE_MultiLayerClear(Engines::Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {} 248 explicit HLE_MultiLayerClear(Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {}
211 249
212 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override { 250 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override {
213 maxwell3d.RefreshParameters(); 251 maxwell3d.RefreshParameters();
214 ASSERT(parameters.size() == 1); 252 ASSERT(parameters.size() == 1);
215 253
216 const Engines::Maxwell3D::Regs::ClearSurface clear_params{parameters[0]}; 254 const Maxwell3D::Regs::ClearSurface clear_params{parameters[0]};
217 const u32 rt_index = clear_params.RT; 255 const u32 rt_index = clear_params.RT;
218 const u32 num_layers = maxwell3d.regs.rt[rt_index].depth; 256 const u32 num_layers = maxwell3d.regs.rt[rt_index].depth;
219 ASSERT(clear_params.layer == 0); 257 ASSERT(clear_params.layer == 0);
@@ -225,11 +263,10 @@ public:
225 263
226class HLE_MultiDrawIndexedIndirectCount final : public HLEMacroImpl { 264class HLE_MultiDrawIndexedIndirectCount final : public HLEMacroImpl {
227public: 265public:
228 explicit HLE_MultiDrawIndexedIndirectCount(Engines::Maxwell3D& maxwell3d_) 266 explicit HLE_MultiDrawIndexedIndirectCount(Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {}
229 : HLEMacroImpl(maxwell3d_) {}
230 267
231 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override { 268 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override {
232 const auto topology = static_cast<Maxwell::Regs::PrimitiveTopology>(parameters[2]); 269 const auto topology = static_cast<Maxwell3D::Regs::PrimitiveTopology>(parameters[2]);
233 if (!IsTopologySafe(topology)) { 270 if (!IsTopologySafe(topology)) {
234 Fallback(parameters); 271 Fallback(parameters);
235 return; 272 return;
@@ -253,17 +290,21 @@ public:
253 auto& params = maxwell3d.draw_manager->GetIndirectParams(); 290 auto& params = maxwell3d.draw_manager->GetIndirectParams();
254 params.is_indexed = true; 291 params.is_indexed = true;
255 params.include_count = true; 292 params.include_count = true;
256 params.count_start_address = maxwell3d.getMacroAddress(4); 293 params.count_start_address = maxwell3d.GetMacroAddress(4);
257 params.indirect_start_address = maxwell3d.getMacroAddress(5); 294 params.indirect_start_address = maxwell3d.GetMacroAddress(5);
258 params.buffer_size = stride * draw_count; 295 params.buffer_size = stride * draw_count;
259 params.max_draw_counts = draw_count; 296 params.max_draw_counts = draw_count;
260 params.stride = stride; 297 params.stride = stride;
261 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; 298 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
262 maxwell3d.engine_state = Maxwell::EngineHint::OnHLEMacro; 299 maxwell3d.engine_state = Maxwell3D::EngineHint::OnHLEMacro;
263 maxwell3d.setHLEReplacementName(0, 0x640, Maxwell::HLEReplaceName::BaseVertex); 300 maxwell3d.SetHLEReplacementAttributeType(
264 maxwell3d.setHLEReplacementName(0, 0x644, Maxwell::HLEReplaceName::BaseInstance); 301 0, 0x640, Maxwell3D::HLEReplacementAttributeType::BaseVertex);
302 maxwell3d.SetHLEReplacementAttributeType(
303 0, 0x644, Maxwell3D::HLEReplacementAttributeType::BaseInstance);
304 maxwell3d.SetHLEReplacementAttributeType(0, 0x648,
305 Maxwell3D::HLEReplacementAttributeType::DrawID);
265 maxwell3d.draw_manager->DrawIndexedIndirect(topology, 0, estimate); 306 maxwell3d.draw_manager->DrawIndexedIndirect(topology, 0, estimate);
266 maxwell3d.engine_state = Maxwell::EngineHint::None; 307 maxwell3d.engine_state = Maxwell3D::EngineHint::None;
267 maxwell3d.replace_table.clear(); 308 maxwell3d.replace_table.clear();
268 } 309 }
269 310
@@ -271,9 +312,8 @@ private:
271 void Fallback(const std::vector<u32>& parameters) { 312 void Fallback(const std::vector<u32>& parameters) {
272 SCOPE_EXIT({ 313 SCOPE_EXIT({
273 // Clean everything. 314 // Clean everything.
274 // Clean everything.
275 maxwell3d.regs.vertex_id_base = 0x0; 315 maxwell3d.regs.vertex_id_base = 0x0;
276 maxwell3d.engine_state = Maxwell::EngineHint::None; 316 maxwell3d.engine_state = Maxwell3D::EngineHint::None;
277 maxwell3d.replace_table.clear(); 317 maxwell3d.replace_table.clear();
278 }); 318 });
279 maxwell3d.RefreshParameters(); 319 maxwell3d.RefreshParameters();
@@ -283,7 +323,7 @@ private:
283 // Nothing to do. 323 // Nothing to do.
284 return; 324 return;
285 } 325 }
286 const auto topology = static_cast<Maxwell::Regs::PrimitiveTopology>(parameters[2]); 326 const auto topology = static_cast<Maxwell3D::Regs::PrimitiveTopology>(parameters[2]);
287 const u32 padding = parameters[3]; 327 const u32 padding = parameters[3];
288 const std::size_t max_draws = parameters[4]; 328 const std::size_t max_draws = parameters[4];
289 329
@@ -297,9 +337,13 @@ private:
297 const u32 base_vertex = parameters[base + 3]; 337 const u32 base_vertex = parameters[base + 3];
298 const u32 base_instance = parameters[base + 4]; 338 const u32 base_instance = parameters[base + 4];
299 maxwell3d.regs.vertex_id_base = base_vertex; 339 maxwell3d.regs.vertex_id_base = base_vertex;
300 maxwell3d.engine_state = Maxwell::EngineHint::OnHLEMacro; 340 maxwell3d.engine_state = Maxwell3D::EngineHint::OnHLEMacro;
301 maxwell3d.setHLEReplacementName(0, 0x640, Maxwell::HLEReplaceName::BaseVertex); 341 maxwell3d.SetHLEReplacementAttributeType(
302 maxwell3d.setHLEReplacementName(0, 0x644, Maxwell::HLEReplaceName::BaseInstance); 342 0, 0x640, Maxwell3D::HLEReplacementAttributeType::BaseVertex);
343 maxwell3d.SetHLEReplacementAttributeType(
344 0, 0x644, Maxwell3D::HLEReplacementAttributeType::BaseInstance);
345 maxwell3d.CallMethod(0x8e3, 0x648, true);
346 maxwell3d.CallMethod(0x8e4, static_cast<u32>(index), true);
303 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; 347 maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
304 maxwell3d.draw_manager->DrawIndex(topology, parameters[base + 2], parameters[base], 348 maxwell3d.draw_manager->DrawIndex(topology, parameters[base + 2], parameters[base],
305 base_vertex, base_instance, parameters[base + 1]); 349 base_vertex, base_instance, parameters[base + 1]);
@@ -309,7 +353,7 @@ private:
309 353
310class HLE_C713C83D8F63CCF3 final : public HLEMacroImpl { 354class HLE_C713C83D8F63CCF3 final : public HLEMacroImpl {
311public: 355public:
312 explicit HLE_C713C83D8F63CCF3(Engines::Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {} 356 explicit HLE_C713C83D8F63CCF3(Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {}
313 357
314 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override { 358 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override {
315 maxwell3d.RefreshParameters(); 359 maxwell3d.RefreshParameters();
@@ -325,7 +369,7 @@ public:
325 369
326class HLE_D7333D26E0A93EDE final : public HLEMacroImpl { 370class HLE_D7333D26E0A93EDE final : public HLEMacroImpl {
327public: 371public:
328 explicit HLE_D7333D26E0A93EDE(Engines::Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {} 372 explicit HLE_D7333D26E0A93EDE(Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {}
329 373
330 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override { 374 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override {
331 maxwell3d.RefreshParameters(); 375 maxwell3d.RefreshParameters();
@@ -341,7 +385,7 @@ public:
341 385
342class HLE_BindShader final : public HLEMacroImpl { 386class HLE_BindShader final : public HLEMacroImpl {
343public: 387public:
344 explicit HLE_BindShader(Engines::Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {} 388 explicit HLE_BindShader(Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {}
345 389
346 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override { 390 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override {
347 maxwell3d.RefreshParameters(); 391 maxwell3d.RefreshParameters();
@@ -371,7 +415,7 @@ public:
371 415
372class HLE_SetRasterBoundingBox final : public HLEMacroImpl { 416class HLE_SetRasterBoundingBox final : public HLEMacroImpl {
373public: 417public:
374 explicit HLE_SetRasterBoundingBox(Engines::Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {} 418 explicit HLE_SetRasterBoundingBox(Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {}
375 419
376 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override { 420 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override {
377 maxwell3d.RefreshParameters(); 421 maxwell3d.RefreshParameters();
@@ -384,60 +428,156 @@ public:
384 } 428 }
385}; 429};
386 430
431template <size_t base_size>
432class HLE_ClearConstBuffer final : public HLEMacroImpl {
433public:
434 explicit HLE_ClearConstBuffer(Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {}
435
436 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override {
437 maxwell3d.RefreshParameters();
438 static constexpr std::array<u32, base_size> zeroes{};
439 auto& regs = maxwell3d.regs;
440 regs.const_buffer.size = static_cast<u32>(base_size);
441 regs.const_buffer.address_high = parameters[0];
442 regs.const_buffer.address_low = parameters[1];
443 regs.const_buffer.offset = 0;
444 maxwell3d.ProcessCBMultiData(zeroes.data(), parameters[2] * 4);
445 }
446};
447
448class HLE_ClearMemory final : public HLEMacroImpl {
449public:
450 explicit HLE_ClearMemory(Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {}
451
452 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override {
453 maxwell3d.RefreshParameters();
454
455 const u32 needed_memory = parameters[2] / sizeof(u32);
456 if (needed_memory > zero_memory.size()) {
457 zero_memory.resize(needed_memory, 0);
458 }
459 auto& regs = maxwell3d.regs;
460 regs.upload.line_length_in = parameters[2];
461 regs.upload.line_count = 1;
462 regs.upload.dest.address_high = parameters[0];
463 regs.upload.dest.address_low = parameters[1];
464 maxwell3d.CallMethod(static_cast<size_t>(MAXWELL3D_REG_INDEX(launch_dma)), 0x1011, true);
465 maxwell3d.CallMultiMethod(static_cast<size_t>(MAXWELL3D_REG_INDEX(inline_data)),
466 zero_memory.data(), needed_memory, needed_memory);
467 }
468
469private:
470 std::vector<u32> zero_memory;
471};
472
473class HLE_TransformFeedbackSetup final : public HLEMacroImpl {
474public:
475 explicit HLE_TransformFeedbackSetup(Maxwell3D& maxwell3d_) : HLEMacroImpl(maxwell3d_) {}
476
477 void Execute(const std::vector<u32>& parameters, [[maybe_unused]] u32 method) override {
478 maxwell3d.RefreshParameters();
479
480 auto& regs = maxwell3d.regs;
481 regs.transform_feedback_enabled = 1;
482 regs.transform_feedback.buffers[0].start_offset = 0;
483 regs.transform_feedback.buffers[1].start_offset = 0;
484 regs.transform_feedback.buffers[2].start_offset = 0;
485 regs.transform_feedback.buffers[3].start_offset = 0;
486
487 regs.upload.line_length_in = 4;
488 regs.upload.line_count = 1;
489 regs.upload.dest.address_high = parameters[0];
490 regs.upload.dest.address_low = parameters[1];
491 maxwell3d.CallMethod(static_cast<size_t>(MAXWELL3D_REG_INDEX(launch_dma)), 0x1011, true);
492 maxwell3d.CallMethod(static_cast<size_t>(MAXWELL3D_REG_INDEX(inline_data)),
493 regs.transform_feedback.controls[0].stride, true);
494 }
495};
496
387} // Anonymous namespace 497} // Anonymous namespace
388 498
389HLEMacro::HLEMacro(Engines::Maxwell3D& maxwell3d_) : maxwell3d{maxwell3d_} { 499HLEMacro::HLEMacro(Maxwell3D& maxwell3d_) : maxwell3d{maxwell3d_} {
390 builders.emplace(0x771BB18C62444DA0ULL, 500 builders.emplace(0xDD6A7FA92A7D2674ULL,
391 std::function<std::unique_ptr<CachedMacro>(Engines::Maxwell3D&)>( 501 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
392 [](Engines::Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> { 502 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
393 return std::make_unique<HLE_771BB18C62444DA0>(maxwell3d__); 503 return std::make_unique<HLE_DrawArrays>(maxwell3d__);
394 })); 504 }));
395 builders.emplace(0x0D61FC9FAAC9FCADULL, 505 builders.emplace(0x0D61FC9FAAC9FCADULL,
396 std::function<std::unique_ptr<CachedMacro>(Engines::Maxwell3D&)>( 506 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
397 [](Engines::Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> { 507 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
398 return std::make_unique<HLE_DrawArraysIndirect>(maxwell3d__); 508 return std::make_unique<HLE_DrawArraysIndirect<false>>(maxwell3d__);
399 })); 509 }));
400 builders.emplace(0x8A4D173EB99A8603ULL, 510 builders.emplace(0x8A4D173EB99A8603ULL,
401 std::function<std::unique_ptr<CachedMacro>(Engines::Maxwell3D&)>( 511 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
402 [](Engines::Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> { 512 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
403 return std::make_unique<HLE_DrawArraysIndirect>(maxwell3d__, true); 513 return std::make_unique<HLE_DrawArraysIndirect<true>>(maxwell3d__);
514 }));
515 builders.emplace(0x2DB33AADB741839CULL,
516 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
517 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
518 return std::make_unique<HLE_DrawIndexed>(maxwell3d__);
519 }));
520 builders.emplace(0x771BB18C62444DA0ULL,
521 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
522 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
523 return std::make_unique<HLE_DrawIndexedIndirect<false>>(maxwell3d__);
404 })); 524 }));
405 builders.emplace(0x0217920100488FF7ULL, 525 builders.emplace(0x0217920100488FF7ULL,
406 std::function<std::unique_ptr<CachedMacro>(Engines::Maxwell3D&)>( 526 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
407 [](Engines::Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> { 527 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
408 return std::make_unique<HLE_DrawIndexedIndirect>(maxwell3d__); 528 return std::make_unique<HLE_DrawIndexedIndirect<true>>(maxwell3d__);
409 })); 529 }));
410 builders.emplace(0x3F5E74B9C9A50164ULL, 530 builders.emplace(0x3F5E74B9C9A50164ULL,
411 std::function<std::unique_ptr<CachedMacro>(Engines::Maxwell3D&)>( 531 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
412 [](Engines::Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> { 532 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
413 return std::make_unique<HLE_MultiDrawIndexedIndirectCount>( 533 return std::make_unique<HLE_MultiDrawIndexedIndirectCount>(
414 maxwell3d__); 534 maxwell3d__);
415 })); 535 }));
416 builders.emplace(0xEAD26C3E2109B06BULL, 536 builders.emplace(0xEAD26C3E2109B06BULL,
417 std::function<std::unique_ptr<CachedMacro>(Engines::Maxwell3D&)>( 537 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
418 [](Engines::Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> { 538 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
419 return std::make_unique<HLE_MultiLayerClear>(maxwell3d__); 539 return std::make_unique<HLE_MultiLayerClear>(maxwell3d__);
420 })); 540 }));
421 builders.emplace(0xC713C83D8F63CCF3ULL, 541 builders.emplace(0xC713C83D8F63CCF3ULL,
422 std::function<std::unique_ptr<CachedMacro>(Engines::Maxwell3D&)>( 542 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
423 [](Engines::Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> { 543 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
424 return std::make_unique<HLE_C713C83D8F63CCF3>(maxwell3d__); 544 return std::make_unique<HLE_C713C83D8F63CCF3>(maxwell3d__);
425 })); 545 }));
426 builders.emplace(0xD7333D26E0A93EDEULL, 546 builders.emplace(0xD7333D26E0A93EDEULL,
427 std::function<std::unique_ptr<CachedMacro>(Engines::Maxwell3D&)>( 547 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
428 [](Engines::Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> { 548 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
429 return std::make_unique<HLE_D7333D26E0A93EDE>(maxwell3d__); 549 return std::make_unique<HLE_D7333D26E0A93EDE>(maxwell3d__);
430 })); 550 }));
431 builders.emplace(0xEB29B2A09AA06D38ULL, 551 builders.emplace(0xEB29B2A09AA06D38ULL,
432 std::function<std::unique_ptr<CachedMacro>(Engines::Maxwell3D&)>( 552 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
433 [](Engines::Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> { 553 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
434 return std::make_unique<HLE_BindShader>(maxwell3d__); 554 return std::make_unique<HLE_BindShader>(maxwell3d__);
435 })); 555 }));
436 builders.emplace(0xDB1341DBEB4C8AF7ULL, 556 builders.emplace(0xDB1341DBEB4C8AF7ULL,
437 std::function<std::unique_ptr<CachedMacro>(Engines::Maxwell3D&)>( 557 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
438 [](Engines::Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> { 558 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
439 return std::make_unique<HLE_SetRasterBoundingBox>(maxwell3d__); 559 return std::make_unique<HLE_SetRasterBoundingBox>(maxwell3d__);
440 })); 560 }));
561 builders.emplace(0x6C97861D891EDf7EULL,
562 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
563 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
564 return std::make_unique<HLE_ClearConstBuffer<0x5F00>>(maxwell3d__);
565 }));
566 builders.emplace(0xD246FDDF3A6173D7ULL,
567 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
568 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
569 return std::make_unique<HLE_ClearConstBuffer<0x7000>>(maxwell3d__);
570 }));
571 builders.emplace(0xEE4D0004BEC8ECF4ULL,
572 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
573 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
574 return std::make_unique<HLE_ClearMemory>(maxwell3d__);
575 }));
576 builders.emplace(0xFC0CF27F5FFAA661ULL,
577 std::function<std::unique_ptr<CachedMacro>(Maxwell3D&)>(
578 [](Maxwell3D& maxwell3d__) -> std::unique_ptr<CachedMacro> {
579 return std::make_unique<HLE_TransformFeedbackSetup>(maxwell3d__);
580 }));
441} 581}
442 582
443HLEMacro::~HLEMacro() = default; 583HLEMacro::~HLEMacro() = default;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index ed7558073..7d48af8e1 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -357,21 +357,21 @@ void RasterizerOpenGL::FlushRegion(VAddr addr, u64 size, VideoCommon::CacheType
357 if (addr == 0 || size == 0) { 357 if (addr == 0 || size == 0) {
358 return; 358 return;
359 } 359 }
360 if (bool(which & VideoCommon::CacheType::TextureCache)) { 360 if (True(which & VideoCommon::CacheType::TextureCache)) {
361 std::scoped_lock lock{texture_cache.mutex}; 361 std::scoped_lock lock{texture_cache.mutex};
362 texture_cache.DownloadMemory(addr, size); 362 texture_cache.DownloadMemory(addr, size);
363 } 363 }
364 if ((bool(which & VideoCommon::CacheType::BufferCache))) { 364 if ((True(which & VideoCommon::CacheType::BufferCache))) {
365 std::scoped_lock lock{buffer_cache.mutex}; 365 std::scoped_lock lock{buffer_cache.mutex};
366 buffer_cache.DownloadMemory(addr, size); 366 buffer_cache.DownloadMemory(addr, size);
367 } 367 }
368 if ((bool(which & VideoCommon::CacheType::QueryCache))) { 368 if ((True(which & VideoCommon::CacheType::QueryCache))) {
369 query_cache.FlushRegion(addr, size); 369 query_cache.FlushRegion(addr, size);
370 } 370 }
371} 371}
372 372
373bool RasterizerOpenGL::MustFlushRegion(VAddr addr, u64 size, VideoCommon::CacheType which) { 373bool RasterizerOpenGL::MustFlushRegion(VAddr addr, u64 size, VideoCommon::CacheType which) {
374 if ((bool(which & VideoCommon::CacheType::BufferCache))) { 374 if ((True(which & VideoCommon::CacheType::BufferCache))) {
375 std::scoped_lock lock{buffer_cache.mutex}; 375 std::scoped_lock lock{buffer_cache.mutex};
376 if (buffer_cache.IsRegionGpuModified(addr, size)) { 376 if (buffer_cache.IsRegionGpuModified(addr, size)) {
377 return true; 377 return true;
@@ -380,7 +380,7 @@ bool RasterizerOpenGL::MustFlushRegion(VAddr addr, u64 size, VideoCommon::CacheT
380 if (!Settings::IsGPULevelHigh()) { 380 if (!Settings::IsGPULevelHigh()) {
381 return false; 381 return false;
382 } 382 }
383 if (bool(which & VideoCommon::CacheType::TextureCache)) { 383 if (True(which & VideoCommon::CacheType::TextureCache)) {
384 std::scoped_lock lock{texture_cache.mutex}; 384 std::scoped_lock lock{texture_cache.mutex};
385 return texture_cache.IsRegionGpuModified(addr, size); 385 return texture_cache.IsRegionGpuModified(addr, size);
386 } 386 }
@@ -392,18 +392,18 @@ void RasterizerOpenGL::InvalidateRegion(VAddr addr, u64 size, VideoCommon::Cache
392 if (addr == 0 || size == 0) { 392 if (addr == 0 || size == 0) {
393 return; 393 return;
394 } 394 }
395 if (bool(which & VideoCommon::CacheType::TextureCache)) { 395 if (True(which & VideoCommon::CacheType::TextureCache)) {
396 std::scoped_lock lock{texture_cache.mutex}; 396 std::scoped_lock lock{texture_cache.mutex};
397 texture_cache.WriteMemory(addr, size); 397 texture_cache.WriteMemory(addr, size);
398 } 398 }
399 if (bool(which & VideoCommon::CacheType::BufferCache)) { 399 if (True(which & VideoCommon::CacheType::BufferCache)) {
400 std::scoped_lock lock{buffer_cache.mutex}; 400 std::scoped_lock lock{buffer_cache.mutex};
401 buffer_cache.WriteMemory(addr, size); 401 buffer_cache.WriteMemory(addr, size);
402 } 402 }
403 if (bool(which & VideoCommon::CacheType::ShaderCache)) { 403 if (True(which & VideoCommon::CacheType::ShaderCache)) {
404 shader_cache.InvalidateRegion(addr, size); 404 shader_cache.InvalidateRegion(addr, size);
405 } 405 }
406 if (bool(which & VideoCommon::CacheType::QueryCache)) { 406 if (True(which & VideoCommon::CacheType::QueryCache)) {
407 query_cache.InvalidateRegion(addr, size); 407 query_cache.InvalidateRegion(addr, size);
408 } 408 }
409} 409}
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index fc746fe2c..242bf9602 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -431,21 +431,21 @@ void RasterizerVulkan::FlushRegion(VAddr addr, u64 size, VideoCommon::CacheType
431 if (addr == 0 || size == 0) { 431 if (addr == 0 || size == 0) {
432 return; 432 return;
433 } 433 }
434 if (bool(which & VideoCommon::CacheType::TextureCache)) { 434 if (True(which & VideoCommon::CacheType::TextureCache)) {
435 std::scoped_lock lock{texture_cache.mutex}; 435 std::scoped_lock lock{texture_cache.mutex};
436 texture_cache.DownloadMemory(addr, size); 436 texture_cache.DownloadMemory(addr, size);
437 } 437 }
438 if ((bool(which & VideoCommon::CacheType::BufferCache))) { 438 if ((True(which & VideoCommon::CacheType::BufferCache))) {
439 std::scoped_lock lock{buffer_cache.mutex}; 439 std::scoped_lock lock{buffer_cache.mutex};
440 buffer_cache.DownloadMemory(addr, size); 440 buffer_cache.DownloadMemory(addr, size);
441 } 441 }
442 if ((bool(which & VideoCommon::CacheType::QueryCache))) { 442 if ((True(which & VideoCommon::CacheType::QueryCache))) {
443 query_cache.FlushRegion(addr, size); 443 query_cache.FlushRegion(addr, size);
444 } 444 }
445} 445}
446 446
447bool RasterizerVulkan::MustFlushRegion(VAddr addr, u64 size, VideoCommon::CacheType which) { 447bool RasterizerVulkan::MustFlushRegion(VAddr addr, u64 size, VideoCommon::CacheType which) {
448 if ((bool(which & VideoCommon::CacheType::BufferCache))) { 448 if ((True(which & VideoCommon::CacheType::BufferCache))) {
449 std::scoped_lock lock{buffer_cache.mutex}; 449 std::scoped_lock lock{buffer_cache.mutex};
450 if (buffer_cache.IsRegionGpuModified(addr, size)) { 450 if (buffer_cache.IsRegionGpuModified(addr, size)) {
451 return true; 451 return true;
@@ -454,7 +454,7 @@ bool RasterizerVulkan::MustFlushRegion(VAddr addr, u64 size, VideoCommon::CacheT
454 if (!Settings::IsGPULevelHigh()) { 454 if (!Settings::IsGPULevelHigh()) {
455 return false; 455 return false;
456 } 456 }
457 if (bool(which & VideoCommon::CacheType::TextureCache)) { 457 if (True(which & VideoCommon::CacheType::TextureCache)) {
458 std::scoped_lock lock{texture_cache.mutex}; 458 std::scoped_lock lock{texture_cache.mutex};
459 return texture_cache.IsRegionGpuModified(addr, size); 459 return texture_cache.IsRegionGpuModified(addr, size);
460 } 460 }
@@ -465,18 +465,18 @@ void RasterizerVulkan::InvalidateRegion(VAddr addr, u64 size, VideoCommon::Cache
465 if (addr == 0 || size == 0) { 465 if (addr == 0 || size == 0) {
466 return; 466 return;
467 } 467 }
468 if (bool(which & VideoCommon::CacheType::TextureCache)) { 468 if (True(which & VideoCommon::CacheType::TextureCache)) {
469 std::scoped_lock lock{texture_cache.mutex}; 469 std::scoped_lock lock{texture_cache.mutex};
470 texture_cache.WriteMemory(addr, size); 470 texture_cache.WriteMemory(addr, size);
471 } 471 }
472 if ((bool(which & VideoCommon::CacheType::BufferCache))) { 472 if ((True(which & VideoCommon::CacheType::BufferCache))) {
473 std::scoped_lock lock{buffer_cache.mutex}; 473 std::scoped_lock lock{buffer_cache.mutex};
474 buffer_cache.WriteMemory(addr, size); 474 buffer_cache.WriteMemory(addr, size);
475 } 475 }
476 if ((bool(which & VideoCommon::CacheType::QueryCache))) { 476 if ((True(which & VideoCommon::CacheType::QueryCache))) {
477 query_cache.InvalidateRegion(addr, size); 477 query_cache.InvalidateRegion(addr, size);
478 } 478 }
479 if ((bool(which & VideoCommon::CacheType::ShaderCache))) { 479 if ((True(which & VideoCommon::CacheType::ShaderCache))) {
480 pipeline_cache.InvalidateRegion(addr, size); 480 pipeline_cache.InvalidateRegion(addr, size);
481 } 481 }
482} 482}
@@ -1050,7 +1050,7 @@ void RasterizerVulkan::UpdateDepthBiasEnable(Tegra::Engines::Maxwell3D::Regs& re
1050 constexpr size_t POINT = 0; 1050 constexpr size_t POINT = 0;
1051 constexpr size_t LINE = 1; 1051 constexpr size_t LINE = 1;
1052 constexpr size_t POLYGON = 2; 1052 constexpr size_t POLYGON = 2;
1053 constexpr std::array POLYGON_OFFSET_ENABLE_LUT = { 1053 static constexpr std::array POLYGON_OFFSET_ENABLE_LUT = {
1054 POINT, // Points 1054 POINT, // Points
1055 LINE, // Lines 1055 LINE, // Lines
1056 LINE, // LineLoop 1056 LINE, // LineLoop
@@ -1159,13 +1159,12 @@ void RasterizerVulkan::UpdateStencilOp(Tegra::Engines::Maxwell3D::Regs& regs) {
1159} 1159}
1160 1160
1161void RasterizerVulkan::UpdateLogicOp(Tegra::Engines::Maxwell3D::Regs& regs) { 1161void RasterizerVulkan::UpdateLogicOp(Tegra::Engines::Maxwell3D::Regs& regs) {
1162 if (!regs.logic_op.enable) {
1163 return;
1164 }
1165 if (!state_tracker.TouchLogicOp()) { 1162 if (!state_tracker.TouchLogicOp()) {
1166 return; 1163 return;
1167 } 1164 }
1168 auto op = static_cast<VkLogicOp>(static_cast<u32>(regs.logic_op.op) - 0x1500); 1165 const auto op_value = static_cast<u32>(regs.logic_op.op);
1166 auto op = op_value >= 0x1500 && op_value < 0x1510 ? static_cast<VkLogicOp>(op_value - 0x1500)
1167 : VK_LOGIC_OP_NO_OP;
1169 scheduler.Record([op](vk::CommandBuffer cmdbuf) { cmdbuf.SetLogicOpEXT(op); }); 1168 scheduler.Record([op](vk::CommandBuffer cmdbuf) { cmdbuf.SetLogicOpEXT(op); });
1170} 1169}
1171 1170
diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.cpp b/src/video_core/renderer_vulkan/vk_state_tracker.cpp
index e5cf97472..d56558a83 100644
--- a/src/video_core/renderer_vulkan/vk_state_tracker.cpp
+++ b/src/video_core/renderer_vulkan/vk_state_tracker.cpp
@@ -251,4 +251,4 @@ void StateTracker::InvalidateState() {
251StateTracker::StateTracker() 251StateTracker::StateTracker()
252 : flags{&default_flags}, default_flags{}, invalidation_flags{MakeInvalidationFlags()} {} 252 : flags{&default_flags}, default_flags{}, invalidation_flags{MakeInvalidationFlags()} {}
253 253
254} // namespace Vulkan \ No newline at end of file 254} // namespace Vulkan
diff --git a/src/video_core/shader_environment.cpp b/src/video_core/shader_environment.cpp
index c34728245..574760f80 100644
--- a/src/video_core/shader_environment.cpp
+++ b/src/video_core/shader_environment.cpp
@@ -351,12 +351,14 @@ std::optional<Shader::ReplaceConstant> GraphicsEnvironment::GetReplaceConstBuffe
351 if (it == maxwell3d->replace_table.end()) { 351 if (it == maxwell3d->replace_table.end()) {
352 return std::nullopt; 352 return std::nullopt;
353 } 353 }
354 const auto converted_value = [](Tegra::Engines::Maxwell3D::HLEReplaceName name) { 354 const auto converted_value = [](Tegra::Engines::Maxwell3D::HLEReplacementAttributeType name) {
355 switch (name) { 355 switch (name) {
356 case Tegra::Engines::Maxwell3D::HLEReplaceName::BaseVertex: 356 case Tegra::Engines::Maxwell3D::HLEReplacementAttributeType::BaseVertex:
357 return Shader::ReplaceConstant::BaseVertex; 357 return Shader::ReplaceConstant::BaseVertex;
358 case Tegra::Engines::Maxwell3D::HLEReplaceName::BaseInstance: 358 case Tegra::Engines::Maxwell3D::HLEReplacementAttributeType::BaseInstance:
359 return Shader::ReplaceConstant::BaseInstance; 359 return Shader::ReplaceConstant::BaseInstance;
360 case Tegra::Engines::Maxwell3D::HLEReplacementAttributeType::DrawID:
361 return Shader::ReplaceConstant::DrawID;
360 default: 362 default:
361 UNREACHABLE(); 363 UNREACHABLE();
362 } 364 }