summaryrefslogtreecommitdiff
path: root/src/video_core/textures
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/textures')
-rw-r--r--src/video_core/textures/convert.cpp14
-rw-r--r--src/video_core/textures/convert.h7
-rw-r--r--src/video_core/textures/decoders.cpp42
-rw-r--r--src/video_core/textures/decoders.h4
-rw-r--r--src/video_core/textures/texture.h31
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
65void ConvertFromGuestToHost(u8* data, PixelFormat pixel_format, u32 width, u32 height, u32 depth, 65void 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
13namespace Tegra::Texture { 13namespace Tegra::Texture {
14 14
15void ConvertFromGuestToHost(u8* data, VideoCore::Surface::PixelFormat pixel_format, u32 width, 15void 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
18void ConvertFromHostToGuest(u8* data, VideoCore::Surface::PixelFormat pixel_format, u32 width, 19void 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
39constexpr u32 gob_size_x = 64; 39constexpr u32 gob_size_x_shift = 6;
40constexpr u32 gob_size_y = 8; 40constexpr u32 gob_size_y_shift = 3;
41constexpr u32 gob_size_z = 1; 41constexpr u32 gob_size_z_shift = 0;
42constexpr u32 gob_size = gob_size_x * gob_size_y * gob_size_z; 42constexpr u32 gob_size_shift = gob_size_x_shift + gob_size_y_shift + gob_size_z_shift;
43
44constexpr u32 gob_size_x = 1U << gob_size_x_shift;
45constexpr u32 gob_size_y = 1U << gob_size_y_shift;
46constexpr u32 gob_size_z = 1U << gob_size_z_shift;
47constexpr u32 gob_size = 1U << gob_size_shift;
48
43constexpr u32 fast_swizzle_align = 16; 49constexpr u32 fast_swizzle_align = 16;
44 50
45constexpr auto legacy_swizzle_table = SwizzleTable<gob_size_y, gob_size_x, gob_size_z>(); 51constexpr 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
171void CopySwizzledData(u32 width, u32 height, u32 depth, u32 bytes_per_pixel, 177void 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
250void SwizzleSubrect(u32 subrect_width, u32 subrect_height, u32 source_pitch, u32 swizzled_width, 258void 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
271void UnswizzleSubrect(u32 subrect_width, u32 subrect_height, u32 dest_pitch, u32 swizzled_width, 281void 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
291void SwizzleKepler(const u32 width, const u32 height, const u32 dst_x, const u32 dst_y, 302void 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
356std::size_t CalculateSize(bool tiled, u32 bytes_per_pixel, u32 width, u32 height, u32 depth, 368std::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.
15inline std::size_t GetGOBSize() { 15inline 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 }