From ed14d31f663e126a8f9fe0ea8abff8e27c46248b Mon Sep 17 00:00:00 2001
From: ameerj <52414509+ameerj@users.noreply.github.com>
Date: Thu, 27 May 2021 00:26:16 -0400
Subject: [PATCH] glsl: Fix non-immediate buffer access

and many other misc implementations
---
 .../backend/glsl/emit_context.cpp             |  1 +
 .../backend/glsl/emit_context.h               | 15 ++++
 .../backend/glsl/emit_glsl.cpp                |  5 ++
 .../backend/glsl/emit_glsl_composite.cpp      | 48 +++++--------
 .../glsl/emit_glsl_context_get_set.cpp        | 68 ++++++++++++++++---
 .../backend/glsl/emit_glsl_convert.cpp        |  2 +-
 .../backend/glsl/emit_glsl_floating_point.cpp |  2 +-
 .../backend/glsl/emit_glsl_instructions.h     | 28 ++++----
 .../backend/glsl/emit_glsl_memory.cpp         | 18 +++--
 .../glsl/emit_glsl_not_implemented.cpp        | 12 +---
 .../backend/glsl/reg_alloc.cpp                |  4 ++
 .../backend/glsl/reg_alloc.h                  |  2 +
 12 files changed, 133 insertions(+), 72 deletions(-)

diff --git a/src/shader_recompiler/backend/glsl/emit_context.cpp b/src/shader_recompiler/backend/glsl/emit_context.cpp
index de19e0fba..2bf0def82 100644
--- a/src/shader_recompiler/backend/glsl/emit_context.cpp
+++ b/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) {
+    header += "#extension GL_ARB_separate_shader_objects : enable\n";
     if (info.uses_int64) {
         header += "#extension GL_ARB_gpu_shader_int64 : enable\n";
     }
diff --git a/src/shader_recompiler/backend/glsl/emit_context.h b/src/shader_recompiler/backend/glsl/emit_context.h
index 1cd051b24..66f70d355 100644
--- a/src/shader_recompiler/backend/glsl/emit_context.h
+++ b/src/shader_recompiler/backend/glsl/emit_context.h
@@ -90,6 +90,21 @@ public:
         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>
     void AddF32x4(const char* format_str, IR::Inst& inst, Args&&... args) {
         Add<Type::F32x4>(format_str, inst, args...);
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl.cpp b/src/shader_recompiler/backend/glsl/emit_glsl.cpp
index 35dbe19ec..644da43f4 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl.cpp
@@ -160,8 +160,13 @@ void EmitCode(EmitContext& ctx, const IR::Program& program) {
             ctx.Add("return;");
             break;
         case IR::AbstractSyntaxNode::Type::Loop:
+            ctx.Add("do{{");
+            break;
         case IR::AbstractSyntaxNode::Type::Repeat:
+            ctx.Add("}}while({});", ctx.reg_alloc.Consume(node.data.repeat.cond));
+            break;
         default:
+            fmt::print("{}", node.type);
             throw NotImplementedException("{}", node.type);
             break;
         }
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_composite.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_composite.cpp
index 048b12f38..aa966a304 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_composite.cpp
+++ b/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);
 }
 
-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,
@@ -37,16 +32,14 @@ void EmitCompositeExtractU32x2(EmitContext& ctx, IR::Inst& inst, std::string_vie
     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,
@@ -135,19 +128,14 @@ void EmitCompositeConstructF32x2(EmitContext& ctx, IR::Inst& inst, std::string_v
     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,
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 441818c0b..796f01883 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
@@ -10,8 +10,18 @@
 #include "shader_recompiler/profile.h"
 
 namespace Shader::Backend::GLSL {
+namespace {
 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,
                    [[maybe_unused]] const IR::Value& offset) {
     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,
                     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,
                     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,
@@ -66,7 +96,23 @@ void EmitGetAttribute(EmitContext& ctx, IR::Inst& inst, IR::Attribute attr,
     case IR::Attribute::PositionY:
     case IR::Attribute::PositionZ:
     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;
     default:
         fmt::print("Get attribute {}", attr);
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_convert.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_convert.cpp
index 0f95d4465..866bcfc4d 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_convert.cpp
+++ b/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,
                        [[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,
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_floating_point.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_floating_point.cpp
index f3d1d1af0..33aba9fef 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_floating_point.cpp
+++ b/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,
                        [[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,
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h b/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h
index c9b53bae2..295b7a8c4 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_instructions.h
+++ b/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);
 void EmitGetCbufF32(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
                     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,
                       std::string_view vertex);
 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);
 void EmitLoadStorage64(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding,
                        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,
                         std::string_view value);
 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 EmitCompositeConstructU32x2(EmitContext& ctx, IR::Inst& inst, std::string_view e1,
                                  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,
                                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,
                               u32 index);
 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);
 void EmitCompositeConstructF32x2(EmitContext& ctx, IR::Inst& inst, std::string_view e1,
                                  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,
                                u32 index);
 void EmitCompositeExtractF32x3(EmitContext& ctx, IR::Inst& inst, std::string_view composite,
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_memory.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_memory.cpp
index 8994c02a2..32cee7d3e 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_memory.cpp
+++ b/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,
                        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,
                        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,
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 42b1e8764..761145a5d 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp
+++ b/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) {
         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) {
@@ -245,7 +237,7 @@ void EmitWriteLocal(EmitContext& ctx, std::string_view word_offset, std::string_
 }
 
 void EmitUndefU1(EmitContext& ctx, IR::Inst& inst) {
-    NotImplemented();
+    ctx.AddU1("{}=false;", inst);
 }
 
 void EmitUndefU8(EmitContext& ctx, IR::Inst& inst) {
diff --git a/src/shader_recompiler/backend/glsl/reg_alloc.cpp b/src/shader_recompiler/backend/glsl/reg_alloc.cpp
index 06f1965b5..a987ce543 100644
--- a/src/shader_recompiler/backend/glsl/reg_alloc.cpp
+++ b/src/shader_recompiler/backend/glsl/reg_alloc.cpp
@@ -137,6 +137,10 @@ std::string RegAlloc::GetGlslType(Type type) {
         return "uvec2 ";
     case Type::F32x2:
         return "vec2 ";
+    case Type::U32x3:
+        return "uvec3 ";
+    case Type::F32x3:
+        return "vec3 ";
     case Type::U32x4:
         return "uvec4 ";
     case Type::F32x4:
diff --git a/src/shader_recompiler/backend/glsl/reg_alloc.h b/src/shader_recompiler/backend/glsl/reg_alloc.h
index 419d0bde0..2dc506c58 100644
--- a/src/shader_recompiler/backend/glsl/reg_alloc.h
+++ b/src/shader_recompiler/backend/glsl/reg_alloc.h
@@ -27,6 +27,8 @@ enum class Type : u32 {
     F64,
     U32x2,
     F32x2,
+    U32x3,
+    F32x3,
     U32x4,
     F32x4,
     Void,