From 0bf4d4c92e793fe64c415249ef673549d986603f Mon Sep 17 00:00:00 2001 From: kd-11 Date: Mon, 9 Mar 2026 22:08:43 +0300 Subject: [PATCH] gl: Add optional row length to GPU image routines --- rpcs3/Emu/RSX/GL/GLCompute.cpp | 6 ++-- rpcs3/Emu/RSX/GL/GLOverlays.cpp | 3 +- rpcs3/Emu/RSX/GL/GLTexture.cpp | 46 +++++++++++++++---------------- rpcs3/Emu/RSX/GL/GLTexture.h | 4 ++- rpcs3/Emu/RSX/GL/GLTextureCache.h | 6 ++-- 5 files changed, 34 insertions(+), 31 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLCompute.cpp b/rpcs3/Emu/RSX/GL/GLCompute.cpp index 5607c149ed..fd31708df7 100644 --- a/rpcs3/Emu/RSX/GL/GLCompute.cpp +++ b/rpcs3/Emu/RSX/GL/GLCompute.cpp @@ -340,7 +340,7 @@ namespace gl void cs_d24x8_to_ssbo::run(gl::command_context& cmd, gl::viewable_image* src, const gl::buffer* dst, u32 out_offset, const coordu& region, const gl::pixel_buffer_layout& layout) { - const auto row_pitch = region.width; + const auto row_pitch = layout.row_length ? layout.row_length : region.width; m_program.uniforms["swap_bytes"] = layout.swap_bytes; m_program.uniforms["output_pitch"] = row_pitch; @@ -390,14 +390,14 @@ namespace gl void cs_rgba8_to_ssbo::run(gl::command_context& cmd, gl::viewable_image* src, const gl::buffer* dst, u32 out_offset, const coordu& region, const gl::pixel_buffer_layout& layout) { - const auto row_pitch = region.width; + const auto row_pitch = layout.row_length ? layout.row_length : region.width; m_program.uniforms["swap_bytes"] = layout.swap_bytes; m_program.uniforms["output_pitch"] = row_pitch; m_program.uniforms["region_offset"] = color2i(region.x, region.y); m_program.uniforms["region_size"] = color2i(region.width, region.height); m_program.uniforms["is_bgra"] = (layout.format == static_cast(gl::texture::format::bgra)); - m_program.uniforms["block_width"] = static_cast(layout.size); + m_program.uniforms["block_width"] = static_cast(layout.block_size); auto data_view = src->get_view(rsx::default_remap_vector.with_encoding(GL_REMAP_IDENTITY), gl::image_aspect::color); diff --git a/rpcs3/Emu/RSX/GL/GLOverlays.cpp b/rpcs3/Emu/RSX/GL/GLOverlays.cpp index 0c4732430c..6be9aba6a0 100644 --- a/rpcs3/Emu/RSX/GL/GLOverlays.cpp +++ b/rpcs3/Emu/RSX/GL/GLOverlays.cpp @@ -551,7 +551,8 @@ namespace gl const pixel_buffer_layout& layout) { const u32 bpp = dst->image()->pitch() / dst->image()->width(); - const u32 row_length = utils::align(dst_region.width * bpp, std::max(layout.alignment, 1)) / bpp; + const u32 aligned_width = utils::align(dst_region.width * bpp, std::max(layout.alignment, 1)) / bpp; + const u32 row_length = layout.row_length ? layout.row_length : aligned_width; program_handle.uniforms["src_pitch"] = row_length; program_handle.uniforms["swap_bytes"] = layout.swap_bytes; diff --git a/rpcs3/Emu/RSX/GL/GLTexture.cpp b/rpcs3/Emu/RSX/GL/GLTexture.cpp index 5dfc663c68..5c85f71c2e 100644 --- a/rpcs3/Emu/RSX/GL/GLTexture.cpp +++ b/rpcs3/Emu/RSX/GL/GLTexture.cpp @@ -166,42 +166,42 @@ namespace gl case texture::internal_format::compressed_rgba_s3tc_dxt1: case texture::internal_format::compressed_rgba_s3tc_dxt3: case texture::internal_format::compressed_rgba_s3tc_dxt5: - return { GL_RGBA, GL_UNSIGNED_BYTE, 1, false }; + return { .format = GL_RGBA, .type = GL_UNSIGNED_BYTE, .block_size = 1, .swap_bytes = false }; case texture::internal_format::r8: - return { GL_RED, GL_UNSIGNED_BYTE, 1, false }; + return { .format = GL_RED, .type = GL_UNSIGNED_BYTE, .block_size = 1, .swap_bytes = false }; case texture::internal_format::r16: - return { GL_RED, GL_UNSIGNED_SHORT, 2, true }; + return { .format = GL_RED, .type = GL_UNSIGNED_SHORT, .block_size = 2, .swap_bytes = true }; case texture::internal_format::r32f: - return { GL_RED, GL_FLOAT, 4, true }; + return { .format = GL_RED, .type = GL_FLOAT, .block_size = 4, .swap_bytes = true }; case texture::internal_format::rg8: - return { GL_RG, GL_UNSIGNED_SHORT, 2, true }; + return { .format = GL_RG, .type = GL_UNSIGNED_SHORT, .block_size = 2, .swap_bytes = true }; case texture::internal_format::rg16: - return { GL_RG, GL_UNSIGNED_SHORT, 2, true }; + return { .format = GL_RG, .type = GL_UNSIGNED_SHORT, .block_size = 2, .swap_bytes = true }; case texture::internal_format::rg16f: - return { GL_RG, GL_HALF_FLOAT, 2, true }; + return { .format = GL_RG, .type = GL_HALF_FLOAT, .block_size = 2, .swap_bytes = true }; case texture::internal_format::rgb565: - return { GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2, true }; + return { .format = GL_RGB, .type = GL_UNSIGNED_SHORT_5_6_5, .block_size = 2, .swap_bytes = true }; case texture::internal_format::rgb5a1: - return { GL_RGB, GL_UNSIGNED_SHORT_5_5_5_1, 2, true }; + return { .format = GL_RGB, .type = GL_UNSIGNED_SHORT_5_5_5_1, .block_size = 2, .swap_bytes = true }; case texture::internal_format::bgr5a1: - return { GL_RGB, GL_UNSIGNED_SHORT_1_5_5_5_REV, 2, true }; + return { .format = GL_RGB, .type = GL_UNSIGNED_SHORT_1_5_5_5_REV, .block_size = 2, .swap_bytes = true }; case texture::internal_format::rgba4: - return { GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4, 2, false }; + return { .format = GL_BGRA, .type = GL_UNSIGNED_SHORT_4_4_4_4, .block_size = 2, .swap_bytes = false }; case texture::internal_format::rgba8: - return { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 4, true }; + return { .format = GL_RGBA, .type = GL_UNSIGNED_INT_8_8_8_8_REV, .block_size = 4, .swap_bytes = true }; case texture::internal_format::bgra8: - return { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4, true }; + return { .format = GL_BGRA, .type = GL_UNSIGNED_INT_8_8_8_8_REV, .block_size = 4, .swap_bytes = true }; case texture::internal_format::rgba16f: - return { GL_RGBA, GL_HALF_FLOAT, 2, true }; + return { .format = GL_RGBA, .type = GL_HALF_FLOAT, .block_size = 2, .swap_bytes = true }; case texture::internal_format::rgba32f: - return { GL_RGBA, GL_FLOAT, 4, true }; + return { .format = GL_RGBA, .type = GL_FLOAT, .block_size = 4, .swap_bytes = true }; case texture::internal_format::depth16: - return { GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 2, true }; + return { .format = GL_DEPTH_COMPONENT, .type = GL_UNSIGNED_SHORT, .block_size = 2, .swap_bytes = true }; case texture::internal_format::depth32f: - return { GL_DEPTH_COMPONENT, GL_FLOAT, 2, true }; + return { .format = GL_DEPTH_COMPONENT, .type = GL_FLOAT, .block_size = 2, .swap_bytes = true }; case texture::internal_format::depth24_stencil8: case texture::internal_format::depth32f_stencil8: - return { GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4, true }; + return { .format = GL_DEPTH_STENCIL, .type = GL_UNSIGNED_INT_24_8, .block_size = 4, .swap_bytes = true }; default: fmt::throw_exception("Unexpected internal format 0x%X", static_cast(format)); } @@ -320,7 +320,7 @@ namespace gl return nullptr; } - switch (pack_info.size) + switch (pack_info.block_size) { case 1: return nullptr; @@ -780,7 +780,7 @@ namespace gl mem_layout.swap_bytes = op.require_swap; mem_layout.format = gl_format; mem_layout.type = gl_type; - mem_layout.size = block_size_in_bytes; + mem_layout.block_size = block_size_in_bytes; // 2. Upload memory to GPU if (!op.require_deswizzle) @@ -1061,7 +1061,7 @@ namespace gl skip_transform = (pack_info.format == unpack_info.format && pack_info.type == unpack_info.type && pack_info.swap_bytes == unpack_info.swap_bytes && - pack_info.size == unpack_info.size); + pack_info.block_size == unpack_info.block_size); } if (skip_transform) [[likely]] @@ -1142,7 +1142,7 @@ namespace gl if (src->aspect() & image_aspect::depth) { // Source is depth, modify unpack rule - if (pack_info.size == 4 && unpack_info.size == 4) + if (pack_info.block_size == 4 && unpack_info.block_size == 4) { unpack_info.swap_bytes = !unpack_info.swap_bytes; } @@ -1150,7 +1150,7 @@ namespace gl else { // Dest is depth, modify pack rule - if (pack_info.size == 4 && unpack_info.size == 4) + if (pack_info.block_size == 4 && unpack_info.block_size == 4) { pack_info.swap_bytes = !pack_info.swap_bytes; } diff --git a/rpcs3/Emu/RSX/GL/GLTexture.h b/rpcs3/Emu/RSX/GL/GLTexture.h index 7b3ff73db4..4a17dae081 100644 --- a/rpcs3/Emu/RSX/GL/GLTexture.h +++ b/rpcs3/Emu/RSX/GL/GLTexture.h @@ -16,9 +16,11 @@ namespace gl { GLenum format; GLenum type; - u8 size; + u32 row_length; + u8 block_size; bool swap_bytes; u8 alignment; + u8 reserved; }; struct image_memory_requirements diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.h b/rpcs3/Emu/RSX/GL/GLTextureCache.h index 6d724c216f..1a4b4f9e1e 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.h +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.h @@ -186,7 +186,7 @@ namespace gl pack_info.format = static_cast(format); pack_info.type = static_cast(type); - pack_info.size = (src->aspect() & image_aspect::stencil) ? 4 : 2; + pack_info.block_size = (src->aspect() & image_aspect::stencil) ? 4 : 2; pack_info.swap_bytes = true; mem_info.image_size_in_texels = src->width() * src->height(); @@ -204,8 +204,8 @@ namespace gl glBindBuffer(GL_SHADER_STORAGE_BUFFER, GL_NONE); glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); - real_pitch = pack_info.size * src->width(); - const u64 data_length = pack_info.size * mem_info.image_size_in_texels; + real_pitch = pack_info.block_size * src->width(); + const u64 data_length = pack_info.block_size * mem_info.image_size_in_texels; scratch_mem.copy_to(&pbo, reinterpret_cast(out_offset), 0, data_length); } else