diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/textures/decoders.cpp | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp index 20ba6d4f6..225c999dc 100644 --- a/src/video_core/textures/decoders.cpp +++ b/src/video_core/textures/decoders.cpp | |||
| @@ -46,6 +46,7 @@ void CopySwizzledData(u32 width, u32 height, u32 bytes_per_pixel, u32 out_bytes_ | |||
| 46 | } | 46 | } |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | //This table represents the internal swizzle of a gob. | ||
| 49 | template <std::size_t N, std::size_t M> | 50 | template <std::size_t N, std::size_t M> |
| 50 | struct alignas(64) SwizzleTable { | 51 | struct alignas(64) SwizzleTable { |
| 51 | constexpr SwizzleTable() { | 52 | constexpr SwizzleTable() { |
| @@ -69,21 +70,25 @@ void FastSwizzleData(u32 width, u32 height, u32 bytes_per_pixel, u8* swizzled_da | |||
| 69 | u8* unswizzled_data, bool unswizzle, u32 block_height) { | 70 | u8* unswizzled_data, bool unswizzle, u32 block_height) { |
| 70 | std::array<u8*, 2> data_ptrs; | 71 | std::array<u8*, 2> data_ptrs; |
| 71 | const std::size_t stride{width * bytes_per_pixel}; | 72 | const std::size_t stride{width * bytes_per_pixel}; |
| 72 | const std::size_t image_width_in_gobs{(stride + 63) / 64}; | 73 | const std::size_t gobs_in_x = 64; |
| 74 | const std::size_t gobs_in_y = 8; | ||
| 75 | const std::size_t gobs_size = gobs_in_x*gobs_in_y; | ||
| 76 | const std::size_t image_width_in_gobs{(stride + gobs_in_x - 1) / gobs_in_x}; | ||
| 73 | const std::size_t copy_size{16}; | 77 | const std::size_t copy_size{16}; |
| 74 | for (std::size_t y = 0; y < height; ++y) { | 78 | for (std::size_t y = 0; y < height; ++y) { |
| 75 | const std::size_t initial_gob = | 79 | const std::size_t initial_gob = |
| 76 | (y / (8 * block_height)) * 512 * block_height * image_width_in_gobs + | 80 | (y / (gobs_in_y * block_height)) * gobs_size * block_height * image_width_in_gobs + |
| 77 | (y % (8 * block_height) / 8) * 512; | 81 | (y % (gobs_in_y * block_height) / gobs_in_y) * gobs_size; |
| 78 | const std::size_t pixel_base{y * width * bytes_per_pixel}; | 82 | const std::size_t pixel_base{y * width * bytes_per_pixel}; |
| 79 | const auto& table = swizzle_table[y % 8]; | 83 | const auto& table = swizzle_table[y % gobs_in_y]; |
| 80 | for (std::size_t xb = 0; xb < stride; xb += copy_size) { | 84 | for (std::size_t xb = 0; xb < stride; xb += copy_size) { |
| 81 | const std::size_t gob_address{initial_gob + (xb / 64) * 512 * block_height}; | 85 | const std::size_t truncated_copy = std::min(copy_size, stride - xb); |
| 86 | const std::size_t gob_address{initial_gob + (xb / gobs_in_x) * gobs_size * block_height}; | ||
| 82 | const std::size_t swizzle_offset{gob_address + table[(xb / 16) % 4]}; | 87 | const std::size_t swizzle_offset{gob_address + table[(xb / 16) % 4]}; |
| 83 | const std::size_t pixel_index{xb + pixel_base}; | 88 | const std::size_t pixel_index{xb + pixel_base}; |
| 84 | data_ptrs[unswizzle] = swizzled_data + swizzle_offset; | 89 | data_ptrs[unswizzle] = swizzled_data + swizzle_offset; |
| 85 | data_ptrs[!unswizzle] = unswizzled_data + pixel_index; | 90 | data_ptrs[!unswizzle] = unswizzled_data + pixel_index; |
| 86 | std::memcpy(data_ptrs[0], data_ptrs[1], copy_size); | 91 | std::memcpy(data_ptrs[0], data_ptrs[1], truncated_copy); |
| 87 | } | 92 | } |
| 88 | } | 93 | } |
| 89 | } | 94 | } |
| @@ -134,7 +139,7 @@ u32 BytesPerPixel(TextureFormat format) { | |||
| 134 | std::vector<u8> UnswizzleTexture(VAddr address, u32 tile_size, u32 bytes_per_pixel, u32 width, | 139 | std::vector<u8> UnswizzleTexture(VAddr address, u32 tile_size, u32 bytes_per_pixel, u32 width, |
| 135 | u32 height, u32 block_height) { | 140 | u32 height, u32 block_height) { |
| 136 | std::vector<u8> unswizzled_data(width * height * bytes_per_pixel); | 141 | std::vector<u8> unswizzled_data(width * height * bytes_per_pixel); |
| 137 | if (bytes_per_pixel % 3 != 0 && (width * bytes_per_pixel) % 16 == 0) { | 142 | if (bytes_per_pixel % 3 != 0) { |
| 138 | FastSwizzleData(width / tile_size, height / tile_size, bytes_per_pixel, | 143 | FastSwizzleData(width / tile_size, height / tile_size, bytes_per_pixel, |
| 139 | Memory::GetPointer(address), unswizzled_data.data(), true, block_height); | 144 | Memory::GetPointer(address), unswizzled_data.data(), true, block_height); |
| 140 | } else { | 145 | } else { |