From 9fc63829098924a374afafc3c75c5a9b555ae322 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sun, 26 Jun 2022 00:32:54 +0300 Subject: [PATCH] gl: Finalize BGRA storage format internals - Performance is terrible but it works properly now --- rpcs3/Emu/RSX/GL/GLCompute.cpp | 6 ++--- rpcs3/Emu/RSX/GL/GLRenderTargets.cpp | 17 +++++++------ rpcs3/Emu/RSX/GL/GLTexture.cpp | 4 ++-- rpcs3/Emu/RSX/GL/GLTextureCache.h | 5 ++-- rpcs3/Emu/RSX/GL/glutils/image.cpp | 9 +++---- rpcs3/Emu/RSX/GL/glutils/state_tracker.hpp | 4 ++-- .../GLSLSnippets/CopyRGBA8ToBuffer.glsl | 12 +--------- rpcs3/Emu/RSX/RSXTexture.cpp | 21 +--------------- rpcs3/Emu/RSX/rsx_utils.h | 24 +++++++++++++++++++ 9 files changed, 48 insertions(+), 54 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLCompute.cpp b/rpcs3/Emu/RSX/GL/GLCompute.cpp index 79bff90c30..eb55642ef4 100644 --- a/rpcs3/Emu/RSX/GL/GLCompute.cpp +++ b/rpcs3/Emu/RSX/GL/GLCompute.cpp @@ -302,8 +302,8 @@ namespace gl m_program.uniforms["region_offset"] = color2i(region.x, region.y); m_program.uniforms["region_size"] = color2i(region.width, region.height); - auto depth_view = src->get_view(0xAAE4, rsx::default_remap_vector, gl::image_aspect::depth); - auto stencil_view = src->get_view(0xAAE4, rsx::default_remap_vector, gl::image_aspect::stencil); + auto depth_view = src->get_view(GL_REMAP_IDENTITY, rsx::default_remap_vector, gl::image_aspect::depth); + auto stencil_view = src->get_view(GL_REMAP_IDENTITY, rsx::default_remap_vector, gl::image_aspect::stencil); depth_view->bind(cmd, GL_COMPUTE_BUFFER_SLOT(0)); stencil_view->bind(cmd, GL_COMPUTE_BUFFER_SLOT(1)); @@ -343,7 +343,7 @@ namespace gl m_program.uniforms["is_bgra"] = (layout.format == static_cast(gl::texture::format::bgra)); m_program.uniforms["block_width"] = static_cast(layout.size); - auto data_view = src->get_view(0xAAE4, rsx::default_remap_vector, gl::image_aspect::color); + auto data_view = src->get_view(GL_REMAP_IDENTITY, rsx::default_remap_vector, gl::image_aspect::color); data_view->bind(cmd, GL_COMPUTE_BUFFER_SLOT(0)); dst->bind_range(gl::buffer::target::ssbo, GL_COMPUTE_BUFFER_SLOT(1), out_offset, row_pitch * 4 * region.height); diff --git a/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp b/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp index 1f4b962406..ccfa7f15bf 100644 --- a/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp +++ b/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp @@ -13,7 +13,7 @@ color_format rsx::internals::surface_color_format_to_gl(rsx::surface_color_forma return{ ::gl::texture::type::ushort_5_6_5, ::gl::texture::format::rgb, ::gl::texture::internal_format::rgb565, true }; case rsx::surface_color_format::a8r8g8b8: - return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::bgra, ::gl::texture::internal_format::bgra8, false }; + return{ ::gl::texture::type::uint_8_8_8_8_rev, ::gl::texture::format::bgra, ::gl::texture::internal_format::bgra8, true }; //These formats discard their alpha component, forced to 0 or 1 //All XBGR formats will have remapping before they can be read back in shaders as DRGB8 @@ -27,19 +27,19 @@ color_format rsx::internals::surface_color_format_to_gl(rsx::surface_color_forma { ::gl::texture::channel::zero, ::gl::texture::channel::r, ::gl::texture::channel::g, ::gl::texture::channel::b } }; case rsx::surface_color_format::x8r8g8b8_z8r8g8b8: - return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::bgra, ::gl::texture::internal_format::bgra8, false, + return{ ::gl::texture::type::uint_8_8_8_8_rev, ::gl::texture::format::bgra, ::gl::texture::internal_format::bgra8, true, { ::gl::texture::channel::zero, ::gl::texture::channel::r, ::gl::texture::channel::g, ::gl::texture::channel::b } }; case rsx::surface_color_format::x8b8g8r8_o8b8g8r8: - return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::rgba, ::gl::texture::internal_format::rgba8, false, - { ::gl::texture::channel::one, ::gl::texture::channel::b, ::gl::texture::channel::g, ::gl::texture::channel::r } }; + return{ ::gl::texture::type::uint_8_8_8_8_rev, ::gl::texture::format::rgba, ::gl::texture::internal_format::rgba8, true, + { ::gl::texture::channel::one, ::gl::texture::channel::r, ::gl::texture::channel::g, ::gl::texture::channel::b } }; case rsx::surface_color_format::x8b8g8r8_z8b8g8r8: - return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::rgba, ::gl::texture::internal_format::rgba8, false, - { ::gl::texture::channel::zero, ::gl::texture::channel::b, ::gl::texture::channel::g, ::gl::texture::channel::r } }; + return{ ::gl::texture::type::uint_8_8_8_8_rev, ::gl::texture::format::rgba, ::gl::texture::internal_format::rgba8, true, + { ::gl::texture::channel::zero, ::gl::texture::channel::r, ::gl::texture::channel::g, ::gl::texture::channel::b } }; case rsx::surface_color_format::x8r8g8b8_o8r8g8b8: - return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::bgra, ::gl::texture::internal_format::bgra8, false, + return{ ::gl::texture::type::uint_8_8_8_8_rev, ::gl::texture::format::bgra, ::gl::texture::internal_format::bgra8, true, { ::gl::texture::channel::one, ::gl::texture::channel::r, ::gl::texture::channel::g, ::gl::texture::channel::b } }; case rsx::surface_color_format::w16z16y16x16: @@ -61,8 +61,7 @@ color_format rsx::internals::surface_color_format_to_gl(rsx::surface_color_forma { ::gl::texture::channel::r, ::gl::texture::channel::r, ::gl::texture::channel::r, ::gl::texture::channel::r } }; case rsx::surface_color_format::a8b8g8r8: - return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::rgba, ::gl::texture::internal_format::rgba8, false, - { ::gl::texture::channel::a, ::gl::texture::channel::b, ::gl::texture::channel::g, ::gl::texture::channel::r } }; + return{ ::gl::texture::type::uint_8_8_8_8_rev, ::gl::texture::format::rgba, ::gl::texture::internal_format::rgba8, true }; default: fmt::throw_exception("Unsupported surface color format 0x%x", static_cast(color_format)); diff --git a/rpcs3/Emu/RSX/GL/GLTexture.cpp b/rpcs3/Emu/RSX/GL/GLTexture.cpp index a765ae0c79..e0caf676d3 100644 --- a/rpcs3/Emu/RSX/GL/GLTexture.cpp +++ b/rpcs3/Emu/RSX/GL/GLTexture.cpp @@ -169,9 +169,9 @@ namespace gl case texture::internal_format::rgba4: return { GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4, 2, false }; case texture::internal_format::rgba8: - return { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, 4, false }; + return { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 4, true }; case texture::internal_format::bgra8: - return { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, 4, false }; + return { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4, true }; case texture::internal_format::rgba16f: return { GL_RGBA, GL_HALF_FLOAT, 2, true }; case texture::internal_format::rgba32f: diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.h b/rpcs3/Emu/RSX/GL/GLTextureCache.h index b1800c384b..ba1d152832 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.h +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.h @@ -713,7 +713,7 @@ namespace gl { case CELL_GCM_TEXTURE_A8R8G8B8: { - cached.set_format(gl::texture::format::bgra, gl::texture::type::uint_8_8_8_8, false); + cached.set_format(gl::texture::format::bgra, gl::texture::type::uint_8_8_8_8_rev, true); break; } case CELL_GCM_TEXTURE_R5G6B5: @@ -814,8 +814,7 @@ namespace gl return (ifmt == gl::texture::internal_format::rgb565); case CELL_GCM_TEXTURE_A8R8G8B8: case CELL_GCM_TEXTURE_D8R8G8B8: - return (ifmt == gl::texture::internal_format::rgba8 || - ifmt == gl::texture::internal_format::bgra8 || + return (ifmt == gl::texture::internal_format::bgra8 || ifmt == gl::texture::internal_format::depth24_stencil8 || ifmt == gl::texture::internal_format::depth32f_stencil8); case CELL_GCM_TEXTURE_B8: diff --git a/rpcs3/Emu/RSX/GL/glutils/image.cpp b/rpcs3/Emu/RSX/GL/glutils/image.cpp index 242691e030..9f268f0b1f 100644 --- a/rpcs3/Emu/RSX/GL/glutils/image.cpp +++ b/rpcs3/Emu/RSX/GL/glutils/image.cpp @@ -24,7 +24,7 @@ namespace gl glGenTextures(1, &m_id); // Must bind to initialize the new texture - gl::get_command_context()->bind_texture(GL_TEMP_IMAGE_SLOT, target, m_id); + gl::get_command_context()->bind_texture(GL_TEMP_IMAGE_SLOT, target, m_id, GL_TRUE); const GLenum storage_fmt = sizedfmt_to_ifmt(sized_format); switch (target) @@ -251,7 +251,7 @@ namespace gl component_swizzle[2] = argb_swizzle[3]; component_swizzle[3] = argb_swizzle[0]; - gl::get_command_context()->bind_texture(GL_TEMP_IMAGE_SLOT, m_target, m_id); + gl::get_command_context()->bind_texture(GL_TEMP_IMAGE_SLOT, m_target, m_id, GL_TRUE); glTexParameteriv(m_target, GL_TEXTURE_SWIZZLE_RGBA, reinterpret_cast(component_swizzle)); } else @@ -267,7 +267,7 @@ namespace gl constexpr u32 depth_stencil_mask = (image_aspect::depth | image_aspect::stencil); ensure((range.aspect_mask & depth_stencil_mask) != depth_stencil_mask); // "Invalid aspect mask combination" - gl::get_command_context()->bind_texture(GL_TEMP_IMAGE_SLOT, m_target, m_id); + gl::get_command_context()->bind_texture(GL_TEMP_IMAGE_SLOT, m_target, m_id, GL_TRUE); glTexParameteri(m_target, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX); } } @@ -287,8 +287,9 @@ namespace gl cmd->bind_texture(layer, m_target, m_id); } - texture_view* viewable_image::get_view(u32 remap_encoding, const std::pair, std::array>& remap, GLenum aspect_flags) + texture_view* viewable_image::get_view(u32 remap_encoding, const std::pair, std::array>& remap_, GLenum aspect_flags) { + auto remap = remap_; const u64 view_aspect = static_cast(aspect_flags) & aspect(); ensure(view_aspect); diff --git a/rpcs3/Emu/RSX/GL/glutils/state_tracker.hpp b/rpcs3/Emu/RSX/GL/glutils/state_tracker.hpp index d3b6304a26..80eceb46ff 100644 --- a/rpcs3/Emu/RSX/GL/glutils/state_tracker.hpp +++ b/rpcs3/Emu/RSX/GL/glutils/state_tracker.hpp @@ -287,12 +287,12 @@ namespace gl glUseProgram(program); } - void bind_texture(GLuint layer, GLenum target, GLuint name) + void bind_texture(GLuint layer, GLenum target, GLuint name, GLboolean force = GL_FALSE) { ensure(layer < 48); auto& bound = bound_textures[layer][target]; - if (bound != name) + if (bound != name || force) { glActiveTexture(GL_TEXTURE0 + layer); glBindTexture(target, name); diff --git a/rpcs3/Emu/RSX/Program/GLSLSnippets/CopyRGBA8ToBuffer.glsl b/rpcs3/Emu/RSX/Program/GLSLSnippets/CopyRGBA8ToBuffer.glsl index 1990359a62..ceb1e2f432 100644 --- a/rpcs3/Emu/RSX/Program/GLSLSnippets/CopyRGBA8ToBuffer.glsl +++ b/rpcs3/Emu/RSX/Program/GLSLSnippets/CopyRGBA8ToBuffer.glsl @@ -77,17 +77,7 @@ void main() } uvec4 bytes = uvec4(color * 255); - uint result; - - if (block_width > 1) - { - // Simulate BE packing as in UINT_8_8_8_8 - result = bytes.w | (bytes.z << 8u) | (bytes.y << 16u) | (bytes.x << 24u); - } - else - { - result = bytes.x | (bytes.y << 8u) | (bytes.z << 16u) | (bytes.w << 24u); - } + uint result = bytes.x | (bytes.y << 8u) | (bytes.z << 16u) | (bytes.w << 24u); // UINT_8_8_8_8_REV uint output_id = input_coord_to_output_id(coord); data[output_id] = result; diff --git a/rpcs3/Emu/RSX/RSXTexture.cpp b/rpcs3/Emu/RSX/RSXTexture.cpp index 96e5b51a86..807d77b6f9 100644 --- a/rpcs3/Emu/RSX/RSXTexture.cpp +++ b/rpcs3/Emu/RSX/RSXTexture.cpp @@ -242,26 +242,7 @@ namespace rsx break; } - //Remapping tables; format is A-R-G-B - //Remap input table. Contains channel index to read color from - const std::array remap_inputs = - { - static_cast(remap_ctl & 0x3), - static_cast((remap_ctl >> 2) & 0x3), - static_cast((remap_ctl >> 4) & 0x3), - static_cast((remap_ctl >> 6) & 0x3), - }; - - //Remap control table. Controls whether the remap value is used, or force either 0 or 1 - const std::array remap_lookup = - { - static_cast((remap_ctl >> 8) & 0x3), - static_cast((remap_ctl >> 10) & 0x3), - static_cast((remap_ctl >> 12) & 0x3), - static_cast((remap_ctl >> 14) & 0x3), - }; - - return std::make_pair(remap_inputs, remap_lookup); + return decode_remap_encoding(remap_ctl); } f32 fragment_texture::bias() const diff --git a/rpcs3/Emu/RSX/rsx_utils.h b/rpcs3/Emu/RSX/rsx_utils.h index 02e82c1e9d..5f8aa34b4a 100644 --- a/rpcs3/Emu/RSX/rsx_utils.h +++ b/rpcs3/Emu/RSX/rsx_utils.h @@ -217,6 +217,30 @@ namespace rsx { CELL_GCM_TEXTURE_REMAP_REMAP, CELL_GCM_TEXTURE_REMAP_REMAP, CELL_GCM_TEXTURE_REMAP_REMAP, CELL_GCM_TEXTURE_REMAP_REMAP } }; + static inline std::pair, std::array> decode_remap_encoding(u32 remap_ctl) + { + // Remapping tables; format is A-R-G-B + // Remap input table. Contains channel index to read color from + const std::array remap_inputs = + { + static_cast(remap_ctl & 0x3), + static_cast((remap_ctl >> 2) & 0x3), + static_cast((remap_ctl >> 4) & 0x3), + static_cast((remap_ctl >> 6) & 0x3), + }; + + // Remap control table. Controls whether the remap value is used, or force either 0 or 1 + const std::array remap_lookup = + { + static_cast((remap_ctl >> 8) & 0x3), + static_cast((remap_ctl >> 10) & 0x3), + static_cast((remap_ctl >> 12) & 0x3), + static_cast((remap_ctl >> 14) & 0x3), + }; + + return std::make_pair(remap_inputs, remap_lookup); + } + template void pad_texture(void* input_pixels, void* output_pixels, u16 input_width, u16 input_height, u16 output_width, u16 /*output_height*/) {