summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/shader_recompiler/backend/glsl/emit_context.cpp86
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_atomic.cpp2
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_bitwise_conversion.cpp4
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp57
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_image.cpp10
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_instructions.h6
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_memory.cpp56
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp56
-rw-r--r--src/shader_recompiler/backend/glsl/var_alloc.cpp6
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
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) {
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
42void EmitBitCastU32F32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { 42void 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
46void EmitBitCastU64F64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { 46void 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
54void EmitBitCastF32U32(EmitContext& ctx, IR::Inst& inst, std::string_view value) { 54void 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
58void EmitBitCastF64U64(EmitContext& ctx, IR::Inst& inst, std::string_view value) { 58void 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
104void EmitGetCbufU32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 102void 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,
128void EmitGetCbufU32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, 126void 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);
105void EmitLoadGlobalS8(EmitContext& ctx); 105void EmitLoadGlobalS8(EmitContext& ctx);
106void EmitLoadGlobalU16(EmitContext& ctx); 106void EmitLoadGlobalU16(EmitContext& ctx);
107void EmitLoadGlobalS16(EmitContext& ctx); 107void EmitLoadGlobalS16(EmitContext& ctx);
108void EmitLoadGlobal32(EmitContext& ctx, std::string_view address); 108void EmitLoadGlobal32(EmitContext& ctx, IR::Inst& inst, std::string_view address);
109void EmitLoadGlobal64(EmitContext& ctx, std::string_view address); 109void EmitLoadGlobal64(EmitContext& ctx, IR::Inst& inst, std::string_view address);
110void EmitLoadGlobal128(EmitContext& ctx, std::string_view address); 110void EmitLoadGlobal128(EmitContext& ctx, IR::Inst& inst, std::string_view address);
111void EmitWriteGlobalU8(EmitContext& ctx); 111void EmitWriteGlobalU8(EmitContext& ctx);
112void EmitWriteGlobalS8(EmitContext& ctx); 112void EmitWriteGlobalS8(EmitContext& ctx);
113void EmitWriteGlobalU16(EmitContext& ctx); 113void 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
11namespace Shader::Backend::GLSL { 11namespace Shader::Backend::GLSL {
12void EmitLoadGlobalU8([[maybe_unused]] EmitContext& ctx) {
13 NotImplemented();
14}
15
16void EmitLoadGlobalS8([[maybe_unused]] EmitContext& ctx) {
17 NotImplemented();
18}
19
20void EmitLoadGlobalU16([[maybe_unused]] EmitContext& ctx) {
21 NotImplemented();
22}
23
24void EmitLoadGlobalS16([[maybe_unused]] EmitContext& ctx) {
25 NotImplemented();
26}
27
28void EmitLoadGlobal32(EmitContext& ctx, IR::Inst& inst, std::string_view address) {
29 ctx.AddU32("{}=LoadGlobal32({});", inst, address);
30}
31
32void EmitLoadGlobal64(EmitContext& ctx, IR::Inst& inst, std::string_view address) {
33 ctx.AddU32x2("{}=LoadGlobal64({});", inst, address);
34}
35
36void EmitLoadGlobal128(EmitContext& ctx, IR::Inst& inst, std::string_view address) {
37 ctx.AddU32x4("{}=LoadGlobal128({});", inst, address);
38}
39
40void EmitWriteGlobalU8([[maybe_unused]] EmitContext& ctx) {
41 NotImplemented();
42}
43
44void EmitWriteGlobalS8([[maybe_unused]] EmitContext& ctx) {
45 NotImplemented();
46}
47
48void EmitWriteGlobalU16([[maybe_unused]] EmitContext& ctx) {
49 NotImplemented();
50}
51
52void EmitWriteGlobalS16([[maybe_unused]] EmitContext& ctx) {
53 NotImplemented();
54}
55
56void EmitWriteGlobal32(EmitContext& ctx, std::string_view address, std::string_view value) {
57 ctx.Add("WriteGlobal32({},{});", address, value);
58}
59
60void EmitWriteGlobal64(EmitContext& ctx, std::string_view address, std::string_view value) {
61 ctx.Add("WriteGlobal64({},{});", address, value);
62}
63
64void EmitWriteGlobal128(EmitContext& ctx, std::string_view address, std::string_view value) {
65 ctx.Add("WriteGlobal128({},{});", address, value);
66}
67
12void EmitLoadStorageU8([[maybe_unused]] EmitContext& ctx, IR::Inst& inst, 68void 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
235void EmitLoadGlobalU8(EmitContext& ctx) {
236 NotImplemented();
237}
238
239void EmitLoadGlobalS8(EmitContext& ctx) {
240 NotImplemented();
241}
242
243void EmitLoadGlobalU16(EmitContext& ctx) {
244 NotImplemented();
245}
246
247void EmitLoadGlobalS16(EmitContext& ctx) {
248 NotImplemented();
249}
250
251void EmitLoadGlobal32(EmitContext& ctx, std::string_view address) {
252 NotImplemented();
253}
254
255void EmitLoadGlobal64(EmitContext& ctx, std::string_view address) {
256 NotImplemented();
257}
258
259void EmitLoadGlobal128(EmitContext& ctx, std::string_view address) {
260 NotImplemented();
261}
262
263void EmitWriteGlobalU8(EmitContext& ctx) {
264 NotImplemented();
265}
266
267void EmitWriteGlobalS8(EmitContext& ctx) {
268 NotImplemented();
269}
270
271void EmitWriteGlobalU16(EmitContext& ctx) {
272 NotImplemented();
273}
274
275void EmitWriteGlobalS16(EmitContext& ctx) {
276 NotImplemented();
277}
278
279void EmitWriteGlobal32(EmitContext& ctx, std::string_view address, std::string_view value) {
280 NotImplemented();
281}
282
283void EmitWriteGlobal64(EmitContext& ctx, std::string_view address, std::string_view value) {
284 NotImplemented();
285}
286
287void EmitWriteGlobal128(EmitContext& ctx, std::string_view address, std::string_view value) {
288 NotImplemented();
289}
290
291void EmitGetZeroFromOp(EmitContext& ctx) { 235void 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) {