diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 7dc2e0560468f65922195066b8b7ebc3f5430972..ece386cdcc7da11c97bbca29c99c218ff8d68d77 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -453,9 +453,13 @@ private:
     void DeclareSamplers() {
         const auto& samplers = ir.GetSamplers();
         for (const auto& sampler : samplers) {
-            std::string sampler_type = [&sampler] {
+            const std::string name{GetSampler(sampler)};
+            const std::string description{"layout (binding = SAMPLER_BINDING_" +
+                                          std::to_string(sampler.GetIndex()) + ") uniform "};
+            std::string sampler_type = [&]() {
                 switch (sampler.GetType()) {
                 case Tegra::Shader::TextureType::Texture1D:
+                    // Special cased, read below.
                     return "sampler1D";
                 case Tegra::Shader::TextureType::Texture2D:
                     return "sampler2D";
@@ -475,8 +479,19 @@ private:
                 sampler_type += "Shadow";
             }
 
-            code.AddLine("layout (binding = SAMPLER_BINDING_{}) uniform {} {};", sampler.GetIndex(),
-                         sampler_type, GetSampler(sampler));
+            if (sampler.GetType() == Tegra::Shader::TextureType::Texture1D) {
+                // 1D textures can be aliased to texture buffers, hide the declarations behind a
+                // preprocessor flag and use one or the other from the GPU state. This has to be
+                // done because shaders don't have enough information to determine the texture type.
+                EmitIfdefIsBuffer(sampler);
+                code.AddLine(description + "samplerBuffer " + name + ';');
+                code.AddLine("#else");
+                code.AddLine(description + sampler_type + ' ' + name + ';');
+                code.AddLine("#endif");
+            } else {
+                // The other texture types (2D, 3D and cubes) don't have this issue.
+                code.AddLine(description + sampler_type + ' ' + name + ';');
+            }
         }
         if (!samplers.empty()) {
             code.AddNewLine();
@@ -1439,13 +1454,28 @@ private:
             else if (next < count)
                 expr += ", ";
         }
+
+        // Store a copy of the expression without the lod to be used with texture buffers
+        std::string expr_buffer = expr;
+
         if (meta->lod) {
             expr += ", ";
             expr += CastOperand(Visit(meta->lod), Type::Int);
         }
         expr += ')';
+        expr += GetSwizzle(meta->element);
 
-        return expr + GetSwizzle(meta->element);
+        expr_buffer += ')';
+        expr_buffer += GetSwizzle(meta->element);
+
+        const std::string tmp{code.GenerateTemporary()};
+        EmitIfdefIsBuffer(meta->sampler);
+        code.AddLine("float " + tmp + " = " + expr_buffer + ';');
+        code.AddLine("#else");
+        code.AddLine("float " + tmp + " = " + expr + ';');
+        code.AddLine("#endif");
+
+        return tmp;
     }
 
     std::string Branch(Operation operation) {
@@ -1756,6 +1786,10 @@ private:
         return GetDeclarationWithSuffix(static_cast<u32>(sampler.GetIndex()), "sampler");
     }
 
+    void EmitIfdefIsBuffer(const Sampler& sampler) {
+        code.AddLine(fmt::format("#ifdef SAMPLER_{}_IS_BUFFER", sampler.GetIndex()));
+    }
+
     std::string GetDeclarationWithSuffix(u32 index, const std::string& name) const {
         return fmt::format("{}_{}_{}", name, index, suffix);
     }