Implemented LoadTile f3d command, I4/I8/RGBA32 texture formats.

This commit is contained in:
kurethedead 2020-05-17 15:48:06 -07:00
parent 166d1b3a73
commit 181e18dfea
1 changed files with 90 additions and 3 deletions

View File

@ -285,6 +285,12 @@ static bool gfx_texture_cache_lookup(int tile, struct TextureHashmapNode **n, co
return false;
}
static void import_texture_rgba32(int tile) {
uint32_t width = rdp.texture_tile.line_size_bytes / 2;
uint32_t height = (rdp.loaded_texture[tile].size_bytes / 2) / rdp.texture_tile.line_size_bytes;
gfx_rapi->upload_texture(rdp.loaded_texture[tile].addr, width, height);
}
static void import_texture_rgba16(int tile) {
uint8_t rgba32_buf[8192];
@ -371,6 +377,41 @@ static void import_texture_ia16(int tile) {
gfx_rapi->upload_texture(rgba32_buf, width, height);
}
static void import_texture_i4(int tile) {
uint8_t rgba32_buf[32768];
for (uint32_t i = 0; i < rdp.loaded_texture[tile].size_bytes * 2; i++) {
uint8_t byte = rdp.loaded_texture[tile].addr[i / 2];
uint8_t intensity = (byte >> (4 - (i % 2) * 4)) & 0xf;
rgba32_buf[4*i + 0] = SCALE_4_8(intensity);
rgba32_buf[4*i + 1] = SCALE_4_8(intensity);
rgba32_buf[4*i + 2] = SCALE_4_8(intensity);
rgba32_buf[4*i + 3] = 255;
}
uint32_t width = rdp.texture_tile.line_size_bytes * 2;
uint32_t height = rdp.loaded_texture[tile].size_bytes / rdp.texture_tile.line_size_bytes;
gfx_rapi->upload_texture(rgba32_buf, width, height);
}
static void import_texture_i8(int tile) {
uint8_t rgba32_buf[16384];
for (uint32_t i = 0; i < rdp.loaded_texture[tile].size_bytes; i++) {
uint8_t intensity = rdp.loaded_texture[tile].addr[i];
rgba32_buf[4*i + 0] = intensity;
rgba32_buf[4*i + 1] = intensity;
rgba32_buf[4*i + 2] = intensity;
rgba32_buf[4*i + 3] = 255;
}
uint32_t width = rdp.texture_tile.line_size_bytes;
uint32_t height = rdp.loaded_texture[tile].size_bytes / rdp.texture_tile.line_size_bytes;
gfx_rapi->upload_texture(rgba32_buf, width, height);
}
static void import_texture_ci4(int tile) {
uint8_t rgba32_buf[32768];
@ -426,7 +467,10 @@ static void import_texture(int tile) {
int t0 = get_time();
if (fmt == G_IM_FMT_RGBA) {
if (siz == G_IM_SIZ_16b) {
if (siz == G_IM_SIZ_32b) {
import_texture_rgba32(tile);
}
else if (siz == G_IM_SIZ_16b) {
import_texture_rgba16(tile);
} else {
abort();
@ -449,6 +493,14 @@ static void import_texture(int tile) {
} else {
abort();
}
} else if (fmt == G_IM_FMT_I) {
if (siz == G_IM_SIZ_4b) {
import_texture_i4(tile);
} else if (siz == G_IM_SIZ_8b) {
import_texture_i8(tile);
} else {
abort();
}
} else {
abort();
}
@ -976,7 +1028,6 @@ static void gfx_dp_set_texture_image(uint32_t format, uint32_t size, uint32_t wi
}
static void gfx_dp_set_tile(uint8_t fmt, uint32_t siz, uint32_t line, uint32_t tmem, uint8_t tile, uint32_t palette, uint32_t cmt, uint32_t maskt, uint32_t shiftt, uint32_t cms, uint32_t masks, uint32_t shifts) {
SUPPORT_CHECK(siz != G_IM_SIZ_32b);
if (tile == G_TX_RENDERTILE) {
SUPPORT_CHECK(palette == 0); // palette should set upper 4 bits of color index in 4b mode
@ -1035,12 +1086,45 @@ static void gfx_dp_load_block(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t
}
uint32_t size_bytes = (lrs + 1) << word_size_shift;
rdp.loaded_texture[rdp.texture_to_load.tile_number].size_bytes = size_bytes;
assert(size_bytes <= 4096 && "bug: too big texture");
rdp.loaded_texture[rdp.texture_to_load.tile_number].addr = rdp.texture_to_load.addr;
rdp.textures_changed[rdp.texture_to_load.tile_number] = true;
}
static void gfx_dp_load_tile(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t lrs, uint32_t lrt) {
if (tile == 1) return;
SUPPORT_CHECK(tile == G_TX_LOADTILE);
SUPPORT_CHECK(uls == 0);
SUPPORT_CHECK(ult == 0);
uint32_t word_size_shift;
switch (rdp.texture_to_load.siz) {
case G_IM_SIZ_4b:
word_size_shift = 0; // Or -1? It's unused in SM64 anyway.
break;
case G_IM_SIZ_8b:
word_size_shift = 0;
break;
case G_IM_SIZ_16b:
word_size_shift = 1;
break;
case G_IM_SIZ_32b:
word_size_shift = 2;
break;
}
uint32_t size_bytes = (((lrs >> G_TEXTURE_IMAGE_FRAC) + 1) * ((lrt >> G_TEXTURE_IMAGE_FRAC) + 1)) << word_size_shift;
rdp.loaded_texture[rdp.texture_to_load.tile_number].size_bytes = size_bytes;
rdp.loaded_texture[rdp.texture_to_load.tile_number].addr = rdp.texture_to_load.addr;
rdp.texture_tile.uls = uls;
rdp.texture_tile.ult = ult;
rdp.texture_tile.lrs = lrs;
rdp.texture_tile.lrt = lrt;
rdp.textures_changed[rdp.texture_to_load.tile_number] = true;
}
static uint8_t color_comb_component(uint32_t v) {
switch (v) {
case G_CCMUX_TEXEL0:
@ -1384,6 +1468,9 @@ static void gfx_run_dl(Gfx* cmd) {
case G_LOADBLOCK:
gfx_dp_load_block(C1(24, 3), C0(12, 12), C0(0, 12), C1(12, 12), C1(0, 12));
break;
case G_LOADTILE:
gfx_dp_load_tile(C1(24, 3), C0(12, 12), C0(0, 12), C1(12, 12), C1(0, 12));
break;
case G_SETTILE:
gfx_dp_set_tile(C0(21, 3), C0(19, 2), C0(9, 9), C0(0, 9), C1(24, 3), C1(20, 4), C1(18, 2), C1(14, 4), C1(10, 4), C1(8, 2), C1(4, 4), C1(0, 4));
break;