diff options
Diffstat (limited to 'src/video_core/textures')
-rw-r--r-- | src/video_core/textures/astc.cpp | 32 | ||||
-rw-r--r-- | src/video_core/textures/astc.h | 2 | ||||
-rw-r--r-- | src/video_core/textures/decoders.cpp | 48 | ||||
-rw-r--r-- | src/video_core/textures/decoders.h | 4 | ||||
-rw-r--r-- | src/video_core/textures/texture.h | 13 |
5 files changed, 58 insertions, 41 deletions
diff --git a/src/video_core/textures/astc.cpp b/src/video_core/textures/astc.cpp index b1feacae9..bc50a4876 100644 --- a/src/video_core/textures/astc.cpp +++ b/src/video_core/textures/astc.cpp @@ -1598,27 +1598,29 @@ static void DecompressBlock(uint8_t inBuf[16], const uint32_t blockWidth, namespace Tegra::Texture::ASTC { std::vector<uint8_t> Decompress(std::vector<uint8_t>& data, uint32_t width, uint32_t height, - uint32_t block_width, uint32_t block_height) { + uint32_t depth, uint32_t block_width, uint32_t block_height) { uint32_t blockIdx = 0; - std::vector<uint8_t> outData(height * width * 4); - for (uint32_t j = 0; j < height; j += block_height) { - for (uint32_t i = 0; i < width; i += block_width) { + std::vector<uint8_t> outData(height * width * depth * 4); + for (uint32_t k = 0; k < depth; k++) { + for (uint32_t j = 0; j < height; j += block_height) { + for (uint32_t i = 0; i < width; i += block_width) { - uint8_t* blockPtr = data.data() + blockIdx * 16; + uint8_t* blockPtr = data.data() + blockIdx * 16; - // Blocks can be at most 12x12 - uint32_t uncompData[144]; - ASTCC::DecompressBlock(blockPtr, block_width, block_height, uncompData); + // Blocks can be at most 12x12 + uint32_t uncompData[144]; + ASTCC::DecompressBlock(blockPtr, block_width, block_height, uncompData); - uint32_t decompWidth = std::min(block_width, width - i); - uint32_t decompHeight = std::min(block_height, height - j); + uint32_t decompWidth = std::min(block_width, width - i); + uint32_t decompHeight = std::min(block_height, height - j); - uint8_t* outRow = outData.data() + (j * width + i) * 4; - for (uint32_t jj = 0; jj < decompHeight; jj++) { - memcpy(outRow + jj * width * 4, uncompData + jj * block_width, decompWidth * 4); - } + uint8_t* outRow = outData.data() + (j * width + i) * 4; + for (uint32_t jj = 0; jj < decompHeight; jj++) { + memcpy(outRow + jj * width * 4, uncompData + jj * block_width, decompWidth * 4); + } - blockIdx++; + blockIdx++; + } } } diff --git a/src/video_core/textures/astc.h b/src/video_core/textures/astc.h index f0d7c0e56..d419dd025 100644 --- a/src/video_core/textures/astc.h +++ b/src/video_core/textures/astc.h @@ -10,6 +10,6 @@ namespace Tegra::Texture::ASTC { std::vector<uint8_t> Decompress(std::vector<uint8_t>& data, uint32_t width, uint32_t height, - uint32_t block_width, uint32_t block_height); + uint32_t depth, uint32_t block_width, uint32_t block_height); } // namespace Tegra::Texture::ASTC diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp index 550ca856c..19f30b1b5 100644 --- a/src/video_core/textures/decoders.cpp +++ b/src/video_core/textures/decoders.cpp @@ -45,7 +45,7 @@ constexpr auto fast_swizzle_table = SwizzleTable<8, 4, 16>(); * Instead of going gob by gob, we map the coordinates inside a block and manage from * those. Block_Width is assumed to be 1. */ -void PreciseProcessBlock(u8* swizzled_data, u8* unswizzled_data, const bool unswizzle, +void PreciseProcessBlock(u8* const swizzled_data, u8* const unswizzled_data, const bool unswizzle, const u32 x_start, const u32 y_start, const u32 z_start, const u32 x_end, const u32 y_end, const u32 z_end, const u32 tile_offset, const u32 xy_block_size, const u32 layer_z, const u32 stride_x, @@ -81,7 +81,7 @@ void PreciseProcessBlock(u8* swizzled_data, u8* unswizzled_data, const bool unsw * Instead of going gob by gob, we map the coordinates inside a block and manage from * those. Block_Width is assumed to be 1. */ -void FastProcessBlock(u8* swizzled_data, u8* unswizzled_data, const bool unswizzle, +void FastProcessBlock(u8* const swizzled_data, u8* const unswizzled_data, const bool unswizzle, const u32 x_start, const u32 y_start, const u32 z_start, const u32 x_end, const u32 y_end, const u32 z_end, const u32 tile_offset, const u32 xy_block_size, const u32 layer_z, const u32 stride_x, @@ -90,10 +90,10 @@ void FastProcessBlock(u8* swizzled_data, u8* unswizzled_data, const bool unswizz u32 z_address = tile_offset; const u32 x_startb = x_start * bytes_per_pixel; const u32 x_endb = x_end * bytes_per_pixel; - const u32 copy_size = 16; - const u32 gob_size_x = 64; - const u32 gob_size_y = 8; - const u32 gob_size_z = 1; + constexpr u32 copy_size = 16; + constexpr u32 gob_size_x = 64; + constexpr u32 gob_size_y = 8; + constexpr u32 gob_size_z = 1; const u32 gob_size = gob_size_x * gob_size_y * gob_size_z; for (u32 z = z_start; z < z_end; z++) { u32 y_address = z_address; @@ -126,23 +126,23 @@ void FastProcessBlock(u8* swizzled_data, u8* unswizzled_data, const bool unswizz * https://envytools.readthedocs.io/en/latest/hw/memory/g80-surface.html#blocklinear-surfaces */ template <bool fast> -void SwizzledData(u8* swizzled_data, u8* unswizzled_data, const bool unswizzle, const u32 width, - const u32 height, const u32 depth, const u32 bytes_per_pixel, +void SwizzledData(u8* const swizzled_data, u8* const unswizzled_data, const bool unswizzle, + const u32 width, const u32 height, const u32 depth, const u32 bytes_per_pixel, const u32 out_bytes_per_pixel, const u32 block_height, const u32 block_depth) { auto div_ceil = [](const u32 x, const u32 y) { return ((x + y - 1) / y); }; const u32 stride_x = width * out_bytes_per_pixel; const u32 layer_z = height * stride_x; - const u32 gob_x_bytes = 64; + constexpr u32 gob_x_bytes = 64; const u32 gob_elements_x = gob_x_bytes / bytes_per_pixel; - const u32 gob_elements_y = 8; - const u32 gob_elements_z = 1; + constexpr u32 gob_elements_y = 8; + constexpr u32 gob_elements_z = 1; const u32 block_x_elements = gob_elements_x; const u32 block_y_elements = gob_elements_y * block_height; const u32 block_z_elements = gob_elements_z * block_depth; const u32 blocks_on_x = div_ceil(width, block_x_elements); const u32 blocks_on_y = div_ceil(height, block_y_elements); const u32 blocks_on_z = div_ceil(depth, block_z_elements); - const u32 gob_size = gob_x_bytes * gob_elements_y * gob_elements_z; + constexpr u32 gob_size = gob_x_bytes * gob_elements_y * gob_elements_z; const u32 xy_block_size = gob_size * block_height; const u32 block_size = xy_block_size * block_depth; u32 tile_offset = 0; @@ -171,7 +171,7 @@ void SwizzledData(u8* swizzled_data, u8* unswizzled_data, const bool unswizzle, } void CopySwizzledData(u32 width, u32 height, u32 depth, u32 bytes_per_pixel, - u32 out_bytes_per_pixel, u8* swizzled_data, u8* unswizzled_data, + u32 out_bytes_per_pixel, u8* const swizzled_data, u8* const unswizzled_data, bool unswizzle, u32 block_height, u32 block_depth) { if (bytes_per_pixel % 3 != 0 && (width * bytes_per_pixel) % 16 == 0) { SwizzledData<true>(swizzled_data, unswizzled_data, unswizzle, width, height, depth, @@ -202,6 +202,8 @@ u32 BytesPerPixel(TextureFormat format) { case TextureFormat::ASTC_2D_5X4: case TextureFormat::ASTC_2D_8X8: case TextureFormat::ASTC_2D_8X5: + case TextureFormat::ASTC_2D_10X8: + case TextureFormat::ASTC_2D_5X5: case TextureFormat::A8R8G8B8: case TextureFormat::A2B10G10R10: case TextureFormat::BF10GF11RF11: @@ -227,12 +229,14 @@ u32 BytesPerPixel(TextureFormat format) { } } -std::vector<u8> UnswizzleTexture(VAddr address, u32 tile_size, u32 bytes_per_pixel, u32 width, - u32 height, u32 depth, u32 block_height, u32 block_depth) { +std::vector<u8> UnswizzleTexture(VAddr address, u32 tile_size_x, u32 tile_size_y, + u32 bytes_per_pixel, u32 width, u32 height, u32 depth, + u32 block_height, u32 block_depth) { std::vector<u8> unswizzled_data(width * height * depth * bytes_per_pixel); - CopySwizzledData(width / tile_size, height / tile_size, depth, bytes_per_pixel, bytes_per_pixel, - Memory::GetPointer(address), unswizzled_data.data(), true, block_height, - block_depth); + CopySwizzledData((width + tile_size_x - 1) / tile_size_x, + (height + tile_size_y - 1) / tile_size_y, depth, bytes_per_pixel, + bytes_per_pixel, Memory::GetPointer(address), unswizzled_data.data(), true, + block_height, block_depth); return unswizzled_data; } @@ -292,6 +296,8 @@ std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat case TextureFormat::BC6H_SF16: case TextureFormat::ASTC_2D_4X4: case TextureFormat::ASTC_2D_8X8: + case TextureFormat::ASTC_2D_5X5: + case TextureFormat::ASTC_2D_10X8: case TextureFormat::A8R8G8B8: case TextureFormat::A2B10G10R10: case TextureFormat::A1B5G5R5: @@ -319,9 +325,9 @@ std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat std::size_t CalculateSize(bool tiled, u32 bytes_per_pixel, u32 width, u32 height, u32 depth, u32 block_height, u32 block_depth) { if (tiled) { - const u32 gobs_in_x = 64; - const u32 gobs_in_y = 8; - const u32 gobs_in_z = 1; + constexpr u32 gobs_in_x = 64; + constexpr u32 gobs_in_y = 8; + constexpr u32 gobs_in_z = 1; const u32 aligned_width = Common::AlignUp(width * bytes_per_pixel, gobs_in_x); const u32 aligned_height = Common::AlignUp(height, gobs_in_y * block_height); const u32 aligned_depth = Common::AlignUp(depth, gobs_in_z * block_depth); diff --git a/src/video_core/textures/decoders.h b/src/video_core/textures/decoders.h index b390219e4..ba065510b 100644 --- a/src/video_core/textures/decoders.h +++ b/src/video_core/textures/decoders.h @@ -19,8 +19,8 @@ inline std::size_t GetGOBSize() { /** * Unswizzles a swizzled texture without changing its format. */ -std::vector<u8> UnswizzleTexture(VAddr address, u32 tile_size, u32 bytes_per_pixel, u32 width, - u32 height, u32 depth, +std::vector<u8> UnswizzleTexture(VAddr address, u32 tile_size_x, u32 tile_size_y, + u32 bytes_per_pixel, u32 width, u32 height, u32 depth, u32 block_height = TICEntry::DefaultBlockHeight, u32 block_depth = TICEntry::DefaultBlockHeight); diff --git a/src/video_core/textures/texture.h b/src/video_core/textures/texture.h index d12d2ecb8..e199d019a 100644 --- a/src/video_core/textures/texture.h +++ b/src/video_core/textures/texture.h @@ -168,20 +168,29 @@ struct TICEntry { // High 16 bits of the pitch value BitField<0, 16, u32> pitch_high; - + BitField<26, 1, u32> use_header_opt_control; + BitField<27, 1, u32> depth_texture; BitField<28, 4, u32> max_mip_level; }; union { BitField<0, 16, u32> width_minus_1; BitField<22, 1, u32> srgb_conversion; BitField<23, 4, TextureType> texture_type; + BitField<29, 3, u32> border_size; }; union { BitField<0, 16, u32> height_minus_1; BitField<16, 15, u32> depth_minus_1; }; + union { + BitField<6, 13, u32> mip_lod_bias; + BitField<27, 3, u32> max_anisotropy; + }; - INSERT_PADDING_BYTES(8); + union { + BitField<0, 4, u32> res_min_mip_level; + BitField<4, 4, u32> res_max_mip_level; + }; GPUVAddr Address() const { return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | address_low); |