@@ -4067,22 +4067,8 @@ float rc_get_var(Bit32u cw, Bit32u shift, float regs[16][4], Bit32u civ)
40674067 }
40684068}
40694069
4070- void bx_geforce_c::d3d_register_combiners (gf_channel* ch, float ps_in[16 ][4 ], float out[4 ])
4071- {
4072- float regs[16 ][4 ];
4073- for (Bit32u ci = 0 ; ci < 4 ; ci++) {
4074- regs[0 ][ci] = 0 .0f ;
4075- regs[3 ][ci] = 1 .0f ;
4076- regs[4 ][ci] = ps_in[1 ][ci];
4077- regs[5 ][ci] = ps_in[2 ][ci];
4078- }
4079- regs[0xe ][3 ] = 0 .0f ;
4080- regs[0xf ][3 ] = 0 .0f ;
4081- for (Bit32u t = 0 ; t < ch->d3d_tex_coord_count ; t++) {
4082- gf_texture* tex = &ch->d3d_texture [t];
4083- if (tex->enabled )
4084- d3d_sample_texture (ch, tex, ps_in[4 + t], regs[8 + t]);
4085- }
4070+ void bx_geforce_c::d3d_register_combiners (gf_channel* ch, float regs[16 ][4 ], float out[4 ])
4071+ {
40864072 for (Bit32u s = 0 ; s < ch->d3d_combiner_control_num_stages ; s++) {
40874073 Bit32u icws[2 ] = {
40884074 ch->d3d_combiner_color_icw [s],
@@ -4310,20 +4296,14 @@ void bx_geforce_c::d3d_pixel_shader(gf_channel* ch,
43104296 for (int comp_index = 0 ; comp_index < 4 ; comp_index++)
43114297 op_result[comp_index] = floor (params[0 ][comp_index]);
43124298 break ;
4313- case 0x17 : { // TEX
4314- Bit32u tex_unit = (dst_word >> 17 ) & 0xf ;
4315- gf_texture* tex = &ch->d3d_texture [tex_unit];
4316- d3d_sample_texture (ch, tex, params[0 ], op_result);
4317- if (((dst_word >> 21 ) & 1 ) != 0 )
4318- for (int comp_index = 0 ; comp_index < 4 ; comp_index++)
4319- op_result[comp_index] = op_result[comp_index] * 2 .0f - 1 .0f ;
4320- break ;
4321- }
43224299 case 0x18 : { // TXP
43234300 float winv = 1 .0f / params[0 ][3 ];
43244301 params[0 ][0 ] *= winv;
43254302 params[0 ][1 ] *= winv;
43264303 params[0 ][2 ] *= winv;
4304+ // fallthrough
4305+ }
4306+ case 0x17 : { // TEX
43274307 Bit32u tex_unit = (dst_word >> 17 ) & 0xf ;
43284308 gf_texture* tex = &ch->d3d_texture [tex_unit];
43294309 d3d_sample_texture (ch, tex, params[0 ], op_result);
@@ -4376,6 +4356,10 @@ void bx_geforce_c::d3d_pixel_shader(gf_channel* ch,
43764356 op_result[comp_index] = dp2a;
43774357 break ;
43784358 }
4359+ case 0x34 : // TXPBEM
4360+ params[0 ][0 ] /= params[0 ][3 ];
4361+ params[0 ][1 ] /= params[0 ][3 ];
4362+ // fallthrough
43794363 case 0x33 : { // TEXBEM
43804364 float coords[3 ];
43814365 coords[0 ] = params[0 ][0 ] + params[1 ][0 ] * params[2 ][0 ] + params[1 ][1 ] * params[2 ][1 ];
@@ -5009,13 +4993,65 @@ void bx_geforce_c::d3d_triangle_clipped(gf_channel* ch, float v0[16][4], float v
50094993 float tmp_regs32[64 ][4 ];
50104994 for (int comp_index = 0 ; comp_index < 4 ; comp_index++)
50114995 tmp_regs16[0 ][comp_index] = ps_in[1 ][comp_index];
5012- if (ch->d3d_combiner_control_num_stages != 0 ) {
5013- d3d_register_combiners (ch, ps_in, tmp_regs16[0 ]);
5014- } else if (ch->d3d_shader_obj != 0 ) {
4996+ bool ps_enable = ch->d3d_shader_obj != 0 ;
4997+ bool rc_enable = ch->d3d_combiner_control_num_stages != 0 ;
4998+ float rc_regs[16 ][4 ];
4999+ if (ps_enable) {
50155000 ps_in[0 ][0 ] = xy[0 ] - ch->d3d_window_offset_x ;
50165001 ps_in[0 ][1 ] = ch->d3d_viewport_height - (xy[1 ] - ch->d3d_window_offset_y );
50175002 ps_in[0 ][2 ] = 0 .0f ;
5018- d3d_pixel_shader (ch, ps_in, tmp_regs16, tmp_regs32);
5003+ if (rc_enable)
5004+ d3d_pixel_shader (ch, ps_in, &rc_regs[8 ], tmp_regs32);
5005+ else
5006+ d3d_pixel_shader (ch, ps_in, tmp_regs16, tmp_regs32);
5007+ }
5008+ if (rc_enable) {
5009+ for (Bit32u ci = 0 ; ci < 4 ; ci++) {
5010+ rc_regs[0 ][ci] = 0 .0f ;
5011+ rc_regs[3 ][ci] = 1 .0f ;
5012+ rc_regs[4 ][ci] = ps_in[1 ][ci];
5013+ rc_regs[5 ][ci] = ps_in[2 ][ci];
5014+ }
5015+ rc_regs[0xe ][3 ] = 0 .0f ;
5016+ rc_regs[0xf ][3 ] = 0 .0f ;
5017+ if (!ps_enable) {
5018+ for (Bit32u t = 0 ; t < ch->d3d_tex_coord_count ; t++) {
5019+ switch (ch->d3d_tex_shader_op [t]) {
5020+ case 0x00 : // NONE
5021+ break ;
5022+ case 0x01 : // PROJECT2D
5023+ case 0x03 : { // CUBEMAP
5024+ gf_texture* tex = &ch->d3d_texture [t];
5025+ d3d_sample_texture (ch, tex, ps_in[4 + t], rc_regs[8 + t]);
5026+ break ;
5027+ }
5028+ case 0x06 : { // BUMPENVMAP
5029+ float * in_coords = ps_in[4 + t];
5030+ float * prev_color = rc_regs[8 + ch->d3d_tex_shader_previous [t]];
5031+ float coords[3 ];
5032+ gf_texture* tex = &ch->d3d_texture [t];
5033+ coords[0 ] = in_coords[0 ] / in_coords[3 ] +
5034+ tex->offset_matrix [0 ] * prev_color[2 ] +
5035+ tex->offset_matrix [3 ] * prev_color[1 ];
5036+ coords[1 ] = in_coords[1 ] / in_coords[3 ] +
5037+ tex->offset_matrix [1 ] * prev_color[2 ] +
5038+ tex->offset_matrix [2 ] * prev_color[1 ];
5039+ coords[2 ] = 0 .0f ;
5040+ d3d_sample_texture (ch, tex, coords, rc_regs[8 + t]);
5041+ break ;
5042+ }
5043+ default : { // not implemented
5044+ float * color = rc_regs[8 + t];
5045+ color[0 ] = 0 .0f ;
5046+ color[1 ] = 0 .5f ;
5047+ color[2 ] = 0 .5f ;
5048+ color[3 ] = 1 .0f ;
5049+ break ;
5050+ }
5051+ }
5052+ }
5053+ }
5054+ d3d_register_combiners (ch, rc_regs, tmp_regs16[0 ]);
50195055 }
50205056 float a = BX_MIN (BX_MAX (tmp_regs16[0 ][3 ], 0 .0f ), 1 .0f );
50215057 if (ch->d3d_alpha_test_enable ) {
@@ -6529,6 +6565,8 @@ void bx_geforce_c::execute_d3d(gf_channel* ch, Bit32u cls, Bit32u method, Bit32u
65296565 tex->enabled = param >> 31 ;
65306566 else
65316567 tex->enabled = (param >> 30 ) & 1 ;
6568+ if (cls == 0x0096 )
6569+ ch->d3d_tex_shader_op [texture_index] = tex->enabled ? 0x01 : 0x00 ;
65326570 } else if ((texture_method == 3 && cls == 0x0096 ) ||
65336571 (texture_method == 4 && cls != 0x0096 )) {
65346572 tex->control1 = param;
@@ -6552,6 +6590,8 @@ void bx_geforce_c::execute_d3d(gf_channel* ch, Bit32u cls, Bit32u method, Bit32u
65526590 (texture_method == 8 && cls == 0x0097 )) {
65536591 tex->pal_dma_obj = (param & 1 ) == 1 ? ch->d3d_b_obj : ch->d3d_a_obj ;
65546592 tex->pal_ofs = param & 0xffffffc0 ;
6593+ } else if (texture_method >= 10 && texture_method <= 13 && cls == 0x0097 ) {
6594+ tex->offset_matrix [texture_method - 10 ] = u.param_float ;
65556595 }
65566596 } else if (method == 0x75b )
65576597 ch->d3d_semaphore_offset = param;
@@ -6576,6 +6616,12 @@ void bx_geforce_c::execute_d3d(gf_channel* ch, Bit32u cls, Bit32u method, Bit32u
65766616 (method == 0x23f && cls == 0x0497 )) {
65776617 ch->d3d_combiner_control = param;
65786618 ch->d3d_combiner_control_num_stages = param & 0xf ;
6619+ } else if (method == 0x79c && cls == 0x0097 ) {
6620+ for (Bit32u i = 0 ; i < 4 ; i++)
6621+ ch->d3d_tex_shader_op [i] = (param >> (i * 5 )) & 0x1f ;
6622+ } else if (method == 0x79e && cls == 0x0097 ) {
6623+ ch->d3d_tex_shader_previous [2 ] = (param >> 16 ) & 3 ;
6624+ ch->d3d_tex_shader_previous [3 ] = (param >> 20 ) & 3 ;
65796625 } else if (method == 0x7a5 ) {
65806626 ch->d3d_transform_execution_mode = param;
65816627 } else if (method == 0x7a7 ) {
0 commit comments