mirror of
https://github.com/yuzu-emu/yuzu-mainline
synced 2024-11-22 18:03:48 +00:00
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:
parent
83227ad981
commit
c7325c6a4c
3 changed files with 41 additions and 7 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue