diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp
index 31eb54123..12434db67 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp
@@ -763,6 +763,37 @@ void Image::DownloadMemory(ImageBufferMap& map,
     }
 }
 
+GLuint Image::StorageHandle() noexcept {
+    switch (info.format) {
+    case PixelFormat::A8B8G8R8_SRGB:
+    case PixelFormat::B8G8R8A8_SRGB:
+    case PixelFormat::BC1_RGBA_SRGB:
+    case PixelFormat::BC2_SRGB:
+    case PixelFormat::BC3_SRGB:
+    case PixelFormat::BC7_SRGB:
+    case PixelFormat::ASTC_2D_4X4_SRGB:
+    case PixelFormat::ASTC_2D_8X8_SRGB:
+    case PixelFormat::ASTC_2D_8X5_SRGB:
+    case PixelFormat::ASTC_2D_5X4_SRGB:
+    case PixelFormat::ASTC_2D_5X5_SRGB:
+    case PixelFormat::ASTC_2D_10X8_SRGB:
+    case PixelFormat::ASTC_2D_6X6_SRGB:
+    case PixelFormat::ASTC_2D_10X10_SRGB:
+    case PixelFormat::ASTC_2D_12X12_SRGB:
+    case PixelFormat::ASTC_2D_8X6_SRGB:
+    case PixelFormat::ASTC_2D_6X5_SRGB:
+        if (store_view.handle != 0) {
+            return store_view.handle;
+        }
+        store_view.Create();
+        glTextureView(store_view.handle, ImageTarget(info), texture.handle, GL_RGBA8, 0,
+                      info.resources.levels, 0, info.resources.layers);
+        return store_view.handle;
+    default:
+        return texture.handle;
+    }
+}
+
 void Image::CopyBufferToImage(const VideoCommon::BufferImageCopy& copy, size_t buffer_offset) {
     // Compressed formats don't have a pixel format or type
     const bool is_compressed = gl_format == GL_NONE;
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h
index 874cf54f4..a6172f009 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.h
+++ b/src/video_core/renderer_opengl/gl_texture_cache.h
@@ -145,6 +145,8 @@ public:
 
     void DownloadMemory(ImageBufferMap& map, std::span<const VideoCommon::BufferImageCopy> copies);
 
+    GLuint StorageHandle() noexcept;
+
     GLuint Handle() const noexcept {
         return texture.handle;
     }
@@ -155,8 +157,8 @@ private:
     void CopyImageToBuffer(const VideoCommon::BufferImageCopy& copy, size_t buffer_offset);
 
     OGLTexture texture;
-    OGLTextureView store_view;
     OGLBuffer buffer;
+    OGLTextureView store_view;
     GLenum gl_internal_format = GL_NONE;
     GLenum gl_format = GL_NONE;
     GLenum gl_type = GL_NONE;
diff --git a/src/video_core/renderer_opengl/util_shaders.cpp b/src/video_core/renderer_opengl/util_shaders.cpp
index 1b58e8617..31ec68505 100644
--- a/src/video_core/renderer_opengl/util_shaders.cpp
+++ b/src/video_core/renderer_opengl/util_shaders.cpp
@@ -93,7 +93,7 @@ void UtilShaders::BlockLinearUpload2D(Image& image, const ImageBufferMap& map,
         glUniform1ui(7, params.block_height_mask);
         glBindBufferRange(GL_SHADER_STORAGE_BUFFER, BINDING_INPUT_BUFFER, map.buffer, input_offset,
                           image.guest_size_bytes - swizzle.buffer_offset);
-        glBindImageTexture(BINDING_OUTPUT_IMAGE, image.Handle(), swizzle.level, GL_TRUE, 0,
+        glBindImageTexture(BINDING_OUTPUT_IMAGE, image.StorageHandle(), swizzle.level, GL_TRUE, 0,
                            GL_WRITE_ONLY, store_format);
         glDispatchCompute(num_dispatches_x, num_dispatches_y, image.info.resources.layers);
     }
@@ -134,7 +134,7 @@ void UtilShaders::BlockLinearUpload3D(Image& image, const ImageBufferMap& map,
         glUniform1ui(9, params.block_depth_mask);
         glBindBufferRange(GL_SHADER_STORAGE_BUFFER, BINDING_INPUT_BUFFER, map.buffer, input_offset,
                           image.guest_size_bytes - swizzle.buffer_offset);
-        glBindImageTexture(BINDING_OUTPUT_IMAGE, image.Handle(), swizzle.level, GL_TRUE, 0,
+        glBindImageTexture(BINDING_OUTPUT_IMAGE, image.StorageHandle(), swizzle.level, GL_TRUE, 0,
                            GL_WRITE_ONLY, store_format);
         glDispatchCompute(num_dispatches_x, num_dispatches_y, num_dispatches_z);
     }
@@ -164,7 +164,8 @@ void UtilShaders::PitchUpload(Image& image, const ImageBufferMap& map,
     glUniform2i(LOC_DESTINATION, 0, 0);
     glUniform1ui(LOC_BYTES_PER_BLOCK, bytes_per_block);
     glUniform1ui(LOC_PITCH, pitch);
-    glBindImageTexture(BINDING_OUTPUT_IMAGE, image.Handle(), 0, GL_FALSE, 0, GL_WRITE_ONLY, format);
+    glBindImageTexture(BINDING_OUTPUT_IMAGE, image.StorageHandle(), 0, GL_FALSE, 0, GL_WRITE_ONLY,
+                       format);
     for (const SwizzleParameters& swizzle : swizzles) {
         const Extent3D num_tiles = swizzle.num_tiles;
         const size_t input_offset = swizzle.buffer_offset + map.offset;
@@ -195,9 +196,9 @@ void UtilShaders::CopyBC4(Image& dst_image, Image& src_image, std::span<const Im
 
         glUniform3ui(LOC_SRC_OFFSET, copy.src_offset.x, copy.src_offset.y, copy.src_offset.z);
         glUniform3ui(LOC_DST_OFFSET, copy.dst_offset.x, copy.dst_offset.y, copy.dst_offset.z);
-        glBindImageTexture(BINDING_INPUT_IMAGE, src_image.Handle(), copy.src_subresource.base_level,
-                           GL_FALSE, 0, GL_READ_ONLY, GL_RG32UI);
-        glBindImageTexture(BINDING_OUTPUT_IMAGE, dst_image.Handle(),
+        glBindImageTexture(BINDING_INPUT_IMAGE, src_image.StorageHandle(),
+                           copy.src_subresource.base_level, GL_FALSE, 0, GL_READ_ONLY, GL_RG32UI);
+        glBindImageTexture(BINDING_OUTPUT_IMAGE, dst_image.StorageHandle(),
                            copy.dst_subresource.base_level, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8UI);
         glDispatchCompute(copy.extent.width, copy.extent.height, copy.extent.depth);
     }