gl_texture_cache: Lazily create non-sRGB texture views for sRGB formats
This creates non-sRGB texture views for sRGB texture formats to allow for interfacing with these views in compute shaders using imageLoad and imageStore. Co-Authored-By: Rodrigo Locatti <reinuseslisp@airmail.cc>
This commit is contained in:
		| @@ -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) { | void Image::CopyBufferToImage(const VideoCommon::BufferImageCopy& copy, size_t buffer_offset) { | ||||||
|     // Compressed formats don't have a pixel format or type |     // Compressed formats don't have a pixel format or type | ||||||
|     const bool is_compressed = gl_format == GL_NONE; |     const bool is_compressed = gl_format == GL_NONE; | ||||||
|   | |||||||
| @@ -145,6 +145,8 @@ public: | |||||||
|  |  | ||||||
|     void DownloadMemory(ImageBufferMap& map, std::span<const VideoCommon::BufferImageCopy> copies); |     void DownloadMemory(ImageBufferMap& map, std::span<const VideoCommon::BufferImageCopy> copies); | ||||||
|  |  | ||||||
|  |     GLuint StorageHandle() noexcept; | ||||||
|  |  | ||||||
|     GLuint Handle() const noexcept { |     GLuint Handle() const noexcept { | ||||||
|         return texture.handle; |         return texture.handle; | ||||||
|     } |     } | ||||||
| @@ -155,8 +157,8 @@ private: | |||||||
|     void CopyImageToBuffer(const VideoCommon::BufferImageCopy& copy, size_t buffer_offset); |     void CopyImageToBuffer(const VideoCommon::BufferImageCopy& copy, size_t buffer_offset); | ||||||
|  |  | ||||||
|     OGLTexture texture; |     OGLTexture texture; | ||||||
|     OGLTextureView store_view; |  | ||||||
|     OGLBuffer buffer; |     OGLBuffer buffer; | ||||||
|  |     OGLTextureView store_view; | ||||||
|     GLenum gl_internal_format = GL_NONE; |     GLenum gl_internal_format = GL_NONE; | ||||||
|     GLenum gl_format = GL_NONE; |     GLenum gl_format = GL_NONE; | ||||||
|     GLenum gl_type = GL_NONE; |     GLenum gl_type = GL_NONE; | ||||||
|   | |||||||
| @@ -93,7 +93,7 @@ void UtilShaders::BlockLinearUpload2D(Image& image, const ImageBufferMap& map, | |||||||
|         glUniform1ui(7, params.block_height_mask); |         glUniform1ui(7, params.block_height_mask); | ||||||
|         glBindBufferRange(GL_SHADER_STORAGE_BUFFER, BINDING_INPUT_BUFFER, map.buffer, input_offset, |         glBindBufferRange(GL_SHADER_STORAGE_BUFFER, BINDING_INPUT_BUFFER, map.buffer, input_offset, | ||||||
|                           image.guest_size_bytes - swizzle.buffer_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); |                            GL_WRITE_ONLY, store_format); | ||||||
|         glDispatchCompute(num_dispatches_x, num_dispatches_y, image.info.resources.layers); |         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); |         glUniform1ui(9, params.block_depth_mask); | ||||||
|         glBindBufferRange(GL_SHADER_STORAGE_BUFFER, BINDING_INPUT_BUFFER, map.buffer, input_offset, |         glBindBufferRange(GL_SHADER_STORAGE_BUFFER, BINDING_INPUT_BUFFER, map.buffer, input_offset, | ||||||
|                           image.guest_size_bytes - swizzle.buffer_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); |                            GL_WRITE_ONLY, store_format); | ||||||
|         glDispatchCompute(num_dispatches_x, num_dispatches_y, num_dispatches_z); |         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); |     glUniform2i(LOC_DESTINATION, 0, 0); | ||||||
|     glUniform1ui(LOC_BYTES_PER_BLOCK, bytes_per_block); |     glUniform1ui(LOC_BYTES_PER_BLOCK, bytes_per_block); | ||||||
|     glUniform1ui(LOC_PITCH, pitch); |     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) { |     for (const SwizzleParameters& swizzle : swizzles) { | ||||||
|         const Extent3D num_tiles = swizzle.num_tiles; |         const Extent3D num_tiles = swizzle.num_tiles; | ||||||
|         const size_t input_offset = swizzle.buffer_offset + map.offset; |         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_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); |         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, |         glBindImageTexture(BINDING_INPUT_IMAGE, src_image.StorageHandle(), | ||||||
|                            GL_FALSE, 0, GL_READ_ONLY, GL_RG32UI); |                            copy.src_subresource.base_level, GL_FALSE, 0, GL_READ_ONLY, GL_RG32UI); | ||||||
|         glBindImageTexture(BINDING_OUTPUT_IMAGE, dst_image.Handle(), |         glBindImageTexture(BINDING_OUTPUT_IMAGE, dst_image.StorageHandle(), | ||||||
|                            copy.dst_subresource.base_level, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8UI); |                            copy.dst_subresource.base_level, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8UI); | ||||||
|         glDispatchCompute(copy.extent.width, copy.extent.height, copy.extent.depth); |         glDispatchCompute(copy.extent.width, copy.extent.height, copy.extent.depth); | ||||||
|     } |     } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user