summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/glsl/emit_context.cpp
diff options
context:
space:
mode:
authorGravatar ameerj2021-06-03 20:24:56 -0400
committerGravatar ameerj2021-07-22 21:51:37 -0400
commit5355568a2dbbb5bc4122109e2bd04ce6903adff1 (patch)
tree076c982eb2e3090ec97297e2d2eafbb17d3afccf /src/shader_recompiler/backend/glsl/emit_context.cpp
parentglsl: Increase NUM_VARS that can be allocated (diff)
downloadyuzu-5355568a2dbbb5bc4122109e2bd04ce6903adff1.tar.gz
yuzu-5355568a2dbbb5bc4122109e2bd04ce6903adff1.tar.xz
yuzu-5355568a2dbbb5bc4122109e2bd04ce6903adff1.zip
glsl: Refactor Global memory functions
Diffstat (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp')
-rw-r--r--src/shader_recompiler/backend/glsl/emit_context.cpp143
1 files changed, 72 insertions, 71 deletions
diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp
index f68f33212..fbc4b9c0f 100644
--- a/src/shader_recompiler/backend/glsl/emit_context.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_context.cpp
@@ -9,11 +9,11 @@
9 9
10namespace Shader::Backend::GLSL { 10namespace Shader::Backend::GLSL {
11namespace { 11namespace {
12u32 CbufIndex(u32 offset) { 12u32 CbufIndex(size_t offset) {
13 return (offset / 4) % 4; 13 return (offset / 4) % 4;
14} 14}
15 15
16char OffsetSwizzle(u32 offset) { 16char CbufSwizzle(size_t offset) {
17 return "xyzw"[CbufIndex(offset)]; 17 return "xyzw"[CbufIndex(offset)];
18} 18}
19 19
@@ -434,79 +434,80 @@ void EmitContext::DefineHelperFunctions() {
434 header += "uint CasMaxS32(uint op_a,uint op_b){return uint(max(int(op_a),int(op_b)));}"; 434 header += "uint CasMaxS32(uint op_a,uint op_b){return uint(max(int(op_a),int(op_b)));}";
435 } 435 }
436 if (info.uses_global_memory) { 436 if (info.uses_global_memory) {
437 std::string write_func{"void WriteGlobal32(uint64_t addr,uint data){\n"}; 437 header += DefineGlobalMemoryFunctions();
438 std::string write_func_64{"void WriteGlobal64(uint64_t addr,uvec2 data){\n"}; 438 }
439 std::string write_func_128{"void WriteGlobal128(uint64_t addr,uvec4 data){\n"}; 439}
440 440
441 std::string load_func{"uint LoadGlobal32(uint64_t addr){\n"}; 441std::string EmitContext::DefineGlobalMemoryFunctions() {
442 std::string load_func_64{"uvec2 LoadGlobal64(uint64_t addr){\n"}; 442 const auto define_body{[&](std::string& func, size_t index, u32 num_components,
443 std::string load_func_128{"uvec4 LoadGlobal128(uint64_t addr){\n"}; 443 std::string_view return_statement) {
444 const size_t num_buffers{info.storage_buffers_descriptors.size()}; 444 const auto& ssbo{info.storage_buffers_descriptors[index]};
445 for (size_t index = 0; index < num_buffers; ++index) { 445 const u32 size_cbuf_offset{ssbo.cbuf_offset + 8};
446 if (!info.nvn_buffer_used[index]) { 446 const auto ssbo_addr{fmt::format("ssbo_addr{}", index)};
447 continue; 447 const auto cbuf{fmt::format("{}_cbuf{}", stage_name, ssbo.cbuf_index)};
448 } 448 std::array<std::string, 2> addr_xy;
449 const auto& ssbo{info.storage_buffers_descriptors[index]}; 449 std::array<std::string, 2> size_xy;
450 const u32 size_cbuf_offset{ssbo.cbuf_offset + 8}; 450 for (size_t i = 0; i < addr_xy.size(); ++i) {
451 const auto ssbo_addr{fmt::format("ssbo_addr{}", index)}; 451 const auto addr_loc{ssbo.cbuf_offset + 4 * i};
452 const auto cbuf{fmt::format("{}_cbuf{}", stage_name, ssbo.cbuf_index)}; 452 const auto size_loc{size_cbuf_offset + 4 * i};
453 const auto cbuf_value{fmt::format( 453 addr_xy[i] = fmt::format("ftou({}[{}].{})", cbuf, addr_loc / 16, CbufSwizzle(addr_loc));
454 "uint64_t {}=packUint2x32(uvec2(ftou({}[{}].{}),ftou({}[{}].{})));", ssbo_addr, 454 size_xy[i] = fmt::format("ftou({}[{}].{})", cbuf, size_loc / 16, CbufSwizzle(size_loc));
455 cbuf, ssbo.cbuf_offset / 16, OffsetSwizzle(ssbo.cbuf_offset), cbuf, 455 }
456 (ssbo.cbuf_offset + 4) / 16, OffsetSwizzle(ssbo.cbuf_offset + 4))}; 456 const auto addr_pack{fmt::format("packUint2x32(uvec2({},{}))", addr_xy[0], addr_xy[1])};
457 const auto addr_statment{fmt::format("uint64_t {}={};", ssbo_addr, addr_pack)};
458 func += addr_statment;
457 459
458 write_func += cbuf_value; 460 const auto size_vec{fmt::format("uvec2({},{})", size_xy[0], size_xy[1])};
459 write_func_64 += cbuf_value; 461 const auto comp_lhs{fmt::format("(addr>={})", ssbo_addr)};
460 write_func_128 += cbuf_value; 462 const auto comp_rhs{fmt::format("(addr<({}+uint64_t({})))", ssbo_addr, size_vec)};
461 load_func += cbuf_value; 463 const auto comparison{fmt::format("if({}&&{}){{", comp_lhs, comp_rhs)};
462 load_func_64 += cbuf_value; 464 func += comparison;
463 load_func_128 += cbuf_value;
464 const auto ssbo_size{fmt::format("ftou({}[{}].{}),ftou({}[{}].{})", cbuf,
465 size_cbuf_offset / 16, OffsetSwizzle(size_cbuf_offset),
466 cbuf, (size_cbuf_offset + 4) / 16,
467 OffsetSwizzle(size_cbuf_offset + 4))};
468 const auto comparison{fmt::format("if((addr>={})&&(addr<({}+\nuint64_t(uvec2({}))))){{",
469 ssbo_addr, ssbo_addr, ssbo_size)};
470 write_func += comparison;
471 write_func_64 += comparison;
472 write_func_128 += comparison;
473 load_func += comparison;
474 load_func_64 += comparison;
475 load_func_128 += comparison;
476 465
477 const auto ssbo_name{fmt::format("{}_ssbo{}", stage_name, index)}; 466 const auto ssbo_name{fmt::format("{}_ssbo{}", stage_name, index)};
478 write_func += fmt::format("{}[uint(addr-{})>>2]=data;return;}}", ssbo_name, ssbo_addr); 467 switch (num_components) {
479 write_func_64 += 468 case 1:
480 fmt::format("{}[uint(addr-{})>>2]=data.x;{}[uint(addr-{}+4)>>2]=data.y;return;}}", 469 func += fmt::format(return_statement, ssbo_name, ssbo_addr);
481 ssbo_name, ssbo_addr, ssbo_name, ssbo_addr); 470 break;
482 write_func_128 += 471 case 2:
483 fmt::format("{}[uint(addr-{})>>2]=data.x;{}[uint(addr-{}+4)>>2]=data.y;{}[uint(" 472 func += fmt::format(return_statement, ssbo_name, ssbo_addr, ssbo_name, ssbo_addr);
484 "addr-{}+8)>>2]=data.z;{}[uint(addr-{}+12)>>2]=data.w;return;}}", 473 break;
485 ssbo_name, ssbo_addr, ssbo_name, ssbo_addr, ssbo_name, ssbo_addr, 474 case 4:
486 ssbo_name, ssbo_addr); 475 func += fmt::format(return_statement, ssbo_name, ssbo_addr, ssbo_name, ssbo_addr,
487 load_func += fmt::format("return {}[uint(addr-{})>>2];}}", ssbo_name, ssbo_addr); 476 ssbo_name, ssbo_addr, ssbo_name, ssbo_addr);
488 load_func_64 += 477 break;
489 fmt::format("return uvec2({}[uint(addr-{})>>2],{}[uint(addr-{}+4)>>2]);}}",
490 ssbo_name, ssbo_addr, ssbo_name, ssbo_addr);
491 load_func_128 += fmt::format("return "
492 "uvec4({}[uint(addr-{})>>2],{}[uint(addr-{}+4)>>2],{}["
493 "uint(addr-{}+8)>>2],{}[uint(addr-{}+12)>>2]);}}",
494 ssbo_name, ssbo_addr, ssbo_name, ssbo_addr, ssbo_name,
495 ssbo_addr, ssbo_name, ssbo_addr);
496 } 478 }
497 write_func += "}\n"; 479 }};
498 write_func_64 += "}\n"; 480 std::string write_func{"void WriteGlobal32(uint64_t addr,uint data){\n"};
499 write_func_128 += "}\n"; 481 std::string write_func_64{"void WriteGlobal64(uint64_t addr,uvec2 data){\n"};
500 load_func += "return 0u;}\n"; 482 std::string write_func_128{"void WriteGlobal128(uint64_t addr,uvec4 data){\n"};
501 load_func_64 += "return uvec2(0);}\n"; 483 std::string load_func{"uint LoadGlobal32(uint64_t addr){\n"};
502 load_func_128 += "return uvec4(0);}\n"; 484 std::string load_func_64{"uvec2 LoadGlobal64(uint64_t addr){\n"};
503 header += write_func; 485 std::string load_func_128{"uvec4 LoadGlobal128(uint64_t addr){\n"};
504 header += write_func_64; 486 const size_t num_buffers{info.storage_buffers_descriptors.size()};
505 header += write_func_128; 487 for (size_t index = 0; index < num_buffers; ++index) {
506 header += load_func; 488 if (!info.nvn_buffer_used[index]) {
507 header += load_func_64; 489 continue;
508 header += load_func_128; 490 }
509 } 491 define_body(write_func, index, 1, "{}[uint(addr-{})>>2]=data;return;}}");
492 define_body(write_func_64, index, 2,
493 "{}[uint(addr-{})>>2]=data.x;{}[uint(addr-{}+4)>>2]=data.y;return;}}");
494 define_body(write_func_128, index, 4,
495 "{}[uint(addr-{})>>2]=data.x;{}[uint(addr-{}+4)>>2]=data.y;{}[uint("
496 "addr-{}+8)>>2]=data.z;{}[uint(addr-{}+12)>>2]=data.w;return;}}");
497 define_body(load_func, index, 1, "return {}[uint(addr-{})>>2];}}");
498 define_body(load_func_64, index, 2,
499 "return uvec2({}[uint(addr-{})>>2],{}[uint(addr-{}+4)>>2]);}}");
500 define_body(load_func_128, index, 4,
501 "return uvec4({}[uint(addr-{})>>2],{}[uint(addr-{}+4)>>2],{}["
502 "uint(addr-{}+8)>>2],{}[uint(addr-{}+12)>>2]);}}");
503 }
504 write_func += "}";
505 write_func_64 += "}";
506 write_func_128 += "}";
507 load_func += "return 0u;}";
508 load_func_64 += "return uvec2(0);}";
509 load_func_128 += "return uvec4(0);}";
510 return write_func + write_func_64 + write_func_128 + load_func + load_func_64 + load_func_128;
510} 511}
511 512
512void EmitContext::SetupImages(Bindings& bindings) { 513void EmitContext::SetupImages(Bindings& bindings) {