1 // Copyright 2018 yuzu Emulator Project
2 // Licensed under GPLv2 or any later version
3 // Refer to the license.txt file included.
4 
5 #pragma once
6 
7 #include <vector>
8 #include "common/common_types.h"
9 #include "video_core/textures/texture.h"
10 
11 namespace Tegra::Texture {
12 
13 constexpr u32 GOB_SIZE_X = 64;
14 constexpr u32 GOB_SIZE_Y = 8;
15 constexpr u32 GOB_SIZE_Z = 1;
16 constexpr u32 GOB_SIZE = GOB_SIZE_X * GOB_SIZE_Y * GOB_SIZE_Z;
17 
18 constexpr std::size_t GOB_SIZE_X_SHIFT = 6;
19 constexpr std::size_t GOB_SIZE_Y_SHIFT = 3;
20 constexpr std::size_t GOB_SIZE_Z_SHIFT = 0;
21 constexpr std::size_t GOB_SIZE_SHIFT = GOB_SIZE_X_SHIFT + GOB_SIZE_Y_SHIFT + GOB_SIZE_Z_SHIFT;
22 
23 /// Unswizzles a swizzled texture without changing its format.
24 void UnswizzleTexture(u8* unswizzled_data, u8* address, u32 tile_size_x, u32 tile_size_y,
25                       u32 bytes_per_pixel, u32 width, u32 height, u32 depth,
26                       u32 block_height = TICEntry::DefaultBlockHeight,
27                       u32 block_depth = TICEntry::DefaultBlockHeight, u32 width_spacing = 0);
28 
29 /// Unswizzles a swizzled texture without changing its format.
30 std::vector<u8> UnswizzleTexture(u8* address, u32 tile_size_x, u32 tile_size_y, u32 bytes_per_pixel,
31                                  u32 width, u32 height, u32 depth,
32                                  u32 block_height = TICEntry::DefaultBlockHeight,
33                                  u32 block_depth = TICEntry::DefaultBlockHeight,
34                                  u32 width_spacing = 0);
35 
36 /// Copies texture data from a buffer and performs swizzling/unswizzling as necessary.
37 void CopySwizzledData(u32 width, u32 height, u32 depth, u32 bytes_per_pixel,
38                       u32 out_bytes_per_pixel, u8* swizzled_data, u8* unswizzled_data,
39                       bool unswizzle, u32 block_height, u32 block_depth, u32 width_spacing);
40 
41 /// This function calculates the correct size of a texture depending if it's tiled or not.
42 std::size_t CalculateSize(bool tiled, u32 bytes_per_pixel, u32 width, u32 height, u32 depth,
43                           u32 block_height, u32 block_depth);
44 
45 /// Copies an untiled subrectangle into a tiled surface.
46 void SwizzleSubrect(u32 subrect_width, u32 subrect_height, u32 source_pitch, u32 swizzled_width,
47                     u32 bytes_per_pixel, u8* swizzled_data, const u8* unswizzled_data,
48                     u32 block_height_bit, u32 offset_x, u32 offset_y);
49 
50 /// Copies a tiled subrectangle into a linear surface.
51 void UnswizzleSubrect(u32 line_length_in, u32 line_count, u32 pitch, u32 width, u32 bytes_per_pixel,
52                       u32 block_height, u32 origin_x, u32 origin_y, u8* output, const u8* input);
53 
54 /// @brief Swizzles a 2D array of pixels into a 3D texture
55 /// @param line_length_in  Number of pixels per line
56 /// @param line_count      Number of lines
57 /// @param pitch           Number of bytes per line
58 /// @param width           Width of the swizzled texture
59 /// @param height          Height of the swizzled texture
60 /// @param bytes_per_pixel Number of bytes used per pixel
61 /// @param block_height    Block height shift
62 /// @param block_depth     Block depth shift
63 /// @param origin_x        Column offset in pixels of the swizzled texture
64 /// @param origin_y        Row offset in pixels of the swizzled texture
65 /// @param output          Pointer to the pixels of the swizzled texture
66 /// @param input           Pointer to the 2D array of pixels used as input
67 /// @pre input and output points to an array large enough to hold the number of bytes used
68 void SwizzleSliceToVoxel(u32 line_length_in, u32 line_count, u32 pitch, u32 width, u32 height,
69                          u32 bytes_per_pixel, u32 block_height, u32 block_depth, u32 origin_x,
70                          u32 origin_y, u8* output, const u8* input);
71 
72 void SwizzleKepler(u32 width, u32 height, u32 dst_x, u32 dst_y, u32 block_height,
73                    std::size_t copy_size, const u8* source_data, u8* swizzle_data);
74 
75 /// Obtains the offset of the gob for positions 'dst_x' & 'dst_y'
76 u64 GetGOBOffset(u32 width, u32 height, u32 dst_x, u32 dst_y, u32 block_height,
77                  u32 bytes_per_pixel);
78 
79 } // namespace Tegra::Texture
80