diff options
Diffstat (limited to 'src/shader_recompiler/backend/glsl/emit_context.cpp')
| -rw-r--r-- | src/shader_recompiler/backend/glsl/emit_context.cpp | 86 |
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 | ||
| 10 | namespace Shader::Backend::GLSL { | 10 | namespace Shader::Backend::GLSL { |
| 11 | namespace { | 11 | namespace { |
| 12 | u32 CbufIndex(u32 offset) { | ||
| 13 | return (offset / 4) % 4; | ||
| 14 | } | ||
| 15 | |||
| 16 | char OffsetSwizzle(u32 offset) { | ||
| 17 | return "xyzw"[CbufIndex(offset)]; | ||
| 18 | } | ||
| 19 | |||
| 12 | std::string_view InterpDecorator(Interpolation interp) { | 20 | std::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 | ||
| 384 | void EmitContext::DefineHelperFunctions() { | 392 | void 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 | ||
| 428 | void EmitContext::SetupImages(Bindings& bindings) { | 512 | void EmitContext::SetupImages(Bindings& bindings) { |