diff --git a/src/video_core/host_shaders/block_linear_unswizzle_2d.comp b/src/video_core/host_shaders/block_linear_unswizzle_2d.comp index 121f60cbd1..2a3446ca66 100644 --- a/src/video_core/host_shaders/block_linear_unswizzle_2d.comp +++ b/src/video_core/host_shaders/block_linear_unswizzle_2d.comp @@ -11,9 +11,8 @@ #define BEGIN_PUSH_CONSTANTS layout(push_constant) uniform PushConstants { #define END_PUSH_CONSTANTS }; #define UNIFORM(n) -#define BINDING_SWIZZLE_BUFFER 0 -#define BINDING_INPUT_BUFFER 1 -#define BINDING_OUTPUT_IMAGE 2 +#define BINDING_INPUT_BUFFER 0 +#define BINDING_OUTPUT_IMAGE 1 #else // ^^^ Vulkan ^^^ // vvv OpenGL vvv @@ -26,8 +25,7 @@ #define BEGIN_PUSH_CONSTANTS #define END_PUSH_CONSTANTS #define UNIFORM(n) layout (location = n) uniform -#define BINDING_SWIZZLE_BUFFER 0 -#define BINDING_INPUT_BUFFER 1 +#define BINDING_INPUT_BUFFER 0 #define BINDING_OUTPUT_IMAGE 0 #endif @@ -43,10 +41,6 @@ UNIFORM(6) uint block_height; UNIFORM(7) uint block_height_mask; END_PUSH_CONSTANTS -layout(binding = BINDING_SWIZZLE_BUFFER, std430) readonly buffer SwizzleTable { - uint swizzle_table[]; -}; - #if HAS_EXTENDED_TYPES layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU8 { uint8_t u8data[]; }; layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU16 { uint16_t u16data[]; }; @@ -71,9 +65,19 @@ const uint GOB_SIZE_SHIFT = GOB_SIZE_X_SHIFT + GOB_SIZE_Y_SHIFT + GOB_SIZE_Z_SHI const uvec2 SWIZZLE_MASK = uvec2(GOB_SIZE_X - 1, GOB_SIZE_Y - 1); +uint SwizzleTable(uint pos) { + const uint t[8] = uint[]( + 0x12100200, 0x13110301, 0x16140604, 0x17150705, + 0x1a180a08, 0x1b190b09, 0x1e1c0e0c, 0x1f1d0f0d + ); + const uint i = pos >> 4; + const uint h = (t[i / 4] >> ((i % 4) * 8)) & 0xff; + return (h << 4) | (pos & 0xf); +} + uint SwizzleOffset(uvec2 pos) { pos = pos & SWIZZLE_MASK; - return swizzle_table[pos.y * 64 + pos.x]; + return SwizzleTable(pos.y * 64 + pos.x); } uvec4 ReadTexel(uint offset) { diff --git a/src/video_core/host_shaders/block_linear_unswizzle_3d.comp b/src/video_core/host_shaders/block_linear_unswizzle_3d.comp index 7fc98accb9..34e4f93307 100644 --- a/src/video_core/host_shaders/block_linear_unswizzle_3d.comp +++ b/src/video_core/host_shaders/block_linear_unswizzle_3d.comp @@ -11,9 +11,8 @@ #define BEGIN_PUSH_CONSTANTS layout(push_constant) uniform PushConstants { #define END_PUSH_CONSTANTS }; #define UNIFORM(n) -#define BINDING_SWIZZLE_BUFFER 0 -#define BINDING_INPUT_BUFFER 1 -#define BINDING_OUTPUT_IMAGE 2 +#define BINDING_INPUT_BUFFER 0 +#define BINDING_OUTPUT_IMAGE 1 #else // ^^^ Vulkan ^^^ // vvv OpenGL vvv @@ -26,8 +25,7 @@ #define BEGIN_PUSH_CONSTANTS #define END_PUSH_CONSTANTS #define UNIFORM(n) layout (location = n) uniform -#define BINDING_SWIZZLE_BUFFER 0 -#define BINDING_INPUT_BUFFER 1 +#define BINDING_INPUT_BUFFER 0 #define BINDING_OUTPUT_IMAGE 0 #endif @@ -45,10 +43,6 @@ UNIFORM(8) uint block_depth; UNIFORM(9) uint block_depth_mask; END_PUSH_CONSTANTS -layout(binding = BINDING_SWIZZLE_BUFFER, std430) readonly buffer SwizzleTable { - uint swizzle_table[]; -}; - #if HAS_EXTENDED_TYPES layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU8 { uint8_t u8data[]; }; layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU16 { uint16_t u16data[]; }; @@ -73,9 +67,19 @@ const uint GOB_SIZE_SHIFT = GOB_SIZE_X_SHIFT + GOB_SIZE_Y_SHIFT + GOB_SIZE_Z_SHI const uvec2 SWIZZLE_MASK = uvec2(GOB_SIZE_X - 1, GOB_SIZE_Y - 1); +uint SwizzleTable(uint pos) { + const uint t[8] = uint[]( + 0x12100200, 0x13110301, 0x16140604, 0x17150705, + 0x1a180a08, 0x1b190b09, 0x1e1c0e0c, 0x1f1d0f0d + ); + const uint i = pos >> 4; + const uint h = (t[i / 4] >> ((i % 4) * 8)) & 0xff; + return (h << 4) | (pos & 0xf); +} + uint SwizzleOffset(uvec2 pos) { pos = pos & SWIZZLE_MASK; - return swizzle_table[pos.y * 64 + pos.x]; + return SwizzleTable(pos.y * 64 + pos.x); } uvec4 ReadTexel(uint offset) { diff --git a/src/video_core/host_shaders/block_linear_unswizzle_3d_bcn.comp b/src/video_core/host_shaders/block_linear_unswizzle_3d_bcn.comp index 6e5a300ecd..e084837f25 100644 --- a/src/video_core/host_shaders/block_linear_unswizzle_3d_bcn.comp +++ b/src/video_core/host_shaders/block_linear_unswizzle_3d_bcn.comp @@ -10,9 +10,8 @@ #define BEGIN_PUSH_CONSTANTS layout(push_constant) uniform PushConstants { #define END_PUSH_CONSTANTS }; #define UNIFORM(n) - #define BINDING_SWIZZLE_BUFFER 0 - #define BINDING_INPUT_BUFFER 1 - #define BINDING_OUTPUT_BUFFER 2 + #define BINDING_INPUT_BUFFER 0 + #define BINDING_OUTPUT_BUFFER 1 #else #extension GL_NV_gpu_shader5 : enable #ifdef GL_NV_gpu_shader5 @@ -23,7 +22,6 @@ #define BEGIN_PUSH_CONSTANTS #define END_PUSH_CONSTANTS #define UNIFORM(n) layout(location = n) uniform - #define BINDING_SWIZZLE_BUFFER 0 #define BINDING_INPUT_BUFFER 1 #define BINDING_OUTPUT_BUFFER 0 #endif @@ -66,13 +64,9 @@ END_PUSH_CONSTANTS #endif // --- Buffers --- -layout(binding = BINDING_SWIZZLE_BUFFER, std430) readonly buffer SwizzleTable { - uint swizzle_table[]; -}; - #if HAS_EXTENDED_TYPES - layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU8 { uint8_t u8data[]; }; - layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU16 { uint16_t u16data[]; }; +layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU8 { uint8_t u8data[]; }; +layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU16 { uint16_t u16data[]; }; #endif layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU32 { uint u32data[]; }; layout(binding = BINDING_INPUT_BUFFER, std430) buffer InputBufferU64 { uvec2 u64data[]; }; @@ -96,10 +90,20 @@ const uint GOB_SIZE_Z_SHIFT = 0; const uint GOB_SIZE_SHIFT = GOB_SIZE_X_SHIFT + GOB_SIZE_Y_SHIFT + GOB_SIZE_Z_SHIFT; const uvec2 SWIZZLE_MASK = uvec2(GOB_SIZE_X - 1u, GOB_SIZE_Y - 1u); +uint SwizzleTable(uint pos) { + const uint t[8] = uint[]( + 0x12100200, 0x13110301, 0x16140604, 0x17150705, + 0x1a180a08, 0x1b190b09, 0x1e1c0e0c, 0x1f1d0f0d + ); + const uint i = pos >> 4; + const uint h = (t[i / 4] >> ((i % 4) * 8)) & 0xff; + return (h << 4) | (pos & 0xf); +} + // --- Helpers --- uint SwizzleOffset(uvec2 pos) { pos &= SWIZZLE_MASK; - return swizzle_table[pos.y * 64u + pos.x]; + return SwizzleTable(pos.y * 64u + pos.x); } uvec4 ReadTexel(uint offset) { diff --git a/src/video_core/renderer_opengl/util_shaders.cpp b/src/video_core/renderer_opengl/util_shaders.cpp index c437013e6a..7ced8c77b4 100644 --- a/src/video_core/renderer_opengl/util_shaders.cpp +++ b/src/video_core/renderer_opengl/util_shaders.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -56,10 +59,8 @@ UtilShaders::UtilShaders(ProgramManager& program_manager_) copy_bc4_program(MakeProgram(OPENGL_COPY_BC4_COMP)), convert_s8d24_program(MakeProgram(OPENGL_CONVERT_S8D24_COMP)), convert_ms_to_nonms_program(MakeProgram(CONVERT_MSAA_TO_NON_MSAA_COMP)), - convert_nonms_to_ms_program(MakeProgram(CONVERT_NON_MSAA_TO_MSAA_COMP)) { - const auto swizzle_table = Tegra::Texture::MakeSwizzleTable(); - swizzle_table_buffer.Create(); - glNamedBufferStorage(swizzle_table_buffer.handle, sizeof(swizzle_table), &swizzle_table, 0); + convert_nonms_to_ms_program(MakeProgram(CONVERT_NON_MSAA_TO_MSAA_COMP)) +{ } UtilShaders::~UtilShaders() = default; @@ -116,13 +117,11 @@ void UtilShaders::ASTCDecode(Image& image, const StagingBufferMap& map, void UtilShaders::BlockLinearUpload2D(Image& image, const StagingBufferMap& map, std::span swizzles) { static constexpr Extent3D WORKGROUP_SIZE{32, 32, 1}; - static constexpr GLuint BINDING_SWIZZLE_BUFFER = 0; - static constexpr GLuint BINDING_INPUT_BUFFER = 1; + static constexpr GLuint BINDING_INPUT_BUFFER = 0; static constexpr GLuint BINDING_OUTPUT_IMAGE = 0; program_manager.BindComputeProgram(block_linear_unswizzle_2d_program.handle); glFlushMappedNamedBufferRange(map.buffer, map.offset, image.guest_size_bytes); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_SWIZZLE_BUFFER, swizzle_table_buffer.handle); const GLenum store_format = StoreFormat(BytesPerBlock(image.info.format)); for (const SwizzleParameters& swizzle : swizzles) { @@ -153,14 +152,11 @@ void UtilShaders::BlockLinearUpload2D(Image& image, const StagingBufferMap& map, void UtilShaders::BlockLinearUpload3D(Image& image, const StagingBufferMap& map, std::span swizzles) { static constexpr Extent3D WORKGROUP_SIZE{16, 8, 8}; - - static constexpr GLuint BINDING_SWIZZLE_BUFFER = 0; - static constexpr GLuint BINDING_INPUT_BUFFER = 1; + static constexpr GLuint BINDING_INPUT_BUFFER = 0; static constexpr GLuint BINDING_OUTPUT_IMAGE = 0; glFlushMappedNamedBufferRange(map.buffer, map.offset, image.guest_size_bytes); program_manager.BindComputeProgram(block_linear_unswizzle_3d_program.handle); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_SWIZZLE_BUFFER, swizzle_table_buffer.handle); const GLenum store_format = StoreFormat(BytesPerBlock(image.info.format)); for (const SwizzleParameters& swizzle : swizzles) { diff --git a/src/video_core/renderer_opengl/util_shaders.h b/src/video_core/renderer_opengl/util_shaders.h index feecd404ca..b290b3e9ed 100644 --- a/src/video_core/renderer_opengl/util_shaders.h +++ b/src/video_core/renderer_opengl/util_shaders.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -45,9 +48,6 @@ public: private: ProgramManager& program_manager; - - OGLBuffer swizzle_table_buffer; - OGLProgram astc_decoder_program; OGLProgram block_linear_unswizzle_2d_program; OGLProgram block_linear_unswizzle_3d_program; diff --git a/src/video_core/renderer_vulkan/vk_compute_pass.cpp b/src/video_core/renderer_vulkan/vk_compute_pass.cpp index 471cbbb0df..0011ec3bf5 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pass.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pass.cpp @@ -653,18 +653,37 @@ void ASTCDecoderPass::Assemble(Image& image, const StagingBufferRef& map, scheduler.Finish(); } -constexpr u32 BL3D_BINDING_SWIZZLE_TABLE = 0; -constexpr u32 BL3D_BINDING_INPUT_BUFFER = 1; -constexpr u32 BL3D_BINDING_OUTPUT_BUFFER = 2; +constexpr u32 BL3D_BINDING_INPUT_BUFFER = 0; +constexpr u32 BL3D_BINDING_OUTPUT_BUFFER = 1; -constexpr std::array BL3D_DESCRIPTOR_SET_BINDINGS{{ - { - .binding = BL3D_BINDING_SWIZZLE_TABLE, - .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // swizzle_table[] - .descriptorCount = 1, - .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, - .pImmutableSamplers = nullptr, - }, +struct alignas(16) BlockLinearUnswizzle3DPushConstants { + u32 blocks_dim[3]; // Offset 0 + u32 bytes_per_block_log2; // Offset 12 + + u32 origin[3]; // Offset 16 + u32 slice_size; // Offset 28 + + u32 block_size; // Offset 32 + u32 x_shift; // Offset 36 + u32 block_height; // Offset 40 + u32 block_height_mask; // Offset 44 + + u32 block_depth; // Offset 48 + u32 block_depth_mask; // Offset 52 + s32 _pad; // Offset 56 + + s32 destination[3]; // Offset 60 + s32 _pad_end; // Offset 72 +}; +static_assert(sizeof(BlockLinearUnswizzle3DPushConstants) <= 128); + +BlockLinearUnswizzle3DPass::BlockLinearUnswizzle3DPass( + const Device& device_, Scheduler& scheduler_, + DescriptorPool& descriptor_pool_, + StagingBufferPool& staging_buffer_pool_, + ComputePassDescriptorQueue& compute_pass_descriptor_queue_) + : ComputePass(device_, scheduler_, descriptor_pool_, + std::array{{ { .binding = BL3D_BINDING_INPUT_BUFFER, .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // block-linear input @@ -679,28 +698,8 @@ constexpr std::array BL3D_DESCRIPTOR_SET_BINDIN .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, .pImmutableSamplers = nullptr, }, -}}; - -constexpr DescriptorBankInfo BL3D_BANK_INFO{ - .uniform_buffers = 0, - .storage_buffers = 3, - .texture_buffers = 0, - .image_buffers = 0, - .textures = 0, - .images = 0, - .score = 3, -}; - -constexpr std::array - BL3D_DESCRIPTOR_UPDATE_TEMPLATE_ENTRY{{ - { - .dstBinding = BL3D_BINDING_SWIZZLE_TABLE, - .dstArrayElement = 0, - .descriptorCount = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - .offset = BL3D_BINDING_SWIZZLE_TABLE * sizeof(DescriptorUpdateEntry), - .stride = sizeof(DescriptorUpdateEntry), - }, + }}, + std::array{{ { .dstBinding = BL3D_BINDING_INPUT_BUFFER, .dstArrayElement = 0, @@ -717,39 +716,16 @@ constexpr std::array .offset = BL3D_BINDING_OUTPUT_BUFFER * sizeof(DescriptorUpdateEntry), .stride = sizeof(DescriptorUpdateEntry), } - }}; - -struct alignas(16) BlockLinearUnswizzle3DPushConstants { - u32 blocks_dim[3]; // Offset 0 - u32 bytes_per_block_log2; // Offset 12 - - u32 origin[3]; // Offset 16 - u32 slice_size; // Offset 28 - - u32 block_size; // Offset 32 - u32 x_shift; // Offset 36 - u32 block_height; // Offset 40 - u32 block_height_mask; // Offset 44 - - u32 block_depth; // Offset 48 - u32 block_depth_mask; // Offset 52 - s32 _pad; // Offset 56 - - s32 destination[3]; // Offset 60 - s32 _pad_end; // Offset 72 -}; -static_assert(sizeof(BlockLinearUnswizzle3DPushConstants) <= 128); - -BlockLinearUnswizzle3DPass::BlockLinearUnswizzle3DPass( - const Device& device_, Scheduler& scheduler_, - DescriptorPool& descriptor_pool_, - StagingBufferPool& staging_buffer_pool_, - ComputePassDescriptorQueue& compute_pass_descriptor_queue_) - : ComputePass( - device_, scheduler_, descriptor_pool_, - BL3D_DESCRIPTOR_SET_BINDINGS, - BL3D_DESCRIPTOR_UPDATE_TEMPLATE_ENTRY, - BL3D_BANK_INFO, + }}, + DescriptorBankInfo{ + .uniform_buffers = 0, + .storage_buffers = 2, + .texture_buffers = 0, + .image_buffers = 0, + .textures = 0, + .images = 0, + .score = 2, + }, COMPUTE_PUSH_CONSTANT_RANGE, BLOCK_LINEAR_UNSWIZZLE_3D_BCN_COMP_SPV), scheduler{scheduler_}, @@ -822,8 +798,6 @@ void BlockLinearUnswizzle3DPass::UnswizzleChunk( pc.blocks_dim[2] = z_count; // Only process the count compute_pass_descriptor_queue.Acquire(scheduler, 3); - compute_pass_descriptor_queue.AddBuffer(*image.runtime->swizzle_table_buffer, 0, - image.runtime->swizzle_table_size); compute_pass_descriptor_queue.AddBuffer(swizzled.buffer, sw.buffer_offset + swizzled.offset, image.guest_size_bytes - sw.buffer_offset); diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 567fd560af..7804e33d46 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -909,40 +909,6 @@ TextureCacheRuntime::TextureCacheRuntime(const Device& device_, Scheduler& sched bl3d_unswizzle_pass.emplace(device, scheduler, descriptor_pool, staging_buffer_pool, compute_pass_descriptor_queue); } - - // --- Create swizzle table buffer --- - { - auto table = Tegra::Texture::MakeSwizzleTable(); - - swizzle_table_size = static_cast(table.size() * sizeof(table[0])); - - auto staging = staging_buffer_pool.Request(swizzle_table_size, MemoryUsage::Upload); - std::memcpy(staging.mapped_span.data(), table.data(), static_cast(swizzle_table_size)); - - VkBufferCreateInfo ci{ - .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, - .size = swizzle_table_size, - .usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | - VK_BUFFER_USAGE_TRANSFER_DST_BIT | - VK_BUFFER_USAGE_TRANSFER_SRC_BIT, - .sharingMode = VK_SHARING_MODE_EXCLUSIVE, - }; - swizzle_table_buffer = memory_allocator.CreateBuffer(ci, MemoryUsage::DeviceLocal); - - scheduler.RequestOutsideRenderPassOperationContext(); - scheduler.Record([staging_buf = staging.buffer, - dst_buf = *swizzle_table_buffer, - size = swizzle_table_size, - src_off = staging.offset](vk::CommandBuffer cmdbuf) { - - const VkBufferCopy region{ - .srcOffset = src_off, - .dstOffset = 0, - .size = size, - }; - cmdbuf.CopyBuffer(staging_buf, dst_buf, region); - }); - } } void TextureCacheRuntime::Finish() { @@ -2484,18 +2450,13 @@ void TextureCacheRuntime::AccelerateImageUpload( if (!Settings::values.gpu_unswizzle_enabled.GetValue() || !bl3d_unswizzle_pass) { if (IsPixelFormatBCn(image.info.format) && image.info.type == ImageType::e3D) { - ASSERT_MSG(false, "GPU unswizzle is disabled for BCn 3D texture"); + ASSERT(false && "GPU unswizzle is disabled for BCn 3D texture"); } ASSERT(false); return; } - if (bl3d_unswizzle_pass && - IsPixelFormatBCn(image.info.format) && - image.info.type == ImageType::e3D && - image.info.resources.levels == 1 && - image.info.resources.layers == 1) { - + if (bl3d_unswizzle_pass && IsPixelFormatBCn(image.info.format) && image.info.type == ImageType::e3D && image.info.resources.levels == 1 && image.info.resources.layers == 1) { return bl3d_unswizzle_pass->Unswizzle(image, map, swizzles, z_start, z_count); } diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index 4bb9687ab0..881135da1b 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project @@ -130,9 +130,6 @@ public: std::optional astc_decoder_pass; std::optional bl3d_unswizzle_pass; - vk::Buffer swizzle_table_buffer; - VkDeviceSize swizzle_table_size = 0; - std::optional msaa_copy_pass; const Settings::ResolutionScalingInfo& resolution; std::array, VideoCore::Surface::MaxPixelFormat> view_formats; diff --git a/src/video_core/textures/decoders.h b/src/video_core/textures/decoders.h index e704076923..1e14a38753 100644 --- a/src/video_core/textures/decoders.h +++ b/src/video_core/textures/decoders.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -23,24 +26,6 @@ constexpr u32 GOB_SIZE_SHIFT = GOB_SIZE_X_SHIFT + GOB_SIZE_Y_SHIFT + GOB_SIZE_Z_ constexpr u32 SWIZZLE_X_BITS = 0b100101111; constexpr u32 SWIZZLE_Y_BITS = 0b011010000; -using SwizzleTable = std::array, GOB_SIZE_Y>; - -/** - * This table represents the internal swizzle of a gob, in format 16 bytes x 2 sector packing. - * Calculates the offset of an (x, y) position within a swizzled texture. - * Taken from the Tegra X1 Technical Reference Manual. pages 1187-1188 - */ -constexpr SwizzleTable MakeSwizzleTable() { - SwizzleTable table{}; - for (u32 y = 0; y < table.size(); ++y) { - for (u32 x = 0; x < table[0].size(); ++x) { - table[y][x] = ((x % 64) / 32) * 256 + ((y % 8) / 2) * 64 + ((x % 32) / 16) * 32 + - (y % 2) * 16 + (x % 16); - } - } - return table; -} - /// Unswizzles a block linear texture into linear memory. void UnswizzleTexture(std::span output, std::span input, u32 bytes_per_pixel, u32 width, u32 height, u32 depth, u32 block_height, u32 block_depth,