mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-04 00:49:02 -06:00 
			
		
		
		
	Merge pull request #8161 from liamwhite/gl-s8d24
OpenGL: fix S8D24 to ABGR8 conversions
This commit is contained in:
		@@ -18,6 +18,7 @@ set(SHADER_FILES
 | 
				
			|||||||
    full_screen_triangle.vert
 | 
					    full_screen_triangle.vert
 | 
				
			||||||
    fxaa.frag
 | 
					    fxaa.frag
 | 
				
			||||||
    fxaa.vert
 | 
					    fxaa.vert
 | 
				
			||||||
 | 
					    opengl_convert_s8d24.comp
 | 
				
			||||||
    opengl_copy_bc4.comp
 | 
					    opengl_copy_bc4.comp
 | 
				
			||||||
    opengl_present.frag
 | 
					    opengl_present.frag
 | 
				
			||||||
    opengl_present.vert
 | 
					    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,
 | 
					TextureCacheRuntime::TextureCacheRuntime(const Device& device_, ProgramManager& program_manager,
 | 
				
			||||||
                                         StateTracker& state_tracker_)
 | 
					                                         StateTracker& state_tracker_)
 | 
				
			||||||
    : device{device_}, state_tracker{state_tracker_},
 | 
					    : device{device_}, state_tracker{state_tracker_}, util_shaders(program_manager),
 | 
				
			||||||
      util_shaders(program_manager), resolution{Settings::values.resolution_info} {
 | 
					      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};
 | 
					    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) {
 | 
					    for (size_t i = 0; i < TARGETS.size(); ++i) {
 | 
				
			||||||
        const GLenum target = TARGETS[i];
 | 
					        const GLenum target = TARGETS[i];
 | 
				
			||||||
@@ -1325,6 +1325,9 @@ Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span<ImageView*, NUM
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Framebuffer::~Framebuffer() = default;
 | 
					Framebuffer::~Framebuffer() = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FormatConversionPass::FormatConversionPass(UtilShaders& util_shaders_)
 | 
				
			||||||
 | 
					    : util_shaders{util_shaders_} {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void FormatConversionPass::ConvertImage(Image& dst_image, Image& src_image,
 | 
					void FormatConversionPass::ConvertImage(Image& dst_image, Image& src_image,
 | 
				
			||||||
                                        std::span<const VideoCommon::ImageCopy> copies) {
 | 
					                                        std::span<const VideoCommon::ImageCopy> copies) {
 | 
				
			||||||
    const GLenum dst_target = ImageTarget(dst_image.info);
 | 
					    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_origin.z, region.width, region.height, region.depth,
 | 
				
			||||||
                            dst_image.GlFormat(), dst_image.GlType(), nullptr);
 | 
					                            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
 | 
					} // namespace OpenGL
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -55,13 +55,14 @@ struct FormatProperties {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class FormatConversionPass {
 | 
					class FormatConversionPass {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    FormatConversionPass() = default;
 | 
					    explicit FormatConversionPass(UtilShaders& util_shaders);
 | 
				
			||||||
    ~FormatConversionPass() = default;
 | 
					    ~FormatConversionPass() = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void ConvertImage(Image& dst_image, Image& src_image,
 | 
					    void ConvertImage(Image& dst_image, Image& src_image,
 | 
				
			||||||
                      std::span<const VideoCommon::ImageCopy> copies);
 | 
					                      std::span<const VideoCommon::ImageCopy> copies);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
 | 
					    UtilShaders& util_shaders;
 | 
				
			||||||
    OGLBuffer intermediate_pbo;
 | 
					    OGLBuffer intermediate_pbo;
 | 
				
			||||||
    size_t pbo_size{};
 | 
					    size_t pbo_size{};
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,6 +13,7 @@
 | 
				
			|||||||
#include "video_core/host_shaders/astc_decoder_comp.h"
 | 
					#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_2d_comp.h"
 | 
				
			||||||
#include "video_core/host_shaders/block_linear_unswizzle_3d_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/opengl_copy_bc4_comp.h"
 | 
				
			||||||
#include "video_core/host_shaders/pitch_unswizzle_comp.h"
 | 
					#include "video_core/host_shaders/pitch_unswizzle_comp.h"
 | 
				
			||||||
#include "video_core/renderer_opengl/gl_shader_manager.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_2d_program(MakeProgram(BLOCK_LINEAR_UNSWIZZLE_2D_COMP)),
 | 
				
			||||||
      block_linear_unswizzle_3d_program(MakeProgram(BLOCK_LINEAR_UNSWIZZLE_3D_COMP)),
 | 
					      block_linear_unswizzle_3d_program(MakeProgram(BLOCK_LINEAR_UNSWIZZLE_3D_COMP)),
 | 
				
			||||||
      pitch_unswizzle_program(MakeProgram(PITCH_UNSWIZZLE_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();
 | 
					    const auto swizzle_table = Tegra::Texture::MakeSwizzleTable();
 | 
				
			||||||
    swizzle_table_buffer.Create();
 | 
					    swizzle_table_buffer.Create();
 | 
				
			||||||
    glNamedBufferStorage(swizzle_table_buffer.handle, sizeof(swizzle_table), &swizzle_table, 0);
 | 
					    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();
 | 
					    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) {
 | 
					GLenum StoreFormat(u32 bytes_per_block) {
 | 
				
			||||||
    switch (bytes_per_block) {
 | 
					    switch (bytes_per_block) {
 | 
				
			||||||
    case 1:
 | 
					    case 1:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,6 +39,8 @@ public:
 | 
				
			|||||||
    void CopyBC4(Image& dst_image, Image& src_image,
 | 
					    void CopyBC4(Image& dst_image, Image& src_image,
 | 
				
			||||||
                 std::span<const VideoCommon::ImageCopy> copies);
 | 
					                 std::span<const VideoCommon::ImageCopy> copies);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void ConvertS8D24(Image& dst_image, std::span<const VideoCommon::ImageCopy> copies);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
    ProgramManager& program_manager;
 | 
					    ProgramManager& program_manager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -49,6 +51,7 @@ private:
 | 
				
			|||||||
    OGLProgram block_linear_unswizzle_3d_program;
 | 
					    OGLProgram block_linear_unswizzle_3d_program;
 | 
				
			||||||
    OGLProgram pitch_unswizzle_program;
 | 
					    OGLProgram pitch_unswizzle_program;
 | 
				
			||||||
    OGLProgram copy_bc4_program;
 | 
					    OGLProgram copy_bc4_program;
 | 
				
			||||||
 | 
					    OGLProgram convert_s8d24_program;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GLenum StoreFormat(u32 bytes_per_block);
 | 
					GLenum StoreFormat(u32 bytes_per_block);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user