diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 5454bacb09..fd4753af74 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -801,9 +801,11 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) {
     }
 
     auto kernel = shader_cache.GetComputeKernel(code_addr);
+    ProgramVariant variant;
+    variant.texture_buffer_usage = SetupComputeTextures(kernel);
     SetupComputeImages(kernel);
 
-    const auto [program, next_bindings] = kernel->GetProgramHandle({});
+    const auto [program, next_bindings] = kernel->GetProgramHandle(variant);
     state.draw.shader_program = program;
     state.draw.program_pipeline = 0;
 
@@ -818,8 +820,6 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) {
     SetupComputeConstBuffers(kernel);
     SetupComputeGlobalMemory(kernel);
 
-    // TODO(Rodrigo): Bind images and samplers
-
     buffer_cache.Unmap();
 
     bind_ubo_pushbuffer.Bind();
@@ -1016,6 +1016,36 @@ TextureBufferUsage RasterizerOpenGL::SetupDrawTextures(Maxwell::ShaderStage stag
     return texture_buffer_usage;
 }
 
+TextureBufferUsage RasterizerOpenGL::SetupComputeTextures(const Shader& kernel) {
+    MICROPROFILE_SCOPE(OpenGL_Texture);
+    const auto& compute = system.GPU().KeplerCompute();
+    const auto& entries = kernel->GetShaderEntries().samplers;
+
+    ASSERT_MSG(entries.size() <= std::size(state.textures),
+               "Exceeded the number of active textures.");
+
+    TextureBufferUsage texture_buffer_usage{0};
+
+    for (u32 bindpoint = 0; bindpoint < entries.size(); ++bindpoint) {
+        const auto& entry = entries[bindpoint];
+        const auto texture = [&]() {
+            if (!entry.IsBindless()) {
+                return compute.GetTexture(entry.GetOffset());
+            }
+            const auto cbuf = entry.GetBindlessCBuf();
+            Tegra::Texture::TextureHandle tex_handle;
+            tex_handle.raw = compute.AccessConstBuffer32(cbuf.first, cbuf.second);
+            return compute.GetTextureInfo(tex_handle, entry.GetOffset());
+        }();
+
+        if (SetupTexture(bindpoint, texture, entry)) {
+            texture_buffer_usage.set(bindpoint);
+        }
+    }
+
+    return texture_buffer_usage;
+}
+
 bool RasterizerOpenGL::SetupTexture(u32 binding, const Tegra::Texture::FullTextureInfo& texture,
                                     const GLShader::SamplerEntry& entry) {
     state.samplers[binding] = sampler_cache.GetSampler(texture.tsc);
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 35265b4a27..eada752e08 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -141,6 +141,9 @@ private:
     TextureBufferUsage SetupDrawTextures(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage,
                                          const Shader& shader, BaseBindings base_bindings);
 
+    /// Configures the textures used in a compute shader. Returns texture buffer usage.
+    TextureBufferUsage SetupComputeTextures(const Shader& kernel);
+
     /// Configures a texture. Returns true when the texture is a texture buffer.
     bool SetupTexture(u32 binding, const Tegra::Texture::FullTextureInfo& texture,
                       const GLShader::SamplerEntry& entry);