From b92634dea644a6061c262f2d2a4e4b03f3e9fff1 Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 29 Aug 2016 17:29:55 +0100 Subject: [PATCH] Added missing Alpha+YIQ texture format to Voodoo. Added depth source select to Voodoo. Fixes graphics issues with Requiem : Avenging Angel --- src/vid_voodoo.c | 37 +++++-- src/vid_voodoo_codegen_x86-64.h | 173 ++++++++++++++++++++++++++++++++ src/vid_voodoo_codegen_x86.h | 171 +++++++++++++++++++++++++++++++ 3 files changed, 371 insertions(+), 10 deletions(-) diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 2b0aa96..b365756 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -597,6 +597,8 @@ enum FBZ_DEPTH_BIAS = (1 << 16), + FBZ_DEPTH_SOURCE = (1 << 20), + FBZ_PARAM_ADJUST = (1 << 26) }; @@ -608,6 +610,7 @@ enum TEX_I8 = 0x3, TEX_AI8 = 0x4, TEX_PAL8 = 0x5, + TEX_A8Y4I2Q2 = 0x9, TEX_R5G6B5 = 0xa, TEX_ARGB1555 = 0xb, TEX_ARGB4444 = 0xc, @@ -1151,6 +1154,13 @@ static inline void tex_read(voodoo_state_t *state, voodoo_texture_state_t *textu state->tex_a = 0xff; break; + case TEX_A8Y4I2Q2: + state->tex_r = state->palette[dat & 0xff].rgba.r; + state->tex_g = state->palette[dat & 0xff].rgba.g; + state->tex_b = state->palette[dat & 0xff].rgba.b; + state->tex_a = dat >> 8; + break; + case TEX_R5G6B5: state->tex_r = rgb565[dat].r; state->tex_g = rgb565[dat].g; @@ -1289,6 +1299,13 @@ static inline void tex_read_4(voodoo_state_t *state, voodoo_texture_state_t *tex state->tex_a = 0xff; break; + case TEX_A8Y4I2Q2: + state->tex_r = (state->palette[dat[0] & 0xff].rgba.r * d[0] + state->palette[dat[1] & 0xff].rgba.r * d[1] + state->palette[dat[2] & 0xff].rgba.r * d[2] + state->palette[dat[3] & 0xff].rgba.r * d[3]) >> 8; + state->tex_g = (state->palette[dat[0] & 0xff].rgba.g * d[0] + state->palette[dat[1] & 0xff].rgba.g * d[1] + state->palette[dat[2] & 0xff].rgba.g * d[2] + state->palette[dat[3] & 0xff].rgba.g * d[3]) >> 8; + state->tex_b = (state->palette[dat[0] & 0xff].rgba.b * d[0] + state->palette[dat[1] & 0xff].rgba.b * d[1] + state->palette[dat[2] & 0xff].rgba.b * d[2] + state->palette[dat[3] & 0xff].rgba.b * d[3]) >> 8; + state->tex_a = ((dat[0] >> 8) * d[0] + (dat[1] >> 8) * d[1] + (dat[2] >> 8) * d[2] + (dat[3] >> 8) * d[3]) >> 8; + break; + case TEX_R5G6B5: state->tex_r = (rgb565[dat[0]].r * d[0] + rgb565[dat[1]].r * d[1] + rgb565[dat[2]].r * d[2] + rgb565[dat[3]].r * d[3]) >> 8; state->tex_g = (rgb565[dat[0]].g * d[0] + rgb565[dat[1]].g * d[1] + rgb565[dat[2]].g * d[2] + rgb565[dat[3]].g * d[3]) >> 8; @@ -1402,7 +1419,7 @@ static inline void voodoo_get_texture(voodoo_t *voodoo, voodoo_params_t *params, } -#define DEPTH_TEST() \ +#define DEPTH_TEST(comp_depth) \ do \ { \ switch (depth_op) \ @@ -1411,42 +1428,42 @@ static inline void voodoo_get_texture(voodoo_t *voodoo, voodoo_params_t *params, voodoo->fbiZFuncFail++; \ goto skip_pixel; \ case DEPTHOP_LESSTHAN: \ - if (!(new_depth < old_depth)) \ + if (!(comp_depth < old_depth)) \ { \ voodoo->fbiZFuncFail++; \ goto skip_pixel; \ } \ break; \ case DEPTHOP_EQUAL: \ - if (!(new_depth == old_depth)) \ + if (!(comp_depth == old_depth)) \ { \ voodoo->fbiZFuncFail++; \ goto skip_pixel; \ } \ break; \ case DEPTHOP_LESSTHANEQUAL: \ - if (!(new_depth <= old_depth)) \ + if (!(comp_depth <= old_depth)) \ { \ voodoo->fbiZFuncFail++; \ goto skip_pixel; \ } \ break; \ case DEPTHOP_GREATERTHAN: \ - if (!(new_depth > old_depth)) \ + if (!(comp_depth > old_depth)) \ { \ voodoo->fbiZFuncFail++; \ goto skip_pixel; \ } \ break; \ case DEPTHOP_NOTEQUAL: \ - if (!(new_depth != old_depth)) \ + if (!(comp_depth != old_depth)) \ { \ voodoo->fbiZFuncFail++; \ goto skip_pixel; \ } \ break; \ case DEPTHOP_GREATERTHANEQUAL: \ - if (!(new_depth >= old_depth)) \ + if (!(comp_depth >= old_depth)) \ { \ voodoo->fbiZFuncFail++; \ goto skip_pixel; \ @@ -1971,7 +1988,7 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood { uint16_t old_depth = aux_mem[x]; - DEPTH_TEST(); + DEPTH_TEST((params->fbzMode & FBZ_DEPTH_SOURCE) ? (params->zaColor & 0xffff) : new_depth); } dat = fb_mem[x]; @@ -3349,7 +3366,7 @@ static void voodoo_fb_writew(uint32_t addr, uint16_t val, void *p) { uint16_t old_depth = *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]); - DEPTH_TEST(); + DEPTH_TEST(new_depth); } if ((params->fbzMode & FBZ_CHROMAKEY) && @@ -3490,7 +3507,7 @@ static void voodoo_fb_writel(uint32_t addr, uint32_t val, void *p) { uint16_t old_depth = *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]); - DEPTH_TEST(); + DEPTH_TEST(new_depth); } if ((params->fbzMode & FBZ_CHROMAKEY) && diff --git a/src/vid_voodoo_codegen_x86-64.h b/src/vid_voodoo_codegen_x86-64.h index da37049..932be77 100644 --- a/src/vid_voodoo_codegen_x86-64.h +++ b/src/vid_voodoo_codegen_x86-64.h @@ -257,6 +257,13 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xb7); addbyte(0x1c); addbyte(0x59); + if (params->fbzMode & FBZ_DEPTH_SOURCE) + { + addbyte(0x0f); /*MOVZX EAX, zaColor[RSI]*/ + addbyte(0xb7); + addbyte(0x86); + addlong(offsetof(voodoo_params_t, zaColor)); + } addbyte(0x39); /*CMP EAX, EBX*/ addbyte(0xd8); if (depthop == DEPTHOP_LESSTHAN) @@ -1308,6 +1315,147 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addlong(0xff000000); break; + case TEX_A8Y4I2Q2: + addbyte(0x48); /*MOV RBP, state->palette[EDI]*/ + addbyte(0x8b); + addbyte(0xaf); + addlong(offsetof(voodoo_state_t, palette)); + addbyte(0x0f); /*MOVZX ECX, AL*/ + addbyte(0xb6); + addbyte(0xc8); + addbyte(0x66); /*MOVD XMM0, [EBP+ECX*4]*/ + addbyte(0x0f); + addbyte(0x6e); + addbyte(0x44); + addbyte(0x8d); + addbyte(0); + addbyte(0x0f); /*MOVZX ECX, AH*/ + addbyte(0xb6); + addbyte(0xcc); + addbyte(0x66); /*PUNPCKLBW XMM0, XMM2*/ + addbyte(0x0f); + addbyte(0x60); + addbyte(0xc2); + addbyte(0xc1); /*SHR EAX, 16*/ + addbyte(0xe8); + addbyte(16); + addbyte(0x66); /*PINSRW XMM0, ECX, 3*/ + addbyte(0x0f); + addbyte(0xc4); + addbyte(0xc1); + addbyte(3); + addbyte(0x0f); /*MOVZX ECX, AL*/ + addbyte(0xb6); + addbyte(0xc8); + addbyte(0x0f); /*MOVZX EAX, AH*/ + addbyte(0xb6); + addbyte(0xc4); + addbyte(0x66); /*MOVD XMM1, [EBP+ECX*4]*/ + addbyte(0x0f); + addbyte(0x6e); + addbyte(0x4c); + addbyte(0x8d); + addbyte(0); + addbyte(0x66); /*PMULLW XMM0, bilinear_lookup[ESI]*/ + addbyte(0x0f); + addbyte(0xd5); + addbyte(0x06); + addbyte(0x0f); /*MOVZX ECX, DL*/ + addbyte(0xb6); + addbyte(0xca); + addbyte(0x66); /*PUNPCKLBW XMM1, XMM2*/ + addbyte(0x0f); + addbyte(0x60); + addbyte(0xca); + addbyte(0x66); /*PINSRW XMM1, EAX, 3*/ + addbyte(0x0f); + addbyte(0xc4); + addbyte(0xc8); + addbyte(3); + addbyte(0x66); /*MOVD XMM3, [EBP+ECX*4]*/ + addbyte(0x0f); + addbyte(0x6e); + addbyte(0x5c); + addbyte(0x8d); + addbyte(0); + addbyte(0x0f); /*MOVZX ECX, DH*/ + addbyte(0xb6); + addbyte(0xce); + addbyte(0xc1); /*SHR EDX, 16*/ + addbyte(0xea); + addbyte(16); + addbyte(0x66); /*PUNPCKLBW XMM3, XMM2*/ + addbyte(0x0f); + addbyte(0x60); + addbyte(0xda); + addbyte(0x66); /*PMULLW XMM1, bilinear_lookup[ESI]+0x10*/ + addbyte(0x0f); + addbyte(0xd5); + addbyte(0x4e); + addbyte(0x10); + addbyte(0x66); /*PINSRW XMM3, ECX, 3*/ + addbyte(0x0f); + addbyte(0xc4); + addbyte(0xd9); + addbyte(3); + addbyte(0x0f); /*MOVZX ECX, DL*/ + addbyte(0xb6); + addbyte(0xca); + addbyte(0x66); /*PADDW XMM0, XMM1*/ + addbyte(0x0f); + addbyte(0xfd); + addbyte(0xc1); + addbyte(0x66); /*MOVD XMM1, [EBP+ECX*4]*/ + addbyte(0x0f); + addbyte(0x6e); + addbyte(0x4c); + addbyte(0x8d); + addbyte(0); + addbyte(0x0f); /*MOVZX ECX, DH*/ + addbyte(0xb6); + addbyte(0xce); + addbyte(0x66); /*PUNPCKLBW XMM1, XMM2*/ + addbyte(0x0f); + addbyte(0x60); + addbyte(0xca); + addbyte(0x66); /*PMULLW XMM3, bilinear_lookup[ESI]+0x20*/ + addbyte(0x0f); + addbyte(0xd5); + addbyte(0x5e); + addbyte(0x20); + addbyte(0x66); /*PINSR1 XMM1, ECX, 3*/ + addbyte(0x0f); + addbyte(0xc4); + addbyte(0xc9); + addbyte(3); + addbyte(0x66); /*PADDW XMM0, XMM3*/ + addbyte(0x0f); + addbyte(0xfd); + addbyte(0xc3); + addbyte(0x66); /*PMULLW XMM1, bilinear_lookup[ESI]+0x30*/ + addbyte(0x0f); + addbyte(0xd5); + addbyte(0x4e); + addbyte(0x30); + addbyte(0x66); /*PADDW XMM0, XMM1*/ + addbyte(0x0f); + addbyte(0xfd); + addbyte(0xc1); + addbyte(0x66); /*PSRLW XMM0, 8*/ + addbyte(0x0f); + addbyte(0x71); + addbyte(0xd0); + addbyte(8); + addbyte(0x66); /*PACKUSWB XMM0, XMM0*/ + addbyte(0x0f); + addbyte(0x67); + addbyte(0xc0); + addbyte(0x66); /*MOV EAX, XMM0*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0xc0); + break; + case TEX_R5G6B5: addbyte(0x49); /*MOV R8, rgb565*/ addbyte(0xb8); @@ -2074,6 +2222,31 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addlong(0xff000000); break; + case TEX_A8Y4I2Q2: + addbyte(0x48); /*MOV RBP, state->palette[EDI]*/ + addbyte(0x8b); + addbyte(0xaf); + addlong(offsetof(voodoo_state_t, palette)); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); + addbyte(0x25); /*AND EAX, 0x000000ff*/ + addlong(0x000000ff); + addbyte(0x8b); /*MOV EAX, [EBP+EAX*4]*/ + addbyte(0x44); + addbyte(0x85); + addbyte(0); + addbyte(0xc1); /*SHL EBX, 16*/ + addbyte(0xe3); + addbyte(16); + addbyte(0x81); /*AND EBX, 0xff000000*/ + addbyte(0xe3); + addlong(0xff000000); + addbyte(0x25); /*AND EAX, 0x00ffffff*/ + addlong(0x00ffffff); + addbyte(0x09); /*OR EAX, EBX*/ + addbyte(0xd8); + break; + case TEX_R5G6B5: addbyte(0x49); /*MOV R8, rgb565*/ addbyte(0xb8); diff --git a/src/vid_voodoo_codegen_x86.h b/src/vid_voodoo_codegen_x86.h index f89fd8c..a55f4bf 100644 --- a/src/vid_voodoo_codegen_x86.h +++ b/src/vid_voodoo_codegen_x86.h @@ -236,6 +236,13 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xb7); addbyte(0x1c); addbyte(0x59); + if (params->fbzMode & FBZ_DEPTH_SOURCE) + { + addbyte(0x0f); /*MOVZX EAX, zaColor[ESI]*/ + addbyte(0xb7); + addbyte(0x86); + addlong(offsetof(voodoo_params_t, zaColor)); + } addbyte(0x39); /*CMP EAX, EBX*/ addbyte(0xd8); if (depthop == DEPTHOP_LESSTHAN) @@ -1286,6 +1293,146 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addlong(0xff000000); break; + case TEX_A8Y4I2Q2: + addbyte(0x8b); /*MOV EBP, state->palette[EDI]*/ + addbyte(0xaf); + addlong(offsetof(voodoo_state_t, palette)); + addbyte(0x0f); /*MOVZX ECX, AL*/ + addbyte(0xb6); + addbyte(0xc8); + addbyte(0x66); /*MOVD XMM0, [EBP+ECX*4]*/ + addbyte(0x0f); + addbyte(0x6e); + addbyte(0x44); + addbyte(0x8d); + addbyte(0); + addbyte(0x0f); /*MOVZX ECX, AH*/ + addbyte(0xb6); + addbyte(0xcc); + addbyte(0x66); /*PUNPCKLBW XMM0, XMM2*/ + addbyte(0x0f); + addbyte(0x60); + addbyte(0xc2); + addbyte(0xc1); /*SHR EAX, 16*/ + addbyte(0xe8); + addbyte(16); + addbyte(0x66); /*PINSRW XMM0, ECX, 3*/ + addbyte(0x0f); + addbyte(0xc4); + addbyte(0xc1); + addbyte(3); + addbyte(0x0f); /*MOVZX ECX, AL*/ + addbyte(0xb6); + addbyte(0xc8); + addbyte(0x0f); /*MOVZX EAX, AH*/ + addbyte(0xb6); + addbyte(0xc4); + addbyte(0x66); /*MOVD XMM1, [EBP+ECX*4]*/ + addbyte(0x0f); + addbyte(0x6e); + addbyte(0x4c); + addbyte(0x8d); + addbyte(0); + addbyte(0x66); /*PMULLW XMM0, bilinear_lookup[ESI]*/ + addbyte(0x0f); + addbyte(0xd5); + addbyte(0x06); + addbyte(0x0f); /*MOVZX ECX, DL*/ + addbyte(0xb6); + addbyte(0xca); + addbyte(0x66); /*PUNPCKLBW XMM1, XMM2*/ + addbyte(0x0f); + addbyte(0x60); + addbyte(0xca); + addbyte(0x66); /*PINSRW XMM1, EAX, 3*/ + addbyte(0x0f); + addbyte(0xc4); + addbyte(0xc8); + addbyte(3); + addbyte(0x66); /*MOVD XMM3, [EBP+ECX*4]*/ + addbyte(0x0f); + addbyte(0x6e); + addbyte(0x5c); + addbyte(0x8d); + addbyte(0); + addbyte(0x0f); /*MOVZX ECX, DH*/ + addbyte(0xb6); + addbyte(0xce); + addbyte(0xc1); /*SHR EDX, 16*/ + addbyte(0xea); + addbyte(16); + addbyte(0x66); /*PUNPCKLBW XMM3, XMM2*/ + addbyte(0x0f); + addbyte(0x60); + addbyte(0xda); + addbyte(0x66); /*PMULLW XMM1, bilinear_lookup[ESI]+0x10*/ + addbyte(0x0f); + addbyte(0xd5); + addbyte(0x4e); + addbyte(0x10); + addbyte(0x66); /*PINSRW XMM3, ECX, 3*/ + addbyte(0x0f); + addbyte(0xc4); + addbyte(0xd9); + addbyte(3); + addbyte(0x0f); /*MOVZX ECX, DL*/ + addbyte(0xb6); + addbyte(0xca); + addbyte(0x66); /*PADDW XMM0, XMM1*/ + addbyte(0x0f); + addbyte(0xfd); + addbyte(0xc1); + addbyte(0x66); /*MOVD XMM1, [EBP+ECX*4]*/ + addbyte(0x0f); + addbyte(0x6e); + addbyte(0x4c); + addbyte(0x8d); + addbyte(0); + addbyte(0x0f); /*MOVZX ECX, DH*/ + addbyte(0xb6); + addbyte(0xce); + addbyte(0x66); /*PUNPCKLBW XMM1, XMM2*/ + addbyte(0x0f); + addbyte(0x60); + addbyte(0xca); + addbyte(0x66); /*PMULLW XMM3, bilinear_lookup[ESI]+0x20*/ + addbyte(0x0f); + addbyte(0xd5); + addbyte(0x5e); + addbyte(0x20); + addbyte(0x66); /*PINSR1 XMM1, ECX, 3*/ + addbyte(0x0f); + addbyte(0xc4); + addbyte(0xc9); + addbyte(3); + addbyte(0x66); /*PADDW XMM0, XMM3*/ + addbyte(0x0f); + addbyte(0xfd); + addbyte(0xc3); + addbyte(0x66); /*PMULLW XMM1, bilinear_lookup[ESI]+0x30*/ + addbyte(0x0f); + addbyte(0xd5); + addbyte(0x4e); + addbyte(0x30); + addbyte(0x66); /*PADDW XMM0, XMM1*/ + addbyte(0x0f); + addbyte(0xfd); + addbyte(0xc1); + addbyte(0x66); /*PSRLW XMM0, 8*/ + addbyte(0x0f); + addbyte(0x71); + addbyte(0xd0); + addbyte(8); + addbyte(0x66); /*PACKUSWB XMM0, XMM0*/ + addbyte(0x0f); + addbyte(0x67); + addbyte(0xc0); + addbyte(0x66); /*MOV EAX, XMM0*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0xc0); + break; + case TEX_R5G6B5: addbyte(0x0f); /*MOVZX ECX, AX*/ addbyte(0xb7); @@ -2037,6 +2184,30 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addlong(0xff000000); break; + case TEX_A8Y4I2Q2: + addbyte(0x8b); /*MOV EBP, state->palette[EDI]*/ + addbyte(0xaf); + addlong(offsetof(voodoo_state_t, palette)); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); + addbyte(0x25); /*AND EAX, 0x000000ff*/ + addlong(0x000000ff); + addbyte(0x8b); /*MOV EAX, [EBP+EAX*4]*/ + addbyte(0x44); + addbyte(0x85); + addbyte(0); + addbyte(0xc1); /*SHL EBX, 16*/ + addbyte(0xe3); + addbyte(16); + addbyte(0x81); /*AND EBX, 0xff000000*/ + addbyte(0xe3); + addlong(0xff000000); + addbyte(0x25); /*AND EAX, 0x00ffffff*/ + addlong(0x00ffffff); + addbyte(0x09); /*OR EAX, EBX*/ + addbyte(0xd8); + break; + case TEX_R5G6B5: addbyte(0x8b); /*MOV EAX, rgb565[EAX*4]*/ addbyte(0x04);