From 188eefeeacc96369524710aa778f6845bc7e8a18 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sat, 30 Dec 2023 02:23:56 +0300 Subject: [PATCH] rsx: Avoid out of bounds write for tiled memory --- rpcs3/Emu/RSX/Common/tiled_dma_copy.hpp | 16 +++++++++++----- .../Program/GLSLSnippets/RSXMemoryTiling.glsl | 7 ++++--- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/rpcs3/Emu/RSX/Common/tiled_dma_copy.hpp b/rpcs3/Emu/RSX/Common/tiled_dma_copy.hpp index 850adebc6d..ab78bfa004 100644 --- a/rpcs3/Emu/RSX/Common/tiled_dma_copy.hpp +++ b/rpcs3/Emu/RSX/Common/tiled_dma_copy.hpp @@ -102,10 +102,11 @@ namespace rsx tile_address ^= ((tile_address >> 11) & 1) << 10; // Calculate relative addresses and sample - uint32_t linear_image_offset = (row * conf.image_pitch) + (col * conf.image_bpp); - uint32_t tile_data_offset = tile_address - (conf.tile_base_address + conf.tile_offset); + const uint32_t linear_image_offset = (row * conf.image_pitch) + (col * conf.image_bpp); + const uint32_t tile_base_offset = tile_address - conf.tile_base_address; // Distance from tile base address + const uint32_t tile_data_offset = tile_base_offset - conf.tile_offset; // Distance from data base address - if (tile_data_offset >= conf.tile_size) + if (tile_base_offset >= conf.tile_size) { // Do not touch anything out of bounds return; @@ -122,7 +123,7 @@ namespace rsx } // Entry point. In GPU code this is handled by dispatch + main - template + template void tile_texel_data(void* dst, const void* src, uint32_t base_address, uint32_t base_offset, uint32_t tile_size, uint8_t bank_sense, uint16_t row_pitch_in_bytes, uint16_t image_width, uint16_t image_height) { // Some constants @@ -148,7 +149,7 @@ namespace rsx const auto [prime, factor] = get_prime_factor(row_pitch_in_bytes); const uint32_t tiles_per_row = prime * factor; - constexpr int op = Reverse ? RSX_DMA_OP_DECODE_TILE : RSX_DMA_OP_ENCODE_TILE; + constexpr int op = Decode ? RSX_DMA_OP_DECODE_TILE : RSX_DMA_OP_ENCODE_TILE; auto src2 = static_cast(const_cast(src)); auto dst2 = static_cast(dst); @@ -184,6 +185,11 @@ namespace rsx } } + static auto tile_texel_data16 = tile_texel_data; + static auto tile_texel_data32 = tile_texel_data; + static auto detile_texel_data16 = tile_texel_data; + static auto detile_texel_data32 = tile_texel_data; + #undef RSX_TILE_WIDTH #undef RSX_TILE_HEIGHT #undef RSX_DMA_OP_ENCODE_TILE diff --git a/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXMemoryTiling.glsl b/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXMemoryTiling.glsl index eebed180c6..da9bc04799 100644 --- a/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXMemoryTiling.glsl +++ b/rpcs3/Emu/RSX/Program/GLSLSnippets/RSXMemoryTiling.glsl @@ -308,10 +308,11 @@ void do_memory_op(const in uint row, const in uint col) tile_address ^= ((tile_address >> 11) & 1) << 10; // Calculate relative addresses and sample - uint linear_image_offset = (row * image_pitch) + (col * image_bpp); - uint tile_data_offset = tile_address - (tile_base_address + tile_offset); + const uint linear_image_offset = (row * image_pitch) + (col * image_bpp); + const uint tile_base_offset = tile_address - conf.tile_base_address; // Distance from tile base address + const uint tile_data_offset = tile_base_offset - conf.tile_offset; // Distance from data base address - if (tile_data_offset >= tile_size) + if (tile_base_offset >= tile_size) { // Do not touch anything out of bounds return;