diff --git a/src/pc/gfx/gfx_cc.c b/src/pc/gfx/gfx_cc.c index aae82288d..12e4bda0e 100644 --- a/src/pc/gfx/gfx_cc.c +++ b/src/pc/gfx/gfx_cc.c @@ -1,5 +1,9 @@ +#include +#include "PR/gbi.h" #include "gfx_cc.h" +#include "gfx_pc.h" +static u8 sAllowCCPrint = 1; void gfx_cc_get_features(uint32_t shader_id, struct CCFeatures *cc_features) { // DO NOT COMMIT: TODO - need to fix this for (int32_t i = 0; i < 4; i++) { @@ -40,3 +44,65 @@ void gfx_cc_get_features(uint32_t shader_id, struct CCFeatures *cc_features) { cc_features->do_mix[1] = cc_features->c[1][1] == cc_features->c[1][3]; cc_features->color_alpha_same = (shader_id & 0xfff) == ((shader_id >> 12) & 0xfff); } + +void gfx_cc_print(struct ColorCombiner *cc) { + if (!sAllowCCPrint) { return; } + printf("\n>> gfx_pc_precomp_shader("); + + struct CombineMode* cm = &cc->cm; + printf("0x%08x, ", cm->rgb1); + printf("0x%08x, ", cm->alpha1); + printf("0x%08x, ", cm->rgb2); + printf("0x%08x, ", cm->alpha2); + printf("0x%08x", cm->flags); + + printf(");"); + printf(" // %016lx", cm->hash); + printf("\n"); +} + +void gfx_cc_precomp(void) { + sAllowCCPrint = 0; + + // DO NOT COMMIT - TODO - need to add an exhaustive list + // .. need to save the cc_prints to a file if dev mode and vanilla + // .. also what happens when we run out of ccs/shaders? + gfx_pc_precomp_shader(0x00030001, 0x02000000, 0x000a0004, 0x0a000b0b, 0x00000011); // 741f2ad014006ca1 + gfx_pc_precomp_shader(0x00040001, 0x00010005, 0x00040002, 0x0b020b05, 0x00000001); // 110404410ba7b38b + gfx_pc_precomp_shader(0x00040001, 0x00030001, 0x00040002, 0x0b030b02, 0x00000001); // 110404410be9b307 + gfx_pc_precomp_shader(0x00040001, 0x00040001, 0x00040002, 0x0b040b02, 0x00000000); // 0084002100596a45 + gfx_pc_precomp_shader(0x00040001, 0x00040001, 0x00040002, 0x0b040b02, 0x00000001); // 110404410c0ab307 + gfx_pc_precomp_shader(0x00040001, 0x00040001, 0x00040002, 0x0b040b02, 0x00000005); // 110404410c0ab30b + gfx_pc_precomp_shader(0x00040001, 0x00050001, 0x00040002, 0x0b050b02, 0x00000001); // 110404410c2bb307 + gfx_pc_precomp_shader(0x00040001, 0x00050001, 0x00040002, 0x0b050b02, 0x00000009); // 110404410c2bb30f + gfx_pc_precomp_shader(0x00040001, 0x01000000, 0x00040002, 0x02000b0b, 0x00000001); // 110404412c86b2e6 + gfx_pc_precomp_shader(0x00040001, 0x04000000, 0x00040002, 0x04000b0b, 0x00000001); // 110404418f86b2e6 + gfx_pc_precomp_shader(0x00040001, 0x04000000, 0x0a000000, 0x0a000b0b, 0x00000013); // ec161ae4d6006ca3 + gfx_pc_precomp_shader(0x00040001, 0x05000000, 0x00040002, 0x05000b0b, 0x00000001); // 11040441b086b2e6 + gfx_pc_precomp_shader(0x00040001, 0x05000000, 0x00040002, 0x05000b0b, 0x00000009); // 11040441b086b2ee + gfx_pc_precomp_shader(0x00040001, 0x05000000, 0x0a000000, 0x0a000b0b, 0x00000013); // ec161b7137006ca3 + gfx_pc_precomp_shader(0x00050001, 0x00050001, 0x00050002, 0x0b050b02, 0x00000001); // 154504410c2bb307 + gfx_pc_precomp_shader(0x00050004, 0x00050004, 0x00050004, 0x0b050b04, 0x00000001); // 154511040c2bb36a + gfx_pc_precomp_shader(0x01000000, 0x00050001, 0x02000000, 0x0b050b02, 0x00000001); // 410000000c2bb307 + gfx_pc_precomp_shader(0x01000000, 0x01000000, 0x02000000, 0x02000000, 0x00000001); // 410000002c86b2e6 + gfx_pc_precomp_shader(0x01000000, 0x01000000, 0x02000000, 0x02000b0b, 0x00000005); // 410000002c86b2ea + gfx_pc_precomp_shader(0x01000000, 0x01000000, 0x0a000000, 0x0a000b0b, 0x00000017); // 0b0000beb3006ca7 + gfx_pc_precomp_shader(0x01000000, 0x04000000, 0x02000000, 0x04000b0b, 0x00000000); // 2100000000596a45 + gfx_pc_precomp_shader(0x01000000, 0x04000000, 0x0a000000, 0x0a000b0b, 0x00000013); // 0b000263d6006ca3 + gfx_pc_precomp_shader(0x01000000, 0x05000000, 0x02000000, 0x05000b0b, 0x00000001); // 41000000b086b2e6 + gfx_pc_precomp_shader(0x01000000, 0x05000000, 0x0a000000, 0x0a000b0b, 0x00000013); // 0b0002f037006ca3 + gfx_pc_precomp_shader(0x01070102, 0x01000102, 0x0a000000, 0x04000b0b, 0x00000011); // c8c3b2bfed8de663 + gfx_pc_precomp_shader(0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x00000001); // 040000008f86b2e6 + gfx_pc_precomp_shader(0x04000000, 0x04000000, 0x04000000, 0x04000b0b, 0x00000000); // 8400000000596a45 + gfx_pc_precomp_shader(0x04000000, 0x04000000, 0x04000000, 0x04000b0b, 0x00000005); // 040000008f86b2ea + gfx_pc_precomp_shader(0x04000000, 0x04000000, 0x0a000000, 0x0a000b0b, 0x00000013); // 8e000263d6006ca3 + gfx_pc_precomp_shader(0x04000000, 0x05000000, 0x04000000, 0x05000b0b, 0x00000001); // 04000000b086b2e6 + gfx_pc_precomp_shader(0x04000000, 0x05000000, 0x04000000, 0x05000b0b, 0x00000005); // 04000000b086b2ea + gfx_pc_precomp_shader(0x04000000, 0x05000000, 0x04000000, 0x05000b0b, 0x00000009); // 04000000b086b2ee + gfx_pc_precomp_shader(0x04060401, 0x04000000, 0x04060402, 0x04000b0b, 0x00000000); // 84c6842100596a45 + gfx_pc_precomp_shader(0x04060401, 0x05000000, 0x04060402, 0x05000b0b, 0x00000001); // 1d970841b086b2e6 + gfx_pc_precomp_shader(0x01000000, 0x04000000, 0x02000000, 0x04000b0b, 0x00000001); // 410000008f86b2e6 + + + sAllowCCPrint = 1; +} \ No newline at end of file diff --git a/src/pc/gfx/gfx_cc.h b/src/pc/gfx/gfx_cc.h index 188142061..8bb60073b 100644 --- a/src/pc/gfx/gfx_cc.h +++ b/src/pc/gfx/gfx_cc.h @@ -79,6 +79,7 @@ struct CombineMode { uint8_t texture_edge : 1; uint8_t use_noise : 1; uint8_t use_2cycle : 1; + uint8_t light_map : 1; }; uint32_t flags; }; @@ -91,8 +92,14 @@ struct CombineMode { struct ColorCombiner { struct CombineMode cm; struct ShaderProgram *prg; - uint8_t shader_input_mapping[16]; - uint8_t shader_commands[16]; + union { + uint8_t shader_input_mapping[16]; + uint64_t shader_input_mapping_as_u64[8]; + }; + union { + uint8_t shader_commands[16]; + uint64_t shader_commands_as_u64[8]; + }; uint64_t hash; }; @@ -101,6 +108,8 @@ extern "C" { #endif void gfx_cc_get_features(uint32_t shader_id, struct CCFeatures *cc_features); +void gfx_cc_print(struct ColorCombiner *cc); +void gfx_cc_precomp(void); #ifdef __cplusplus } diff --git a/src/pc/gfx/gfx_opengl.c b/src/pc/gfx/gfx_opengl.c index b294f9e1c..49c9969d6 100644 --- a/src/pc/gfx/gfx_opengl.c +++ b/src/pc/gfx/gfx_opengl.c @@ -393,7 +393,11 @@ static struct ShaderProgram *gfx_opengl_create_and_load_new_shader(struct ColorC append_line(fs_buf, &fs_len, "vec4 texVal0 = sampleTex(uTex0, vTexCoord, uTex0Size, uTex0Filter);"); } if (used_textures[1]) { - append_line(fs_buf, &fs_len, "vec4 texVal1 = sampleTex(uTex1, vTexCoord, uTex1Size, uTex1Filter);"); + if (cc->cm.light_map) { + append_line(fs_buf, &fs_len, "vec4 texVal1 = sampleTex(uTex1, vInput1.rg, uTex1Size, uTex1Filter);"); + } else { + append_line(fs_buf, &fs_len, "vec4 texVal1 = sampleTex(uTex1, vTexCoord, uTex1Size, uTex1Filter);"); + } } append_str(fs_buf, &fs_len, (opt_alpha) ? "vec4 texel = " : "vec3 texel = "); diff --git a/src/pc/gfx/gfx_pc.c b/src/pc/gfx/gfx_pc.c index 7ca76f4c4..d53a325c3 100644 --- a/src/pc/gfx/gfx_pc.c +++ b/src/pc/gfx/gfx_pc.c @@ -228,23 +228,34 @@ static void gfx_flush(void) { } } -static void combine_mode_update_hash(struct CombineMode* mode) { +static void combine_mode_update_hash(struct CombineMode* cm) { uint64_t hash = 5381; - hash = (hash << 5) + hash + mode->rgb1; - hash = (hash << 5) + hash + mode->alpha1; - hash = (hash << 5) + hash + mode->rgb2; - hash = (hash << 5) + hash + mode->alpha2; - hash = (hash << 5) + hash + mode->flags; + cm->hash = 0; - mode->hash = hash; + hash = (hash << 5) + hash + ((u64)cm->rgb1 << 32); + if (cm->use_alpha) { + hash = (hash << 5) + hash + ((u64)cm->alpha1); + } + + if (cm->use_2cycle) { + hash = (hash << 5) + hash + ((u64)cm->rgb2 << 32); + if (cm->use_alpha) { + hash = (hash << 5) + hash + ((u64)cm->alpha2); + } + } + + hash = (hash << 5) + hash + cm->flags; + + cm->hash = hash; } static void color_combiner_update_hash(struct ColorCombiner* cc) { uint64_t hash = cc->cm.hash; - for (int i = 0; i < SHADER_CMD_LENGTH; i++) { - hash = (hash << 5) + hash + cc->shader_commands[i]; + for (int i = 0; i < 8; i++) { + hash = (hash << 5) + hash + cc->shader_input_mapping_as_u64[i]; + hash = (hash << 5) + hash + cc->shader_commands_as_u64[i]; } cc->hash = hash; @@ -315,6 +326,7 @@ static void gfx_generate_cc(struct ColorCombiner *cc) { color_combiner_update_hash(cc); cc->prg = gfx_lookup_or_create_shader_program(cc); + gfx_cc_print(cc); } static struct ColorCombiner *gfx_lookup_or_create_color_combiner(struct CombineMode* cm) { @@ -330,12 +342,15 @@ static struct ColorCombiner *gfx_lookup_or_create_color_combiner(struct CombineM return prev_combiner = &color_combiner_pool[i]; } } + gfx_flush(); struct ColorCombiner *comb = &color_combiner_pool[color_combiner_pool_size++]; - comb->cm = *cm; + memcpy(&comb->cm, cm, sizeof(struct CombineMode)); gfx_generate_cc(comb); + printf(">> added %016lx\n", comb->cm.hash); + return prev_combiner = comb; } @@ -1017,8 +1032,9 @@ static void OPTIMIZE_O3 gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t cm->use_noise = (rdp.other_mode_l & G_AC_DITHER) == G_AC_DITHER; cm->use_2cycle = (rdp.other_mode_h & (3U << G_MDSFT_CYCLETYPE)) == G_CYC_2CYCLE; cm->use_fog = (rdp.other_mode_l >> 30) == G_BL_CLR_FOG; + cm->light_map = (cm->alpha1 == 0x08040000); - if (cm->texture_edge) { + if (cm->texture_edge || cm->light_map) { cm->use_alpha = true; } @@ -1102,6 +1118,22 @@ static void OPTIMIZE_O3 gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t struct RGBA tmp = { 0 }; for (int a = 0; a < (cm->use_alpha ? 2 : 1 ); a++) { u8 mapping = comb->shader_input_mapping[j]; + + if (cm->light_map && mapping == CC_SHADE) { + if (a == 0) { + struct RGBA* col = &v_arr[i]->color; + printf("light: "); + buf_vbo[buf_vbo_len++] = ( (((uint16_t)col->g) << 8) | ((uint16_t)col->r) ) / 65535.0f; + printf(" %f", buf_vbo[buf_vbo_len-1]); + buf_vbo[buf_vbo_len++] = 1.0f - (( (((uint16_t)col->a) << 8) | ((uint16_t)col->b) ) / 65535.0f); + printf(", %f\n", buf_vbo[buf_vbo_len-1]); + buf_vbo[buf_vbo_len++] = 0; + } else { + buf_vbo[buf_vbo_len++] = 1; + } + continue; + } + switch (mapping) { case CC_PRIM: color = &rdp.prim_color; @@ -1577,6 +1609,8 @@ static inline uint32_t color_comb_alpha(uint32_t a, uint32_t b, uint32_t c, uint static void gfx_dp_set_combine_mode(uint32_t rgb1, uint32_t alpha1, uint32_t rgb2, uint32_t alpha2) { //printf(">>> combine: %08x %08x %08x %08x\n", rgb1, alpha1, rgb2, alpha2); + memset(&rdp.combine_mode, 0, sizeof(struct CombineMode)); + rdp.combine_mode.rgb1 = rgb1; rdp.combine_mode.alpha1 = alpha1; @@ -2030,40 +2064,7 @@ void gfx_init(struct GfxWindowManagerAPI *wapi, struct GfxRenderingAPI *rapi, co gfx_wapi->init(window_title); gfx_rapi->init(); - /* - // DO NOT COMMIT: TODO must update these! - // Used in the 120 star TAS - static uint32_t precomp_shaders[] = { - 0x01200200, - 0x00000045, - 0x00000200, - 0x01200a00, - 0x00000a00, - 0x01a00045, - 0x00000551, - 0x01045045, - 0x05a00a00, - 0x01200045, - 0x05045045, - 0x01045a00, - 0x01a00a00, - 0x0000038d, - 0x01081081, - 0x0120038d, - 0x03200045, - 0x03200a00, - 0x01a00a6f, - 0x01141045, - 0x07a00a00, - 0x05200200, - 0x03200200, - 0x09200200, - 0x0920038d, - 0x09200045 - }; - - for (size_t i = 0; i < sizeof(precomp_shaders) / sizeof(uint32_t); i++) - gfx_precomp_shaders(precomp_shaders[i]);*/ + gfx_cc_precomp(); } #ifdef EXTERNAL_DATA @@ -2357,6 +2358,15 @@ static void OPTIMIZE_O3 djui_gfx_sp_simple_tri1(uint8_t vtx1_idx, uint8_t vtx2_i */ } +void gfx_pc_precomp_shader(uint32_t rgb1, uint32_t alpha1, uint32_t rgb2, uint32_t alpha2, uint32_t flags) { + gfx_dp_set_combine_mode(rgb1, alpha1, rgb2, alpha2); + + struct CombineMode* cm = &rdp.combine_mode; + cm->flags = flags; + + gfx_lookup_or_create_color_combiner(cm); +} + void OPTIMIZE_O3 djui_gfx_run_dl(Gfx* cmd) { uint32_t opcode = cmd->words.w0 >> 24; switch (opcode) { diff --git a/src/pc/gfx/gfx_pc.h b/src/pc/gfx/gfx_pc.h index 76b066d14..b5e7f383c 100644 --- a/src/pc/gfx/gfx_pc.h +++ b/src/pc/gfx/gfx_pc.h @@ -26,6 +26,7 @@ void gfx_run(Gfx *commands); void gfx_end_frame(void); void gfx_precache_textures(void); void gfx_shutdown(void); +void gfx_pc_precomp_shader(uint32_t rgb1, uint32_t alpha1, uint32_t rgb2, uint32_t alpha2, uint32_t flags); #ifdef __cplusplus }