summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/backend/glsl/emit_context.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp')
-rw-r--r--src/shader_recompiler/backend/glsl/emit_context.cpp86
1 files changed, 85 insertions, 1 deletions
diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp
index 5048c8b68..f68f33212 100644
--- a/src/shader_recompiler/backend/glsl/emit_context.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_context.cpp
@@ -9,6 +9,14 @@
9 9
10namespace Shader::Backend::GLSL { 10namespace Shader::Backend::GLSL {
11namespace { 11namespace {
12u32 CbufIndex(u32 offset) {
13 return (offset / 4) % 4;
14}
15
16char OffsetSwizzle(u32 offset) {
17 return "xyzw"[CbufIndex(offset)];
18}
19
12std::string_view InterpDecorator(Interpolation interp) { 20std::string_view InterpDecorator(Interpolation interp) {
13 switch (interp) { 21 switch (interp) {
14 case Interpolation::Smooth: 22 case Interpolation::Smooth:
@@ -382,6 +390,8 @@ void EmitContext::DefineGenericOutput(size_t index, u32 invocations) {
382} 390}
383 391
384void EmitContext::DefineHelperFunctions() { 392void EmitContext::DefineHelperFunctions() {
393 header += "\n#define ftoi floatBitsToInt\n#define ftou floatBitsToUint\n"
394 "#define itof intBitsToFloat\n#define utof uintBitsToFloat\n";
385 if (info.uses_global_increment || info.uses_shared_increment) { 395 if (info.uses_global_increment || info.uses_shared_increment) {
386 header += "uint CasIncrement(uint op_a,uint op_b){return(op_a>=op_b)?0u:(op_a+1u);}\n"; 396 header += "uint CasIncrement(uint op_a,uint op_b){return(op_a>=op_b)?0u:(op_a+1u);}\n";
387 } 397 }
@@ -391,7 +401,7 @@ void EmitContext::DefineHelperFunctions() {
391 } 401 }
392 if (info.uses_atomic_f32_add) { 402 if (info.uses_atomic_f32_add) {
393 header += "uint CasFloatAdd(uint op_a,float op_b){return " 403 header += "uint CasFloatAdd(uint op_a,float op_b){return "
394 "floatBitsToUint(uintBitsToFloat(op_a)+op_b);}\n"; 404 "ftou(utof(op_a)+op_b);}\n";
395 } 405 }
396 if (info.uses_atomic_f32x2_add) { 406 if (info.uses_atomic_f32x2_add) {
397 header += "uint CasFloatAdd32x2(uint op_a,vec2 op_b){return " 407 header += "uint CasFloatAdd32x2(uint op_a,vec2 op_b){return "
@@ -423,6 +433,80 @@ void EmitContext::DefineHelperFunctions() {
423 if (info.uses_atomic_s32_max) { 433 if (info.uses_atomic_s32_max) {
424 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)));}";
425 } 435 }
436 if (info.uses_global_memory) {
437 std::string write_func{"void WriteGlobal32(uint64_t addr,uint data){\n"};
438 std::string write_func_64{"void WriteGlobal64(uint64_t addr,uvec2 data){\n"};
439 std::string write_func_128{"void WriteGlobal128(uint64_t addr,uvec4 data){\n"};
440
441 std::string load_func{"uint LoadGlobal32(uint64_t addr){\n"};
442 std::string load_func_64{"uvec2 LoadGlobal64(uint64_t addr){\n"};
443 std::string load_func_128{"uvec4 LoadGlobal128(uint64_t addr){\n"};
444 const size_t num_buffers{info.storage_buffers_descriptors.size()};
445 for (size_t index = 0; index < num_buffers; ++index) {
446 if (!info.nvn_buffer_used[index]) {
447 continue;
448 }
449 const auto& ssbo{info.storage_buffers_descriptors[index]};
450 const u32 size_cbuf_offset{ssbo.cbuf_offset + 8};
451 const auto ssbo_addr{fmt::format("ssbo_addr{}", index)};
452 const auto cbuf{fmt::format("{}_cbuf{}", stage_name, ssbo.cbuf_index)};
453 const auto cbuf_value{fmt::format(
454 "uint64_t {}=packUint2x32(uvec2(ftou({}[{}].{}),ftou({}[{}].{})));", ssbo_addr,
455 cbuf, ssbo.cbuf_offset / 16, OffsetSwizzle(ssbo.cbuf_offset), cbuf,
456 (ssbo.cbuf_offset + 4) / 16, OffsetSwizzle(ssbo.cbuf_offset + 4))};
457
458 write_func += cbuf_value;
459 write_func_64 += cbuf_value;
460 write_func_128 += cbuf_value;
461 load_func += cbuf_value;
462 load_func_64 += cbuf_value;
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
477 const auto ssbo_name{fmt::format("{}_ssbo{}", stage_name, index)};
478 write_func += fmt::format("{}[uint(addr-{})>>2]=data;return;}}", ssbo_name, ssbo_addr);
479 write_func_64 +=
480 fmt::format("{}[uint(addr-{})>>2]=data.x;{}[uint(addr-{}+4)>>2]=data.y;return;}}",
481 ssbo_name, ssbo_addr, ssbo_name, ssbo_addr);
482 write_func_128 +=
483 fmt::format("{}[uint(addr-{})>>2]=data.x;{}[uint(addr-{}+4)>>2]=data.y;{}[uint("
484 "addr-{}+8)>>2]=data.z;{}[uint(addr-{}+12)>>2]=data.w;return;}}",
485 ssbo_name, ssbo_addr, ssbo_name, ssbo_addr, ssbo_name, ssbo_addr,
486 ssbo_name, ssbo_addr);
487 load_func += fmt::format("return {}[uint(addr-{})>>2];}}", ssbo_name, ssbo_addr);
488 load_func_64 +=
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 }
497 write_func += "}\n";
498 write_func_64 += "}\n";
499 write_func_128 += "}\n";
500 load_func += "return 0u;}\n";
501 load_func_64 += "return uvec2(0);}\n";
502 load_func_128 += "return uvec4(0);}\n";
503 header += write_func;
504 header += write_func_64;
505 header += write_func_128;
506 header += load_func;
507 header += load_func_64;
508 header += load_func_128;
509 }
426} 510}
427 511
428void EmitContext::SetupImages(Bindings& bindings) { 512void EmitContext::SetupImages(Bindings& bindings) {