diff options
Diffstat (limited to 'src')
16 files changed, 60 insertions, 211 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_context.cpp b/src/shader_recompiler/backend/spirv/emit_context.cpp index 794cd4ed8..32f679f2a 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/emit_context.cpp | |||
| @@ -510,7 +510,8 @@ void EmitContext::DefineOutputs(const Info& info) { | |||
| 510 | const Id type{TypeArray(F32[1], Constant(U32[1], 8U))}; | 510 | const Id type{TypeArray(F32[1], Constant(U32[1], 8U))}; |
| 511 | clip_distances = DefineOutput(*this, type, spv::BuiltIn::ClipDistance); | 511 | clip_distances = DefineOutput(*this, type, spv::BuiltIn::ClipDistance); |
| 512 | } | 512 | } |
| 513 | if (info.stores_viewport_index && !ignore_viewport_layer) { | 513 | if (info.stores_viewport_index && |
| 514 | (profile.support_viewport_index_layer_non_geometry || stage == Shader::Stage::Geometry)) { | ||
| 514 | if (stage == Stage::Fragment) { | 515 | if (stage == Stage::Fragment) { |
| 515 | throw NotImplementedException("Storing ViewportIndex in Fragment stage"); | 516 | throw NotImplementedException("Storing ViewportIndex in Fragment stage"); |
| 516 | } | 517 | } |
diff --git a/src/shader_recompiler/backend/spirv/emit_context.h b/src/shader_recompiler/backend/spirv/emit_context.h index 1573c2560..f4715a709 100644 --- a/src/shader_recompiler/backend/spirv/emit_context.h +++ b/src/shader_recompiler/backend/spirv/emit_context.h | |||
| @@ -134,8 +134,6 @@ public: | |||
| 134 | 134 | ||
| 135 | std::vector<Id> interfaces; | 135 | std::vector<Id> interfaces; |
| 136 | 136 | ||
| 137 | bool ignore_viewport_layer{}; | ||
| 138 | |||
| 139 | private: | 137 | private: |
| 140 | void DefineCommonTypes(const Info& info); | 138 | void DefineCommonTypes(const Info& info); |
| 141 | void DefineCommonConstants(); | 139 | void DefineCommonConstants(); |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp index cc6b98f7e..191380db0 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp | |||
| @@ -228,11 +228,9 @@ void SetupCapabilities(const Profile& profile, const Info& info, EmitContext& ct | |||
| 228 | if (info.stores_viewport_index) { | 228 | if (info.stores_viewport_index) { |
| 229 | ctx.AddCapability(spv::Capability::MultiViewport); | 229 | ctx.AddCapability(spv::Capability::MultiViewport); |
| 230 | if (profile.support_viewport_index_layer_non_geometry && | 230 | if (profile.support_viewport_index_layer_non_geometry && |
| 231 | ctx.stage == Shader::Stage::VertexB) { | 231 | ctx.stage != Shader::Stage::Geometry) { |
| 232 | ctx.AddExtension("SPV_EXT_shader_viewport_index_layer"); | 232 | ctx.AddExtension("SPV_EXT_shader_viewport_index_layer"); |
| 233 | ctx.AddCapability(spv::Capability::ShaderViewportIndexLayerEXT); | 233 | ctx.AddCapability(spv::Capability::ShaderViewportIndexLayerEXT); |
| 234 | } else { | ||
| 235 | ctx.ignore_viewport_layer = true; | ||
| 236 | } | 234 | } |
| 237 | } | 235 | } |
| 238 | if (!profile.support_vertex_instance_id && (info.loads_instance_id || info.loads_vertex_id)) { | 236 | if (!profile.support_vertex_instance_id && (info.loads_instance_id || info.loads_vertex_id)) { |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.h b/src/shader_recompiler/backend/spirv/emit_spirv.h index 17a452e0e..5d0f16b3a 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv.h | |||
| @@ -28,7 +28,9 @@ void EmitSelectionMerge(EmitContext& ctx, Id merge_label); | |||
| 28 | void EmitReturn(EmitContext& ctx); | 28 | void EmitReturn(EmitContext& ctx); |
| 29 | void EmitUnreachable(EmitContext& ctx); | 29 | void EmitUnreachable(EmitContext& ctx); |
| 30 | void EmitDemoteToHelperInvocation(EmitContext& ctx, Id continue_label); | 30 | void EmitDemoteToHelperInvocation(EmitContext& ctx, Id continue_label); |
| 31 | void EmitMemoryBarrier(EmitContext& ctx, IR::Inst* inst); | 31 | void EmitMemoryBarrierWorkgroupLevel(EmitContext& ctx); |
| 32 | void EmitMemoryBarrierDeviceLevel(EmitContext& ctx); | ||
| 33 | void EmitMemoryBarrierSystemLevel(EmitContext& ctx); | ||
| 32 | void EmitPrologue(EmitContext& ctx); | 34 | void EmitPrologue(EmitContext& ctx); |
| 33 | void EmitEpilogue(EmitContext& ctx); | 35 | void EmitEpilogue(EmitContext& ctx); |
| 34 | void EmitGetRegister(EmitContext& ctx); | 36 | void EmitGetRegister(EmitContext& ctx); |
| @@ -60,14 +62,6 @@ void EmitSetZFlag(EmitContext& ctx); | |||
| 60 | void EmitSetSFlag(EmitContext& ctx); | 62 | void EmitSetSFlag(EmitContext& ctx); |
| 61 | void EmitSetCFlag(EmitContext& ctx); | 63 | void EmitSetCFlag(EmitContext& ctx); |
| 62 | void EmitSetOFlag(EmitContext& ctx); | 64 | void EmitSetOFlag(EmitContext& ctx); |
| 63 | void EmitGetFCSMFlag(EmitContext& ctx); | ||
| 64 | void EmitGetTAFlag(EmitContext& ctx); | ||
| 65 | void EmitGetTRFlag(EmitContext& ctx); | ||
| 66 | void EmitGetMXFlag(EmitContext& ctx); | ||
| 67 | void EmitSetFCSMFlag(EmitContext& ctx); | ||
| 68 | void EmitSetTAFlag(EmitContext& ctx); | ||
| 69 | void EmitSetTRFlag(EmitContext& ctx); | ||
| 70 | void EmitSetMXFlag(EmitContext& ctx); | ||
| 71 | Id EmitWorkgroupId(EmitContext& ctx); | 65 | Id EmitWorkgroupId(EmitContext& ctx); |
| 72 | Id EmitLocalInvocationId(EmitContext& ctx); | 66 | Id EmitLocalInvocationId(EmitContext& ctx); |
| 73 | Id EmitLoadLocal(EmitContext& ctx, Id word_offset); | 67 | Id EmitLoadLocal(EmitContext& ctx, Id word_offset); |
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_barriers.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_barriers.cpp index 413ac25a0..18f512319 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_barriers.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_barriers.cpp | |||
| @@ -7,34 +7,27 @@ | |||
| 7 | 7 | ||
| 8 | namespace Shader::Backend::SPIRV { | 8 | namespace Shader::Backend::SPIRV { |
| 9 | namespace { | 9 | namespace { |
| 10 | spv::Scope MemoryScopeToSpirVScope(IR::MemoryScope scope) { | 10 | void EmitMemoryBarrierImpl(EmitContext& ctx, spv::Scope scope) { |
| 11 | switch (scope) { | ||
| 12 | case IR::MemoryScope::Warp: | ||
| 13 | return spv::Scope::Subgroup; | ||
| 14 | case IR::MemoryScope::Workgroup: | ||
| 15 | return spv::Scope::Workgroup; | ||
| 16 | case IR::MemoryScope::Device: | ||
| 17 | return spv::Scope::Device; | ||
| 18 | case IR::MemoryScope::System: | ||
| 19 | return spv::Scope::CrossDevice; | ||
| 20 | case IR::MemoryScope::DontCare: | ||
| 21 | return spv::Scope::Invocation; | ||
| 22 | default: | ||
| 23 | throw NotImplementedException("Unknown memory scope!"); | ||
| 24 | } | ||
| 25 | } | ||
| 26 | |||
| 27 | } // namespace | ||
| 28 | |||
| 29 | void EmitMemoryBarrier(EmitContext& ctx, IR::Inst* inst) { | ||
| 30 | const auto info{inst->Flags<IR::BarrierInstInfo>()}; | ||
| 31 | const auto semantics = | 11 | const auto semantics = |
| 32 | spv::MemorySemanticsMask::AcquireRelease | spv::MemorySemanticsMask::UniformMemory | | 12 | spv::MemorySemanticsMask::AcquireRelease | spv::MemorySemanticsMask::UniformMemory | |
| 33 | spv::MemorySemanticsMask::WorkgroupMemory | spv::MemorySemanticsMask::AtomicCounterMemory | | 13 | spv::MemorySemanticsMask::WorkgroupMemory | spv::MemorySemanticsMask::AtomicCounterMemory | |
| 34 | spv::MemorySemanticsMask::ImageMemory; | 14 | spv::MemorySemanticsMask::ImageMemory; |
| 35 | const auto scope = MemoryScopeToSpirVScope(info.scope); | ||
| 36 | ctx.OpMemoryBarrier(ctx.Constant(ctx.U32[1], static_cast<u32>(scope)), | 15 | ctx.OpMemoryBarrier(ctx.Constant(ctx.U32[1], static_cast<u32>(scope)), |
| 37 | ctx.Constant(ctx.U32[1], static_cast<u32>(semantics))); | 16 | ctx.Constant(ctx.U32[1], static_cast<u32>(semantics))); |
| 38 | } | 17 | } |
| 39 | 18 | ||
| 19 | } // Anonymous namespace | ||
| 20 | |||
| 21 | void EmitMemoryBarrierWorkgroupLevel(EmitContext& ctx) { | ||
| 22 | EmitMemoryBarrierImpl(ctx, spv::Scope::Workgroup); | ||
| 23 | } | ||
| 24 | |||
| 25 | void EmitMemoryBarrierDeviceLevel(EmitContext& ctx) { | ||
| 26 | EmitMemoryBarrierImpl(ctx, spv::Scope::Device); | ||
| 27 | } | ||
| 28 | |||
| 29 | void EmitMemoryBarrierSystemLevel(EmitContext& ctx) { | ||
| 30 | EmitMemoryBarrierImpl(ctx, spv::Scope::CrossDevice); | ||
| 31 | } | ||
| 32 | |||
| 40 | } // namespace Shader::Backend::SPIRV | 33 | } // namespace Shader::Backend::SPIRV |
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 f13c0ee72..caab9aa12 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 | |||
| @@ -58,7 +58,10 @@ std::optional<Id> OutputAttrPointer(EmitContext& ctx, IR::Attribute attr) { | |||
| 58 | return ctx.OpAccessChain(ctx.output_f32, ctx.clip_distances, clip_num); | 58 | return ctx.OpAccessChain(ctx.output_f32, ctx.clip_distances, clip_num); |
| 59 | } | 59 | } |
| 60 | case IR::Attribute::ViewportIndex: | 60 | case IR::Attribute::ViewportIndex: |
| 61 | return ctx.ignore_viewport_layer ? std::nullopt : std::optional<Id>{ctx.viewport_index}; | 61 | return (ctx.profile.support_viewport_index_layer_non_geometry || |
| 62 | ctx.stage == Shader::Stage::Geometry) | ||
| 63 | ? std::optional<Id>{ctx.viewport_index} | ||
| 64 | : std::nullopt; | ||
| 62 | default: | 65 | default: |
| 63 | throw NotImplementedException("Read attribute {}", attr); | 66 | throw NotImplementedException("Read attribute {}", attr); |
| 64 | } | 67 | } |
| @@ -206,7 +209,7 @@ Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr) { | |||
| 206 | } | 209 | } |
| 207 | 210 | ||
| 208 | void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, Id value) { | 211 | void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, Id value) { |
| 209 | auto output = OutputAttrPointer(ctx, attr); | 212 | const std::optional<Id> output{OutputAttrPointer(ctx, attr)}; |
| 210 | if (!output) { | 213 | if (!output) { |
| 211 | return; | 214 | return; |
| 212 | } | 215 | } |
| @@ -263,38 +266,6 @@ void EmitSetOFlag(EmitContext&) { | |||
| 263 | throw NotImplementedException("SPIR-V Instruction"); | 266 | throw NotImplementedException("SPIR-V Instruction"); |
| 264 | } | 267 | } |
| 265 | 268 | ||
| 266 | void EmitGetFCSMFlag(EmitContext&) { | ||
| 267 | throw NotImplementedException("SPIR-V Instruction"); | ||
| 268 | } | ||
| 269 | |||
| 270 | void EmitGetTAFlag(EmitContext&) { | ||
| 271 | throw NotImplementedException("SPIR-V Instruction"); | ||
| 272 | } | ||
| 273 | |||
| 274 | void EmitGetTRFlag(EmitContext&) { | ||
| 275 | throw NotImplementedException("SPIR-V Instruction"); | ||
| 276 | } | ||
| 277 | |||
| 278 | void EmitGetMXFlag(EmitContext&) { | ||
| 279 | throw NotImplementedException("SPIR-V Instruction"); | ||
| 280 | } | ||
| 281 | |||
| 282 | void EmitSetFCSMFlag(EmitContext&) { | ||
| 283 | throw NotImplementedException("SPIR-V Instruction"); | ||
| 284 | } | ||
| 285 | |||
| 286 | void EmitSetTAFlag(EmitContext&) { | ||
| 287 | throw NotImplementedException("SPIR-V Instruction"); | ||
| 288 | } | ||
| 289 | |||
| 290 | void EmitSetTRFlag(EmitContext&) { | ||
| 291 | throw NotImplementedException("SPIR-V Instruction"); | ||
| 292 | } | ||
| 293 | |||
| 294 | void EmitSetMXFlag(EmitContext&) { | ||
| 295 | throw NotImplementedException("SPIR-V Instruction"); | ||
| 296 | } | ||
| 297 | |||
| 298 | Id EmitWorkgroupId(EmitContext& ctx) { | 269 | Id EmitWorkgroupId(EmitContext& ctx) { |
| 299 | return ctx.OpLoad(ctx.U32[3], ctx.workgroup_id); | 270 | return ctx.OpLoad(ctx.U32[3], ctx.workgroup_id); |
| 300 | } | 271 | } |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp index b5f61956a..5e94edd74 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp +++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp | |||
| @@ -82,8 +82,17 @@ void IREmitter::SelectionMerge(Block* merge_block) { | |||
| 82 | Inst(Opcode::SelectionMerge, merge_block); | 82 | Inst(Opcode::SelectionMerge, merge_block); |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | void IREmitter::MemoryBarrier(BarrierInstInfo info) { | 85 | void IREmitter::MemoryBarrier(MemoryScope scope) { |
| 86 | Inst(Opcode::MemoryBarrier, Flags{info}); | 86 | switch (scope) { |
| 87 | case MemoryScope::Workgroup: | ||
| 88 | Inst(Opcode::MemoryBarrierWorkgroupLevel); | ||
| 89 | case MemoryScope::Device: | ||
| 90 | Inst(Opcode::MemoryBarrierDeviceLevel); | ||
| 91 | case MemoryScope::System: | ||
| 92 | Inst(Opcode::MemoryBarrierSystemLevel); | ||
| 93 | default: | ||
| 94 | throw InvalidArgument("Invalid memory scope {}", scope); | ||
| 95 | } | ||
| 87 | } | 96 | } |
| 88 | 97 | ||
| 89 | void IREmitter::Return() { | 98 | void IREmitter::Return() { |
| @@ -202,38 +211,6 @@ void IREmitter::SetOFlag(const U1& value) { | |||
| 202 | Inst(Opcode::SetOFlag, value); | 211 | Inst(Opcode::SetOFlag, value); |
| 203 | } | 212 | } |
| 204 | 213 | ||
| 205 | U1 IREmitter::GetFCSMFlag() { | ||
| 206 | return Inst<U1>(Opcode::GetFCSMFlag); | ||
| 207 | } | ||
| 208 | |||
| 209 | U1 IREmitter::GetTAFlag() { | ||
| 210 | return Inst<U1>(Opcode::GetTAFlag); | ||
| 211 | } | ||
| 212 | |||
| 213 | U1 IREmitter::GetTRFlag() { | ||
| 214 | return Inst<U1>(Opcode::GetTRFlag); | ||
| 215 | } | ||
| 216 | |||
| 217 | U1 IREmitter::GetMXFlag() { | ||
| 218 | return Inst<U1>(Opcode::GetMXFlag); | ||
| 219 | } | ||
| 220 | |||
| 221 | void IREmitter::SetFCSMFlag(const U1& value) { | ||
| 222 | Inst(Opcode::SetFCSMFlag, value); | ||
| 223 | } | ||
| 224 | |||
| 225 | void IREmitter::SetTAFlag(const U1& value) { | ||
| 226 | Inst(Opcode::SetTAFlag, value); | ||
| 227 | } | ||
| 228 | |||
| 229 | void IREmitter::SetTRFlag(const U1& value) { | ||
| 230 | Inst(Opcode::SetTRFlag, value); | ||
| 231 | } | ||
| 232 | |||
| 233 | void IREmitter::SetMXFlag(const U1& value) { | ||
| 234 | Inst(Opcode::SetMXFlag, value); | ||
| 235 | } | ||
| 236 | |||
| 237 | static U1 GetFlowTest(IREmitter& ir, FlowTest flow_test) { | 214 | static U1 GetFlowTest(IREmitter& ir, FlowTest flow_test) { |
| 238 | switch (flow_test) { | 215 | switch (flow_test) { |
| 239 | case FlowTest::F: | 216 | case FlowTest::F: |
| @@ -292,9 +269,9 @@ static U1 GetFlowTest(IREmitter& ir, FlowTest flow_test) { | |||
| 292 | return ir.LogicalOr(ir.GetSFlag(), ir.GetZFlag()); | 269 | return ir.LogicalOr(ir.GetSFlag(), ir.GetZFlag()); |
| 293 | case FlowTest::RGT: | 270 | case FlowTest::RGT: |
| 294 | return ir.LogicalAnd(ir.LogicalNot(ir.GetSFlag()), ir.LogicalNot(ir.GetZFlag())); | 271 | return ir.LogicalAnd(ir.LogicalNot(ir.GetSFlag()), ir.LogicalNot(ir.GetZFlag())); |
| 295 | |||
| 296 | case FlowTest::FCSM_TR: | 272 | case FlowTest::FCSM_TR: |
| 297 | return ir.LogicalAnd(ir.GetFCSMFlag(), ir.GetTRFlag()); | 273 | // LOG_WARNING(ShaderDecompiler, "FCSM_TR CC State (Stubbed)"); |
| 274 | return ir.Imm1(false); | ||
| 298 | case FlowTest::CSM_TA: | 275 | case FlowTest::CSM_TA: |
| 299 | case FlowTest::CSM_TR: | 276 | case FlowTest::CSM_TR: |
| 300 | case FlowTest::CSM_MX: | 277 | case FlowTest::CSM_MX: |
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h index e034d672f..14b743975 100644 --- a/src/shader_recompiler/frontend/ir/ir_emitter.h +++ b/src/shader_recompiler/frontend/ir/ir_emitter.h | |||
| @@ -70,16 +70,6 @@ public: | |||
| 70 | void SetCFlag(const U1& value); | 70 | void SetCFlag(const U1& value); |
| 71 | void SetOFlag(const U1& value); | 71 | void SetOFlag(const U1& value); |
| 72 | 72 | ||
| 73 | [[nodiscard]] U1 GetFCSMFlag(); | ||
| 74 | [[nodiscard]] U1 GetTAFlag(); | ||
| 75 | [[nodiscard]] U1 GetTRFlag(); | ||
| 76 | [[nodiscard]] U1 GetMXFlag(); | ||
| 77 | |||
| 78 | void SetFCSMFlag(const U1& value); | ||
| 79 | void SetTAFlag(const U1& value); | ||
| 80 | void SetTRFlag(const U1& value); | ||
| 81 | void SetMXFlag(const U1& value); | ||
| 82 | |||
| 83 | [[nodiscard]] U1 Condition(IR::Condition cond); | 73 | [[nodiscard]] U1 Condition(IR::Condition cond); |
| 84 | [[nodiscard]] U1 GetFlowTestResult(FlowTest test); | 74 | [[nodiscard]] U1 GetFlowTestResult(FlowTest test); |
| 85 | 75 | ||
| @@ -138,7 +128,7 @@ public: | |||
| 138 | [[nodiscard]] Value Select(const U1& condition, const Value& true_value, | 128 | [[nodiscard]] Value Select(const U1& condition, const Value& true_value, |
| 139 | const Value& false_value); | 129 | const Value& false_value); |
| 140 | 130 | ||
| 141 | [[nodiscard]] void MemoryBarrier(BarrierInstInfo info); | 131 | [[nodiscard]] void MemoryBarrier(MemoryScope scope); |
| 142 | 132 | ||
| 143 | template <typename Dest, typename Source> | 133 | template <typename Dest, typename Source> |
| 144 | [[nodiscard]] Dest BitCast(const Source& value); | 134 | [[nodiscard]] Dest BitCast(const Source& value); |
diff --git a/src/shader_recompiler/frontend/ir/modifiers.h b/src/shader_recompiler/frontend/ir/modifiers.h index 7730c25a9..2aa4ac79b 100644 --- a/src/shader_recompiler/frontend/ir/modifiers.h +++ b/src/shader_recompiler/frontend/ir/modifiers.h | |||
| @@ -25,13 +25,7 @@ enum class FpRounding : u8 { | |||
| 25 | RZ, // Round towards zero | 25 | RZ, // Round towards zero |
| 26 | }; | 26 | }; |
| 27 | 27 | ||
| 28 | enum class MemoryScope : u32 { | 28 | enum class MemoryScope : u32 { DontCare, Warp, Workgroup, Device, System }; |
| 29 | DontCare, | ||
| 30 | Warp, | ||
| 31 | Workgroup, | ||
| 32 | Device, | ||
| 33 | System | ||
| 34 | }; | ||
| 35 | 29 | ||
| 36 | struct FpControl { | 30 | struct FpControl { |
| 37 | bool no_contraction{false}; | 31 | bool no_contraction{false}; |
| @@ -40,11 +34,6 @@ struct FpControl { | |||
| 40 | }; | 34 | }; |
| 41 | static_assert(sizeof(FpControl) <= sizeof(u32)); | 35 | static_assert(sizeof(FpControl) <= sizeof(u32)); |
| 42 | 36 | ||
| 43 | union BarrierInstInfo { | ||
| 44 | u32 raw; | ||
| 45 | BitField<0, 3, MemoryScope> scope; | ||
| 46 | }; | ||
| 47 | |||
| 48 | union TextureInstInfo { | 37 | union TextureInstInfo { |
| 49 | u32 raw; | 38 | u32 raw; |
| 50 | BitField<0, 8, TextureType> type; | 39 | BitField<0, 8, TextureType> type; |
diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc index 74e956930..3640a5d24 100644 --- a/src/shader_recompiler/frontend/ir/opcodes.inc +++ b/src/shader_recompiler/frontend/ir/opcodes.inc | |||
| @@ -17,7 +17,9 @@ OPCODE(Unreachable, Void, | |||
| 17 | OPCODE(DemoteToHelperInvocation, Void, Label, ) | 17 | OPCODE(DemoteToHelperInvocation, Void, Label, ) |
| 18 | 18 | ||
| 19 | // Barriers | 19 | // Barriers |
| 20 | OPCODE(MemoryBarrier, Void, ) | 20 | OPCODE(MemoryBarrierWorkgroupLevel, Void, ) |
| 21 | OPCODE(MemoryBarrierDeviceLevel, Void, ) | ||
| 22 | OPCODE(MemoryBarrierSystemLevel, Void, ) | ||
| 21 | 23 | ||
| 22 | // Special operations | 24 | // Special operations |
| 23 | OPCODE(Prologue, Void, ) | 25 | OPCODE(Prologue, Void, ) |
| @@ -49,18 +51,10 @@ OPCODE(GetZFlag, U1, Void | |||
| 49 | OPCODE(GetSFlag, U1, Void, ) | 51 | OPCODE(GetSFlag, U1, Void, ) |
| 50 | OPCODE(GetCFlag, U1, Void, ) | 52 | OPCODE(GetCFlag, U1, Void, ) |
| 51 | OPCODE(GetOFlag, U1, Void, ) | 53 | OPCODE(GetOFlag, U1, Void, ) |
| 52 | OPCODE(GetFCSMFlag, U1, Void, ) | ||
| 53 | OPCODE(GetTAFlag, U1, Void, ) | ||
| 54 | OPCODE(GetTRFlag, U1, Void, ) | ||
| 55 | OPCODE(GetMXFlag, U1, Void, ) | ||
| 56 | OPCODE(SetZFlag, Void, U1, ) | 54 | OPCODE(SetZFlag, Void, U1, ) |
| 57 | OPCODE(SetSFlag, Void, U1, ) | 55 | OPCODE(SetSFlag, Void, U1, ) |
| 58 | OPCODE(SetCFlag, Void, U1, ) | 56 | OPCODE(SetCFlag, Void, U1, ) |
| 59 | OPCODE(SetOFlag, Void, U1, ) | 57 | OPCODE(SetOFlag, Void, U1, ) |
| 60 | OPCODE(SetFCSMFlag, Void, U1, ) | ||
| 61 | OPCODE(SetTAFlag, Void, U1, ) | ||
| 62 | OPCODE(SetTRFlag, Void, U1, ) | ||
| 63 | OPCODE(SetMXFlag, Void, U1, ) | ||
| 64 | OPCODE(WorkgroupId, U32x3, ) | 58 | OPCODE(WorkgroupId, U32x3, ) |
| 65 | OPCODE(LocalInvocationId, U32x3, ) | 59 | OPCODE(LocalInvocationId, U32x3, ) |
| 66 | OPCODE(LaneId, U32, ) | 60 | OPCODE(LaneId, U32, ) |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/barrier_operations.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/barrier_operations.cpp index 933af572c..26d5e276b 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/barrier_operations.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/barrier_operations.cpp | |||
| @@ -5,8 +5,8 @@ | |||
| 5 | #include "common/bit_field.h" | 5 | #include "common/bit_field.h" |
| 6 | #include "common/common_types.h" | 6 | #include "common/common_types.h" |
| 7 | #include "shader_recompiler/frontend/ir/modifiers.h" | 7 | #include "shader_recompiler/frontend/ir/modifiers.h" |
| 8 | #include "shader_recompiler/frontend/maxwell/translate/impl/impl.h" | ||
| 9 | #include "shader_recompiler/frontend/maxwell/opcodes.h" | 8 | #include "shader_recompiler/frontend/maxwell/opcodes.h" |
| 9 | #include "shader_recompiler/frontend/maxwell/translate/impl/impl.h" | ||
| 10 | 10 | ||
| 11 | namespace Shader::Maxwell { | 11 | namespace Shader::Maxwell { |
| 12 | namespace { | 12 | namespace { |
| @@ -21,28 +21,24 @@ enum class LocalScope : u64 { | |||
| 21 | IR::MemoryScope LocalScopeToMemoryScope(LocalScope scope) { | 21 | IR::MemoryScope LocalScopeToMemoryScope(LocalScope scope) { |
| 22 | switch (scope) { | 22 | switch (scope) { |
| 23 | case LocalScope::CTG: | 23 | case LocalScope::CTG: |
| 24 | return IR::MemoryScope::Warp; | 24 | return IR::MemoryScope::Workgroup; |
| 25 | case LocalScope::GL: | 25 | case LocalScope::GL: |
| 26 | return IR::MemoryScope::Device; | 26 | return IR::MemoryScope::Device; |
| 27 | case LocalScope::SYS: | 27 | case LocalScope::SYS: |
| 28 | return IR::MemoryScope::System; | 28 | return IR::MemoryScope::System; |
| 29 | case LocalScope::VC: | ||
| 30 | return IR::MemoryScope::Workgroup; // or should be device? | ||
| 31 | default: | 29 | default: |
| 32 | throw NotImplementedException("Unimplemented Local Scope {}", scope); | 30 | throw NotImplementedException("Unimplemented Local Scope {}", scope); |
| 33 | } | 31 | } |
| 34 | } | 32 | } |
| 35 | 33 | ||
| 36 | } // namespace | 34 | } // Anonymous namespace |
| 37 | 35 | ||
| 38 | void TranslatorVisitor::MEMBAR(u64 inst) { | 36 | void TranslatorVisitor::MEMBAR(u64 inst) { |
| 39 | union { | 37 | union { |
| 40 | u64 raw; | 38 | u64 raw; |
| 41 | BitField<8, 2, LocalScope> scope; | 39 | BitField<8, 2, LocalScope> scope; |
| 42 | } membar{inst}; | 40 | } membar{inst}; |
| 43 | IR::BarrierInstInfo info{}; | 41 | ir.MemoryBarrier(LocalScopeToMemoryScope(membar.scope)); |
| 44 | info.scope.Assign(LocalScopeToMemoryScope(membar.scope)); | ||
| 45 | ir.MemoryBarrier(info); | ||
| 46 | } | 42 | } |
| 47 | 43 | ||
| 48 | void TranslatorVisitor::DEPBAR() { | 44 | void TranslatorVisitor::DEPBAR() { |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/move_special_register.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/move_special_register.cpp index 731ac643f..7d9c42a83 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/move_special_register.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/move_special_register.cpp | |||
| @@ -96,8 +96,10 @@ enum class SpecialRegister : u64 { | |||
| 96 | case SpecialRegister::SR_CTAID_Z: | 96 | case SpecialRegister::SR_CTAID_Z: |
| 97 | return ir.WorkgroupIdZ(); | 97 | return ir.WorkgroupIdZ(); |
| 98 | case SpecialRegister::SR_WSCALEFACTOR_XY: | 98 | case SpecialRegister::SR_WSCALEFACTOR_XY: |
| 99 | // LOG_WARNING(ShaderDecompiler, "SR_WSCALEFACTOR_XY (Stubbed)"); | ||
| 99 | return ir.Imm32(Common::BitCast<u32>(1.0f)); | 100 | return ir.Imm32(Common::BitCast<u32>(1.0f)); |
| 100 | case SpecialRegister::SR_WSCALEFACTOR_Z: | 101 | case SpecialRegister::SR_WSCALEFACTOR_Z: |
| 102 | // LOG_WARNING(ShaderDecompiler, "SR_WSCALEFACTOR_Z (Stubbed)"); | ||
| 101 | return ir.Imm32(Common::BitCast<u32>(1.0f)); | 103 | return ir.Imm32(Common::BitCast<u32>(1.0f)); |
| 102 | case SpecialRegister::SR_LANEID: | 104 | case SpecialRegister::SR_LANEID: |
| 103 | return ir.LaneId(); | 105 | return ir.LaneId(); |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/vote.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/vote.cpp index 2acabb662..d508e1e23 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/vote.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/vote.cpp | |||
| @@ -50,10 +50,7 @@ void TranslatorVisitor::VOTE(u64 insn) { | |||
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | void TranslatorVisitor::VOTE_vtg(u64) { | 52 | void TranslatorVisitor::VOTE_vtg(u64) { |
| 53 | // LOG_WARNING("VOTE.VTG: Stubbed!"); | 53 | // LOG_WARNING(ShaderDecompiler, "VOTE.VTG: Stubbed!"); |
| 54 | auto imm = ir.Imm1(false); | ||
| 55 | ir.SetFCSMFlag(imm); | ||
| 56 | ir.SetTRFlag(imm); | ||
| 57 | } | 54 | } |
| 58 | 55 | ||
| 59 | } // namespace Shader::Maxwell | 56 | } // namespace Shader::Maxwell |
diff --git a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp index 8999c3a3d..1720d7a09 100644 --- a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp +++ b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp | |||
| @@ -374,17 +374,14 @@ std::optional<IR::Value> FoldCompositeExtractImpl(IR::Value inst_value, IR::Opco | |||
| 374 | if (inst->Opcode() == construct) { | 374 | if (inst->Opcode() == construct) { |
| 375 | return inst->Arg(first_index); | 375 | return inst->Arg(first_index); |
| 376 | } | 376 | } |
| 377 | |||
| 378 | if (inst->Opcode() != insert) { | 377 | if (inst->Opcode() != insert) { |
| 379 | return std::nullopt; | 378 | return std::nullopt; |
| 380 | } | 379 | } |
| 381 | |||
| 382 | IR::Value value_index{inst->Arg(2)}; | 380 | IR::Value value_index{inst->Arg(2)}; |
| 383 | if (!value_index.IsImmediate()) { | 381 | if (!value_index.IsImmediate()) { |
| 384 | return std::nullopt; | 382 | return std::nullopt; |
| 385 | } | 383 | } |
| 386 | 384 | const u32 second_index{value_index.U32()}; | |
| 387 | const u32 second_index = value_index.U32(); | ||
| 388 | if (first_index != second_index) { | 385 | if (first_index != second_index) { |
| 389 | IR::Value value_composite{inst->Arg(0)}; | 386 | IR::Value value_composite{inst->Arg(0)}; |
| 390 | if (value_composite.IsImmediate()) { | 387 | if (value_composite.IsImmediate()) { |
| @@ -404,8 +401,8 @@ void FoldCompositeExtract(IR::Inst& inst, IR::Opcode construct, IR::Opcode inser | |||
| 404 | if (!value_2.IsImmediate()) { | 401 | if (!value_2.IsImmediate()) { |
| 405 | return; | 402 | return; |
| 406 | } | 403 | } |
| 407 | const u32 first_index = value_2.U32(); | 404 | const u32 first_index{value_2.U32()}; |
| 408 | auto result = FoldCompositeExtractImpl(value_1, insert, construct, first_index); | 405 | const std::optional result{FoldCompositeExtractImpl(value_1, insert, construct, first_index)}; |
| 409 | if (!result) { | 406 | if (!result) { |
| 410 | return; | 407 | return; |
| 411 | } | 408 | } |
diff --git a/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp b/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp index d4bae249b..8876a5c33 100644 --- a/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp +++ b/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp | |||
| @@ -4,9 +4,9 @@ | |||
| 4 | 4 | ||
| 5 | #include <algorithm> | 5 | #include <algorithm> |
| 6 | #include <compare> | 6 | #include <compare> |
| 7 | #include <map> | ||
| 7 | #include <optional> | 8 | #include <optional> |
| 8 | #include <ranges> | 9 | #include <ranges> |
| 9 | #include <map> | ||
| 10 | 10 | ||
| 11 | #include <boost/container/flat_set.hpp> | 11 | #include <boost/container/flat_set.hpp> |
| 12 | #include <boost/container/small_vector.hpp> | 12 | #include <boost/container/small_vector.hpp> |
| @@ -295,12 +295,12 @@ void CollectStorageBuffers(IR::Block& block, IR::Inst& inst, StorageBufferSet& s | |||
| 295 | } | 295 | } |
| 296 | } | 296 | } |
| 297 | // Collect storage buffer and the instruction | 297 | // Collect storage buffer and the instruction |
| 298 | const bool is_a_write = IsGlobalMemoryWrite(inst); | 298 | const bool is_a_write{IsGlobalMemoryWrite(inst)}; |
| 299 | auto it = writes_map.find(*storage_buffer); | 299 | auto it{writes_map.find(*storage_buffer)}; |
| 300 | if (it == writes_map.end()) { | 300 | if (it == writes_map.end()) { |
| 301 | writes_map[*storage_buffer] = is_a_write; | 301 | writes_map[*storage_buffer] = is_a_write; |
| 302 | } else { | 302 | } else { |
| 303 | it->second = it->second || is_a_write; | 303 | it->second = it->second || is_a_write; |
| 304 | } | 304 | } |
| 305 | storage_buffer_set.insert(*storage_buffer); | 305 | storage_buffer_set.insert(*storage_buffer); |
| 306 | to_replace.push_back(StorageInst{ | 306 | to_replace.push_back(StorageInst{ |
diff --git a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp index 7dab33034..72d4abb77 100644 --- a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp +++ b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp | |||
| @@ -38,10 +38,6 @@ struct ZeroFlagTag : FlagTag {}; | |||
| 38 | struct SignFlagTag : FlagTag {}; | 38 | struct SignFlagTag : FlagTag {}; |
| 39 | struct CarryFlagTag : FlagTag {}; | 39 | struct CarryFlagTag : FlagTag {}; |
| 40 | struct OverflowFlagTag : FlagTag {}; | 40 | struct OverflowFlagTag : FlagTag {}; |
| 41 | struct FCSMFlagTag : FlagTag {}; | ||
| 42 | struct TAFlagTag : FlagTag {}; | ||
| 43 | struct TRFlagTag : FlagTag {}; | ||
| 44 | struct MXFlagTag : FlagTag {}; | ||
| 45 | 41 | ||
| 46 | struct GotoVariable : FlagTag { | 42 | struct GotoVariable : FlagTag { |
| 47 | GotoVariable() = default; | 43 | GotoVariable() = default; |
| @@ -57,8 +53,7 @@ struct IndirectBranchVariable { | |||
| 57 | }; | 53 | }; |
| 58 | 54 | ||
| 59 | using Variant = std::variant<IR::Reg, IR::Pred, ZeroFlagTag, SignFlagTag, CarryFlagTag, | 55 | using Variant = std::variant<IR::Reg, IR::Pred, ZeroFlagTag, SignFlagTag, CarryFlagTag, |
| 60 | OverflowFlagTag, FCSMFlagTag, TAFlagTag, TRFlagTag, MXFlagTag, | 56 | OverflowFlagTag, GotoVariable, IndirectBranchVariable>; |
| 61 | GotoVariable, IndirectBranchVariable>; | ||
| 62 | using ValueMap = boost::container::flat_map<IR::Block*, IR::Value, std::less<IR::Block*>>; | 57 | using ValueMap = boost::container::flat_map<IR::Block*, IR::Value, std::less<IR::Block*>>; |
| 63 | 58 | ||
| 64 | struct DefTable { | 59 | struct DefTable { |
| @@ -94,22 +89,6 @@ struct DefTable { | |||
| 94 | return overflow_flag; | 89 | return overflow_flag; |
| 95 | } | 90 | } |
| 96 | 91 | ||
| 97 | [[nodiscard]] ValueMap& operator[](FCSMFlagTag) noexcept { | ||
| 98 | return fcsm_flag; | ||
| 99 | } | ||
| 100 | |||
| 101 | [[nodiscard]] ValueMap& operator[](TAFlagTag) noexcept { | ||
| 102 | return ta_flag; | ||
| 103 | } | ||
| 104 | |||
| 105 | [[nodiscard]] ValueMap& operator[](TRFlagTag) noexcept { | ||
| 106 | return tr_flag; | ||
| 107 | } | ||
| 108 | |||
| 109 | [[nodiscard]] ValueMap& operator[](MXFlagTag) noexcept { | ||
| 110 | return mr_flag; | ||
| 111 | } | ||
| 112 | |||
| 113 | std::array<ValueMap, IR::NUM_USER_REGS> regs; | 92 | std::array<ValueMap, IR::NUM_USER_REGS> regs; |
| 114 | std::array<ValueMap, IR::NUM_USER_PREDS> preds; | 93 | std::array<ValueMap, IR::NUM_USER_PREDS> preds; |
| 115 | boost::container::flat_map<u32, ValueMap> goto_vars; | 94 | boost::container::flat_map<u32, ValueMap> goto_vars; |
| @@ -118,10 +97,6 @@ struct DefTable { | |||
| 118 | ValueMap sign_flag; | 97 | ValueMap sign_flag; |
| 119 | ValueMap carry_flag; | 98 | ValueMap carry_flag; |
| 120 | ValueMap overflow_flag; | 99 | ValueMap overflow_flag; |
| 121 | ValueMap fcsm_flag; | ||
| 122 | ValueMap ta_flag; | ||
| 123 | ValueMap tr_flag; | ||
| 124 | ValueMap mr_flag; | ||
| 125 | }; | 100 | }; |
| 126 | 101 | ||
| 127 | IR::Opcode UndefOpcode(IR::Reg) noexcept { | 102 | IR::Opcode UndefOpcode(IR::Reg) noexcept { |
| @@ -272,18 +247,6 @@ void VisitInst(Pass& pass, IR::Block* block, IR::Inst& inst) { | |||
| 272 | case IR::Opcode::SetOFlag: | 247 | case IR::Opcode::SetOFlag: |
| 273 | pass.WriteVariable(OverflowFlagTag{}, block, inst.Arg(0)); | 248 | pass.WriteVariable(OverflowFlagTag{}, block, inst.Arg(0)); |
| 274 | break; | 249 | break; |
| 275 | case IR::Opcode::SetFCSMFlag: | ||
| 276 | pass.WriteVariable(FCSMFlagTag{}, block, inst.Arg(0)); | ||
| 277 | break; | ||
| 278 | case IR::Opcode::SetTAFlag: | ||
| 279 | pass.WriteVariable(TAFlagTag{}, block, inst.Arg(0)); | ||
| 280 | break; | ||
| 281 | case IR::Opcode::SetTRFlag: | ||
| 282 | pass.WriteVariable(TRFlagTag{}, block, inst.Arg(0)); | ||
| 283 | break; | ||
| 284 | case IR::Opcode::SetMXFlag: | ||
| 285 | pass.WriteVariable(MXFlagTag{}, block, inst.Arg(0)); | ||
| 286 | break; | ||
| 287 | case IR::Opcode::GetRegister: | 250 | case IR::Opcode::GetRegister: |
| 288 | if (const IR::Reg reg{inst.Arg(0).Reg()}; reg != IR::Reg::RZ) { | 251 | if (const IR::Reg reg{inst.Arg(0).Reg()}; reg != IR::Reg::RZ) { |
| 289 | inst.ReplaceUsesWith(pass.ReadVariable(reg, block)); | 252 | inst.ReplaceUsesWith(pass.ReadVariable(reg, block)); |
| @@ -312,17 +275,6 @@ void VisitInst(Pass& pass, IR::Block* block, IR::Inst& inst) { | |||
| 312 | case IR::Opcode::GetOFlag: | 275 | case IR::Opcode::GetOFlag: |
| 313 | inst.ReplaceUsesWith(pass.ReadVariable(OverflowFlagTag{}, block)); | 276 | inst.ReplaceUsesWith(pass.ReadVariable(OverflowFlagTag{}, block)); |
| 314 | break; | 277 | break; |
| 315 | case IR::Opcode::GetFCSMFlag: | ||
| 316 | inst.ReplaceUsesWith(pass.ReadVariable(FCSMFlagTag{}, block)); | ||
| 317 | break; | ||
| 318 | case IR::Opcode::GetTAFlag: | ||
| 319 | inst.ReplaceUsesWith(pass.ReadVariable(TAFlagTag{}, block)); | ||
| 320 | break; | ||
| 321 | case IR::Opcode::GetTRFlag: | ||
| 322 | inst.ReplaceUsesWith(pass.ReadVariable(TRFlagTag{}, block)); | ||
| 323 | break; | ||
| 324 | case IR::Opcode::GetMXFlag: | ||
| 325 | inst.ReplaceUsesWith(pass.ReadVariable(MXFlagTag{}, block)); | ||
| 326 | break; | 278 | break; |
| 327 | default: | 279 | default: |
| 328 | break; | 280 | break; |