Просмотр исходного кода

glsl: Fix non-immediate buffer access

and many other misc implementations
ameerj 5 лет назад
Родитель
Сommit
ed14d31f66

+ 1 - 0
src/shader_recompiler/backend/glsl/emit_context.cpp

@@ -88,6 +88,7 @@ EmitContext::EmitContext(IR::Program& program, Bindings& bindings, const Profile
 }
 }
 
 
 void EmitContext::SetupExtensions(std::string& header) {
 void EmitContext::SetupExtensions(std::string& header) {
+    header += "#extension GL_ARB_separate_shader_objects : enable\n";
     if (info.uses_int64) {
     if (info.uses_int64) {
         header += "#extension GL_ARB_gpu_shader_int64 : enable\n";
         header += "#extension GL_ARB_gpu_shader_int64 : enable\n";
     }
     }

+ 15 - 0
src/shader_recompiler/backend/glsl/emit_context.h

@@ -90,6 +90,21 @@ public:
         Add<Type::F32x2>(format_str, inst, args...);
         Add<Type::F32x2>(format_str, inst, args...);
     }
     }
 
 
+    template <typename... Args>
+    void AddU32x3(const char* format_str, IR::Inst& inst, Args&&... args) {
+        Add<Type::U32x3>(format_str, inst, args...);
+    }
+
+    template <typename... Args>
+    void AddF32x3(const char* format_str, IR::Inst& inst, Args&&... args) {
+        Add<Type::F32x3>(format_str, inst, args...);
+    }
+
+    template <typename... Args>
+    void AddU32x4(const char* format_str, IR::Inst& inst, Args&&... args) {
+        Add<Type::U32x4>(format_str, inst, args...);
+    }
+
     template <typename... Args>
     template <typename... Args>
     void AddF32x4(const char* format_str, IR::Inst& inst, Args&&... args) {
     void AddF32x4(const char* format_str, IR::Inst& inst, Args&&... args) {
         Add<Type::F32x4>(format_str, inst, args...);
         Add<Type::F32x4>(format_str, inst, args...);

+ 5 - 0
src/shader_recompiler/backend/glsl/emit_glsl.cpp

@@ -160,8 +160,13 @@ void EmitCode(EmitContext& ctx, const IR::Program& program) {
             ctx.Add("return;");
             ctx.Add("return;");
             break;
             break;
         case IR::AbstractSyntaxNode::Type::Loop:
         case IR::AbstractSyntaxNode::Type::Loop:
+            ctx.Add("do{{");
+            break;
         case IR::AbstractSyntaxNode::Type::Repeat:
         case IR::AbstractSyntaxNode::Type::Repeat:
+            ctx.Add("}}while({});", ctx.reg_alloc.Consume(node.data.repeat.cond));
+            break;
         default:
         default:
+            fmt::print("{}", node.type);
             throw NotImplementedException("{}", node.type);
             throw NotImplementedException("{}", node.type);
             break;
             break;
         }
         }

+ 18 - 30
src/shader_recompiler/backend/glsl/emit_glsl_composite.cpp

@@ -17,19 +17,14 @@ void EmitCompositeConstructU32x2(EmitContext& ctx, IR::Inst& inst, std::string_v
     ctx.AddU32x2("{}=uvec2({},{});", inst, e1, e2);
     ctx.AddU32x2("{}=uvec2({},{});", inst, e1, e2);
 }
 }
 
 
-void EmitCompositeConstructU32x3([[maybe_unused]] EmitContext& ctx,
-                                 [[maybe_unused]] std::string_view e1,
-                                 [[maybe_unused]] std::string_view e2,
-                                 [[maybe_unused]] std::string_view e3) {
-    throw NotImplementedException("GLSL Instruction");
+void EmitCompositeConstructU32x3(EmitContext& ctx, IR::Inst& inst, std::string_view e1,
+                                 std::string_view e2, std::string_view e3) {
+    ctx.AddU32x3("{}=uvec3({},{},{});", inst, e1, e2, e3);
 }
 }
 
 
-void EmitCompositeConstructU32x4([[maybe_unused]] EmitContext& ctx,
-                                 [[maybe_unused]] std::string_view e1,
-                                 [[maybe_unused]] std::string_view e2,
-                                 [[maybe_unused]] std::string_view e3,
-                                 [[maybe_unused]] std::string_view e4) {
-    throw NotImplementedException("GLSL Instruction");
+void EmitCompositeConstructU32x4(EmitContext& ctx, IR::Inst& inst, std::string_view e1,
+                                 std::string_view e2, std::string_view e3, std::string_view e4) {
+    ctx.AddU32x4("{}=uvec4({},{},{},{});", inst, e1, e2, e3, e4);
 }
 }
 
 
 void EmitCompositeExtractU32x2(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
 void EmitCompositeExtractU32x2(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
@@ -37,16 +32,14 @@ void EmitCompositeExtractU32x2(EmitContext& ctx, IR::Inst& inst, std::string_vie
     ctx.AddU32("{}={}.{};", inst, composite, SWIZZLE[index]);
     ctx.AddU32("{}={}.{};", inst, composite, SWIZZLE[index]);
 }
 }
 
 
-void EmitCompositeExtractU32x3([[maybe_unused]] EmitContext& ctx,
-                               [[maybe_unused]] std::string_view composite,
-                               [[maybe_unused]] u32 index) {
-    throw NotImplementedException("GLSL Instruction");
+void EmitCompositeExtractU32x3(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
+                               u32 index) {
+    ctx.AddU32("{}={}.{};", inst, composite, SWIZZLE[index]);
 }
 }
 
 
-void EmitCompositeExtractU32x4([[maybe_unused]] EmitContext& ctx,
-                               [[maybe_unused]] std::string_view composite,
-                               [[maybe_unused]] u32 index) {
-    throw NotImplementedException("GLSL Instruction");
+void EmitCompositeExtractU32x4(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
+                               u32 index) {
+    ctx.AddU32("{}={}.{};", inst, composite, SWIZZLE[index]);
 }
 }
 
 
 void EmitCompositeInsertU32x2([[maybe_unused]] EmitContext& ctx,
 void EmitCompositeInsertU32x2([[maybe_unused]] EmitContext& ctx,
@@ -135,19 +128,14 @@ void EmitCompositeConstructF32x2(EmitContext& ctx, IR::Inst& inst, std::string_v
     ctx.AddF32x2("{}=vec2({},{});", inst, e1, e2);
     ctx.AddF32x2("{}=vec2({},{});", inst, e1, e2);
 }
 }
 
 
-void EmitCompositeConstructF32x3([[maybe_unused]] EmitContext& ctx,
-                                 [[maybe_unused]] std::string_view e1,
-                                 [[maybe_unused]] std::string_view e2,
-                                 [[maybe_unused]] std::string_view e3) {
-    throw NotImplementedException("GLSL Instruction");
+void EmitCompositeConstructF32x3(EmitContext& ctx, IR::Inst& inst, std::string_view e1,
+                                 std::string_view e2, std::string_view e3) {
+    ctx.AddF32x3("{}=vec3({},{},{});", inst, e1, e2, e3);
 }
 }
 
 
-void EmitCompositeConstructF32x4([[maybe_unused]] EmitContext& ctx,
-                                 [[maybe_unused]] std::string_view e1,
-                                 [[maybe_unused]] std::string_view e2,
-                                 [[maybe_unused]] std::string_view e3,
-                                 [[maybe_unused]] std::string_view e4) {
-    throw NotImplementedException("GLSL Instruction");
+void EmitCompositeConstructF32x4(EmitContext& ctx, IR::Inst& inst, std::string_view e1,
+                                 std::string_view e2, std::string_view e3, std::string_view e4) {
+    ctx.AddF32x4("{}=vec4({},{},{},{});", inst, e1, e2, e3, e4);
 }
 }
 
 
 void EmitCompositeExtractF32x2(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
 void EmitCompositeExtractF32x2(EmitContext& ctx, IR::Inst& inst, std::string_view composite,

+ 57 - 11
src/shader_recompiler/backend/glsl/emit_glsl_context_get_set.cpp

@@ -10,8 +10,18 @@
 #include "shader_recompiler/profile.h"
 #include "shader_recompiler/profile.h"
 
 
 namespace Shader::Backend::GLSL {
 namespace Shader::Backend::GLSL {
+namespace {
 static constexpr std::string_view SWIZZLE{"xyzw"};
 static constexpr std::string_view SWIZZLE{"xyzw"};
 
 
+u32 CbufIndex(u32 offset) {
+    return (offset / 4) % 4;
+}
+
+char OffsetSwizzle(u32 offset) {
+    return SWIZZLE[CbufIndex(offset)];
+}
+} // namespace
+
 void EmitGetCbufU8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] const IR::Value& binding,
 void EmitGetCbufU8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] const IR::Value& binding,
                    [[maybe_unused]] const IR::Value& offset) {
                    [[maybe_unused]] const IR::Value& offset) {
     throw NotImplementedException("GLSL");
     throw NotImplementedException("GLSL");
@@ -34,22 +44,42 @@ void EmitGetCbufS16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] const IR
 
 
 void EmitGetCbufU32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
 void EmitGetCbufU32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
                     const IR::Value& offset) {
                     const IR::Value& offset) {
-    const auto u32_offset{offset.U32()};
-    const auto index{(u32_offset / 4) % 4};
-    ctx.AddU32("{}=floatBitsToUint(cbuf{}[{}].{});", inst, binding.U32(), u32_offset / 16,
-               SWIZZLE[index]);
+    if (offset.IsImmediate()) {
+        ctx.AddU32("{}=floatBitsToUint(cbuf{}[{}].{});", inst, binding.U32(), offset.U32() / 16,
+                   OffsetSwizzle(offset.U32()));
+    } else {
+        const auto offset_var{ctx.reg_alloc.Consume(offset)};
+        ctx.AddU32("{}=floatBitsToUint(cbuf{}[{}/16][({}/4)%4]);", inst, binding.U32(), offset_var,
+                   offset_var);
+    }
 }
 }
 
 
 void EmitGetCbufF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
 void EmitGetCbufF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
                     const IR::Value& offset) {
                     const IR::Value& offset) {
-    const auto u32_offset{offset.U32()};
-    const auto index{(u32_offset / 4) % 4};
-    ctx.AddF32("{}=cbuf{}[{}].{};", inst, binding.U32(), u32_offset / 16, SWIZZLE[index]);
+    if (offset.IsImmediate()) {
+        ctx.AddF32("{}=cbuf{}[{}].{};", inst, binding.U32(), offset.U32() / 16,
+                   OffsetSwizzle(offset.U32()));
+    } else {
+        const auto offset_var{ctx.reg_alloc.Consume(offset)};
+        ctx.AddF32("{}=cbuf{}[{}/16][({}/4)%4];", inst, binding.U32(), offset_var, offset_var);
+    }
 }
 }
 
 
-void EmitGetCbufU32x2([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] const IR::Value& binding,
-                      [[maybe_unused]] const IR::Value& offset) {
-    throw NotImplementedException("GLSL");
+void EmitGetCbufU32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
+                      const IR::Value& offset) {
+    if (offset.IsImmediate()) {
+        const auto u32_offset{offset.U32()};
+        const auto index{(u32_offset / 4) % 4};
+        ctx.AddU32x2("{}=uvec2(floatBitsToUint(cbuf{}[{}].{}),floatBitsToUint(cbuf{}[{}].{}));",
+                     inst, binding.U32(), offset.U32() / 16, OffsetSwizzle(offset.U32()),
+                     binding.U32(), (offset.U32() + 1) / 16, OffsetSwizzle(offset.U32() + 1));
+    } else {
+        const auto offset_var{ctx.reg_alloc.Consume(offset)};
+        ctx.AddU32x2("{}=uvec2(floatBitsToUint(cbuf{}[{}/16][({}/"
+                     "4)%4]),floatBitsToUint(cbuf{}[({}+1)/16][(({}+1/4))%4]));",
+                     inst, binding.U32(), offset_var, offset_var, binding.U32(), offset_var,
+                     offset_var);
+    }
 }
 }
 
 
 void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr,
 void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr,
@@ -66,7 +96,23 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr,
     case IR::Attribute::PositionY:
     case IR::Attribute::PositionY:
     case IR::Attribute::PositionZ:
     case IR::Attribute::PositionZ:
     case IR::Attribute::PositionW:
     case IR::Attribute::PositionW:
-        ctx.AddF32("{}=gl_Position.{};", inst, swizzle);
+        switch (ctx.stage) {
+        case Stage::VertexA:
+        case Stage::VertexB:
+            ctx.AddF32("{}=gl_Position.{};", inst, swizzle);
+            break;
+        case Stage::Fragment:
+            ctx.AddF32("{}=gl_FragCoord.{};", inst, swizzle);
+            break;
+        default:
+            throw NotImplementedException("Get Position for stage {}", ctx.stage);
+        }
+        break;
+    case IR::Attribute::InstanceId:
+        ctx.AddS32("{}=gl_InstanceID;", inst, ctx.attrib_name);
+        break;
+    case IR::Attribute::VertexId:
+        ctx.AddS32("{}=gl_VertexID;", inst, ctx.attrib_name);
         break;
         break;
     default:
     default:
         fmt::print("Get attribute {}", attr);
         fmt::print("Get attribute {}", attr);

+ 1 - 1
src/shader_recompiler/backend/glsl/emit_glsl_convert.cpp

@@ -197,7 +197,7 @@ void EmitConvertF32U8([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::In
 
 
 void EmitConvertF32U16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst,
 void EmitConvertF32U16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst,
                        [[maybe_unused]] std::string_view value) {
                        [[maybe_unused]] std::string_view value) {
-    throw NotImplementedException("GLSL Instruction");
+    ctx.AddF32("{}=float({});", inst, value);
 }
 }
 
 
 void EmitConvertF32U32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst,
 void EmitConvertF32U32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst,

+ 1 - 1
src/shader_recompiler/backend/glsl/emit_glsl_floating_point.cpp

@@ -133,7 +133,7 @@ void EmitFPRecip64(EmitContext& ctx, IR::Inst& inst, std::string_view value) {
 
 
 void EmitFPRecipSqrt32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst,
 void EmitFPRecipSqrt32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst,
                        [[maybe_unused]] std::string_view value) {
                        [[maybe_unused]] std::string_view value) {
-    throw NotImplementedException("GLSL Instruction");
+    ctx.AddF32("{}=1/sqrt({});", inst, value);
 }
 }
 
 
 void EmitFPRecipSqrt64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst,
 void EmitFPRecipSqrt64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst,

+ 16 - 12
src/shader_recompiler/backend/glsl/emit_glsl_instructions.h

@@ -60,7 +60,8 @@ void EmitGetCbufU32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
                     const IR::Value& offset);
                     const IR::Value& offset);
 void EmitGetCbufF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
 void EmitGetCbufF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
                     const IR::Value& offset);
                     const IR::Value& offset);
-void EmitGetCbufU32x2(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset);
+void EmitGetCbufU32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
+                      const IR::Value& offset);
 void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr,
 void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr,
                       std::string_view vertex);
                       std::string_view vertex);
 void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, std::string_view value,
 void EmitSetAttribute(EmitContext& ctx, IR::Attribute attr, std::string_view value,
@@ -116,7 +117,8 @@ void EmitLoadStorage32(EmitContext& ctx, IR::Inst& inst, const IR::Value& bindin
                        const IR::Value& offset);
                        const IR::Value& offset);
 void EmitLoadStorage64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
 void EmitLoadStorage64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
                        const IR::Value& offset);
                        const IR::Value& offset);
-void EmitLoadStorage128(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset);
+void EmitLoadStorage128(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
+                        const IR::Value& offset);
 void EmitWriteStorageU8(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset,
 void EmitWriteStorageU8(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset,
                         std::string_view value);
                         std::string_view value);
 void EmitWriteStorageS8(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset,
 void EmitWriteStorageS8(EmitContext& ctx, const IR::Value& binding, const IR::Value& offset,
@@ -145,14 +147,16 @@ void EmitWriteSharedU64(EmitContext& ctx, std::string_view offset, std::string_v
 void EmitWriteSharedU128(EmitContext& ctx, std::string_view offset, std::string_view value);
 void EmitWriteSharedU128(EmitContext& ctx, std::string_view offset, std::string_view value);
 void EmitCompositeConstructU32x2(EmitContext& ctx, IR::Inst& inst, std::string_view e1,
 void EmitCompositeConstructU32x2(EmitContext& ctx, IR::Inst& inst, std::string_view e1,
                                  std::string_view e2);
                                  std::string_view e2);
-void EmitCompositeConstructU32x3(EmitContext& ctx, std::string_view e1, std::string_view e2,
-                                 std::string_view e3);
-void EmitCompositeConstructU32x4(EmitContext& ctx, std::string_view e1, std::string_view e2,
-                                 std::string_view e3, std::string_view e4);
+void EmitCompositeConstructU32x3(EmitContext& ctx, IR::Inst& inst, std::string_view e1,
+                                 std::string_view e2, std::string_view e3);
+void EmitCompositeConstructU32x4(EmitContext& ctx, IR::Inst& inst, std::string_view e1,
+                                 std::string_view e2, std::string_view e3, std::string_view e4);
 void EmitCompositeExtractU32x2(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
 void EmitCompositeExtractU32x2(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
                                u32 index);
                                u32 index);
-void EmitCompositeExtractU32x3(EmitContext& ctx, std::string_view composite, u32 index);
-void EmitCompositeExtractU32x4(EmitContext& ctx, std::string_view composite, u32 index);
+void EmitCompositeExtractU32x3(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
+                               u32 index);
+void EmitCompositeExtractU32x4(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
+                               u32 index);
 void EmitCompositeInsertU32x2(EmitContext& ctx, std::string_view composite, std::string_view object,
 void EmitCompositeInsertU32x2(EmitContext& ctx, std::string_view composite, std::string_view object,
                               u32 index);
                               u32 index);
 void EmitCompositeInsertU32x3(EmitContext& ctx, std::string_view composite, std::string_view object,
 void EmitCompositeInsertU32x3(EmitContext& ctx, std::string_view composite, std::string_view object,
@@ -175,10 +179,10 @@ void EmitCompositeInsertF16x4(EmitContext& ctx, std::string_view composite, std:
                               u32 index);
                               u32 index);
 void EmitCompositeConstructF32x2(EmitContext& ctx, IR::Inst& inst, std::string_view e1,
 void EmitCompositeConstructF32x2(EmitContext& ctx, IR::Inst& inst, std::string_view e1,
                                  std::string_view e2);
                                  std::string_view e2);
-void EmitCompositeConstructF32x3(EmitContext& ctx, std::string_view e1, std::string_view e2,
-                                 std::string_view e3);
-void EmitCompositeConstructF32x4(EmitContext& ctx, std::string_view e1, std::string_view e2,
-                                 std::string_view e3, std::string_view e4);
+void EmitCompositeConstructF32x3(EmitContext& ctx, IR::Inst& inst, std::string_view e1,
+                                 std::string_view e2, std::string_view e3);
+void EmitCompositeConstructF32x4(EmitContext& ctx, IR::Inst& inst, std::string_view e1,
+                                 std::string_view e2, std::string_view e3, std::string_view e4);
 void EmitCompositeExtractF32x2(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
 void EmitCompositeExtractF32x2(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
                                u32 index);
                                u32 index);
 void EmitCompositeExtractF32x3(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
 void EmitCompositeExtractF32x3(EmitContext& ctx, IR::Inst& inst, std::string_view composite,

+ 11 - 7
src/shader_recompiler/backend/glsl/emit_glsl_memory.cpp

@@ -34,19 +34,23 @@ void EmitLoadStorageS16([[maybe_unused]] EmitContext& ctx,
 
 
 void EmitLoadStorage32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
 void EmitLoadStorage32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
                        const IR::Value& offset) {
                        const IR::Value& offset) {
-    ctx.AddU32("{}=ssbo{}[{}];", inst, binding.U32(), offset.U32());
+    const auto offset_var{ctx.reg_alloc.Consume(offset)};
+    ctx.AddU32("{}=ssbo{}[{}];", inst, binding.U32(), offset_var);
 }
 }
 
 
 void EmitLoadStorage64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
 void EmitLoadStorage64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
                        const IR::Value& offset) {
                        const IR::Value& offset) {
-    ctx.AddU32x2("{}=uvec2(ssbo{}[{}],ssbo{}[{}]);", inst, binding.U32(), offset.U32(),
-                 binding.U32(), offset.U32() + 1);
+    const auto offset_var{ctx.reg_alloc.Consume(offset)};
+    ctx.AddU32x2("{}=uvec2(ssbo{}[{}],ssbo{}[{}+1]);", inst, binding.U32(), offset_var,
+                 binding.U32(), offset_var);
 }
 }
 
 
-void EmitLoadStorage128([[maybe_unused]] EmitContext& ctx,
-                        [[maybe_unused]] const IR::Value& binding,
-                        [[maybe_unused]] const IR::Value& offset) {
-    throw NotImplementedException("GLSL Instrucion");
+void EmitLoadStorage128(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
+                        const IR::Value& offset) {
+    const auto offset_var{ctx.reg_alloc.Consume(offset)};
+    ctx.AddU32x4("{}=uvec4(ssbo{}[{}],ssbo{}[{}+1],ssbo{}[{}+2],ssbo{}[{}+3]);", inst,
+                 binding.U32(), offset_var, binding.U32(), offset_var, binding.U32(), offset_var,
+                 binding.U32(), offset_var);
 }
 }
 
 
 void EmitWriteStorageU8([[maybe_unused]] EmitContext& ctx,
 void EmitWriteStorageU8([[maybe_unused]] EmitContext& ctx,

+ 2 - 10
src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp

@@ -50,15 +50,7 @@ void EmitPhiMove(EmitContext& ctx, const IR::Value& phi_value, const IR::Value&
     if (phi_reg == val_reg) {
     if (phi_reg == val_reg) {
         return;
         return;
     }
     }
-    if (phi_type == value.Type()) {
-        ctx.Add("{}={}; // PHI MOVE", phi_reg, val_reg);
-    } else if (phi_type == IR::Type::U32 && value.Type() == IR::Type::F32) {
-        ctx.Add("{}=floatBitsToUint({}); // CAST PHI MOVE", phi_reg, val_reg);
-    } else {
-        throw NotImplementedException("{} to {} move", phi_type, value.Type());
-        const auto cast{ctx.reg_alloc.GetGlslType(phi_type)};
-        ctx.Add("{}={}({}); // CAST PHI MOVE", phi_reg, cast, val_reg);
-    }
+    ctx.Add("{}={};", phi_reg, val_reg);
 }
 }
 
 
 void EmitBranch(EmitContext& ctx, std::string_view label) {
 void EmitBranch(EmitContext& ctx, std::string_view label) {
@@ -245,7 +237,7 @@ void EmitWriteLocal(EmitContext& ctx, std::string_view word_offset, std::string_
 }
 }
 
 
 void EmitUndefU1(EmitContext& ctx, IR::Inst& inst) {
 void EmitUndefU1(EmitContext& ctx, IR::Inst& inst) {
-    NotImplemented();
+    ctx.AddU1("{}=false;", inst);
 }
 }
 
 
 void EmitUndefU8(EmitContext& ctx, IR::Inst& inst) {
 void EmitUndefU8(EmitContext& ctx, IR::Inst& inst) {

+ 4 - 0
src/shader_recompiler/backend/glsl/reg_alloc.cpp

@@ -137,6 +137,10 @@ std::string RegAlloc::GetGlslType(Type type) {
         return "uvec2 ";
         return "uvec2 ";
     case Type::F32x2:
     case Type::F32x2:
         return "vec2 ";
         return "vec2 ";
+    case Type::U32x3:
+        return "uvec3 ";
+    case Type::F32x3:
+        return "vec3 ";
     case Type::U32x4:
     case Type::U32x4:
         return "uvec4 ";
         return "uvec4 ";
     case Type::F32x4:
     case Type::F32x4:

+ 2 - 0
src/shader_recompiler/backend/glsl/reg_alloc.h

@@ -27,6 +27,8 @@ enum class Type : u32 {
     F64,
     F64,
     U32x2,
     U32x2,
     F32x2,
     F32x2,
+    U32x3,
+    F32x3,
     U32x4,
     U32x4,
     F32x4,
     F32x4,
     Void,
     Void,