diff options
| author | 2023-01-03 10:01:25 -0500 | |
|---|---|---|
| committer | 2023-01-04 14:39:42 -0500 | |
| commit | a0c697124ced080f58866825e2e323e8682bbd7f (patch) | |
| tree | 73830fc46134be10d7feffc3da11aa9f0ea58ffb /src | |
| parent | Texture Cache: Implement async texture downloads. (diff) | |
| download | yuzu-a0c697124ced080f58866825e2e323e8682bbd7f.tar.gz yuzu-a0c697124ced080f58866825e2e323e8682bbd7f.tar.xz yuzu-a0c697124ced080f58866825e2e323e8682bbd7f.zip | |
Video_core: Address feedback
Diffstat (limited to 'src')
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 | ||
| 228 | constexpr size_t NUM_GENERICS = 32; | 229 | constexpr 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 { | |||
| 19 | enum class ReplaceConstant : u32 { | 19 | enum class ReplaceConstant : u32 { |
| 20 | BaseInstance, | 20 | BaseInstance, |
| 21 | BaseVertex, | 21 | BaseVertex, |
| 22 | DrawID, | ||
| 22 | }; | 23 | }; |
| 23 | 24 | ||
| 24 | enum class TextureType : u32 { | 25 | enum 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 | |||
| 94 | void DrawManager::DrawArrayIndirect(PrimitiveTopology topology) { | 94 | void 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 | ||
| 100 | void DrawManager::DrawIndexedIndirect(PrimitiveTopology topology, u32 index_first, | 100 | void 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 | ||
| 111 | void DrawManager::SetInlineIndexBuffer(u32 index) { | 111 | void DrawManager::SetInlineIndexBuffer(u32 index) { |
| @@ -216,9 +216,12 @@ void DrawManager::ProcessDraw(bool draw_indexed, u32 instance_count) { | |||
| 216 | } | 216 | } |
| 217 | } | 217 | } |
| 218 | 218 | ||
| 219 | void DrawManager::ProcessDrawIndirect(bool draw_indexed) { | 219 | void 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 | ||
| 222 | void Maxwell3D::RefreshParametersImpl() { | 222 | void 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() { | |||
| 537 | void Maxwell3D::ProcessQueryCondition() { | 536 | void 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 | ||
| 592 | void Maxwell3D::ProcessCounterReset() { | 590 | void 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 | ||
| 688 | void Maxwell3D::setHLEReplacementName(u32 bank, u32 offset, HLEReplaceName name) { | 686 | void 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 | |||
| 3117 | private: | 3120 | private: |
| 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 | ||
| 26 | MICROPROFILE_DEFINE(MacroHLE, "GPU", "Execute macro hle", MP_RGB(128, 192, 192)); | 26 | MICROPROFILE_DEFINE(MacroHLE, "GPU", "Execute macro HLE", MP_RGB(128, 192, 192)); |
| 27 | 27 | ||
| 28 | namespace Tegra { | 28 | namespace 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 | ||
| 16 | namespace Tegra { | 16 | namespace Tegra { |
| 17 | 17 | ||
| 18 | using Maxwell = Engines::Maxwell3D; | 18 | using Maxwell3D = Engines::Maxwell3D; |
| 19 | 19 | ||
| 20 | namespace { | 20 | namespace { |
| 21 | 21 | ||
| 22 | bool IsTopologySafe(Maxwell::Regs::PrimitiveTopology topology) { | 22 | bool 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 | ||
| 45 | class HLEMacroImpl : public CachedMacro { | 45 | class HLEMacroImpl : public CachedMacro { |
| 46 | public: | 46 | public: |
| 47 | explicit HLEMacroImpl(Engines::Maxwell3D& maxwell3d_) : maxwell3d{maxwell3d_} {} | 47 | explicit HLEMacroImpl(Maxwell3D& maxwell3d_) : maxwell3d{maxwell3d_} {} |
| 48 | 48 | ||
| 49 | protected: | 49 | protected: |
| 50 | Engines::Maxwell3D& maxwell3d; | 50 | Maxwell3D& maxwell3d; |
| 51 | }; | 51 | }; |
| 52 | 52 | ||
| 53 | class HLE_771BB18C62444DA0 final : public HLEMacroImpl { | 53 | class HLE_DrawArrays final : public HLEMacroImpl { |
| 54 | public: | 54 | public: |
| 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 | |||
| 66 | class HLE_DrawIndexed final : public HLEMacroImpl { | ||
| 67 | public: | ||
| 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 | */ | ||
| 89 | template <bool extended> | ||
| 68 | class HLE_DrawArraysIndirect final : public HLEMacroImpl { | 90 | class HLE_DrawArraysIndirect final : public HLEMacroImpl { |
| 69 | public: | 91 | public: |
| 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 | */ | ||
| 169 | template <bool extended> | ||
| 144 | class HLE_DrawIndexedIndirect final : public HLEMacroImpl { | 170 | class HLE_DrawIndexedIndirect final : public HLEMacroImpl { |
| 145 | public: | 171 | public: |
| 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 | ||
| 182 | private: | 214 | private: |
| @@ -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 | ||
| 208 | class HLE_MultiLayerClear final : public HLEMacroImpl { | 246 | class HLE_MultiLayerClear final : public HLEMacroImpl { |
| 209 | public: | 247 | public: |
| 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 | ||
| 226 | class HLE_MultiDrawIndexedIndirectCount final : public HLEMacroImpl { | 264 | class HLE_MultiDrawIndexedIndirectCount final : public HLEMacroImpl { |
| 227 | public: | 265 | public: |
| 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 | ||
| 310 | class HLE_C713C83D8F63CCF3 final : public HLEMacroImpl { | 354 | class HLE_C713C83D8F63CCF3 final : public HLEMacroImpl { |
| 311 | public: | 355 | public: |
| 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 | ||
| 326 | class HLE_D7333D26E0A93EDE final : public HLEMacroImpl { | 370 | class HLE_D7333D26E0A93EDE final : public HLEMacroImpl { |
| 327 | public: | 371 | public: |
| 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 | ||
| 342 | class HLE_BindShader final : public HLEMacroImpl { | 386 | class HLE_BindShader final : public HLEMacroImpl { |
| 343 | public: | 387 | public: |
| 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 | ||
| 372 | class HLE_SetRasterBoundingBox final : public HLEMacroImpl { | 416 | class HLE_SetRasterBoundingBox final : public HLEMacroImpl { |
| 373 | public: | 417 | public: |
| 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 | ||
| 431 | template <size_t base_size> | ||
| 432 | class HLE_ClearConstBuffer final : public HLEMacroImpl { | ||
| 433 | public: | ||
| 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 | |||
| 448 | class HLE_ClearMemory final : public HLEMacroImpl { | ||
| 449 | public: | ||
| 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 | |||
| 469 | private: | ||
| 470 | std::vector<u32> zero_memory; | ||
| 471 | }; | ||
| 472 | |||
| 473 | class HLE_TransformFeedbackSetup final : public HLEMacroImpl { | ||
| 474 | public: | ||
| 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 | ||
| 389 | HLEMacro::HLEMacro(Engines::Maxwell3D& maxwell3d_) : maxwell3d{maxwell3d_} { | 499 | HLEMacro::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 | ||
| 443 | HLEMacro::~HLEMacro() = default; | 583 | HLEMacro::~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 | ||
| 373 | bool RasterizerOpenGL::MustFlushRegion(VAddr addr, u64 size, VideoCommon::CacheType which) { | 373 | bool 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 | ||
| 447 | bool RasterizerVulkan::MustFlushRegion(VAddr addr, u64 size, VideoCommon::CacheType which) { | 447 | bool 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 | ||
| 1161 | void RasterizerVulkan::UpdateLogicOp(Tegra::Engines::Maxwell3D::Regs& regs) { | 1161 | void 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() { | |||
| 251 | StateTracker::StateTracker() | 251 | StateTracker::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 | } |