diff options
Diffstat (limited to 'src/video_core/textures')
-rw-r--r-- | src/video_core/textures/decoders.cpp | 23 | ||||
-rw-r--r-- | src/video_core/textures/decoders.h | 3 | ||||
-rw-r--r-- | src/video_core/textures/texture.h | 25 |
3 files changed, 43 insertions, 8 deletions
diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp index 2e87281eb..4df687786 100644 --- a/src/video_core/textures/decoders.cpp +++ b/src/video_core/textures/decoders.cpp @@ -48,31 +48,39 @@ u32 BytesPerPixel(TextureFormat format) { case TextureFormat::DXT1: // In this case a 'pixel' actually refers to a 4x4 tile. return 8; + case TextureFormat::DXT23: + case TextureFormat::DXT45: + // In this case a 'pixel' actually refers to a 4x4 tile. + return 16; case TextureFormat::A8R8G8B8: return 4; + case TextureFormat::B5G6R5: + return 2; default: UNIMPLEMENTED_MSG("Format not implemented"); break; } } -std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height) { +std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height, + u32 block_height) { u8* data = Memory::GetPointer(address); u32 bytes_per_pixel = BytesPerPixel(format); - static constexpr u32 DefaultBlockHeight = 16; - std::vector<u8> unswizzled_data(width * height * bytes_per_pixel); switch (format) { case TextureFormat::DXT1: - // In the DXT1 format, each 4x4 tile is swizzled instead of just individual pixel values. + case TextureFormat::DXT23: + case TextureFormat::DXT45: + // In the DXT formats, each 4x4 tile is swizzled instead of just individual pixel values. CopySwizzledData(width / 4, height / 4, bytes_per_pixel, bytes_per_pixel, data, - unswizzled_data.data(), true, DefaultBlockHeight); + unswizzled_data.data(), true, block_height); break; case TextureFormat::A8R8G8B8: + case TextureFormat::B5G6R5: CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data, - unswizzled_data.data(), true, DefaultBlockHeight); + unswizzled_data.data(), true, block_height); break; default: UNIMPLEMENTED_MSG("Format not implemented"); @@ -89,7 +97,10 @@ std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat // TODO(Subv): Implement. switch (format) { case TextureFormat::DXT1: + case TextureFormat::DXT23: + case TextureFormat::DXT45: case TextureFormat::A8R8G8B8: + case TextureFormat::B5G6R5: // TODO(Subv): For the time being just forward the same data without any decoding. rgba_data = texture_data; break; diff --git a/src/video_core/textures/decoders.h b/src/video_core/textures/decoders.h index 0c21694ff..a700911cf 100644 --- a/src/video_core/textures/decoders.h +++ b/src/video_core/textures/decoders.h @@ -14,7 +14,8 @@ namespace Texture { /** * Unswizzles a swizzled texture without changing its format. */ -std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height); +std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height, + u32 block_height = TICEntry::DefaultBlockHeight); /** * Decodes an unswizzled texture into a A8R8G8B8 texture. diff --git a/src/video_core/textures/texture.h b/src/video_core/textures/texture.h index 9d443ea90..86e45aa88 100644 --- a/src/video_core/textures/texture.h +++ b/src/video_core/textures/texture.h @@ -4,6 +4,7 @@ #pragma once +#include "common/assert.h" #include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" @@ -14,6 +15,7 @@ namespace Texture { enum class TextureFormat : u32 { A8R8G8B8 = 0x8, + B5G6R5 = 0x15, DXT1 = 0x24, DXT23 = 0x25, DXT45 = 0x26, @@ -57,6 +59,8 @@ union TextureHandle { static_assert(sizeof(TextureHandle) == 4, "TextureHandle has wrong size"); struct TICEntry { + static constexpr u32 DefaultBlockHeight = 16; + union { u32 raw; BitField<0, 7, TextureFormat> format; @@ -70,7 +74,12 @@ struct TICEntry { BitField<0, 16, u32> address_high; BitField<21, 3, TICHeaderVersion> header_version; }; - INSERT_PADDING_BYTES(4); + union { + BitField<3, 3, u32> block_height; + + // High 16 bits of the pitch value + BitField<0, 16, u32> pitch_high; + }; union { BitField<0, 16, u32> width_minus_1; BitField<23, 4, TextureType> texture_type; @@ -82,6 +91,13 @@ struct TICEntry { return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | address_low); } + u32 Pitch() const { + ASSERT(header_version == TICHeaderVersion::Pitch || + header_version == TICHeaderVersion::PitchColorKey); + // The pitch value is 21 bits, and is 32B aligned. + return pitch_high << 5; + } + u32 Width() const { return width_minus_1 + 1; } @@ -90,6 +106,13 @@ struct TICEntry { return height_minus_1 + 1; } + u32 BlockHeight() const { + ASSERT(header_version == TICHeaderVersion::BlockLinear || + header_version == TICHeaderVersion::BlockLinearColorKey); + // The block height is stored in log2 format. + return 1 << block_height; + } + bool IsTiled() const { return header_version == TICHeaderVersion::BlockLinear || header_version == TICHeaderVersion::BlockLinearColorKey; |