diff options
| author | 2021-05-28 21:24:52 -0400 | |
|---|---|---|
| committer | 2021-07-22 21:51:36 -0400 | |
| commit | 8ba814efb295f0b8494b3679c484c7ceab31c392 (patch) | |
| tree | 7c81176bc12ea7b99309d2748e03c61aa2bf64b8 /src/shader_recompiler/backend/glsl | |
| parent | glsl: Fix integer conversions, implement clamp CC (diff) | |
| download | yuzu-8ba814efb295f0b8494b3679c484c7ceab31c392.tar.gz yuzu-8ba814efb295f0b8494b3679c484c7ceab31c392.tar.xz yuzu-8ba814efb295f0b8494b3679c484c7ceab31c392.zip | |
glsl: Better Storage access and wip warps
Diffstat (limited to 'src/shader_recompiler/backend/glsl')
8 files changed, 133 insertions, 62 deletions
diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp index 3530e89e5..db62ba73b 100644 --- a/src/shader_recompiler/backend/glsl/emit_context.cpp +++ b/src/shader_recompiler/backend/glsl/emit_context.cpp | |||
| @@ -122,6 +122,10 @@ void EmitContext::SetupExtensions(std::string&) { | |||
| 122 | header += "#extension GL_AMD_gpu_shader_half_float : enable\n"; | 122 | header += "#extension GL_AMD_gpu_shader_half_float : enable\n"; |
| 123 | } | 123 | } |
| 124 | } | 124 | } |
| 125 | if (info.uses_subgroup_invocation_id || info.uses_subgroup_mask || info.uses_subgroup_vote || | ||
| 126 | info.uses_subgroup_shuffles || info.uses_fswzadd) { | ||
| 127 | header += "#extension GL_ARB_shader_ballot : enable\n"; | ||
| 128 | } | ||
| 125 | } | 129 | } |
| 126 | 130 | ||
| 127 | void EmitContext::DefineConstantBuffers(Bindings& bindings) { | 131 | void EmitContext::DefineConstantBuffers(Bindings& bindings) { |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl.cpp b/src/shader_recompiler/backend/glsl/emit_glsl.cpp index 992e4b82e..800de58b7 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl.cpp | |||
| @@ -183,8 +183,11 @@ std::string EmitGLSL(const Profile& profile, const RuntimeInfo& runtime_info, IR | |||
| 183 | for (size_t index = 0; index < ctx.reg_alloc.num_used_registers; ++index) { | 183 | for (size_t index = 0; index < ctx.reg_alloc.num_used_registers; ++index) { |
| 184 | ctx.header += fmt::format("{} R{};", ctx.reg_alloc.reg_types[index], index); | 184 | ctx.header += fmt::format("{} R{};", ctx.reg_alloc.reg_types[index], index); |
| 185 | } | 185 | } |
| 186 | // TODO: track CC usage | 186 | // TODO: track usage |
| 187 | ctx.header += "uint carry;"; | 187 | ctx.header += "uint carry;"; |
| 188 | if (program.info.uses_subgroup_shuffles) { | ||
| 189 | ctx.header += "bool shfl_in_bounds;\n"; | ||
| 190 | } | ||
| 188 | ctx.code.insert(0, ctx.header); | 191 | ctx.code.insert(0, ctx.header); |
| 189 | ctx.code += "}"; | 192 | ctx.code += "}"; |
| 190 | fmt::print("\n{}\n", ctx.code); | 193 | fmt::print("\n{}\n", ctx.code); |
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 67d308c49..2286177a7 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 | |||
| @@ -20,22 +20,26 @@ char OffsetSwizzle(u32 offset) { | |||
| 20 | } | 20 | } |
| 21 | } // namespace | 21 | } // namespace |
| 22 | 22 | ||
| 23 | void EmitGetCbufU8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] const IR::Value& binding, | 23 | void EmitGetCbufU8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, |
| 24 | [[maybe_unused]] const IR::Value& binding, | ||
| 24 | [[maybe_unused]] const IR::Value& offset) { | 25 | [[maybe_unused]] const IR::Value& offset) { |
| 25 | throw NotImplementedException("GLSL"); | 26 | throw NotImplementedException("GLSL"); |
| 26 | } | 27 | } |
| 27 | 28 | ||
| 28 | void EmitGetCbufS8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] const IR::Value& binding, | 29 | void EmitGetCbufS8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, |
| 30 | [[maybe_unused]] const IR::Value& binding, | ||
| 29 | [[maybe_unused]] const IR::Value& offset) { | 31 | [[maybe_unused]] const IR::Value& offset) { |
| 30 | throw NotImplementedException("GLSL"); | 32 | throw NotImplementedException("GLSL"); |
| 31 | } | 33 | } |
| 32 | 34 | ||
| 33 | void EmitGetCbufU16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] const IR::Value& binding, | 35 | void EmitGetCbufU16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, |
| 36 | [[maybe_unused]] const IR::Value& binding, | ||
| 34 | [[maybe_unused]] const IR::Value& offset) { | 37 | [[maybe_unused]] const IR::Value& offset) { |
| 35 | throw NotImplementedException("GLSL"); | 38 | throw NotImplementedException("GLSL"); |
| 36 | } | 39 | } |
| 37 | 40 | ||
| 38 | void EmitGetCbufS16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] const IR::Value& binding, | 41 | void EmitGetCbufS16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, |
| 42 | [[maybe_unused]] const IR::Value& binding, | ||
| 39 | [[maybe_unused]] const IR::Value& offset) { | 43 | [[maybe_unused]] const IR::Value& offset) { |
| 40 | throw NotImplementedException("GLSL"); | 44 | throw NotImplementedException("GLSL"); |
| 41 | } | 45 | } |
| @@ -151,4 +155,8 @@ void EmitSetFragColor(EmitContext& ctx, u32 index, u32 component, std::string_vi | |||
| 151 | ctx.Add("frag_color{}.{}={};", index, swizzle, value); | 155 | ctx.Add("frag_color{}.{}={};", index, swizzle, value); |
| 152 | } | 156 | } |
| 153 | 157 | ||
| 158 | void EmitLocalInvocationId(EmitContext& ctx, IR::Inst& inst) { | ||
| 159 | ctx.AddU32x3("{}=gl_LocalInvocationID;", inst); | ||
| 160 | } | ||
| 161 | |||
| 154 | } // namespace Shader::Backend::GLSL | 162 | } // namespace Shader::Backend::GLSL |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h b/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h index b54fe684e..07408d9e9 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h +++ b/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h | |||
| @@ -52,10 +52,14 @@ void EmitSetGotoVariable(EmitContext& ctx); | |||
| 52 | void EmitGetGotoVariable(EmitContext& ctx); | 52 | void EmitGetGotoVariable(EmitContext& ctx); |
| 53 | void EmitSetIndirectBranchVariable(EmitContext& ctx); | 53 | void EmitSetIndirectBranchVariable(EmitContext& ctx); |
| 54 | void EmitGetIndirectBranchVariable(EmitContext& ctx); | 54 | void EmitGetIndirectBranchVariable(EmitContext& ctx); |
| 55 | void EmitGetCbufU8(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset); | 55 | void EmitGetCbufU8(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 56 | void EmitGetCbufS8(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset); | 56 | const IR::Value& offset); |
| 57 | void EmitGetCbufU16(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset); | 57 | void EmitGetCbufS8(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 58 | void EmitGetCbufS16(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset); | 58 | const IR::Value& offset); |
| 59 | void EmitGetCbufU16(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | ||
| 60 | const IR::Value& offset); | ||
| 61 | void EmitGetCbufS16(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | ||
| 62 | const IR::Value& offset); | ||
| 59 | void EmitGetCbufU32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 63 | void EmitGetCbufU32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 60 | const IR::Value& offset); | 64 | const IR::Value& offset); |
| 61 | void EmitGetCbufF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 65 | void EmitGetCbufF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| @@ -83,7 +87,7 @@ void EmitSetSFlag(EmitContext& ctx); | |||
| 83 | void EmitSetCFlag(EmitContext& ctx); | 87 | void EmitSetCFlag(EmitContext& ctx); |
| 84 | void EmitSetOFlag(EmitContext& ctx); | 88 | void EmitSetOFlag(EmitContext& ctx); |
| 85 | void EmitWorkgroupId(EmitContext& ctx); | 89 | void EmitWorkgroupId(EmitContext& ctx); |
| 86 | void EmitLocalInvocationId(EmitContext& ctx); | 90 | void EmitLocalInvocationId(EmitContext& ctx, IR::Inst& inst); |
| 87 | void EmitInvocationId(EmitContext& ctx); | 91 | void EmitInvocationId(EmitContext& ctx); |
| 88 | void EmitSampleId(EmitContext& ctx); | 92 | void EmitSampleId(EmitContext& ctx); |
| 89 | void EmitIsHelperInvocation(EmitContext& ctx); | 93 | void EmitIsHelperInvocation(EmitContext& ctx); |
| @@ -109,10 +113,14 @@ void EmitWriteGlobalS16(EmitContext& ctx); | |||
| 109 | void EmitWriteGlobal32(EmitContext& ctx, std::string_view address, std::string_view value); | 113 | void EmitWriteGlobal32(EmitContext& ctx, std::string_view address, std::string_view value); |
| 110 | void EmitWriteGlobal64(EmitContext& ctx, std::string_view address, std::string_view value); | 114 | void EmitWriteGlobal64(EmitContext& ctx, std::string_view address, std::string_view value); |
| 111 | void EmitWriteGlobal128(EmitContext& ctx, std::string_view address, std::string_view value); | 115 | void EmitWriteGlobal128(EmitContext& ctx, std::string_view address, std::string_view value); |
| 112 | void EmitLoadStorageU8(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset); | 116 | void EmitLoadStorageU8(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 113 | void EmitLoadStorageS8(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset); | 117 | const IR::Value& offset); |
| 114 | void EmitLoadStorageU16(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset); | 118 | void EmitLoadStorageS8(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 115 | void EmitLoadStorageS16(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset); | 119 | const IR::Value& offset); |
| 120 | void EmitLoadStorageU16(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | ||
| 121 | const IR::Value& offset); | ||
| 122 | void EmitLoadStorageS16(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | ||
| 123 | const IR::Value& offset); | ||
| 116 | void EmitLoadStorage32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 124 | void EmitLoadStorage32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 117 | const IR::Value& offset); | 125 | const IR::Value& offset); |
| 118 | void EmitLoadStorage64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 126 | void EmitLoadStorage64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_integer.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_integer.cpp index 34f880f1b..07e1a4b51 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_integer.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_integer.cpp | |||
| @@ -156,12 +156,12 @@ void EmitBitwiseNot32(EmitContext& ctx, IR::Inst& inst, std::string_view value) | |||
| 156 | 156 | ||
| 157 | void EmitFindSMsb32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 157 | void EmitFindSMsb32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, |
| 158 | [[maybe_unused]] std::string_view value) { | 158 | [[maybe_unused]] std::string_view value) { |
| 159 | throw NotImplementedException("GLSL Instruction"); | 159 | ctx.AddU32("{}=findMSB(int({}));", inst, value); |
| 160 | } | 160 | } |
| 161 | 161 | ||
| 162 | void EmitFindUMsb32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 162 | void EmitFindUMsb32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, |
| 163 | [[maybe_unused]] std::string_view value) { | 163 | [[maybe_unused]] std::string_view value) { |
| 164 | throw NotImplementedException("GLSL Instruction"); | 164 | ctx.AddU32("{}=findMSB(uint({}));", inst, value); |
| 165 | } | 165 | } |
| 166 | 166 | ||
| 167 | void EmitSMin32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { | 167 | void EmitSMin32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_memory.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_memory.cpp index 708c9685b..09ad35e44 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_memory.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_memory.cpp | |||
| @@ -8,45 +8,55 @@ | |||
| 8 | #include "shader_recompiler/frontend/ir/value.h" | 8 | #include "shader_recompiler/frontend/ir/value.h" |
| 9 | 9 | ||
| 10 | namespace Shader::Backend::GLSL { | 10 | namespace Shader::Backend::GLSL { |
| 11 | void EmitLoadStorageU8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] const IR::Value& binding, | 11 | void EmitLoadStorageU8([[maybe_unused]] EmitContext& ctx, IR::Inst& inst, |
| 12 | [[maybe_unused]] const IR::Value& binding, | ||
| 12 | [[maybe_unused]] const IR::Value& offset) { | 13 | [[maybe_unused]] const IR::Value& offset) { |
| 13 | throw NotImplementedException("GLSL Instrucion"); | 14 | const auto offset_var{ctx.reg_alloc.Consume(offset)}; |
| 15 | ctx.AddU32("{}=bitfieldExtract(ssbo{}[{}/4],int({}%4)*8,8);", inst, binding.U32(), offset_var, | ||
| 16 | offset_var); | ||
| 14 | } | 17 | } |
| 15 | 18 | ||
| 16 | void EmitLoadStorageS8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] const IR::Value& binding, | 19 | void EmitLoadStorageS8([[maybe_unused]] EmitContext& ctx, IR::Inst& inst, |
| 20 | [[maybe_unused]] const IR::Value& binding, | ||
| 17 | [[maybe_unused]] const IR::Value& offset) { | 21 | [[maybe_unused]] const IR::Value& offset) { |
| 18 | throw NotImplementedException("GLSL Instrucion"); | 22 | const auto offset_var{ctx.reg_alloc.Consume(offset)}; |
| 23 | ctx.AddS32("{}=bitfieldExtract(int(ssbo{}[{}/4]),int({}%4)*8,8);", inst, binding.U32(), | ||
| 24 | offset_var, offset_var); | ||
| 19 | } | 25 | } |
| 20 | 26 | ||
| 21 | void EmitLoadStorageU16([[maybe_unused]] EmitContext& ctx, | 27 | void EmitLoadStorageU16([[maybe_unused]] EmitContext& ctx, IR::Inst& inst, |
| 22 | [[maybe_unused]] const IR::Value& binding, | 28 | [[maybe_unused]] const IR::Value& binding, |
| 23 | [[maybe_unused]] const IR::Value& offset) { | 29 | [[maybe_unused]] const IR::Value& offset) { |
| 24 | throw NotImplementedException("GLSL Instrucion"); | 30 | const auto offset_var{ctx.reg_alloc.Consume(offset)}; |
| 31 | ctx.AddU32("{}=bitfieldExtract(ssbo{}[{}/4],int(({}/2)%2)*16,16);", inst, binding.U32(), | ||
| 32 | offset_var, offset_var); | ||
| 25 | } | 33 | } |
| 26 | 34 | ||
| 27 | void EmitLoadStorageS16([[maybe_unused]] EmitContext& ctx, | 35 | void EmitLoadStorageS16([[maybe_unused]] EmitContext& ctx, IR::Inst& inst, |
| 28 | [[maybe_unused]] const IR::Value& binding, | 36 | [[maybe_unused]] const IR::Value& binding, |
| 29 | [[maybe_unused]] const IR::Value& offset) { | 37 | [[maybe_unused]] const IR::Value& offset) { |
| 30 | throw NotImplementedException("GLSL Instrucion"); | 38 | const auto offset_var{ctx.reg_alloc.Consume(offset)}; |
| 39 | ctx.AddS32("{}=bitfieldExtract(int(ssbo{}[{}/4]),int(({}/2)%2)*16,16);", inst, binding.U32(), | ||
| 40 | offset_var, offset_var); | ||
| 31 | } | 41 | } |
| 32 | 42 | ||
| 33 | void EmitLoadStorage32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 43 | void EmitLoadStorage32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 34 | const IR::Value& offset) { | 44 | const IR::Value& offset) { |
| 35 | const auto offset_var{ctx.reg_alloc.Consume(offset)}; | 45 | const auto offset_var{ctx.reg_alloc.Consume(offset)}; |
| 36 | ctx.AddU32("{}=ssbo{}[{}];", inst, binding.U32(), offset_var); | 46 | ctx.AddU32("{}=ssbo{}[{}/4];", inst, binding.U32(), offset_var); |
| 37 | } | 47 | } |
| 38 | 48 | ||
| 39 | void EmitLoadStorage64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 49 | void EmitLoadStorage64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 40 | const IR::Value& offset) { | 50 | const IR::Value& offset) { |
| 41 | const auto offset_var{ctx.reg_alloc.Consume(offset)}; | 51 | const auto offset_var{ctx.reg_alloc.Consume(offset)}; |
| 42 | ctx.AddU32x2("{}=uvec2(ssbo{}[{}],ssbo{}[{}+1]);", inst, binding.U32(), offset_var, | 52 | ctx.AddU32x2("{}=uvec2(ssbo{}[{}/4],ssbo{}[{}/4+1]);", inst, binding.U32(), offset_var, |
| 43 | binding.U32(), offset_var); | 53 | binding.U32(), offset_var); |
| 44 | } | 54 | } |
| 45 | 55 | ||
| 46 | void EmitLoadStorage128(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 56 | void EmitLoadStorage128(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 47 | const IR::Value& offset) { | 57 | const IR::Value& offset) { |
| 48 | const auto offset_var{ctx.reg_alloc.Consume(offset)}; | 58 | const auto offset_var{ctx.reg_alloc.Consume(offset)}; |
| 49 | ctx.AddU32x4("{}=uvec4(ssbo{}[{}],ssbo{}[{}+1],ssbo{}[{}+2],ssbo{}[{}+3]);", inst, | 59 | ctx.AddU32x4("{}=uvec4(ssbo{}[{}/4],ssbo{}[{}/4+1],ssbo{}[{}/4+2],ssbo{}[{}/4+3]);", inst, |
| 50 | binding.U32(), offset_var, binding.U32(), offset_var, binding.U32(), offset_var, | 60 | binding.U32(), offset_var, binding.U32(), offset_var, binding.U32(), offset_var, |
| 51 | binding.U32(), offset_var); | 61 | binding.U32(), offset_var); |
| 52 | } | 62 | } |
| @@ -55,47 +65,59 @@ void EmitWriteStorageU8([[maybe_unused]] EmitContext& ctx, | |||
| 55 | [[maybe_unused]] const IR::Value& binding, | 65 | [[maybe_unused]] const IR::Value& binding, |
| 56 | [[maybe_unused]] const IR::Value& offset, | 66 | [[maybe_unused]] const IR::Value& offset, |
| 57 | [[maybe_unused]] std::string_view value) { | 67 | [[maybe_unused]] std::string_view value) { |
| 58 | throw NotImplementedException("GLSL Instrucion"); | 68 | const auto offset_var{ctx.reg_alloc.Consume(offset)}; |
| 69 | ctx.Add("ssbo{}[{}/4]=bitfieldInsert(ssbo{}[{}/4],{},int({}%4)*8,8);", binding.U32(), | ||
| 70 | offset_var, binding.U32(), offset_var, value, offset_var); | ||
| 59 | } | 71 | } |
| 60 | 72 | ||
| 61 | void EmitWriteStorageS8([[maybe_unused]] EmitContext& ctx, | 73 | void EmitWriteStorageS8([[maybe_unused]] EmitContext& ctx, |
| 62 | [[maybe_unused]] const IR::Value& binding, | 74 | [[maybe_unused]] const IR::Value& binding, |
| 63 | [[maybe_unused]] const IR::Value& offset, | 75 | [[maybe_unused]] const IR::Value& offset, |
| 64 | [[maybe_unused]] std::string_view value) { | 76 | [[maybe_unused]] std::string_view value) { |
| 65 | throw NotImplementedException("GLSL Instrucion"); | 77 | const auto offset_var{ctx.reg_alloc.Consume(offset)}; |
| 78 | ctx.Add("ssbo{}[{}/4]=bitfieldInsert(ssbo{}[{}/4],{},int({}%4)*8,8);", binding.U32(), | ||
| 79 | offset_var, binding.U32(), offset_var, value, offset_var); | ||
| 66 | } | 80 | } |
| 67 | 81 | ||
| 68 | void EmitWriteStorageU16([[maybe_unused]] EmitContext& ctx, | 82 | void EmitWriteStorageU16([[maybe_unused]] EmitContext& ctx, |
| 69 | [[maybe_unused]] const IR::Value& binding, | 83 | [[maybe_unused]] const IR::Value& binding, |
| 70 | [[maybe_unused]] const IR::Value& offset, | 84 | [[maybe_unused]] const IR::Value& offset, |
| 71 | [[maybe_unused]] std::string_view value) { | 85 | [[maybe_unused]] std::string_view value) { |
| 72 | throw NotImplementedException("GLSL Instrucion"); | 86 | const auto offset_var{ctx.reg_alloc.Consume(offset)}; |
| 87 | ctx.Add("ssbo{}[{}/4]=bitfieldInsert(ssbo{}[{}/4],{},int(({}/2)%2)*16,16);", binding.U32(), | ||
| 88 | offset_var, binding.U32(), offset_var, value, offset_var); | ||
| 73 | } | 89 | } |
| 74 | 90 | ||
| 75 | void EmitWriteStorageS16([[maybe_unused]] EmitContext& ctx, | 91 | void EmitWriteStorageS16([[maybe_unused]] EmitContext& ctx, |
| 76 | [[maybe_unused]] const IR::Value& binding, | 92 | [[maybe_unused]] const IR::Value& binding, |
| 77 | [[maybe_unused]] const IR::Value& offset, | 93 | [[maybe_unused]] const IR::Value& offset, |
| 78 | [[maybe_unused]] std::string_view value) { | 94 | [[maybe_unused]] std::string_view value) { |
| 79 | throw NotImplementedException("GLSL Instrucion"); | 95 | const auto offset_var{ctx.reg_alloc.Consume(offset)}; |
| 96 | ctx.Add("ssbo{}[{}/4]=bitfieldInsert(ssbo{}[{}/4],{},int(({}/2)%2)*16,16);", binding.U32(), | ||
| 97 | offset_var, binding.U32(), offset_var, value, offset_var); | ||
| 80 | } | 98 | } |
| 81 | 99 | ||
| 82 | void EmitWriteStorage32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset, | 100 | void EmitWriteStorage32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset, |
| 83 | std::string_view value) { | 101 | std::string_view value) { |
| 84 | const auto offset_var{ctx.reg_alloc.Consume(offset)}; | 102 | const auto offset_var{ctx.reg_alloc.Consume(offset)}; |
| 85 | ctx.Add("ssbo{}[{}]={};", binding.U32(), offset_var, value); | 103 | ctx.Add("ssbo{}[{}/4]={};", binding.U32(), offset_var, value); |
| 86 | } | 104 | } |
| 87 | 105 | ||
| 88 | void EmitWriteStorage64(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset, | 106 | void EmitWriteStorage64(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset, |
| 89 | std::string_view value) { | 107 | std::string_view value) { |
| 90 | const auto offset_var{ctx.reg_alloc.Consume(offset)}; | 108 | const auto offset_var{ctx.reg_alloc.Consume(offset)}; |
| 91 | ctx.Add("ssbo{}[{}]={}.x;", binding.U32(), offset_var, value); | 109 | ctx.Add("ssbo{}[{}/4]={}.x;", binding.U32(), offset_var, value); |
| 92 | ctx.Add("ssbo{}[{}+1]={}.y;", binding.U32(), offset_var, value); | 110 | ctx.Add("ssbo{}[({}/4)+1]={}.y;", binding.U32(), offset_var, value); |
| 93 | } | 111 | } |
| 94 | 112 | ||
| 95 | void EmitWriteStorage128([[maybe_unused]] EmitContext& ctx, | 113 | void EmitWriteStorage128([[maybe_unused]] EmitContext& ctx, |
| 96 | [[maybe_unused]] const IR::Value& binding, | 114 | [[maybe_unused]] const IR::Value& binding, |
| 97 | [[maybe_unused]] const IR::Value& offset, | 115 | [[maybe_unused]] const IR::Value& offset, |
| 98 | [[maybe_unused]] std::string_view value) { | 116 | [[maybe_unused]] std::string_view value) { |
| 99 | throw NotImplementedException("GLSL Instrucion"); | 117 | const auto offset_var{ctx.reg_alloc.Consume(offset)}; |
| 118 | ctx.Add("ssbo{}[{}/4]={}.x;", binding.U32(), offset_var, value); | ||
| 119 | ctx.Add("ssbo{}[({}/4)+1]={}.y;", binding.U32(), offset_var, value); | ||
| 120 | ctx.Add("ssbo{}[({}/4)+2]={}.z;", binding.U32(), offset_var, value); | ||
| 121 | ctx.Add("ssbo{}[({}/4)+3]={}.w;", binding.U32(), offset_var, value); | ||
| 100 | } | 122 | } |
| 101 | } // namespace Shader::Backend::GLSL | 123 | } // namespace Shader::Backend::GLSL |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp index 3bac8899b..ec80f3cef 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp | |||
| @@ -206,10 +206,6 @@ void EmitWorkgroupId(EmitContext& ctx) { | |||
| 206 | NotImplemented(); | 206 | NotImplemented(); |
| 207 | } | 207 | } |
| 208 | 208 | ||
| 209 | void EmitLocalInvocationId(EmitContext& ctx) { | ||
| 210 | NotImplemented(); | ||
| 211 | } | ||
| 212 | |||
| 213 | void EmitInvocationId(EmitContext& ctx) { | 209 | void EmitInvocationId(EmitContext& ctx) { |
| 214 | NotImplemented(); | 210 | NotImplemented(); |
| 215 | } | 211 | } |
| @@ -626,27 +622,4 @@ void EmitSubgroupGeMask(EmitContext& ctx) { | |||
| 626 | NotImplemented(); | 622 | NotImplemented(); |
| 627 | } | 623 | } |
| 628 | 624 | ||
| 629 | void EmitShuffleIndex(EmitContext& ctx, IR::Inst& inst, std::string_view value, | ||
| 630 | std::string_view index, std::string_view clamp, | ||
| 631 | std::string_view segmentation_mask) { | ||
| 632 | NotImplemented(); | ||
| 633 | } | ||
| 634 | |||
| 635 | void EmitShuffleUp(EmitContext& ctx, IR::Inst& inst, std::string_view value, std::string_view index, | ||
| 636 | std::string_view clamp, std::string_view segmentation_mask) { | ||
| 637 | NotImplemented(); | ||
| 638 | } | ||
| 639 | |||
| 640 | void EmitShuffleDown(EmitContext& ctx, IR::Inst& inst, std::string_view value, | ||
| 641 | std::string_view index, std::string_view clamp, | ||
| 642 | std::string_view segmentation_mask) { | ||
| 643 | NotImplemented(); | ||
| 644 | } | ||
| 645 | |||
| 646 | void EmitShuffleButterfly(EmitContext& ctx, IR::Inst& inst, std::string_view value, | ||
| 647 | std::string_view index, std::string_view clamp, | ||
| 648 | std::string_view segmentation_mask) { | ||
| 649 | NotImplemented(); | ||
| 650 | } | ||
| 651 | |||
| 652 | } // namespace Shader::Backend::GLSL | 625 | } // namespace Shader::Backend::GLSL |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_warp.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_warp.cpp index aebdf8a3a..0a488188b 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_warp.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_warp.cpp | |||
| @@ -8,6 +8,59 @@ | |||
| 8 | #include "shader_recompiler/frontend/ir/value.h" | 8 | #include "shader_recompiler/frontend/ir/value.h" |
| 9 | 9 | ||
| 10 | namespace Shader::Backend::GLSL { | 10 | namespace Shader::Backend::GLSL { |
| 11 | namespace { | ||
| 12 | void SetInBoundsFlag(EmitContext& ctx, IR::Inst& inst) { | ||
| 13 | IR::Inst* const in_bounds{inst.GetAssociatedPseudoOperation(IR::Opcode::GetInBoundsFromOp)}; | ||
| 14 | if (!in_bounds) { | ||
| 15 | return; | ||
| 16 | } | ||
| 17 | |||
| 18 | ctx.AddU1("{}=shfl_in_bounds;", *in_bounds); | ||
| 19 | in_bounds->Invalidate(); | ||
| 20 | } | ||
| 21 | } // namespace | ||
| 22 | |||
| 23 | void EmitShuffleIndex(EmitContext& ctx, IR::Inst& inst, std::string_view value, | ||
| 24 | std::string_view index, std::string_view clamp, | ||
| 25 | std::string_view segmentation_mask) { | ||
| 26 | ctx.Add("shfl_in_bounds=int(gl_SubGroupInvocationARB-{})>=int((gl_SubGroupInvocationARB&{})|({}" | ||
| 27 | "&~{}));", | ||
| 28 | index, segmentation_mask, clamp, segmentation_mask); | ||
| 29 | SetInBoundsFlag(ctx, inst); | ||
| 30 | ctx.AddU32("{}=shfl_in_bounds?{}:gl_SubGroupInvocationARB-{};", inst, value, index); | ||
| 31 | } | ||
| 32 | |||
| 33 | void EmitShuffleUp(EmitContext& ctx, IR::Inst& inst, std::string_view value, std::string_view index, | ||
| 34 | std::string_view clamp, std::string_view segmentation_mask) { | ||
| 35 | ctx.Add("shfl_in_bounds=int(gl_SubGroupInvocationARB-{})>=int((gl_SubGroupInvocationARB&{})|({}" | ||
| 36 | "&~{}));", | ||
| 37 | index, segmentation_mask, clamp, segmentation_mask); | ||
| 38 | SetInBoundsFlag(ctx, inst); | ||
| 39 | ctx.AddU32("{}=shfl_in_bounds?readInvocationARB({},gl_SubGroupInvocationARB-{}):" | ||
| 40 | "{};", | ||
| 41 | inst, value, index, value); | ||
| 42 | } | ||
| 43 | |||
| 44 | void EmitShuffleDown(EmitContext& ctx, IR::Inst& inst, std::string_view value, | ||
| 45 | std::string_view index, std::string_view clamp, | ||
| 46 | std::string_view segmentation_mask) { | ||
| 47 | ctx.Add("shfl_in_bounds=int(gl_SubGroupInvocationARB-{})>=int((gl_SubGroupInvocationARB&{})|({}" | ||
| 48 | "&~{}));", | ||
| 49 | index, segmentation_mask, clamp, segmentation_mask); | ||
| 50 | SetInBoundsFlag(ctx, inst); | ||
| 51 | ctx.AddU32("{}=shfl_in_bounds?{}:gl_SubGroupInvocationARB-{};", inst, value, index); | ||
| 52 | } | ||
| 53 | |||
| 54 | void EmitShuffleButterfly(EmitContext& ctx, IR::Inst& inst, std::string_view value, | ||
| 55 | std::string_view index, std::string_view clamp, | ||
| 56 | std::string_view segmentation_mask) { | ||
| 57 | ctx.Add("shfl_in_bounds=int(gl_SubGroupInvocationARB-{})>=int((gl_SubGroupInvocationARB&{})|({}" | ||
| 58 | "&~{}));", | ||
| 59 | index, segmentation_mask, clamp, segmentation_mask); | ||
| 60 | SetInBoundsFlag(ctx, inst); | ||
| 61 | ctx.AddU32("{}=shfl_in_bounds?{}:gl_SubGroupInvocationARB-{};", inst, value, index); | ||
| 62 | } | ||
| 63 | |||
| 11 | void EmitFSwizzleAdd([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 64 | void EmitFSwizzleAdd([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, |
| 12 | [[maybe_unused]] std::string_view op_a, [[maybe_unused]] std::string_view op_b, | 65 | [[maybe_unused]] std::string_view op_a, [[maybe_unused]] std::string_view op_b, |
| 13 | [[maybe_unused]] std::string_view swizzle) { | 66 | [[maybe_unused]] std::string_view swizzle) { |