diff options
Diffstat (limited to 'src/video_core/textures')
| -rw-r--r-- | src/video_core/textures/convert.cpp | 14 | ||||
| -rw-r--r-- | src/video_core/textures/convert.h | 7 | ||||
| -rw-r--r-- | src/video_core/textures/decoders.cpp | 42 | ||||
| -rw-r--r-- | src/video_core/textures/decoders.h | 4 | ||||
| -rw-r--r-- | src/video_core/textures/texture.h | 31 |
5 files changed, 62 insertions, 36 deletions
diff --git a/src/video_core/textures/convert.cpp b/src/video_core/textures/convert.cpp index 82050bd51..f3efa7eb0 100644 --- a/src/video_core/textures/convert.cpp +++ b/src/video_core/textures/convert.cpp | |||
| @@ -62,19 +62,19 @@ static void ConvertZ24S8ToS8Z24(u8* data, u32 width, u32 height) { | |||
| 62 | SwapS8Z24ToZ24S8<true>(data, width, height); | 62 | SwapS8Z24ToZ24S8<true>(data, width, height); |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | void ConvertFromGuestToHost(u8* data, PixelFormat pixel_format, u32 width, u32 height, u32 depth, | 65 | void ConvertFromGuestToHost(u8* in_data, u8* out_data, PixelFormat pixel_format, u32 width, |
| 66 | bool convert_astc, bool convert_s8z24) { | 66 | u32 height, u32 depth, bool convert_astc, bool convert_s8z24) { |
| 67 | if (convert_astc && IsPixelFormatASTC(pixel_format)) { | 67 | if (convert_astc && IsPixelFormatASTC(pixel_format)) { |
| 68 | // Convert ASTC pixel formats to RGBA8, as most desktop GPUs do not support ASTC. | 68 | // Convert ASTC pixel formats to RGBA8, as most desktop GPUs do not support ASTC. |
| 69 | u32 block_width{}; | 69 | u32 block_width{}; |
| 70 | u32 block_height{}; | 70 | u32 block_height{}; |
| 71 | std::tie(block_width, block_height) = GetASTCBlockSize(pixel_format); | 71 | std::tie(block_width, block_height) = GetASTCBlockSize(pixel_format); |
| 72 | const std::vector<u8> rgba8_data = | 72 | const std::vector<u8> rgba8_data = Tegra::Texture::ASTC::Decompress( |
| 73 | Tegra::Texture::ASTC::Decompress(data, width, height, depth, block_width, block_height); | 73 | in_data, width, height, depth, block_width, block_height); |
| 74 | std::copy(rgba8_data.begin(), rgba8_data.end(), data); | 74 | std::copy(rgba8_data.begin(), rgba8_data.end(), out_data); |
| 75 | 75 | ||
| 76 | } else if (convert_s8z24 && pixel_format == PixelFormat::S8Z24) { | 76 | } else if (convert_s8z24 && pixel_format == PixelFormat::S8Z24) { |
| 77 | Tegra::Texture::ConvertS8Z24ToZ24S8(data, width, height); | 77 | Tegra::Texture::ConvertS8Z24ToZ24S8(in_data, width, height); |
| 78 | } | 78 | } |
| 79 | } | 79 | } |
| 80 | 80 | ||
| @@ -90,4 +90,4 @@ void ConvertFromHostToGuest(u8* data, PixelFormat pixel_format, u32 width, u32 h | |||
| 90 | } | 90 | } |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | } // namespace Tegra::Texture \ No newline at end of file | 93 | } // namespace Tegra::Texture |
diff --git a/src/video_core/textures/convert.h b/src/video_core/textures/convert.h index 12542e71c..d5d6c77bb 100644 --- a/src/video_core/textures/convert.h +++ b/src/video_core/textures/convert.h | |||
| @@ -12,10 +12,11 @@ enum class PixelFormat; | |||
| 12 | 12 | ||
| 13 | namespace Tegra::Texture { | 13 | namespace Tegra::Texture { |
| 14 | 14 | ||
| 15 | void ConvertFromGuestToHost(u8* data, VideoCore::Surface::PixelFormat pixel_format, u32 width, | 15 | void ConvertFromGuestToHost(u8* in_data, u8* out_data, VideoCore::Surface::PixelFormat pixel_format, |
| 16 | u32 height, u32 depth, bool convert_astc, bool convert_s8z24); | 16 | u32 width, u32 height, u32 depth, bool convert_astc, |
| 17 | bool convert_s8z24); | ||
| 17 | 18 | ||
| 18 | void ConvertFromHostToGuest(u8* data, VideoCore::Surface::PixelFormat pixel_format, u32 width, | 19 | void ConvertFromHostToGuest(u8* data, VideoCore::Surface::PixelFormat pixel_format, u32 width, |
| 19 | u32 height, u32 depth, bool convert_astc, bool convert_s8z24); | 20 | u32 height, u32 depth, bool convert_astc, bool convert_s8z24); |
| 20 | 21 | ||
| 21 | } // namespace Tegra::Texture \ No newline at end of file | 22 | } // namespace Tegra::Texture |
diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp index 217805386..7e8295944 100644 --- a/src/video_core/textures/decoders.cpp +++ b/src/video_core/textures/decoders.cpp | |||
| @@ -36,10 +36,16 @@ struct alignas(64) SwizzleTable { | |||
| 36 | std::array<std::array<u16, M>, N> values{}; | 36 | std::array<std::array<u16, M>, N> values{}; |
| 37 | }; | 37 | }; |
| 38 | 38 | ||
| 39 | constexpr u32 gob_size_x = 64; | 39 | constexpr u32 gob_size_x_shift = 6; |
| 40 | constexpr u32 gob_size_y = 8; | 40 | constexpr u32 gob_size_y_shift = 3; |
| 41 | constexpr u32 gob_size_z = 1; | 41 | constexpr u32 gob_size_z_shift = 0; |
| 42 | constexpr u32 gob_size = gob_size_x * gob_size_y * gob_size_z; | 42 | constexpr u32 gob_size_shift = gob_size_x_shift + gob_size_y_shift + gob_size_z_shift; |
| 43 | |||
| 44 | constexpr u32 gob_size_x = 1U << gob_size_x_shift; | ||
| 45 | constexpr u32 gob_size_y = 1U << gob_size_y_shift; | ||
| 46 | constexpr u32 gob_size_z = 1U << gob_size_z_shift; | ||
| 47 | constexpr u32 gob_size = 1U << gob_size_shift; | ||
| 48 | |||
| 43 | constexpr u32 fast_swizzle_align = 16; | 49 | constexpr u32 fast_swizzle_align = 16; |
| 44 | 50 | ||
| 45 | constexpr auto legacy_swizzle_table = SwizzleTable<gob_size_y, gob_size_x, gob_size_z>(); | 51 | constexpr auto legacy_swizzle_table = SwizzleTable<gob_size_y, gob_size_x, gob_size_z>(); |
| @@ -171,14 +177,16 @@ void SwizzledData(u8* const swizzled_data, u8* const unswizzled_data, const bool | |||
| 171 | void CopySwizzledData(u32 width, u32 height, u32 depth, u32 bytes_per_pixel, | 177 | void CopySwizzledData(u32 width, u32 height, u32 depth, u32 bytes_per_pixel, |
| 172 | u32 out_bytes_per_pixel, u8* const swizzled_data, u8* const unswizzled_data, | 178 | u32 out_bytes_per_pixel, u8* const swizzled_data, u8* const unswizzled_data, |
| 173 | bool unswizzle, u32 block_height, u32 block_depth, u32 width_spacing) { | 179 | bool unswizzle, u32 block_height, u32 block_depth, u32 width_spacing) { |
| 180 | const u32 block_height_size{1U << block_height}; | ||
| 181 | const u32 block_depth_size{1U << block_depth}; | ||
| 174 | if (bytes_per_pixel % 3 != 0 && (width * bytes_per_pixel) % fast_swizzle_align == 0) { | 182 | if (bytes_per_pixel % 3 != 0 && (width * bytes_per_pixel) % fast_swizzle_align == 0) { |
| 175 | SwizzledData<true>(swizzled_data, unswizzled_data, unswizzle, width, height, depth, | 183 | SwizzledData<true>(swizzled_data, unswizzled_data, unswizzle, width, height, depth, |
| 176 | bytes_per_pixel, out_bytes_per_pixel, block_height, block_depth, | 184 | bytes_per_pixel, out_bytes_per_pixel, block_height_size, |
| 177 | width_spacing); | 185 | block_depth_size, width_spacing); |
| 178 | } else { | 186 | } else { |
| 179 | SwizzledData<false>(swizzled_data, unswizzled_data, unswizzle, width, height, depth, | 187 | SwizzledData<false>(swizzled_data, unswizzled_data, unswizzle, width, height, depth, |
| 180 | bytes_per_pixel, out_bytes_per_pixel, block_height, block_depth, | 188 | bytes_per_pixel, out_bytes_per_pixel, block_height_size, |
| 181 | width_spacing); | 189 | block_depth_size, width_spacing); |
| 182 | } | 190 | } |
| 183 | } | 191 | } |
| 184 | 192 | ||
| @@ -248,7 +256,9 @@ std::vector<u8> UnswizzleTexture(u8* address, u32 tile_size_x, u32 tile_size_y, | |||
| 248 | } | 256 | } |
| 249 | 257 | ||
| 250 | void SwizzleSubrect(u32 subrect_width, u32 subrect_height, u32 source_pitch, u32 swizzled_width, | 258 | void SwizzleSubrect(u32 subrect_width, u32 subrect_height, u32 source_pitch, u32 swizzled_width, |
| 251 | u32 bytes_per_pixel, u8* swizzled_data, u8* unswizzled_data, u32 block_height) { | 259 | u32 bytes_per_pixel, u8* swizzled_data, u8* unswizzled_data, |
| 260 | u32 block_height_bit) { | ||
| 261 | const u32 block_height = 1U << block_height_bit; | ||
| 252 | const u32 image_width_in_gobs{(swizzled_width * bytes_per_pixel + (gob_size_x - 1)) / | 262 | const u32 image_width_in_gobs{(swizzled_width * bytes_per_pixel + (gob_size_x - 1)) / |
| 253 | gob_size_x}; | 263 | gob_size_x}; |
| 254 | for (u32 line = 0; line < subrect_height; ++line) { | 264 | for (u32 line = 0; line < subrect_height; ++line) { |
| @@ -269,8 +279,9 @@ void SwizzleSubrect(u32 subrect_width, u32 subrect_height, u32 source_pitch, u32 | |||
| 269 | } | 279 | } |
| 270 | 280 | ||
| 271 | void UnswizzleSubrect(u32 subrect_width, u32 subrect_height, u32 dest_pitch, u32 swizzled_width, | 281 | void UnswizzleSubrect(u32 subrect_width, u32 subrect_height, u32 dest_pitch, u32 swizzled_width, |
| 272 | u32 bytes_per_pixel, u8* swizzled_data, u8* unswizzled_data, u32 block_height, | 282 | u32 bytes_per_pixel, u8* swizzled_data, u8* unswizzled_data, |
| 273 | u32 offset_x, u32 offset_y) { | 283 | u32 block_height_bit, u32 offset_x, u32 offset_y) { |
| 284 | const u32 block_height = 1U << block_height_bit; | ||
| 274 | for (u32 line = 0; line < subrect_height; ++line) { | 285 | for (u32 line = 0; line < subrect_height; ++line) { |
| 275 | const u32 y2 = line + offset_y; | 286 | const u32 y2 = line + offset_y; |
| 276 | const u32 gob_address_y = (y2 / (gob_size_y * block_height)) * gob_size * block_height + | 287 | const u32 gob_address_y = (y2 / (gob_size_y * block_height)) * gob_size * block_height + |
| @@ -289,8 +300,9 @@ void UnswizzleSubrect(u32 subrect_width, u32 subrect_height, u32 dest_pitch, u32 | |||
| 289 | } | 300 | } |
| 290 | 301 | ||
| 291 | void SwizzleKepler(const u32 width, const u32 height, const u32 dst_x, const u32 dst_y, | 302 | void SwizzleKepler(const u32 width, const u32 height, const u32 dst_x, const u32 dst_y, |
| 292 | const u32 block_height, const std::size_t copy_size, const u8* source_data, | 303 | const u32 block_height_bit, const std::size_t copy_size, const u8* source_data, |
| 293 | u8* swizzle_data) { | 304 | u8* swizzle_data) { |
| 305 | const u32 block_height = 1U << block_height_bit; | ||
| 294 | const u32 image_width_in_gobs{(width + gob_size_x - 1) / gob_size_x}; | 306 | const u32 image_width_in_gobs{(width + gob_size_x - 1) / gob_size_x}; |
| 295 | std::size_t count = 0; | 307 | std::size_t count = 0; |
| 296 | for (std::size_t y = dst_y; y < height && count < copy_size; ++y) { | 308 | for (std::size_t y = dst_y; y < height && count < copy_size; ++y) { |
| @@ -356,9 +368,9 @@ std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat | |||
| 356 | std::size_t CalculateSize(bool tiled, u32 bytes_per_pixel, u32 width, u32 height, u32 depth, | 368 | std::size_t CalculateSize(bool tiled, u32 bytes_per_pixel, u32 width, u32 height, u32 depth, |
| 357 | u32 block_height, u32 block_depth) { | 369 | u32 block_height, u32 block_depth) { |
| 358 | if (tiled) { | 370 | if (tiled) { |
| 359 | const u32 aligned_width = Common::AlignUp(width * bytes_per_pixel, gob_size_x); | 371 | const u32 aligned_width = Common::AlignBits(width * bytes_per_pixel, gob_size_x_shift); |
| 360 | const u32 aligned_height = Common::AlignUp(height, gob_size_y * block_height); | 372 | const u32 aligned_height = Common::AlignBits(height, gob_size_y_shift + block_height); |
| 361 | const u32 aligned_depth = Common::AlignUp(depth, gob_size_z * block_depth); | 373 | const u32 aligned_depth = Common::AlignBits(depth, gob_size_z_shift + block_depth); |
| 362 | return aligned_width * aligned_height * aligned_depth; | 374 | return aligned_width * aligned_height * aligned_depth; |
| 363 | } else { | 375 | } else { |
| 364 | return width * height * depth * bytes_per_pixel; | 376 | return width * height * depth * bytes_per_pixel; |
diff --git a/src/video_core/textures/decoders.h b/src/video_core/textures/decoders.h index e072d8401..eaec9b5a5 100644 --- a/src/video_core/textures/decoders.h +++ b/src/video_core/textures/decoders.h | |||
| @@ -12,8 +12,8 @@ namespace Tegra::Texture { | |||
| 12 | 12 | ||
| 13 | // GOBSize constant. Calculated by 64 bytes in x multiplied by 8 y coords, represents | 13 | // GOBSize constant. Calculated by 64 bytes in x multiplied by 8 y coords, represents |
| 14 | // an small rect of (64/bytes_per_pixel)X8. | 14 | // an small rect of (64/bytes_per_pixel)X8. |
| 15 | inline std::size_t GetGOBSize() { | 15 | inline std::size_t GetGOBSizeShift() { |
| 16 | return 512; | 16 | return 9; |
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | /// Unswizzles a swizzled texture without changing its format. | 19 | /// Unswizzles a swizzled texture without changing its format. |
diff --git a/src/video_core/textures/texture.h b/src/video_core/textures/texture.h index 219bfd559..e3be018b9 100644 --- a/src/video_core/textures/texture.h +++ b/src/video_core/textures/texture.h | |||
| @@ -52,9 +52,9 @@ enum class TextureFormat : u32 { | |||
| 52 | DXT45 = 0x26, | 52 | DXT45 = 0x26, |
| 53 | DXN1 = 0x27, | 53 | DXN1 = 0x27, |
| 54 | DXN2 = 0x28, | 54 | DXN2 = 0x28, |
| 55 | Z24S8 = 0x29, | 55 | S8Z24 = 0x29, |
| 56 | X8Z24 = 0x2a, | 56 | X8Z24 = 0x2a, |
| 57 | S8Z24 = 0x2b, | 57 | Z24S8 = 0x2b, |
| 58 | X4V4Z24__COV4R4V = 0x2c, | 58 | X4V4Z24__COV4R4V = 0x2c, |
| 59 | X4V4Z24__COV8R8V = 0x2d, | 59 | X4V4Z24__COV8R8V = 0x2d, |
| 60 | V8Z24__COV4R12V = 0x2e, | 60 | V8Z24__COV4R12V = 0x2e, |
| @@ -172,12 +172,16 @@ struct TICEntry { | |||
| 172 | BitField<26, 1, u32> use_header_opt_control; | 172 | BitField<26, 1, u32> use_header_opt_control; |
| 173 | BitField<27, 1, u32> depth_texture; | 173 | BitField<27, 1, u32> depth_texture; |
| 174 | BitField<28, 4, u32> max_mip_level; | 174 | BitField<28, 4, u32> max_mip_level; |
| 175 | |||
| 176 | BitField<0, 16, u32> buffer_high_width_minus_one; | ||
| 175 | }; | 177 | }; |
| 176 | union { | 178 | union { |
| 177 | BitField<0, 16, u32> width_minus_1; | 179 | BitField<0, 16, u32> width_minus_1; |
| 178 | BitField<22, 1, u32> srgb_conversion; | 180 | BitField<22, 1, u32> srgb_conversion; |
| 179 | BitField<23, 4, TextureType> texture_type; | 181 | BitField<23, 4, TextureType> texture_type; |
| 180 | BitField<29, 3, u32> border_size; | 182 | BitField<29, 3, u32> border_size; |
| 183 | |||
| 184 | BitField<0, 16, u32> buffer_low_width_minus_one; | ||
| 181 | }; | 185 | }; |
| 182 | union { | 186 | union { |
| 183 | BitField<0, 16, u32> height_minus_1; | 187 | BitField<0, 16, u32> height_minus_1; |
| @@ -206,7 +210,10 @@ struct TICEntry { | |||
| 206 | } | 210 | } |
| 207 | 211 | ||
| 208 | u32 Width() const { | 212 | u32 Width() const { |
| 209 | return width_minus_1 + 1; | 213 | if (header_version != TICHeaderVersion::OneDBuffer) { |
| 214 | return width_minus_1 + 1; | ||
| 215 | } | ||
| 216 | return (buffer_high_width_minus_one << 16) | buffer_low_width_minus_one; | ||
| 210 | } | 217 | } |
| 211 | 218 | ||
| 212 | u32 Height() const { | 219 | u32 Height() const { |
| @@ -219,20 +226,17 @@ struct TICEntry { | |||
| 219 | 226 | ||
| 220 | u32 BlockWidth() const { | 227 | u32 BlockWidth() const { |
| 221 | ASSERT(IsTiled()); | 228 | ASSERT(IsTiled()); |
| 222 | // The block height is stored in log2 format. | 229 | return block_width; |
| 223 | return 1 << block_width; | ||
| 224 | } | 230 | } |
| 225 | 231 | ||
| 226 | u32 BlockHeight() const { | 232 | u32 BlockHeight() const { |
| 227 | ASSERT(IsTiled()); | 233 | ASSERT(IsTiled()); |
| 228 | // The block height is stored in log2 format. | 234 | return block_height; |
| 229 | return 1 << block_height; | ||
| 230 | } | 235 | } |
| 231 | 236 | ||
| 232 | u32 BlockDepth() const { | 237 | u32 BlockDepth() const { |
| 233 | ASSERT(IsTiled()); | 238 | ASSERT(IsTiled()); |
| 234 | // The block height is stored in log2 format. | 239 | return block_depth; |
| 235 | return 1 << block_depth; | ||
| 236 | } | 240 | } |
| 237 | 241 | ||
| 238 | bool IsTiled() const { | 242 | bool IsTiled() const { |
| @@ -240,6 +244,15 @@ struct TICEntry { | |||
| 240 | header_version == TICHeaderVersion::BlockLinearColorKey; | 244 | header_version == TICHeaderVersion::BlockLinearColorKey; |
| 241 | } | 245 | } |
| 242 | 246 | ||
| 247 | bool IsLineal() const { | ||
| 248 | return header_version == TICHeaderVersion::Pitch || | ||
| 249 | header_version == TICHeaderVersion::PitchColorKey; | ||
| 250 | } | ||
| 251 | |||
| 252 | bool IsBuffer() const { | ||
| 253 | return header_version == TICHeaderVersion::OneDBuffer; | ||
| 254 | } | ||
| 255 | |||
| 243 | bool IsSrgbConversionEnabled() const { | 256 | bool IsSrgbConversionEnabled() const { |
| 244 | return srgb_conversion != 0; | 257 | return srgb_conversion != 0; |
| 245 | } | 258 | } |