OpenGL: fix S8D24 to ABGR8 conversions
This commit is contained in:
parent
0c1b954e07
commit
52ebdd42c6
6 changed files with 58 additions and 4 deletions
|
@ -18,6 +18,7 @@ set(SHADER_FILES
|
|||
full_screen_triangle.vert
|
||||
fxaa.frag
|
||||
fxaa.vert
|
||||
opengl_convert_s8d24.comp
|
||||
opengl_copy_bc4.comp
|
||||
opengl_present.frag
|
||||
opengl_present.vert
|
||||
|
|
18
src/video_core/host_shaders/opengl_convert_s8d24.comp
Normal file
18
src/video_core/host_shaders/opengl_convert_s8d24.comp
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2022 yuzu Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#version 430 core
|
||||
|
||||
layout(local_size_x = 16, local_size_y = 8) in;
|
||||
|
||||
layout(binding = 0, rgba8ui) restrict uniform uimage2D destination;
|
||||
layout(location = 0) uniform uvec3 size;
|
||||
|
||||
void main() {
|
||||
if (any(greaterThanEqual(gl_GlobalInvocationID, size))) {
|
||||
return;
|
||||
}
|
||||
uvec4 components = imageLoad(destination, ivec2(gl_GlobalInvocationID.xy));
|
||||
imageStore(destination, ivec2(gl_GlobalInvocationID.xy), components.wxyz);
|
||||
}
|
|
@ -409,8 +409,8 @@ ImageBufferMap::~ImageBufferMap() {
|
|||
|
||||
TextureCacheRuntime::TextureCacheRuntime(const Device& device_, ProgramManager& program_manager,
|
||||
StateTracker& state_tracker_)
|
||||
: device{device_}, state_tracker{state_tracker_},
|
||||
util_shaders(program_manager), resolution{Settings::values.resolution_info} {
|
||||
: device{device_}, state_tracker{state_tracker_}, util_shaders(program_manager),
|
||||
format_conversion_pass{util_shaders}, resolution{Settings::values.resolution_info} {
|
||||
static constexpr std::array TARGETS{GL_TEXTURE_1D_ARRAY, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_3D};
|
||||
for (size_t i = 0; i < TARGETS.size(); ++i) {
|
||||
const GLenum target = TARGETS[i];
|
||||
|
@ -1325,6 +1325,9 @@ Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span<ImageView*, NUM
|
|||
|
||||
Framebuffer::~Framebuffer() = default;
|
||||
|
||||
FormatConversionPass::FormatConversionPass(UtilShaders& util_shaders_)
|
||||
: util_shaders{util_shaders_} {}
|
||||
|
||||
void FormatConversionPass::ConvertImage(Image& dst_image, Image& src_image,
|
||||
std::span<const VideoCommon::ImageCopy> copies) {
|
||||
const GLenum dst_target = ImageTarget(dst_image.info);
|
||||
|
@ -1357,6 +1360,12 @@ void FormatConversionPass::ConvertImage(Image& dst_image, Image& src_image,
|
|||
dst_origin.z, region.width, region.height, region.depth,
|
||||
dst_image.GlFormat(), dst_image.GlType(), nullptr);
|
||||
}
|
||||
|
||||
// Swap component order of S8D24 to ABGR8 reinterprets
|
||||
if (src_image.info.format == PixelFormat::D24_UNORM_S8_UINT &&
|
||||
dst_image.info.format == PixelFormat::A8B8G8R8_UNORM) {
|
||||
util_shaders.ConvertS8D24(dst_image, copies);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace OpenGL
|
||||
|
|
|
@ -55,13 +55,14 @@ struct FormatProperties {
|
|||
|
||||
class FormatConversionPass {
|
||||
public:
|
||||
FormatConversionPass() = default;
|
||||
explicit FormatConversionPass(UtilShaders& util_shaders);
|
||||
~FormatConversionPass() = default;
|
||||
|
||||
void ConvertImage(Image& dst_image, Image& src_image,
|
||||
std::span<const VideoCommon::ImageCopy> copies);
|
||||
|
||||
private:
|
||||
UtilShaders& util_shaders;
|
||||
OGLBuffer intermediate_pbo;
|
||||
size_t pbo_size{};
|
||||
};
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "video_core/host_shaders/astc_decoder_comp.h"
|
||||
#include "video_core/host_shaders/block_linear_unswizzle_2d_comp.h"
|
||||
#include "video_core/host_shaders/block_linear_unswizzle_3d_comp.h"
|
||||
#include "video_core/host_shaders/opengl_convert_s8d24_comp.h"
|
||||
#include "video_core/host_shaders/opengl_copy_bc4_comp.h"
|
||||
#include "video_core/host_shaders/pitch_unswizzle_comp.h"
|
||||
#include "video_core/renderer_opengl/gl_shader_manager.h"
|
||||
|
@ -50,7 +51,8 @@ UtilShaders::UtilShaders(ProgramManager& program_manager_)
|
|||
block_linear_unswizzle_2d_program(MakeProgram(BLOCK_LINEAR_UNSWIZZLE_2D_COMP)),
|
||||
block_linear_unswizzle_3d_program(MakeProgram(BLOCK_LINEAR_UNSWIZZLE_3D_COMP)),
|
||||
pitch_unswizzle_program(MakeProgram(PITCH_UNSWIZZLE_COMP)),
|
||||
copy_bc4_program(MakeProgram(OPENGL_COPY_BC4_COMP)) {
|
||||
copy_bc4_program(MakeProgram(OPENGL_COPY_BC4_COMP)),
|
||||
convert_s8d24_program(MakeProgram(OPENGL_CONVERT_S8D24_COMP)) {
|
||||
const auto swizzle_table = Tegra::Texture::MakeSwizzleTable();
|
||||
swizzle_table_buffer.Create();
|
||||
glNamedBufferStorage(swizzle_table_buffer.handle, sizeof(swizzle_table), &swizzle_table, 0);
|
||||
|
@ -248,6 +250,26 @@ void UtilShaders::CopyBC4(Image& dst_image, Image& src_image, std::span<const Im
|
|||
program_manager.RestoreGuestCompute();
|
||||
}
|
||||
|
||||
void UtilShaders::ConvertS8D24(Image& dst_image, std::span<const ImageCopy> copies) {
|
||||
static constexpr GLuint BINDING_DESTINATION = 0;
|
||||
static constexpr GLuint LOC_SIZE = 0;
|
||||
|
||||
program_manager.BindComputeProgram(convert_s8d24_program.handle);
|
||||
for (const ImageCopy& copy : copies) {
|
||||
ASSERT(copy.src_subresource.base_layer == 0);
|
||||
ASSERT(copy.src_subresource.num_layers == 1);
|
||||
ASSERT(copy.dst_subresource.base_layer == 0);
|
||||
ASSERT(copy.dst_subresource.num_layers == 1);
|
||||
|
||||
glUniform3ui(LOC_SIZE, copy.extent.width, copy.extent.height, copy.extent.depth);
|
||||
glBindImageTexture(BINDING_DESTINATION, dst_image.StorageHandle(),
|
||||
copy.dst_subresource.base_level, GL_TRUE, 0, GL_READ_WRITE, GL_RGBA8UI);
|
||||
glDispatchCompute(Common::DivCeil(copy.extent.width, 16u),
|
||||
Common::DivCeil(copy.extent.height, 8u), copy.extent.depth);
|
||||
}
|
||||
program_manager.RestoreGuestCompute();
|
||||
}
|
||||
|
||||
GLenum StoreFormat(u32 bytes_per_block) {
|
||||
switch (bytes_per_block) {
|
||||
case 1:
|
||||
|
|
|
@ -39,6 +39,8 @@ public:
|
|||
void CopyBC4(Image& dst_image, Image& src_image,
|
||||
std::span<const VideoCommon::ImageCopy> copies);
|
||||
|
||||
void ConvertS8D24(Image& dst_image, std::span<const VideoCommon::ImageCopy> copies);
|
||||
|
||||
private:
|
||||
ProgramManager& program_manager;
|
||||
|
||||
|
@ -49,6 +51,7 @@ private:
|
|||
OGLProgram block_linear_unswizzle_3d_program;
|
||||
OGLProgram pitch_unswizzle_program;
|
||||
OGLProgram copy_bc4_program;
|
||||
OGLProgram convert_s8d24_program;
|
||||
};
|
||||
|
||||
GLenum StoreFormat(u32 bytes_per_block);
|
||||
|
|
Loading…
Reference in a new issue