Skip to content

Instantly share code, notes, and snippets.

@FernandoS27
Last active September 20, 2018 23:38
Show Gist options
  • Save FernandoS27/79a031fe7acdb83c63f8c216d4b93494 to your computer and use it in GitHub Desktop.
Save FernandoS27/79a031fe7acdb83c63f8c216d4b93494 to your computer and use it in GitHub Desktop.
// Example program
#include <iostream>
#include <string>
#include <cmath>
#include <utility>
#include <array>
#include <cstring>
typedef unsigned char u8;
typedef unsigned int u32;
struct pixel {
u32 a;
u32 b;
u32 c;
u32 d;
};
void ProcessGob(u8* swizzled_data, u8* unswizzled_data, bool unswizzle, const u32 gob_offset,
const u32 linear_offset, const u32 stride, const u32 bytes_x, const u32 max_y) {
std::array<u8*, 2> data_ptrs;
u32 offset = linear_offset;
for (u32 y = 0; y < max_y; y++) {
u32 swizzle_offset = gob_offset + y * bytes_x;
data_ptrs[unswizzle] = swizzled_data + swizzle_offset;
data_ptrs[!unswizzle] = unswizzled_data + offset;
std::memcpy(data_ptrs[0], data_ptrs[1], bytes_x);
offset += stride;
}
}
inline u32 div_ceil(u32 x, u32 y) {
return ((x + y - 1) / y);
}
void CopySwizzledDataNew(u8* swizzled_data, u8* unswizzled_data, bool unswizzle, u32 width,
u32 height, u32 depth, u32 bytes_per_pixel, u32 block_width,
u32 block_height, u32 block_depth) {
u32 stride_x = width * bytes_per_pixel;
u32 layer_z = height * stride_x;
u32 gob_elements_x = 64 / bytes_per_pixel;
u32 gob_elements_y = 4;
u32 gob_elements_z = 1;
u32 block_x_elements = gob_elements_x * block_width;
u32 block_y_elements = gob_elements_y * block_height;
u32 block_z_elements = gob_elements_z * block_depth;
u32 blocks_on_x = div_ceil(width, block_x_elements);
u32 blocks_on_y = div_ceil(height, block_y_elements);
u32 blocks_on_z = div_ceil(depth, block_z_elements);
u32 blocks = blocks_on_x * blocks_on_y * blocks_on_z;
u32 tile_offset = 0;
for (u32 b = 0; b < blocks; b++) {
u32 x_block = b % blocks_on_x;
u32 y_block = (b / blocks_on_x) % blocks_on_y;
u32 z_block = (b / (blocks_on_x*blocks_on_y)) % blocks_on_z;
u32 x_elements = std::min((width - x_block * block_x_elements), block_x_elements);
u32 y_elements = std::min((height - y_block * block_y_elements), block_y_elements);
u32 z_elements = std::min((depth - z_block * block_z_elements), block_z_elements);
u32 gobs_x = div_ceil(x_elements, gob_elements_x);
u32 gobs_y = div_ceil(y_elements, gob_elements_y);
u32 gobs_z = div_ceil(z_elements, gob_elements_z);
u32 z_adress = z_block * block_z_elements * layer_z;
for (u32 gz = 0; gz < gobs_z; gz++) {
u32 y_adress = y_block * block_y_elements * stride_x;
for (u32 gy = 0; gy < gobs_y; gy++) {
u32 y_gob_size = std::min((y_elements - gy * gob_elements_y), gob_elements_y);
u32 x_adress = x_block * block_x_elements * bytes_per_pixel;
for (u32 gx = 0; gx < gobs_x; gx++) {
u32 x_gob_size = std::min((x_elements - gx * gob_elements_x), gob_elements_x);
ProcessGob(swizzled_data, unswizzled_data, unswizzle, tile_offset, z_adress + y_adress + x_adress, stride_x, x_gob_size*bytes_per_pixel, y_gob_size);
tile_offset += y_gob_size * x_gob_size * bytes_per_pixel;
x_adress += x_gob_size * bytes_per_pixel;
}
y_adress += y_gob_size * stride_x;
}
z_adress += layer_z;
}
}
}
void printTexture(pixel texture[3][17][13]) {
for(u32 z = 0; z < 3; z++)
{
for(u32 y = 0; y < 17; y++)
{
for(u32 x = 0; x < 13; x++)
{
std::cout << std::hex << texture[z][y][x].a << ", ";
}
std::cout << std::endl;
}
std::cout << std::endl;
std::cout << std::endl;
}
}
int main()
{
u32 i = 0;
pixel texture[3][17][13];
pixel texture2[3][17][13];
for(u32 z = 0; z < 3; z++)
{
for(u32 y = 0; y < 17; y++)
{
for(u32 x = 0; x < 13; x++)
{
texture[z][y][x].a = i;
texture[z][y][x].b = 0;
texture[z][y][x].c = 0;
texture[z][y][x].d = 0;
texture2[z][y][x].a = 0xFFF;
texture2[z][y][x].b = 0;
texture2[z][y][x].c = 0;
texture2[z][y][x].d = 0;
i+=16;
}
}
}
//printTexture(texture);
CopySwizzledDataNew(reinterpret_cast<u8*>(&texture[0][0][0]), reinterpret_cast<u8*>(&texture2[0][0][0]),true,13,17,3,16,2,2,2);
printTexture(texture2);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment