summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend
diff options
context:
space:
mode:
authorGravatar ameerj2021-06-03 22:25:06 -0400
committerGravatar ameerj2021-07-22 21:51:37 -0400
commit0a0b0a73d82057a309b6b0427c29c7e15e2b356f (patch)
tree0982ab6ae4b27b69a97cad77beb551e9508d537e /src/shader_recompiler/backend
parentglsl: Cleanup and address feedback (diff)
downloadyuzu-0a0b0a73d82057a309b6b0427c29c7e15e2b356f.tar.gz
yuzu-0a0b0a73d82057a309b6b0427c29c7e15e2b356f.tar.xz
yuzu-0a0b0a73d82057a309b6b0427c29c7e15e2b356f.zip
glsl: Fix <32-bit SSBO writes
and more cleanup
Diffstat (limited to 'src/shader_recompiler/backend')
-rw-r--r--src/shader_recompiler/backend/glsl/emit_context.cpp52
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp7
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp2
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_memory.cpp32
4 files changed, 43 insertions, 50 deletions
diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp
index ae5ac752d..ecc7335ba 100644
--- a/src/shader_recompiler/backend/glsl/emit_context.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_context.cpp
@@ -433,8 +433,7 @@ void EmitContext::DefineHelperFunctions() {
433} 433}
434 434
435std::string EmitContext::DefineGlobalMemoryFunctions() { 435std::string EmitContext::DefineGlobalMemoryFunctions() {
436 const auto define_body{[&](std::string& func, size_t index, u32 num_components, 436 const auto define_body{[&](std::string& func, size_t index, std::string_view return_statement) {
437 std::string_view return_statement) {
438 const auto& ssbo{info.storage_buffers_descriptors[index]}; 437 const auto& ssbo{info.storage_buffers_descriptors[index]};
439 const u32 size_cbuf_offset{ssbo.cbuf_offset + 8}; 438 const u32 size_cbuf_offset{ssbo.cbuf_offset + 8};
440 const auto ssbo_addr{fmt::format("ssbo_addr{}", index)}; 439 const auto ssbo_addr{fmt::format("ssbo_addr{}", index)};
@@ -458,42 +457,31 @@ std::string EmitContext::DefineGlobalMemoryFunctions() {
458 func += comparison; 457 func += comparison;
459 458
460 const auto ssbo_name{fmt::format("{}_ssbo{}", stage_name, index)}; 459 const auto ssbo_name{fmt::format("{}_ssbo{}", stage_name, index)};
461 switch (num_components) { 460 func += fmt::format(return_statement, ssbo_name, ssbo_addr);
462 case 1:
463 func += fmt::format(return_statement, ssbo_name, ssbo_addr);
464 break;
465 case 2:
466 func += fmt::format(return_statement, ssbo_name, ssbo_addr, ssbo_name, ssbo_addr);
467 break;
468 case 4:
469 func += fmt::format(return_statement, ssbo_name, ssbo_addr, ssbo_name, ssbo_addr,
470 ssbo_name, ssbo_addr, ssbo_name, ssbo_addr);
471 break;
472 }
473 }}; 461 }};
474 std::string write_func{"void WriteGlobal32(uint64_t addr,uint data){\n"}; 462 std::string write_func{"void WriteGlobal32(uint64_t addr,uint data){"};
475 std::string write_func_64{"void WriteGlobal64(uint64_t addr,uvec2 data){\n"}; 463 std::string write_func_64{"void WriteGlobal64(uint64_t addr,uvec2 data){"};
476 std::string write_func_128{"void WriteGlobal128(uint64_t addr,uvec4 data){\n"}; 464 std::string write_func_128{"void WriteGlobal128(uint64_t addr,uvec4 data){"};
477 std::string load_func{"uint LoadGlobal32(uint64_t addr){\n"}; 465 std::string load_func{"uint LoadGlobal32(uint64_t addr){"};
478 std::string load_func_64{"uvec2 LoadGlobal64(uint64_t addr){\n"}; 466 std::string load_func_64{"uvec2 LoadGlobal64(uint64_t addr){"};
479 std::string load_func_128{"uvec4 LoadGlobal128(uint64_t addr){\n"}; 467 std::string load_func_128{"uvec4 LoadGlobal128(uint64_t addr){"};
480 const size_t num_buffers{info.storage_buffers_descriptors.size()}; 468 const size_t num_buffers{info.storage_buffers_descriptors.size()};
481 for (size_t index = 0; index < num_buffers; ++index) { 469 for (size_t index = 0; index < num_buffers; ++index) {
482 if (!info.nvn_buffer_used[index]) { 470 if (!info.nvn_buffer_used[index]) {
483 continue; 471 continue;
484 } 472 }
485 define_body(write_func, index, 1, "{}[uint(addr-{})>>2]=data;return;}}"); 473 define_body(write_func, index, "{0}[uint(addr-{1})>>2]=data;return;}}");
486 define_body(write_func_64, index, 2, 474 define_body(write_func_64, index,
487 "{}[uint(addr-{})>>2]=data.x;{}[uint(addr-{}+4)>>2]=data.y;return;}}"); 475 "{0}[uint(addr-{1})>>2]=data.x;{0}[uint(addr-{1}+4)>>2]=data.y;return;}}");
488 define_body(write_func_128, index, 4, 476 define_body(write_func_128, index,
489 "{}[uint(addr-{})>>2]=data.x;{}[uint(addr-{}+4)>>2]=data.y;{}[uint(" 477 "{0}[uint(addr-{1})>>2]=data.x;{0}[uint(addr-{1}+4)>>2]=data.y;{0}[uint("
490 "addr-{}+8)>>2]=data.z;{}[uint(addr-{}+12)>>2]=data.w;return;}}"); 478 "addr-{1}+8)>>2]=data.z;{0}[uint(addr-{1}+12)>>2]=data.w;return;}}");
491 define_body(load_func, index, 1, "return {}[uint(addr-{})>>2];}}"); 479 define_body(load_func, index, "return {0}[uint(addr-{1})>>2];}}");
492 define_body(load_func_64, index, 2, 480 define_body(load_func_64, index,
493 "return uvec2({}[uint(addr-{})>>2],{}[uint(addr-{}+4)>>2]);}}"); 481 "return uvec2({0}[uint(addr-{1})>>2],{0}[uint(addr-{1}+4)>>2]);}}");
494 define_body(load_func_128, index, 4, 482 define_body(load_func_128, index,
495 "return uvec4({}[uint(addr-{})>>2],{}[uint(addr-{}+4)>>2],{}[" 483 "return uvec4({0}[uint(addr-{1})>>2],{0}[uint(addr-{1}+4)>>2],{0}["
496 "uint(addr-{}+8)>>2],{}[uint(addr-{}+12)>>2]);}}"); 484 "uint(addr-{1}+8)>>2],{0}[uint(addr-{1}+12)>>2]);}}");
497 } 485 }
498 write_func += "}"; 486 write_func += "}";
499 write_func_64 += "}"; 487 write_func_64 += "}";
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp
index 5ba39261b..1568bb7cf 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp
@@ -11,11 +11,8 @@
11 11
12namespace Shader::Backend::GLSL { 12namespace Shader::Backend::GLSL {
13namespace { 13namespace {
14constexpr const char cas_loop[]{R"(for (;;){{ 14constexpr char cas_loop[]{
15 uint old_value={}; 15 "for (;;){{uint old={};{}=atomicCompSwap({},old,{}({},{}));if({}==old){{break;}}}}"};
16 {}=atomicCompSwap({},old_value,{}({},{}));
17 if ({}==old_value){{break;}}
18}})"};
19 16
20void SharedCasFunction(EmitContext& ctx, IR::Inst& inst, std::string_view offset, 17void SharedCasFunction(EmitContext& ctx, IR::Inst& inst, std::string_view offset,
21 std::string_view value, std::string_view function) { 18 std::string_view value, std::string_view function) {
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 d986e1b1a..b2caa222a 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
@@ -11,7 +11,7 @@
11 11
12namespace Shader::Backend::GLSL { 12namespace Shader::Backend::GLSL {
13namespace { 13namespace {
14static constexpr std::string_view SWIZZLE{"xyzw"}; 14constexpr char SWIZZLE[]{"xyzw"};
15 15
16u32 CbufIndex(u32 offset) { 16u32 CbufIndex(u32 offset) {
17 return (offset / 4) % 4; 17 return (offset / 4) % 4;
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_memory.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_memory.cpp
index bc4363824..500e5c290 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_memory.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_memory.cpp
@@ -9,6 +9,18 @@
9#include "shader_recompiler/frontend/ir/value.h" 9#include "shader_recompiler/frontend/ir/value.h"
10 10
11namespace Shader::Backend::GLSL { 11namespace Shader::Backend::GLSL {
12namespace {
13constexpr char cas_loop[]{"for(;;){{uint old_value={};uint "
14 "cas_result=atomicCompSwap({},old_value,bitfieldInsert({},{},{},{}));"
15 "if(cas_result==old_value){{break;}}}}"};
16
17void SsboWriteCas(EmitContext& ctx, const IR::Value& binding, std::string_view offset_var,
18 std::string_view value, std::string_view bit_offset, u32 num_bits) {
19 const auto ssbo{fmt::format("{}_ssbo{}[{}>>2]", ctx.stage_name, binding.U32(), offset_var)};
20 ctx.Add(cas_loop, ssbo, ssbo, ssbo, value, bit_offset, num_bits);
21}
22} // Anonymous namespace
23
12void EmitLoadGlobalU8([[maybe_unused]] EmitContext& ctx) { 24void EmitLoadGlobalU8([[maybe_unused]] EmitContext& ctx) {
13 NotImplemented(); 25 NotImplemented();
14} 26}
@@ -125,9 +137,8 @@ void EmitWriteStorageU8([[maybe_unused]] EmitContext& ctx,
125 [[maybe_unused]] const IR::Value& offset, 137 [[maybe_unused]] const IR::Value& offset,
126 [[maybe_unused]] std::string_view value) { 138 [[maybe_unused]] std::string_view value) {
127 const auto offset_var{ctx.var_alloc.Consume(offset)}; 139 const auto offset_var{ctx.var_alloc.Consume(offset)};
128 ctx.Add("{}_ssbo{}[{}>>2]=bitfieldInsert({}_ssbo{}[{}>>2],{},int({}%4)*8,8);", ctx.stage_name, 140 const auto bit_offset{fmt::format("int({}%4)*8", offset_var)};
129 binding.U32(), offset_var, ctx.stage_name, binding.U32(), offset_var, value, 141 SsboWriteCas(ctx, binding, offset_var, value, bit_offset, 8);
130 offset_var);
131} 142}
132 143
133void EmitWriteStorageS8([[maybe_unused]] EmitContext& ctx, 144void EmitWriteStorageS8([[maybe_unused]] EmitContext& ctx,
@@ -135,9 +146,8 @@ void EmitWriteStorageS8([[maybe_unused]] EmitContext& ctx,
135 [[maybe_unused]] const IR::Value& offset, 146 [[maybe_unused]] const IR::Value& offset,
136 [[maybe_unused]] std::string_view value) { 147 [[maybe_unused]] std::string_view value) {
137 const auto offset_var{ctx.var_alloc.Consume(offset)}; 148 const auto offset_var{ctx.var_alloc.Consume(offset)};
138 ctx.Add("{}_ssbo{}[{}>>2]=bitfieldInsert({}_ssbo{}[{}>>2],{},int({}%4)*8,8);", ctx.stage_name, 149 const auto bit_offset{fmt::format("int({}%4)*8", offset_var)};
139 binding.U32(), offset_var, ctx.stage_name, binding.U32(), offset_var, value, 150 SsboWriteCas(ctx, binding, offset_var, value, bit_offset, 8);
140 offset_var);
141} 151}
142 152
143void EmitWriteStorageU16([[maybe_unused]] EmitContext& ctx, 153void EmitWriteStorageU16([[maybe_unused]] EmitContext& ctx,
@@ -145,9 +155,8 @@ void EmitWriteStorageU16([[maybe_unused]] EmitContext& ctx,
145 [[maybe_unused]] const IR::Value& offset, 155 [[maybe_unused]] const IR::Value& offset,
146 [[maybe_unused]] std::string_view value) { 156 [[maybe_unused]] std::string_view value) {
147 const auto offset_var{ctx.var_alloc.Consume(offset)}; 157 const auto offset_var{ctx.var_alloc.Consume(offset)};
148 ctx.Add("{}_ssbo{}[{}>>2]=bitfieldInsert({}_ssbo{}[{}>>2],{},int(({}>>1)%2)*16,16);", 158 const auto bit_offset{fmt::format("int(({}>>1)%2)*16", offset_var)};
149 ctx.stage_name, binding.U32(), offset_var, ctx.stage_name, binding.U32(), offset_var, 159 SsboWriteCas(ctx, binding, offset_var, value, bit_offset, 16);
150 value, offset_var);
151} 160}
152 161
153void EmitWriteStorageS16([[maybe_unused]] EmitContext& ctx, 162void EmitWriteStorageS16([[maybe_unused]] EmitContext& ctx,
@@ -155,9 +164,8 @@ void EmitWriteStorageS16([[maybe_unused]] EmitContext& ctx,
155 [[maybe_unused]] const IR::Value& offset, 164 [[maybe_unused]] const IR::Value& offset,
156 [[maybe_unused]] std::string_view value) { 165 [[maybe_unused]] std::string_view value) {
157 const auto offset_var{ctx.var_alloc.Consume(offset)}; 166 const auto offset_var{ctx.var_alloc.Consume(offset)};
158 ctx.Add("{}_ssbo{}[{}>>2]=bitfieldInsert({}_ssbo{}[{}>>2],{},int(({}>>1)%2)*16,16);", 167 const auto bit_offset{fmt::format("int(({}>>1)%2)*16", offset_var)};
159 ctx.stage_name, binding.U32(), offset_var, ctx.stage_name, binding.U32(), offset_var, 168 SsboWriteCas(ctx, binding, offset_var, value, bit_offset, 16);
160 value, offset_var);
161} 169}
162 170
163void EmitWriteStorage32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset, 171void EmitWriteStorage32(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset,