Voodoo stippling support for 3D

This commit is contained in:
Cacodemon345
2025-12-21 22:00:24 +06:00
parent 2ad2579d42
commit e59bb4dc2e
4 changed files with 120 additions and 8 deletions

View File

@@ -653,14 +653,15 @@ codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *pa
static inline void
voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int depthop)
{
int block_pos = 0;
int z_skip_pos = 0;
int a_skip_pos = 0;
int amask_skip_pos = 0;
int chroma_skip_pos = 0;
int depth_jump_pos = 0;
int depth_jump_pos2 = 0;
int loop_jump_pos = 0;
int block_pos = 0;
int z_skip_pos = 0;
int a_skip_pos = 0;
int amask_skip_pos = 0;
int stipple_skip_pos = 0;
int chroma_skip_pos = 0;
int depth_jump_pos = 0;
int depth_jump_pos2 = 0;
int loop_jump_pos = 0;
#if 0
xmm_01_w = (__m128i)0x0001000100010001ull;
xmm_ff_w = (__m128i)0x00ff00ff00ff00ffull;
@@ -766,6 +767,69 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params,
addquad((uint64_t) (uintptr_t) &i_00_ff_w);
loop_jump_pos = block_pos;
if (params->fbzMode & FBZ_STIPPLE) {
/* Stipple enabled. */
if (params->fbzMode & FBZ_STIPPLE_PATT) {
/* x64's BT instruction is too slow. So use TEST instead. */
addbyte(0x4c); /* MOV RBX, R14(real_y)*/
addbyte(0x89);
addbyte(0xf3);
addbyte(0x83); /* AND EBX, 3 */
addbyte(0xe3);
addbyte(0x03);
addbyte(0xc1); /* SHL EBX, 3 */
addbyte(0xe3);
addbyte(0x03);
addbyte(0x8b); /*MOV EAX, state->x[EDI]*/
addbyte(0x87);
addlong(offsetof(voodoo_state_t, x));
addbyte(0xf7); /* NOT EAX */
addbyte(0xd0);
addbyte(0x83); /* AND EAX, 7 */
addbyte(0xe0);
addbyte(0x07);
addbyte(0x09); /* OR EAX, EBX */
addbyte(0xc3);
addbyte(0x88); /* MOV CL, AL */
addbyte(0xc1);
addbyte(0xb8); /* MOV EAX, 1*/
addlong(1);
addbyte(0xd3); /* SHL EAX, CL */
addbyte(0xe0);
addbyte(0x85); /* TEST state->stipple[EDI], EAX */
addbyte(0x87);
addlong(offsetof(voodoo_state_t, stipple));
addbyte(0x0f); /* JZ stipple_skip_pos */
addbyte(0x84);
stipple_skip_pos = block_pos;
addlong(0);
} else {
addbyte(0xd1); /* ROR state->stipple[EDI], 1*/
addbyte(0x8f);
addlong(offsetof(voodoo_state_t, stipple));
addbyte(0xf7); /* TEST state->stipple[EDI], 0x80000000 */
addbyte(0x87);
addlong(offsetof(voodoo_state_t, stipple));
addlong(0x80000000);
addbyte(0x0f); /* JZ stipple_skip_pos */
addbyte(0x84);
stipple_skip_pos = block_pos;
addlong(0);
}
}
addbyte(0x4c); /*MOV RSI, R15*/
addbyte(0x89);
addbyte(0xfe);
@@ -3190,6 +3254,8 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params,
*(uint32_t *) &code_block[chroma_skip_pos] = (block_pos - chroma_skip_pos) - 4;
if (amask_skip_pos)
*(uint32_t *) &code_block[amask_skip_pos] = (block_pos - amask_skip_pos) - 4;
if (stipple_skip_pos)
*(uint32_t *) &code_block[stipple_skip_pos] = (block_pos - stipple_skip_pos) - 4;
addbyte(0x4c); /*MOV RSI, R15*/
addbyte(0x89);

View File

@@ -358,6 +358,7 @@ enum {
enum {
FBZ_CHROMAKEY = (1 << 1),
FBZ_STIPPLE = (1 << 2),
FBZ_W_BUFFER = (1 << 3),
FBZ_DEPTH_ENABLE = (1 << 4),
@@ -366,6 +367,8 @@ enum {
FBZ_DEPTH_WMASK = (1 << 10),
FBZ_DITHER_2x2 = (1 << 11),
FBZ_STIPPLE_PATT = (1 << 12),
FBZ_ALPHA_MASK = (1 << 13),
FBZ_DRAW_FRONT = 0x0000,

View File

@@ -254,6 +254,19 @@ voodoo_fb_writew(uint32_t addr, uint16_t val, void *priv)
int colbfog_g = 0;
int colbfog_b = 0;
if (params->fbzMode & FBZ_STIPPLE) {
if (params->fbzMode & FBZ_STIPPLE_PATT) {
int index = ((y & 3) << 3) | (~x & 7);
if (!(params->stipple & (1 << index)))
goto skip_pixel;
} else {
voodoo->params.stipple = (voodoo->params.stipple << 1) | (voodoo->params.stipple >> 31);
if (!(voodoo->params.stipple & 0x80000000)) {
goto skip_pixel;
}
}
}
if (params->fbzMode & FBZ_DEPTH_ENABLE) {
uint16_t old_depth = *(uint16_t *) (&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]);
@@ -449,6 +462,19 @@ voodoo_fb_writel(uint32_t addr, uint32_t val, void *priv)
int colbfog_g = 0;
int colbfog_b = 0;
if (params->fbzMode & FBZ_STIPPLE) {
if (params->fbzMode & FBZ_STIPPLE_PATT) {
int index = ((y & 3) << 3) | (~(x + c) & 7);
if (!(params->stipple & (1 << index)))
goto skip_pixel;
} else {
voodoo->params.stipple = (voodoo->params.stipple << 1) | (voodoo->params.stipple >> 31);
if (!(voodoo->params.stipple & 0x80000000)) {
goto skip_pixel;
}
}
}
if (params->fbzMode & FBZ_DEPTH_ENABLE) {
uint16_t old_depth = *(uint16_t *) (&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]);

View File

@@ -88,6 +88,8 @@ typedef struct voodoo_state_t {
uint32_t texBaseAddr;
int lod_frac[2];
int stipple;
} voodoo_state_t;
#ifdef ENABLE_VOODOO_RENDER_LOG
@@ -990,6 +992,20 @@ voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *
w_depth = 0xffff;
}
if (params->fbzMode & FBZ_STIPPLE) {
if (params->fbzMode & FBZ_STIPPLE_PATT) {
int index = ((real_y & 3) << 3) | (~x & 7);
if (!(state->stipple & (1 << index)))
goto skip_pixel;
} else {
state->stipple = (state->stipple << 1) | (state->stipple >> 31);
if (!(state->stipple & 0x80000000)) {
goto skip_pixel;
}
}
}
#if 0
w_depth = CLAMP16(w_depth);
#endif
@@ -1560,6 +1576,7 @@ voodoo_render_log("voodoo_triangle %i %i %i : vA %f, %f vB %f, %f vC %f, %f f
if (lodbias & 0x20)
lodbias |= ~0x3f;
state.tmu[1].lod = LOD + (lodbias << 6);
state.stipple = params->stipple;
voodoo_half_triangle(voodoo, params, &state, vertexAy_adjusted, vertexCy_adjusted, odd_even);
}