diff options
Diffstat (limited to 'src/shader_recompiler/backend')
9 files changed, 185 insertions, 98 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) { |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp index 5394f4a8c..f8d2c12db 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp | |||
| @@ -39,7 +39,7 @@ void SsboCasFunctionF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& bindi | |||
| 39 | ctx.var_alloc.Consume(offset))}; | 39 | ctx.var_alloc.Consume(offset))}; |
| 40 | const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32)}; | 40 | const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U32)}; |
| 41 | ctx.Add(cas_loop.data(), ssbo, ret, ssbo, function, ssbo, value, ret); | 41 | ctx.Add(cas_loop.data(), ssbo, ret, ssbo, function, ssbo, value, ret); |
| 42 | ctx.AddF32("{}=uintBitsToFloat({});", inst, ret); | 42 | ctx.AddF32("{}=utof({});", inst, ret); |
| 43 | } | 43 | } |
| 44 | } // namespace | 44 | } // namespace |
| 45 | 45 | ||
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_bitwise_conversion.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_bitwise_conversion.cpp index 1e860f11a..0e617c8d8 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_bitwise_conversion.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_bitwise_conversion.cpp | |||
| @@ -40,7 +40,7 @@ void EmitBitCastU16F16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::I | |||
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | void EmitBitCastU32F32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | 42 | void EmitBitCastU32F32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { |
| 43 | ctx.AddU32("{}=floatBitsToUint({});", inst, value); | 43 | ctx.AddU32("{}=ftou({});", inst, value); |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | void EmitBitCastU64F64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | 46 | void EmitBitCastU64F64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { |
| @@ -52,7 +52,7 @@ void EmitBitCastF16U16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::I | |||
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | void EmitBitCastF32U32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | 54 | void EmitBitCastF32U32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { |
| 55 | ctx.AddF32("{}=uintBitsToFloat({});", inst, value); | 55 | ctx.AddF32("{}=utof({});", inst, value); |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | void EmitBitCastF64U64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { | 58 | void EmitBitCastF64U64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { |
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 ebaf50abd..19b51a813 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 | |||
| @@ -45,14 +45,13 @@ void EmitGetCbufU8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& | |||
| 45 | [[maybe_unused]] const IR::Value& binding, | 45 | [[maybe_unused]] const IR::Value& binding, |
| 46 | [[maybe_unused]] const IR::Value& offset) { | 46 | [[maybe_unused]] const IR::Value& offset) { |
| 47 | if (offset.IsImmediate()) { | 47 | if (offset.IsImmediate()) { |
| 48 | ctx.AddU32("{}=bitfieldExtract(floatBitsToUint({}_cbuf{}[{}].{}),int({}),8);", inst, | 48 | ctx.AddU32("{}=bitfieldExtract(ftou({}_cbuf{}[{}].{}),int({}),8);", inst, ctx.stage_name, |
| 49 | ctx.stage_name, binding.U32(), offset.U32() / 16, OffsetSwizzle(offset.U32()), | 49 | binding.U32(), offset.U32() / 16, OffsetSwizzle(offset.U32()), |
| 50 | (offset.U32() % 4) * 8); | 50 | (offset.U32() % 4) * 8); |
| 51 | } else { | 51 | } else { |
| 52 | const auto offset_var{ctx.var_alloc.Consume(offset)}; | 52 | const auto offset_var{ctx.var_alloc.Consume(offset)}; |
| 53 | ctx.AddU32( | 53 | ctx.AddU32("{}=bitfieldExtract(ftou({}_cbuf{}[{}/16][({}>>2)%4]),int(({}%4)*8),8);", inst, |
| 54 | "{}=bitfieldExtract(floatBitsToUint({}_cbuf{}[{}/16][({}>>2)%4]),int(({}%4)*8),8);", | 54 | ctx.stage_name, binding.U32(), offset_var, offset_var, offset_var); |
| 55 | inst, ctx.stage_name, binding.U32(), offset_var, offset_var, offset_var); | ||
| 56 | } | 55 | } |
| 57 | } | 56 | } |
| 58 | 57 | ||
| @@ -60,14 +59,13 @@ void EmitGetCbufS8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& | |||
| 60 | [[maybe_unused]] const IR::Value& binding, | 59 | [[maybe_unused]] const IR::Value& binding, |
| 61 | [[maybe_unused]] const IR::Value& offset) { | 60 | [[maybe_unused]] const IR::Value& offset) { |
| 62 | if (offset.IsImmediate()) { | 61 | if (offset.IsImmediate()) { |
| 63 | ctx.AddU32("{}=bitfieldExtract(floatBitsToInt({}_cbuf{}[{}].{}),int({}),8);", inst, | 62 | ctx.AddU32("{}=bitfieldExtract(ftoi({}_cbuf{}[{}].{}),int({}),8);", inst, ctx.stage_name, |
| 64 | ctx.stage_name, binding.U32(), offset.U32() / 16, OffsetSwizzle(offset.U32()), | 63 | binding.U32(), offset.U32() / 16, OffsetSwizzle(offset.U32()), |
| 65 | (offset.U32() % 4) * 8); | 64 | (offset.U32() % 4) * 8); |
| 66 | } else { | 65 | } else { |
| 67 | const auto offset_var{ctx.var_alloc.Consume(offset)}; | 66 | const auto offset_var{ctx.var_alloc.Consume(offset)}; |
| 68 | ctx.AddU32( | 67 | ctx.AddU32("{}=bitfieldExtract(ftoi({}_cbuf{}[{}/16][({}>>2)%4]),int(({}%4)*8),8);", inst, |
| 69 | "{}=bitfieldExtract(floatBitsToInt({}_cbuf{}[{}/16][({}>>2)%4]),int(({}%4)*8),8);", | 68 | ctx.stage_name, binding.U32(), offset_var, offset_var, offset_var); |
| 70 | inst, ctx.stage_name, binding.U32(), offset_var, offset_var, offset_var); | ||
| 71 | } | 69 | } |
| 72 | } | 70 | } |
| 73 | 71 | ||
| @@ -75,12 +73,12 @@ void EmitGetCbufU16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst | |||
| 75 | [[maybe_unused]] const IR::Value& binding, | 73 | [[maybe_unused]] const IR::Value& binding, |
| 76 | [[maybe_unused]] const IR::Value& offset) { | 74 | [[maybe_unused]] const IR::Value& offset) { |
| 77 | if (offset.IsImmediate()) { | 75 | if (offset.IsImmediate()) { |
| 78 | ctx.AddU32("{}=bitfieldExtract(floatBitsToUint({}_cbuf{}[{}].{}),int({}),16);", inst, | 76 | ctx.AddU32("{}=bitfieldExtract(ftou({}_cbuf{}[{}].{}),int({}),16);", inst, ctx.stage_name, |
| 79 | ctx.stage_name, binding.U32(), offset.U32() / 16, OffsetSwizzle(offset.U32()), | 77 | binding.U32(), offset.U32() / 16, OffsetSwizzle(offset.U32()), |
| 80 | ((offset.U32() / 2) % 2) * 16); | 78 | ((offset.U32() / 2) % 2) * 16); |
| 81 | } else { | 79 | } else { |
| 82 | const auto offset_var{ctx.var_alloc.Consume(offset)}; | 80 | const auto offset_var{ctx.var_alloc.Consume(offset)}; |
| 83 | ctx.AddU32("{}=bitfieldExtract(floatBitsToUint({}_cbuf{}[{}/16][({}>>2)%4]),int((({}/" | 81 | ctx.AddU32("{}=bitfieldExtract(ftou({}_cbuf{}[{}/16][({}>>2)%4]),int((({}/" |
| 84 | "2)%2)*16),16);", | 82 | "2)%2)*16),16);", |
| 85 | inst, ctx.stage_name, binding.U32(), offset_var, offset_var, offset_var); | 83 | inst, ctx.stage_name, binding.U32(), offset_var, offset_var, offset_var); |
| 86 | } | 84 | } |
| @@ -90,12 +88,12 @@ void EmitGetCbufS16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst | |||
| 90 | [[maybe_unused]] const IR::Value& binding, | 88 | [[maybe_unused]] const IR::Value& binding, |
| 91 | [[maybe_unused]] const IR::Value& offset) { | 89 | [[maybe_unused]] const IR::Value& offset) { |
| 92 | if (offset.IsImmediate()) { | 90 | if (offset.IsImmediate()) { |
| 93 | ctx.AddU32("{}=bitfieldExtract(floatBitsToInt({}_cbuf{}[{}].{}),int({}),16);", inst, | 91 | ctx.AddU32("{}=bitfieldExtract(ftoi({}_cbuf{}[{}].{}),int({}),16);", inst, ctx.stage_name, |
| 94 | ctx.stage_name, binding.U32(), offset.U32() / 16, OffsetSwizzle(offset.U32()), | 92 | binding.U32(), offset.U32() / 16, OffsetSwizzle(offset.U32()), |
| 95 | ((offset.U32() / 2) % 2) * 16); | 93 | ((offset.U32() / 2) % 2) * 16); |
| 96 | } else { | 94 | } else { |
| 97 | const auto offset_var{ctx.var_alloc.Consume(offset)}; | 95 | const auto offset_var{ctx.var_alloc.Consume(offset)}; |
| 98 | ctx.AddU32("{}=bitfieldExtract(floatBitsToInt({}_cbuf{}[{}/16][({}>>2)%4]),int((({}/" | 96 | ctx.AddU32("{}=bitfieldExtract(ftoi({}_cbuf{}[{}/16][({}>>2)%4]),int((({}/" |
| 99 | "2)%2)*16),16);", | 97 | "2)%2)*16),16);", |
| 100 | inst, ctx.stage_name, binding.U32(), offset_var, offset_var, offset_var); | 98 | inst, ctx.stage_name, binding.U32(), offset_var, offset_var, offset_var); |
| 101 | } | 99 | } |
| @@ -104,12 +102,12 @@ void EmitGetCbufS16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst | |||
| 104 | void EmitGetCbufU32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 102 | void EmitGetCbufU32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 105 | const IR::Value& offset) { | 103 | const IR::Value& offset) { |
| 106 | if (offset.IsImmediate()) { | 104 | if (offset.IsImmediate()) { |
| 107 | ctx.AddU32("{}=floatBitsToUint({}_cbuf{}[{}].{});", inst, ctx.stage_name, binding.U32(), | 105 | ctx.AddU32("{}=ftou({}_cbuf{}[{}].{});", inst, ctx.stage_name, binding.U32(), |
| 108 | offset.U32() / 16, OffsetSwizzle(offset.U32())); | 106 | offset.U32() / 16, OffsetSwizzle(offset.U32())); |
| 109 | } else { | 107 | } else { |
| 110 | const auto offset_var{ctx.var_alloc.Consume(offset)}; | 108 | const auto offset_var{ctx.var_alloc.Consume(offset)}; |
| 111 | ctx.AddU32("{}=floatBitsToUint({}_cbuf{}[{}/16][({}>>2)%4]);", inst, ctx.stage_name, | 109 | ctx.AddU32("{}=ftou({}_cbuf{}[{}/16][({}>>2)%4]);", inst, ctx.stage_name, binding.U32(), |
| 112 | binding.U32(), offset_var, offset_var); | 110 | offset_var, offset_var); |
| 113 | } | 111 | } |
| 114 | } | 112 | } |
| 115 | 113 | ||
| @@ -128,15 +126,14 @@ void EmitGetCbufF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | |||
| 128 | void EmitGetCbufU32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, | 126 | void EmitGetCbufU32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, |
| 129 | const IR::Value& offset) { | 127 | const IR::Value& offset) { |
| 130 | if (offset.IsImmediate()) { | 128 | if (offset.IsImmediate()) { |
| 131 | ctx.AddU32x2( | 129 | ctx.AddU32x2("{}=uvec2(ftou({}_cbuf{}[{}].{}),ftou({}_cbuf{}[{}].{}));", inst, |
| 132 | "{}=uvec2(floatBitsToUint({}_cbuf{}[{}].{}),floatBitsToUint({}_cbuf{}[{}].{}));", inst, | 130 | ctx.stage_name, binding.U32(), offset.U32() / 16, OffsetSwizzle(offset.U32()), |
| 133 | ctx.stage_name, binding.U32(), offset.U32() / 16, OffsetSwizzle(offset.U32()), | 131 | ctx.stage_name, binding.U32(), (offset.U32() + 4) / 16, |
| 134 | ctx.stage_name, binding.U32(), (offset.U32() + 4) / 16, | 132 | OffsetSwizzle(offset.U32() + 4)); |
| 135 | OffsetSwizzle(offset.U32() + 4)); | ||
| 136 | } else { | 133 | } else { |
| 137 | const auto offset_var{ctx.var_alloc.Consume(offset)}; | 134 | const auto offset_var{ctx.var_alloc.Consume(offset)}; |
| 138 | ctx.AddU32x2("{}=uvec2(floatBitsToUint({}_cbuf{}[{}/16][({}/" | 135 | ctx.AddU32x2("{}=uvec2(ftou({}_cbuf{}[{}/16][({}/" |
| 139 | "4)%4]),floatBitsToUint({}_cbuf{}[({}+4)/16][(({}+4)>>2)%4]));", | 136 | "4)%4]),ftou({}_cbuf{}[({}+4)/16][(({}+4)>>2)%4]));", |
| 140 | inst, ctx.stage_name, binding.U32(), offset_var, offset_var, ctx.stage_name, | 137 | inst, ctx.stage_name, binding.U32(), offset_var, offset_var, ctx.stage_name, |
| 141 | binding.U32(), offset_var, offset_var); | 138 | binding.U32(), offset_var, offset_var); |
| 142 | } | 139 | } |
| @@ -180,13 +177,13 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr, | |||
| 180 | ctx.AddF32("{}=gl_PointCoord.{};", inst, swizzle); | 177 | ctx.AddF32("{}=gl_PointCoord.{};", inst, swizzle); |
| 181 | break; | 178 | break; |
| 182 | case IR::Attribute::InstanceId: | 179 | case IR::Attribute::InstanceId: |
| 183 | ctx.AddF32("{}=intBitsToFloat(gl_InstanceID);", inst); | 180 | ctx.AddF32("{}=itof(gl_InstanceID);", inst); |
| 184 | break; | 181 | break; |
| 185 | case IR::Attribute::VertexId: | 182 | case IR::Attribute::VertexId: |
| 186 | ctx.AddF32("{}=intBitsToFloat(gl_VertexID);", inst); | 183 | ctx.AddF32("{}=itof(gl_VertexID);", inst); |
| 187 | break; | 184 | break; |
| 188 | case IR::Attribute::FrontFace: | 185 | case IR::Attribute::FrontFace: |
| 189 | ctx.AddF32("{}=intBitsToFloat(gl_FrontFacing?-1:0);", inst); | 186 | ctx.AddF32("{}=itof(gl_FrontFacing?-1:0);", inst); |
| 190 | break; | 187 | break; |
| 191 | case IR::Attribute::TessellationEvaluationPointU: | 188 | case IR::Attribute::TessellationEvaluationPointU: |
| 192 | case IR::Attribute::TessellationEvaluationPointV: | 189 | case IR::Attribute::TessellationEvaluationPointV: |
| @@ -231,7 +228,7 @@ void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, std::string_view val | |||
| 231 | // layer extension"); | 228 | // layer extension"); |
| 232 | break; | 229 | break; |
| 233 | } | 230 | } |
| 234 | ctx.Add("gl_ViewportIndex=floatBitsToInt({});", value); | 231 | ctx.Add("gl_ViewportIndex=ftoi({});", value); |
| 235 | break; | 232 | break; |
| 236 | case IR::Attribute::ClipDistance0: | 233 | case IR::Attribute::ClipDistance0: |
| 237 | case IR::Attribute::ClipDistance1: | 234 | case IR::Attribute::ClipDistance1: |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp index 8c54f0fb3..37ddd57d3 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp | |||
| @@ -212,7 +212,11 @@ void EmitImageSampleDrefImplicitLod([[maybe_unused]] EmitContext& ctx, | |||
| 212 | } | 212 | } |
| 213 | } else { | 213 | } else { |
| 214 | if (ctx.stage == Stage::Fragment) { | 214 | if (ctx.stage == Stage::Fragment) { |
| 215 | ctx.AddF32("{}=texture({},{}({},{}){});", inst, texture, cast, coords, dref, bias); | 215 | if (info.type == TextureType::ColorArrayCube) { |
| 216 | ctx.AddF32("{}=texture({},vec4({}),{});", inst, texture, coords, dref); | ||
| 217 | } else { | ||
| 218 | ctx.AddF32("{}=texture({},{}({},{}){});", inst, texture, cast, coords, dref, bias); | ||
| 219 | } | ||
| 216 | } else { | 220 | } else { |
| 217 | ctx.AddF32("{}=textureLod({},{}({},{}),0.0);", inst, texture, cast, coords, dref); | 221 | ctx.AddF32("{}=textureLod({},{}({},{}),0.0);", inst, texture, cast, coords, dref); |
| 218 | } | 222 | } |
| @@ -238,6 +242,7 @@ void EmitImageSampleDrefExplicitLod([[maybe_unused]] EmitContext& ctx, | |||
| 238 | throw NotImplementedException("EmitImageSampleDrefExplicitLod Lod clamp samples"); | 242 | throw NotImplementedException("EmitImageSampleDrefExplicitLod Lod clamp samples"); |
| 239 | } | 243 | } |
| 240 | const auto texture{Texture(ctx, info, index)}; | 244 | const auto texture{Texture(ctx, info, index)}; |
| 245 | const auto cast{ShadowSamplerVecCast(info.type)}; | ||
| 241 | if (!offset.IsEmpty()) { | 246 | if (!offset.IsEmpty()) { |
| 242 | const auto offset_str{CastToIntVec(ctx.var_alloc.Consume(offset), info)}; | 247 | const auto offset_str{CastToIntVec(ctx.var_alloc.Consume(offset), info)}; |
| 243 | if (info.type == TextureType::ColorArrayCube) { | 248 | if (info.type == TextureType::ColorArrayCube) { |
| @@ -251,7 +256,8 @@ void EmitImageSampleDrefExplicitLod([[maybe_unused]] EmitContext& ctx, | |||
| 251 | if (info.type == TextureType::ColorArrayCube) { | 256 | if (info.type == TextureType::ColorArrayCube) { |
| 252 | ctx.AddF32("{}=textureLod({},{},{},{});", inst, texture, coords, dref, lod_lc); | 257 | ctx.AddF32("{}=textureLod({},{},{},{});", inst, texture, coords, dref, lod_lc); |
| 253 | } else { | 258 | } else { |
| 254 | ctx.AddF32("{}=textureLod({},vec3({},{}),{});", inst, texture, coords, dref, lod_lc); | 259 | ctx.AddF32("{}=textureLod({},{}({},{}),{});", inst, texture, cast, coords, dref, |
| 260 | lod_lc); | ||
| 255 | } | 261 | } |
| 256 | } | 262 | } |
| 257 | } | 263 | } |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h b/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h index 89ded3614..90dcfcef7 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h +++ b/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h | |||
| @@ -105,9 +105,9 @@ void EmitLoadGlobalU8(EmitContext& ctx); | |||
| 105 | void EmitLoadGlobalS8(EmitContext& ctx); | 105 | void EmitLoadGlobalS8(EmitContext& ctx); |
| 106 | void EmitLoadGlobalU16(EmitContext& ctx); | 106 | void EmitLoadGlobalU16(EmitContext& ctx); |
| 107 | void EmitLoadGlobalS16(EmitContext& ctx); | 107 | void EmitLoadGlobalS16(EmitContext& ctx); |
| 108 | void EmitLoadGlobal32(EmitContext& ctx, std::string_view address); | 108 | void EmitLoadGlobal32(EmitContext& ctx, IR::Inst& inst, std::string_view address); |
| 109 | void EmitLoadGlobal64(EmitContext& ctx, std::string_view address); | 109 | void EmitLoadGlobal64(EmitContext& ctx, IR::Inst& inst, std::string_view address); |
| 110 | void EmitLoadGlobal128(EmitContext& ctx, std::string_view address); | 110 | void EmitLoadGlobal128(EmitContext& ctx, IR::Inst& inst, std::string_view address); |
| 111 | void EmitWriteGlobalU8(EmitContext& ctx); | 111 | void EmitWriteGlobalU8(EmitContext& ctx); |
| 112 | void EmitWriteGlobalS8(EmitContext& ctx); | 112 | void EmitWriteGlobalS8(EmitContext& ctx); |
| 113 | void EmitWriteGlobalU16(EmitContext& ctx); | 113 | void EmitWriteGlobalU16(EmitContext& ctx); |
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_memory.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_memory.cpp index a4411b68b..bc4363824 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_memory.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_memory.cpp | |||
| @@ -9,6 +9,62 @@ | |||
| 9 | #include "shader_recompiler/frontend/ir/value.h" | 9 | #include "shader_recompiler/frontend/ir/value.h" |
| 10 | 10 | ||
| 11 | namespace Shader::Backend::GLSL { | 11 | namespace Shader::Backend::GLSL { |
| 12 | void EmitLoadGlobalU8([[maybe_unused]] EmitContext& ctx) { | ||
| 13 | NotImplemented(); | ||
| 14 | } | ||
| 15 | |||
| 16 | void EmitLoadGlobalS8([[maybe_unused]] EmitContext& ctx) { | ||
| 17 | NotImplemented(); | ||
| 18 | } | ||
| 19 | |||
| 20 | void EmitLoadGlobalU16([[maybe_unused]] EmitContext& ctx) { | ||
| 21 | NotImplemented(); | ||
| 22 | } | ||
| 23 | |||
| 24 | void EmitLoadGlobalS16([[maybe_unused]] EmitContext& ctx) { | ||
| 25 | NotImplemented(); | ||
| 26 | } | ||
| 27 | |||
| 28 | void EmitLoadGlobal32(EmitContext& ctx, IR::Inst& inst, std::string_view address) { | ||
| 29 | ctx.AddU32("{}=LoadGlobal32({});", inst, address); | ||
| 30 | } | ||
| 31 | |||
| 32 | void EmitLoadGlobal64(EmitContext& ctx, IR::Inst& inst, std::string_view address) { | ||
| 33 | ctx.AddU32x2("{}=LoadGlobal64({});", inst, address); | ||
| 34 | } | ||
| 35 | |||
| 36 | void EmitLoadGlobal128(EmitContext& ctx, IR::Inst& inst, std::string_view address) { | ||
| 37 | ctx.AddU32x4("{}=LoadGlobal128({});", inst, address); | ||
| 38 | } | ||
| 39 | |||
| 40 | void EmitWriteGlobalU8([[maybe_unused]] EmitContext& ctx) { | ||
| 41 | NotImplemented(); | ||
| 42 | } | ||
| 43 | |||
| 44 | void EmitWriteGlobalS8([[maybe_unused]] EmitContext& ctx) { | ||
| 45 | NotImplemented(); | ||
| 46 | } | ||
| 47 | |||
| 48 | void EmitWriteGlobalU16([[maybe_unused]] EmitContext& ctx) { | ||
| 49 | NotImplemented(); | ||
| 50 | } | ||
| 51 | |||
| 52 | void EmitWriteGlobalS16([[maybe_unused]] EmitContext& ctx) { | ||
| 53 | NotImplemented(); | ||
| 54 | } | ||
| 55 | |||
| 56 | void EmitWriteGlobal32(EmitContext& ctx, std::string_view address, std::string_view value) { | ||
| 57 | ctx.Add("WriteGlobal32({},{});", address, value); | ||
| 58 | } | ||
| 59 | |||
| 60 | void EmitWriteGlobal64(EmitContext& ctx, std::string_view address, std::string_view value) { | ||
| 61 | ctx.Add("WriteGlobal64({},{});", address, value); | ||
| 62 | } | ||
| 63 | |||
| 64 | void EmitWriteGlobal128(EmitContext& ctx, std::string_view address, std::string_view value) { | ||
| 65 | ctx.Add("WriteGlobal128({},{});", address, value); | ||
| 66 | } | ||
| 67 | |||
| 12 | void EmitLoadStorageU8([[maybe_unused]] EmitContext& ctx, IR::Inst& inst, | 68 | void EmitLoadStorageU8([[maybe_unused]] EmitContext& ctx, IR::Inst& inst, |
| 13 | [[maybe_unused]] const IR::Value& binding, | 69 | [[maybe_unused]] const IR::Value& binding, |
| 14 | [[maybe_unused]] const IR::Value& offset) { | 70 | [[maybe_unused]] const IR::Value& offset) { |
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 cf7b2a51e..cac803146 100644 --- a/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp +++ b/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp | |||
| @@ -232,62 +232,6 @@ void EmitUndefU64(EmitContext& ctx, IR::Inst& inst) { | |||
| 232 | NotImplemented(); | 232 | NotImplemented(); |
| 233 | } | 233 | } |
| 234 | 234 | ||
| 235 | void EmitLoadGlobalU8(EmitContext& ctx) { | ||
| 236 | NotImplemented(); | ||
| 237 | } | ||
| 238 | |||
| 239 | void EmitLoadGlobalS8(EmitContext& ctx) { | ||
| 240 | NotImplemented(); | ||
| 241 | } | ||
| 242 | |||
| 243 | void EmitLoadGlobalU16(EmitContext& ctx) { | ||
| 244 | NotImplemented(); | ||
| 245 | } | ||
| 246 | |||
| 247 | void EmitLoadGlobalS16(EmitContext& ctx) { | ||
| 248 | NotImplemented(); | ||
| 249 | } | ||
| 250 | |||
| 251 | void EmitLoadGlobal32(EmitContext& ctx, std::string_view address) { | ||
| 252 | NotImplemented(); | ||
| 253 | } | ||
| 254 | |||
| 255 | void EmitLoadGlobal64(EmitContext& ctx, std::string_view address) { | ||
| 256 | NotImplemented(); | ||
| 257 | } | ||
| 258 | |||
| 259 | void EmitLoadGlobal128(EmitContext& ctx, std::string_view address) { | ||
| 260 | NotImplemented(); | ||
| 261 | } | ||
| 262 | |||
| 263 | void EmitWriteGlobalU8(EmitContext& ctx) { | ||
| 264 | NotImplemented(); | ||
| 265 | } | ||
| 266 | |||
| 267 | void EmitWriteGlobalS8(EmitContext& ctx) { | ||
| 268 | NotImplemented(); | ||
| 269 | } | ||
| 270 | |||
| 271 | void EmitWriteGlobalU16(EmitContext& ctx) { | ||
| 272 | NotImplemented(); | ||
| 273 | } | ||
| 274 | |||
| 275 | void EmitWriteGlobalS16(EmitContext& ctx) { | ||
| 276 | NotImplemented(); | ||
| 277 | } | ||
| 278 | |||
| 279 | void EmitWriteGlobal32(EmitContext& ctx, std::string_view address, std::string_view value) { | ||
| 280 | NotImplemented(); | ||
| 281 | } | ||
| 282 | |||
| 283 | void EmitWriteGlobal64(EmitContext& ctx, std::string_view address, std::string_view value) { | ||
| 284 | NotImplemented(); | ||
| 285 | } | ||
| 286 | |||
| 287 | void EmitWriteGlobal128(EmitContext& ctx, std::string_view address, std::string_view value) { | ||
| 288 | NotImplemented(); | ||
| 289 | } | ||
| 290 | |||
| 291 | void EmitGetZeroFromOp(EmitContext& ctx) { | 235 | void EmitGetZeroFromOp(EmitContext& ctx) { |
| 292 | NotImplemented(); | 236 | NotImplemented(); |
| 293 | } | 237 | } |
diff --git a/src/shader_recompiler/backend/glsl/var_alloc.cpp b/src/shader_recompiler/backend/glsl/var_alloc.cpp index 1ab64add4..0ae56651e 100644 --- a/src/shader_recompiler/backend/glsl/var_alloc.cpp +++ b/src/shader_recompiler/backend/glsl/var_alloc.cpp | |||
| @@ -58,13 +58,13 @@ std::string FormatFloat(std::string_view value, IR::Type type) { | |||
| 58 | // TODO: Confirm FP64 nan/inf | 58 | // TODO: Confirm FP64 nan/inf |
| 59 | if (type == IR::Type::F32) { | 59 | if (type == IR::Type::F32) { |
| 60 | if (value == "nan") { | 60 | if (value == "nan") { |
| 61 | return "uintBitsToFloat(0x7fc00000)"; | 61 | return "utof(0x7fc00000)"; |
| 62 | } | 62 | } |
| 63 | if (value == "inf") { | 63 | if (value == "inf") { |
| 64 | return "uintBitsToFloat(0x7f800000)"; | 64 | return "utof(0x7f800000)"; |
| 65 | } | 65 | } |
| 66 | if (value == "-inf") { | 66 | if (value == "-inf") { |
| 67 | return "uintBitsToFloat(0xff800000)"; | 67 | return "utof(0xff800000)"; |
| 68 | } | 68 | } |
| 69 | } | 69 | } |
| 70 | if (value.find_first_of('e') != std::string_view::npos) { | 70 | if (value.find_first_of('e') != std::string_view::npos) { |