Fix ASTC Decompressor to support depth parameter
This commit is contained in:
		| @@ -58,16 +58,14 @@ void SurfaceParams::InitCacheParameters(Tegra::GPUVAddr gpu_addr_) { | |||||||
|  |  | ||||||
| std::size_t SurfaceParams::InnerMipmapMemorySize(u32 mip_level, bool force_gl, bool layer_only, | std::size_t SurfaceParams::InnerMipmapMemorySize(u32 mip_level, bool force_gl, bool layer_only, | ||||||
|                                                  bool uncompressed) const { |                                                  bool uncompressed) const { | ||||||
|     const u32 compression_factor{GetCompressionFactor(pixel_format)}; |     const u32 tile_x{GetDefaultBlockWidth(pixel_format)}; | ||||||
|  |     const u32 tile_y{GetDefaultBlockHeight(pixel_format)}; | ||||||
|     const u32 bytes_per_pixel{GetBytesPerPixel(pixel_format)}; |     const u32 bytes_per_pixel{GetBytesPerPixel(pixel_format)}; | ||||||
|     u32 m_depth = (layer_only ? 1U : depth); |     u32 m_depth = (layer_only ? 1U : depth); | ||||||
|     u32 m_width = MipWidth(mip_level); |     u32 m_width = MipWidth(mip_level); | ||||||
|     u32 m_height = MipHeight(mip_level); |     u32 m_height = MipHeight(mip_level); | ||||||
|     m_width = uncompressed ? m_width |     m_width = uncompressed ? m_width : std::max(1U, (m_width + tile_x - 1) / tile_x); | ||||||
|                            : std::max(1U, (m_width + compression_factor - 1) / compression_factor); |     m_height = uncompressed ? m_height : std::max(1U, (m_height + tile_y - 1) / tile_y); | ||||||
|     m_height = uncompressed |  | ||||||
|                    ? m_height |  | ||||||
|                    : std::max(1U, (m_height + compression_factor - 1) / compression_factor); |  | ||||||
|     m_depth = std::max(1U, m_depth >> mip_level); |     m_depth = std::max(1U, m_depth >> mip_level); | ||||||
|     u32 m_block_height = MipBlockHeight(mip_level); |     u32 m_block_height = MipBlockHeight(mip_level); | ||||||
|     u32 m_block_depth = MipBlockDepth(mip_level); |     u32 m_block_depth = MipBlockDepth(mip_level); | ||||||
| @@ -366,8 +364,8 @@ void MortonCopy(u32 stride, u32 block_height, u32 height, u32 block_depth, u32 d | |||||||
|  |  | ||||||
|     // With the BCn formats (DXT and DXN), each 4x4 tile is swizzled instead of just individual |     // With the BCn formats (DXT and DXN), each 4x4 tile is swizzled instead of just individual | ||||||
|     // pixel values. |     // pixel values. | ||||||
|     const u32 tile_size_x{SurfaceParams::GetDefaultBlockWidth(format)}; |     const u32 tile_size_x{GetDefaultBlockWidth(format)}; | ||||||
|     const u32 tile_size_y{SurfaceParams::GetDefaultBlockHeight(format)}; |     const u32 tile_size_y{GetDefaultBlockHeight(format)}; | ||||||
|  |  | ||||||
|     if (morton_to_gl) { |     if (morton_to_gl) { | ||||||
|         const std::vector<u8> data = |         const std::vector<u8> data = | ||||||
| @@ -906,7 +904,7 @@ static void ConvertG8R8ToR8G8(std::vector<u8>& data, u32 width, u32 height) { | |||||||
|  * typical desktop GPUs. |  * typical desktop GPUs. | ||||||
|  */ |  */ | ||||||
| static void ConvertFormatAsNeeded_LoadGLBuffer(std::vector<u8>& data, PixelFormat pixel_format, | static void ConvertFormatAsNeeded_LoadGLBuffer(std::vector<u8>& data, PixelFormat pixel_format, | ||||||
|                                                u32 width, u32 height) { |                                                u32 width, u32 height, u32 depth) { | ||||||
|     switch (pixel_format) { |     switch (pixel_format) { | ||||||
|     case PixelFormat::ASTC_2D_4X4: |     case PixelFormat::ASTC_2D_4X4: | ||||||
|     case PixelFormat::ASTC_2D_8X8: |     case PixelFormat::ASTC_2D_8X8: | ||||||
| @@ -922,7 +920,8 @@ static void ConvertFormatAsNeeded_LoadGLBuffer(std::vector<u8>& data, PixelForma | |||||||
|         u32 block_width{}; |         u32 block_width{}; | ||||||
|         u32 block_height{}; |         u32 block_height{}; | ||||||
|         std::tie(block_width, block_height) = GetASTCBlockSize(pixel_format); |         std::tie(block_width, block_height) = GetASTCBlockSize(pixel_format); | ||||||
|         data = Tegra::Texture::ASTC::Decompress(data, width, height, block_width, block_height); |         data = | ||||||
|  |             Tegra::Texture::ASTC::Decompress(data, width, height, depth, block_width, block_height); | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|     case PixelFormat::S8Z24: |     case PixelFormat::S8Z24: | ||||||
| @@ -982,7 +981,7 @@ void CachedSurface::LoadGLBuffer() { | |||||||
|     } |     } | ||||||
|     for (u32 i = 0; i < params.max_mip_level; i++) |     for (u32 i = 0; i < params.max_mip_level; i++) | ||||||
|         ConvertFormatAsNeeded_LoadGLBuffer(gl_buffer[i], params.pixel_format, params.MipWidth(i), |         ConvertFormatAsNeeded_LoadGLBuffer(gl_buffer[i], params.pixel_format, params.MipWidth(i), | ||||||
|                                            params.MipHeight(i)); |                                            params.MipHeight(i), params.MipDepth(i)); | ||||||
| } | } | ||||||
|  |  | ||||||
| MICROPROFILE_DEFINE(OpenGL_SurfaceFlush, "OpenGL", "Surface Flush", MP_RGB(128, 192, 64)); | MICROPROFILE_DEFINE(OpenGL_SurfaceFlush, "OpenGL", "Surface Flush", MP_RGB(128, 192, 64)); | ||||||
|   | |||||||
| @@ -139,7 +139,7 @@ struct SurfaceParams { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     u32 MipDepth(u32 mip_level) const { |     u32 MipDepth(u32 mip_level) const { | ||||||
|         return std::max(1U, depth >> mip_level); |         return is_layered ? depth : std::max(1U, depth >> mip_level); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Auto block resizing algorithm from: |     // Auto block resizing algorithm from: | ||||||
|   | |||||||
| @@ -297,6 +297,8 @@ PixelFormat PixelFormatFromTextureFormat(Tegra::Texture::TextureFormat format, | |||||||
|         return is_srgb ? PixelFormat::ASTC_2D_4X4_SRGB : PixelFormat::ASTC_2D_4X4; |         return is_srgb ? PixelFormat::ASTC_2D_4X4_SRGB : PixelFormat::ASTC_2D_4X4; | ||||||
|     case Tegra::Texture::TextureFormat::ASTC_2D_5X4: |     case Tegra::Texture::TextureFormat::ASTC_2D_5X4: | ||||||
|         return is_srgb ? PixelFormat::ASTC_2D_5X4_SRGB : PixelFormat::ASTC_2D_5X4; |         return is_srgb ? PixelFormat::ASTC_2D_5X4_SRGB : PixelFormat::ASTC_2D_5X4; | ||||||
|  |     case Tegra::Texture::TextureFormat::ASTC_2D_5X5: | ||||||
|  |         return is_srgb ? PixelFormat::ASTC_2D_5X5_SRGB : PixelFormat::ASTC_2D_5X5; | ||||||
|     case Tegra::Texture::TextureFormat::ASTC_2D_8X8: |     case Tegra::Texture::TextureFormat::ASTC_2D_8X8: | ||||||
|         return is_srgb ? PixelFormat::ASTC_2D_8X8_SRGB : PixelFormat::ASTC_2D_8X8; |         return is_srgb ? PixelFormat::ASTC_2D_8X8_SRGB : PixelFormat::ASTC_2D_8X8; | ||||||
|     case Tegra::Texture::TextureFormat::ASTC_2D_8X5: |     case Tegra::Texture::TextureFormat::ASTC_2D_8X5: | ||||||
| @@ -440,10 +442,12 @@ bool IsPixelFormatASTC(PixelFormat format) { | |||||||
|     switch (format) { |     switch (format) { | ||||||
|     case PixelFormat::ASTC_2D_4X4: |     case PixelFormat::ASTC_2D_4X4: | ||||||
|     case PixelFormat::ASTC_2D_5X4: |     case PixelFormat::ASTC_2D_5X4: | ||||||
|  |     case PixelFormat::ASTC_2D_5X5: | ||||||
|     case PixelFormat::ASTC_2D_8X8: |     case PixelFormat::ASTC_2D_8X8: | ||||||
|     case PixelFormat::ASTC_2D_8X5: |     case PixelFormat::ASTC_2D_8X5: | ||||||
|     case PixelFormat::ASTC_2D_4X4_SRGB: |     case PixelFormat::ASTC_2D_4X4_SRGB: | ||||||
|     case PixelFormat::ASTC_2D_5X4_SRGB: |     case PixelFormat::ASTC_2D_5X4_SRGB: | ||||||
|  |     case PixelFormat::ASTC_2D_5X5_SRGB: | ||||||
|     case PixelFormat::ASTC_2D_8X8_SRGB: |     case PixelFormat::ASTC_2D_8X8_SRGB: | ||||||
|     case PixelFormat::ASTC_2D_8X5_SRGB: |     case PixelFormat::ASTC_2D_8X5_SRGB: | ||||||
|         return true; |         return true; | ||||||
| @@ -453,27 +457,7 @@ bool IsPixelFormatASTC(PixelFormat format) { | |||||||
| } | } | ||||||
|  |  | ||||||
| std::pair<u32, u32> GetASTCBlockSize(PixelFormat format) { | std::pair<u32, u32> GetASTCBlockSize(PixelFormat format) { | ||||||
|     switch (format) { |     return {GetDefaultBlockWidth(format), GetDefaultBlockHeight(format)}; | ||||||
|     case PixelFormat::ASTC_2D_4X4: |  | ||||||
|         return {4, 4}; |  | ||||||
|     case PixelFormat::ASTC_2D_5X4: |  | ||||||
|         return {5, 4}; |  | ||||||
|     case PixelFormat::ASTC_2D_8X8: |  | ||||||
|         return {8, 8}; |  | ||||||
|     case PixelFormat::ASTC_2D_8X5: |  | ||||||
|         return {8, 5}; |  | ||||||
|     case PixelFormat::ASTC_2D_4X4_SRGB: |  | ||||||
|         return {4, 4}; |  | ||||||
|     case PixelFormat::ASTC_2D_5X4_SRGB: |  | ||||||
|         return {5, 4}; |  | ||||||
|     case PixelFormat::ASTC_2D_8X8_SRGB: |  | ||||||
|         return {8, 8}; |  | ||||||
|     case PixelFormat::ASTC_2D_8X5_SRGB: |  | ||||||
|         return {8, 5}; |  | ||||||
|     default: |  | ||||||
|         LOG_CRITICAL(HW_GPU, "Unhandled format: {}", static_cast<u32>(format)); |  | ||||||
|         UNREACHABLE(); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| bool IsFormatBCn(PixelFormat format) { | bool IsFormatBCn(PixelFormat format) { | ||||||
|   | |||||||
| @@ -72,19 +72,21 @@ enum class PixelFormat { | |||||||
|     ASTC_2D_8X8_SRGB = 54, |     ASTC_2D_8X8_SRGB = 54, | ||||||
|     ASTC_2D_8X5_SRGB = 55, |     ASTC_2D_8X5_SRGB = 55, | ||||||
|     ASTC_2D_5X4_SRGB = 56, |     ASTC_2D_5X4_SRGB = 56, | ||||||
|  |     ASTC_2D_5X5 = 57, | ||||||
|  |     ASTC_2D_5X5_SRGB = 58, | ||||||
|  |  | ||||||
|     MaxColorFormat, |     MaxColorFormat, | ||||||
|  |  | ||||||
|     // Depth formats |     // Depth formats | ||||||
|     Z32F = 57, |     Z32F = 59, | ||||||
|     Z16 = 58, |     Z16 = 60, | ||||||
|  |  | ||||||
|     MaxDepthFormat, |     MaxDepthFormat, | ||||||
|  |  | ||||||
|     // DepthStencil formats |     // DepthStencil formats | ||||||
|     Z24S8 = 59, |     Z24S8 = 61, | ||||||
|     S8Z24 = 60, |     S8Z24 = 62, | ||||||
|     Z32FS8 = 61, |     Z32FS8 = 63, | ||||||
|  |  | ||||||
|     MaxDepthStencilFormat, |     MaxDepthStencilFormat, | ||||||
|  |  | ||||||
| @@ -188,6 +190,8 @@ static constexpr u32 GetCompressionFactor(PixelFormat format) { | |||||||
|         4, // ASTC_2D_8X8_SRGB |         4, // ASTC_2D_8X8_SRGB | ||||||
|         4, // ASTC_2D_8X5_SRGB |         4, // ASTC_2D_8X5_SRGB | ||||||
|         4, // ASTC_2D_5X4_SRGB |         4, // ASTC_2D_5X4_SRGB | ||||||
|  |         4, // ASTC_2D_5X5 | ||||||
|  |         4, // ASTC_2D_5X5_SRGB | ||||||
|         1, // Z32F |         1, // Z32F | ||||||
|         1, // Z16 |         1, // Z16 | ||||||
|         1, // Z24S8 |         1, // Z24S8 | ||||||
| @@ -199,6 +203,79 @@ static constexpr u32 GetCompressionFactor(PixelFormat format) { | |||||||
|     return compression_factor_table[static_cast<std::size_t>(format)]; |     return compression_factor_table[static_cast<std::size_t>(format)]; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static constexpr u32 GetDefaultBlockWidth(PixelFormat format) { | ||||||
|  |     if (format == PixelFormat::Invalid) | ||||||
|  |         return 0; | ||||||
|  |     constexpr std::array<u32, MaxPixelFormat> block_width_table = {{ | ||||||
|  |         1, // ABGR8U | ||||||
|  |         1, // ABGR8S | ||||||
|  |         1, // ABGR8UI | ||||||
|  |         1, // B5G6R5U | ||||||
|  |         1, // A2B10G10R10U | ||||||
|  |         1, // A1B5G5R5U | ||||||
|  |         1, // R8U | ||||||
|  |         1, // R8UI | ||||||
|  |         1, // RGBA16F | ||||||
|  |         1, // RGBA16U | ||||||
|  |         1, // RGBA16UI | ||||||
|  |         1, // R11FG11FB10F | ||||||
|  |         1, // RGBA32UI | ||||||
|  |         4, // DXT1 | ||||||
|  |         4, // DXT23 | ||||||
|  |         4, // DXT45 | ||||||
|  |         4, // DXN1 | ||||||
|  |         4, // DXN2UNORM | ||||||
|  |         4, // DXN2SNORM | ||||||
|  |         4, // BC7U | ||||||
|  |         4, // BC6H_UF16 | ||||||
|  |         4, // BC6H_SF16 | ||||||
|  |         4, // ASTC_2D_4X4 | ||||||
|  |         1, // G8R8U | ||||||
|  |         1, // G8R8S | ||||||
|  |         1, // BGRA8 | ||||||
|  |         1, // RGBA32F | ||||||
|  |         1, // RG32F | ||||||
|  |         1, // R32F | ||||||
|  |         1, // R16F | ||||||
|  |         1, // R16U | ||||||
|  |         1, // R16S | ||||||
|  |         1, // R16UI | ||||||
|  |         1, // R16I | ||||||
|  |         1, // RG16 | ||||||
|  |         1, // RG16F | ||||||
|  |         1, // RG16UI | ||||||
|  |         1, // RG16I | ||||||
|  |         1, // RG16S | ||||||
|  |         1, // RGB32F | ||||||
|  |         1, // RGBA8_SRGB | ||||||
|  |         1, // RG8U | ||||||
|  |         1, // RG8S | ||||||
|  |         1, // RG32UI | ||||||
|  |         1, // R32UI | ||||||
|  |         8, // ASTC_2D_8X8 | ||||||
|  |         8, // ASTC_2D_8X5 | ||||||
|  |         5, // ASTC_2D_5X4 | ||||||
|  |         1, // BGRA8_SRGB | ||||||
|  |         4, // DXT1_SRGB | ||||||
|  |         4, // DXT23_SRGB | ||||||
|  |         4, // DXT45_SRGB | ||||||
|  |         4, // BC7U_SRGB | ||||||
|  |         4, // ASTC_2D_4X4_SRGB | ||||||
|  |         8, // ASTC_2D_8X8_SRGB | ||||||
|  |         8, // ASTC_2D_8X5_SRGB | ||||||
|  |         5, // ASTC_2D_5X4_SRGB | ||||||
|  |         5, // ASTC_2D_5X5 | ||||||
|  |         5, // ASTC_2D_5X5_SRGB | ||||||
|  |         1, // Z32F | ||||||
|  |         1, // Z16 | ||||||
|  |         1, // Z24S8 | ||||||
|  |         1, // S8Z24 | ||||||
|  |         1, // Z32FS8 | ||||||
|  |     }}; | ||||||
|  |     ASSERT(static_cast<std::size_t>(format) < block_width_table.size()); | ||||||
|  |     return block_width_table[static_cast<std::size_t>(format)]; | ||||||
|  | } | ||||||
|  |  | ||||||
| static constexpr u32 GetDefaultBlockHeight(PixelFormat format) { | static constexpr u32 GetDefaultBlockHeight(PixelFormat format) { | ||||||
|     if (format == PixelFormat::Invalid) |     if (format == PixelFormat::Invalid) | ||||||
|         return 0; |         return 0; | ||||||
| @@ -261,6 +338,8 @@ static constexpr u32 GetDefaultBlockHeight(PixelFormat format) { | |||||||
|         8, // ASTC_2D_8X8_SRGB |         8, // ASTC_2D_8X8_SRGB | ||||||
|         5, // ASTC_2D_8X5_SRGB |         5, // ASTC_2D_8X5_SRGB | ||||||
|         4, // ASTC_2D_5X4_SRGB |         4, // ASTC_2D_5X4_SRGB | ||||||
|  |         5, // ASTC_2D_5X5 | ||||||
|  |         5, // ASTC_2D_5X5_SRGB | ||||||
|         1, // Z32F |         1, // Z32F | ||||||
|         1, // Z16 |         1, // Z16 | ||||||
|         1, // Z24S8 |         1, // Z24S8 | ||||||
| @@ -299,7 +378,7 @@ static constexpr u32 GetFormatBpp(PixelFormat format) { | |||||||
|         128, // BC7U |         128, // BC7U | ||||||
|         128, // BC6H_UF16 |         128, // BC6H_UF16 | ||||||
|         128, // BC6H_SF16 |         128, // BC6H_SF16 | ||||||
|         32,  // ASTC_2D_4X4 |         128, // ASTC_2D_4X4 | ||||||
|         16,  // G8R8U |         16,  // G8R8U | ||||||
|         16,  // G8R8S |         16,  // G8R8S | ||||||
|         32,  // BGRA8 |         32,  // BGRA8 | ||||||
| @@ -322,18 +401,20 @@ static constexpr u32 GetFormatBpp(PixelFormat format) { | |||||||
|         16,  // RG8S |         16,  // RG8S | ||||||
|         64,  // RG32UI |         64,  // RG32UI | ||||||
|         32,  // R32UI |         32,  // R32UI | ||||||
|         16,  // ASTC_2D_8X8 |         128, // ASTC_2D_8X8 | ||||||
|         16,  // ASTC_2D_8X5 |         128, // ASTC_2D_8X5 | ||||||
|         32,  // ASTC_2D_5X4 |         128, // ASTC_2D_5X4 | ||||||
|         32,  // BGRA8_SRGB |         32,  // BGRA8_SRGB | ||||||
|         64,  // DXT1_SRGB |         64,  // DXT1_SRGB | ||||||
|         128, // DXT23_SRGB |         128, // DXT23_SRGB | ||||||
|         128, // DXT45_SRGB |         128, // DXT45_SRGB | ||||||
|         128, // BC7U |         128, // BC7U | ||||||
|         32,  // ASTC_2D_4X4_SRGB |         128, // ASTC_2D_4X4_SRGB | ||||||
|         16,  // ASTC_2D_8X8_SRGB |         128, // ASTC_2D_8X8_SRGB | ||||||
|         16,  // ASTC_2D_8X5_SRGB |         128, // ASTC_2D_8X5_SRGB | ||||||
|         32,  // ASTC_2D_5X4_SRGB |         128, // ASTC_2D_5X4_SRGB | ||||||
|  |         128, // ASTC_2D_5X5 | ||||||
|  |         128, // ASTC_2D_5X5_SRGB | ||||||
|         32,  // Z32F |         32,  // Z32F | ||||||
|         16,  // Z16 |         16,  // Z16 | ||||||
|         32,  // Z24S8 |         32,  // Z24S8 | ||||||
|   | |||||||
| @@ -1598,9 +1598,10 @@ static void DecompressBlock(uint8_t inBuf[16], const uint32_t blockWidth, | |||||||
| namespace Tegra::Texture::ASTC { | namespace Tegra::Texture::ASTC { | ||||||
|  |  | ||||||
| std::vector<uint8_t> Decompress(std::vector<uint8_t>& data, uint32_t width, uint32_t height, | 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; |     uint32_t blockIdx = 0; | ||||||
|     std::vector<uint8_t> outData(height * width * 4); |     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 j = 0; j < height; j += block_height) { | ||||||
|             for (uint32_t i = 0; i < width; i += block_width) { |             for (uint32_t i = 0; i < width; i += block_width) { | ||||||
|  |  | ||||||
| @@ -1621,6 +1622,7 @@ std::vector<uint8_t> Decompress(std::vector<uint8_t>& data, uint32_t width, uint | |||||||
|                 blockIdx++; |                 blockIdx++; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     return outData; |     return outData; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -10,6 +10,6 @@ | |||||||
| namespace Tegra::Texture::ASTC { | namespace Tegra::Texture::ASTC { | ||||||
|  |  | ||||||
| std::vector<uint8_t> Decompress(std::vector<uint8_t>& data, uint32_t width, uint32_t height, | 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 | } // namespace Tegra::Texture::ASTC | ||||||
|   | |||||||
| @@ -386,9 +386,9 @@ void GraphicsSurfaceWidget::OnUpdate() { | |||||||
|  |  | ||||||
|     // TODO(bunnei): Will not work with BCn formats that swizzle 4x4 tiles. |     // TODO(bunnei): Will not work with BCn formats that swizzle 4x4 tiles. | ||||||
|     // Needs to be fixed if we plan to use this feature more, otherwise we may remove it. |     // Needs to be fixed if we plan to use this feature more, otherwise we may remove it. | ||||||
|     auto unswizzled_data = |     auto unswizzled_data = Tegra::Texture::UnswizzleTexture( | ||||||
|         Tegra::Texture::UnswizzleTexture(*address, 1, 1, Tegra::Texture::BytesPerPixel(surface_format), |         *address, 1, 1, Tegra::Texture::BytesPerPixel(surface_format), surface_width, | ||||||
|                                          surface_width, surface_height, 1U); |         surface_height, 1U); | ||||||
|  |  | ||||||
|     auto texture_data = Tegra::Texture::DecodeTexture(unswizzled_data, surface_format, |     auto texture_data = Tegra::Texture::DecodeTexture(unswizzled_data, surface_format, | ||||||
|                                                       surface_width, surface_height); |                                                       surface_width, surface_height); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 FernandoS27
					FernandoS27