diff options
Diffstat (limited to 'src/shader_recompiler/backend/glasm')
7 files changed, 43 insertions, 1 deletions
diff --git a/src/shader_recompiler/backend/glasm/emit_context.cpp b/src/shader_recompiler/backend/glasm/emit_context.cpp index 069c019ad..8fd459dfe 100644 --- a/src/shader_recompiler/backend/glasm/emit_context.cpp +++ b/src/shader_recompiler/backend/glasm/emit_context.cpp | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #include "shader_recompiler/backend/bindings.h" | 7 | #include "shader_recompiler/backend/bindings.h" |
| 8 | #include "shader_recompiler/backend/glasm/emit_context.h" | 8 | #include "shader_recompiler/backend/glasm/emit_context.h" |
| 9 | #include "shader_recompiler/backend/glasm/emit_glasm.h" | ||
| 9 | #include "shader_recompiler/frontend/ir/program.h" | 10 | #include "shader_recompiler/frontend/ir/program.h" |
| 10 | #include "shader_recompiler/profile.h" | 11 | #include "shader_recompiler/profile.h" |
| 11 | #include "shader_recompiler/runtime_info.h" | 12 | #include "shader_recompiler/runtime_info.h" |
| @@ -55,7 +56,8 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile | |||
| 55 | } | 56 | } |
| 56 | if (!runtime_info.glasm_use_storage_buffers) { | 57 | if (!runtime_info.glasm_use_storage_buffers) { |
| 57 | if (const size_t num = info.storage_buffers_descriptors.size(); num > 0) { | 58 | if (const size_t num = info.storage_buffers_descriptors.size(); num > 0) { |
| 58 | Add("PARAM c[{}]={{program.local[0..{}]}};", num, num - 1); | 59 | const size_t index{num + PROGRAM_LOCAL_PARAMETER_STORAGE_BUFFER_BASE}; |
| 60 | Add("PARAM c[{}]={{program.local[0..{}]}};", index, index - 1); | ||
| 59 | } | 61 | } |
| 60 | } | 62 | } |
| 61 | stage = program.stage; | 63 | stage = program.stage; |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm.cpp b/src/shader_recompiler/backend/glasm/emit_glasm.cpp index 4ce1c4f54..004658546 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm.cpp | |||
| @@ -448,6 +448,9 @@ std::string EmitGLASM(const Profile& profile, const RuntimeInfo& runtime_info, I | |||
| 448 | header += fmt::format("SHARED_MEMORY {};", program.shared_memory_size); | 448 | header += fmt::format("SHARED_MEMORY {};", program.shared_memory_size); |
| 449 | header += fmt::format("SHARED shared_mem[]={{program.sharedmem}};"); | 449 | header += fmt::format("SHARED shared_mem[]={{program.sharedmem}};"); |
| 450 | } | 450 | } |
| 451 | if (program.info.uses_rescaling_uniform) { | ||
| 452 | header += "PARAM scaling[1]={program.local[0..0]};"; | ||
| 453 | } | ||
| 451 | header += "TEMP "; | 454 | header += "TEMP "; |
| 452 | for (size_t index = 0; index < ctx.reg_alloc.NumUsedRegisters(); ++index) { | 455 | for (size_t index = 0; index < ctx.reg_alloc.NumUsedRegisters(); ++index) { |
| 453 | header += fmt::format("R{},", index); | 456 | header += fmt::format("R{},", index); |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm.h b/src/shader_recompiler/backend/glasm/emit_glasm.h index bcb55f062..292655acb 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm.h +++ b/src/shader_recompiler/backend/glasm/emit_glasm.h | |||
| @@ -13,6 +13,8 @@ | |||
| 13 | 13 | ||
| 14 | namespace Shader::Backend::GLASM { | 14 | namespace Shader::Backend::GLASM { |
| 15 | 15 | ||
| 16 | constexpr u32 PROGRAM_LOCAL_PARAMETER_STORAGE_BUFFER_BASE = 1; | ||
| 17 | |||
| 16 | [[nodiscard]] std::string EmitGLASM(const Profile& profile, const RuntimeInfo& runtime_info, | 18 | [[nodiscard]] std::string EmitGLASM(const Profile& profile, const RuntimeInfo& runtime_info, |
| 17 | IR::Program& program, Bindings& bindings); | 19 | IR::Program& program, Bindings& bindings); |
| 18 | 20 | ||
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp index 09e3a9b82..d325d31c7 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp | |||
| @@ -608,6 +608,24 @@ void EmitImageWrite(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, Re | |||
| 608 | ctx.Add("STOREIM.{} {},{},{},{};", format, image, color, coord, type); | 608 | ctx.Add("STOREIM.{} {},{},{},{};", format, image, color, coord, type); |
| 609 | } | 609 | } |
| 610 | 610 | ||
| 611 | void EmitIsTextureScaled(EmitContext& ctx, IR::Inst& inst, const IR::Value& index) { | ||
| 612 | if (!index.IsImmediate()) { | ||
| 613 | throw NotImplementedException("Non-constant texture rescaling"); | ||
| 614 | } | ||
| 615 | ctx.Add("AND.U RC.x,scaling[0].x,{};" | ||
| 616 | "SNE.S {},RC.x,0;", | ||
| 617 | 1u << index.U32(), ctx.reg_alloc.Define(inst)); | ||
| 618 | } | ||
| 619 | |||
| 620 | void EmitIsImageScaled(EmitContext& ctx, IR::Inst& inst, const IR::Value& index) { | ||
| 621 | if (!index.IsImmediate()) { | ||
| 622 | throw NotImplementedException("Non-constant texture rescaling"); | ||
| 623 | } | ||
| 624 | ctx.Add("AND.U RC.x,scaling[0].y,{};" | ||
| 625 | "SNE.S {},RC.x,0;", | ||
| 626 | 1u << index.U32(), ctx.reg_alloc.Define(inst)); | ||
| 627 | } | ||
| 628 | |||
| 611 | void EmitImageAtomicIAdd32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, Register coord, | 629 | void EmitImageAtomicIAdd32(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, Register coord, |
| 612 | ScalarU32 value) { | 630 | ScalarU32 value) { |
| 613 | ImageAtomic(ctx, inst, index, coord, value, "ADD.U32"); | 631 | ImageAtomic(ctx, inst, index, coord, value, "ADD.U32"); |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h b/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h index 12afda43b..1f343bff5 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h +++ b/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h | |||
| @@ -72,6 +72,7 @@ void EmitInvocationId(EmitContext& ctx, IR::Inst& inst); | |||
| 72 | void EmitSampleId(EmitContext& ctx, IR::Inst& inst); | 72 | void EmitSampleId(EmitContext& ctx, IR::Inst& inst); |
| 73 | void EmitIsHelperInvocation(EmitContext& ctx, IR::Inst& inst); | 73 | void EmitIsHelperInvocation(EmitContext& ctx, IR::Inst& inst); |
| 74 | void EmitYDirection(EmitContext& ctx, IR::Inst& inst); | 74 | void EmitYDirection(EmitContext& ctx, IR::Inst& inst); |
| 75 | void EmitResolutionDownFactor(EmitContext& ctx, IR::Inst& inst); | ||
| 75 | void EmitLoadLocal(EmitContext& ctx, IR::Inst& inst, ScalarU32 word_offset); | 76 | void EmitLoadLocal(EmitContext& ctx, IR::Inst& inst, ScalarU32 word_offset); |
| 76 | void EmitWriteLocal(EmitContext& ctx, ScalarU32 word_offset, ScalarU32 value); | 77 | void EmitWriteLocal(EmitContext& ctx, ScalarU32 word_offset, ScalarU32 value); |
| 77 | void EmitUndefU1(EmitContext& ctx, IR::Inst& inst); | 78 | void EmitUndefU1(EmitContext& ctx, IR::Inst& inst); |
| @@ -303,6 +304,8 @@ void EmitIAdd64(EmitContext& ctx, IR::Inst& inst, Register a, Register b); | |||
| 303 | void EmitISub32(EmitContext& ctx, IR::Inst& inst, ScalarS32 a, ScalarS32 b); | 304 | void EmitISub32(EmitContext& ctx, IR::Inst& inst, ScalarS32 a, ScalarS32 b); |
| 304 | void EmitISub64(EmitContext& ctx, IR::Inst& inst, Register a, Register b); | 305 | void EmitISub64(EmitContext& ctx, IR::Inst& inst, Register a, Register b); |
| 305 | void EmitIMul32(EmitContext& ctx, IR::Inst& inst, ScalarS32 a, ScalarS32 b); | 306 | void EmitIMul32(EmitContext& ctx, IR::Inst& inst, ScalarS32 a, ScalarS32 b); |
| 307 | void EmitSDiv32(EmitContext& ctx, IR::Inst& inst, ScalarS32 a, ScalarS32 b); | ||
| 308 | void EmitUDiv32(EmitContext& ctx, IR::Inst& inst, ScalarU32 a, ScalarU32 b); | ||
| 306 | void EmitINeg32(EmitContext& ctx, IR::Inst& inst, ScalarS32 value); | 309 | void EmitINeg32(EmitContext& ctx, IR::Inst& inst, ScalarS32 value); |
| 307 | void EmitINeg64(EmitContext& ctx, IR::Inst& inst, Register value); | 310 | void EmitINeg64(EmitContext& ctx, IR::Inst& inst, Register value); |
| 308 | void EmitIAbs32(EmitContext& ctx, IR::Inst& inst, ScalarS32 value); | 311 | void EmitIAbs32(EmitContext& ctx, IR::Inst& inst, ScalarS32 value); |
| @@ -553,6 +556,8 @@ void EmitImageGradient(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, | |||
| 553 | void EmitImageRead(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, Register coord); | 556 | void EmitImageRead(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, Register coord); |
| 554 | void EmitImageWrite(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, Register coord, | 557 | void EmitImageWrite(EmitContext& ctx, IR::Inst& inst, const IR::Value& index, Register coord, |
| 555 | Register color); | 558 | Register color); |
| 559 | void EmitIsTextureScaled(EmitContext& ctx, IR::Inst& inst, const IR::Value& index); | ||
| 560 | void EmitIsImageScaled(EmitContext& ctx, IR::Inst& inst, const IR::Value& index); | ||
| 556 | void EmitBindlessImageAtomicIAdd32(EmitContext&); | 561 | void EmitBindlessImageAtomicIAdd32(EmitContext&); |
| 557 | void EmitBindlessImageAtomicSMin32(EmitContext&); | 562 | void EmitBindlessImageAtomicSMin32(EmitContext&); |
| 558 | void EmitBindlessImageAtomicUMin32(EmitContext&); | 563 | void EmitBindlessImageAtomicUMin32(EmitContext&); |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_integer.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_integer.cpp index f55c26b76..8aa494a4d 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_integer.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_integer.cpp | |||
| @@ -90,6 +90,14 @@ void EmitIMul32(EmitContext& ctx, IR::Inst& inst, ScalarS32 a, ScalarS32 b) { | |||
| 90 | ctx.Add("MUL.S {}.x,{},{};", inst, a, b); | 90 | ctx.Add("MUL.S {}.x,{},{};", inst, a, b); |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | void EmitSDiv32(EmitContext& ctx, IR::Inst& inst, ScalarS32 a, ScalarS32 b) { | ||
| 94 | ctx.Add("DIV.S {}.x,{},{};", inst, a, b); | ||
| 95 | } | ||
| 96 | |||
| 97 | void EmitUDiv32(EmitContext& ctx, IR::Inst& inst, ScalarU32 a, ScalarU32 b) { | ||
| 98 | ctx.Add("DIV.U {}.x,{},{};", inst, a, b); | ||
| 99 | } | ||
| 100 | |||
| 93 | void EmitINeg32(EmitContext& ctx, IR::Inst& inst, ScalarS32 value) { | 101 | void EmitINeg32(EmitContext& ctx, IR::Inst& inst, ScalarS32 value) { |
| 94 | if (value.type != Type::Register && static_cast<s32>(value.imm_u32) < 0) { | 102 | if (value.type != Type::Register && static_cast<s32>(value.imm_u32) < 0) { |
| 95 | ctx.Add("MOV.S {},{};", inst, -static_cast<s32>(value.imm_u32)); | 103 | ctx.Add("MOV.S {},{};", inst, -static_cast<s32>(value.imm_u32)); |
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp index e537f6073..681aeda8d 100644 --- a/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp +++ b/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp | |||
| @@ -210,6 +210,10 @@ void EmitYDirection(EmitContext& ctx, IR::Inst& inst) { | |||
| 210 | ctx.Add("MOV.F {}.x,y_direction[0].w;", inst); | 210 | ctx.Add("MOV.F {}.x,y_direction[0].w;", inst); |
| 211 | } | 211 | } |
| 212 | 212 | ||
| 213 | void EmitResolutionDownFactor(EmitContext& ctx, IR::Inst& inst) { | ||
| 214 | ctx.Add("MOV.F {}.x,scaling[0].z;", inst); | ||
| 215 | } | ||
| 216 | |||
| 213 | void EmitUndefU1(EmitContext& ctx, IR::Inst& inst) { | 217 | void EmitUndefU1(EmitContext& ctx, IR::Inst& inst) { |
| 214 | ctx.Add("MOV.S {}.x,0;", inst); | 218 | ctx.Add("MOV.S {}.x,0;", inst); |
| 215 | } | 219 | } |