Commit d60ece20 authored by Stefan Dösinger's avatar Stefan Dösinger Committed by Alexandre Julliard

wined3d: Implement secondary color in the arbfp ffp pipeline.

parent 8b1727ae
...@@ -2221,10 +2221,11 @@ const shader_backend_t arb_program_shader_backend = { ...@@ -2221,10 +2221,11 @@ const shader_backend_t arb_program_shader_backend = {
}; };
/* ARB_fragment_program fixed function pipeline replacement definitions */ /* ARB_fragment_program fixed function pipeline replacement definitions */
#define ARB_FFP_CONST_TFACTOR 0 #define ARB_FFP_CONST_TFACTOR 0
#define ARB_FFP_CONST_CONSTANT(i) ((ARB_FFP_CONST_TFACTOR) + 1 + i) #define ARB_FFP_CONST_SPECULAR_ENABLE ((ARB_FFP_CONST_TFACTOR) + 1)
#define ARB_FFP_CONST_BUMPMAT(i) ((ARB_FFP_CONST_CONSTANT(7)) + 1 + i) #define ARB_FFP_CONST_CONSTANT(i) ((ARB_FFP_CONST_SPECULAR_ENABLE) + 1 + i)
#define ARB_FFP_CONST_LUMINANCE(i) ((ARB_FFP_CONST_BUMPMAT(7)) + 1 + i) #define ARB_FFP_CONST_BUMPMAT(i) ((ARB_FFP_CONST_CONSTANT(7)) + 1 + i)
#define ARB_FFP_CONST_LUMINANCE(i) ((ARB_FFP_CONST_BUMPMAT(7)) + 1 + i)
struct arbfp_ffp_desc struct arbfp_ffp_desc
{ {
...@@ -2340,6 +2341,31 @@ static void state_texfactor_arbfp(DWORD state, IWineD3DStateBlockImpl *statebloc ...@@ -2340,6 +2341,31 @@ static void state_texfactor_arbfp(DWORD state, IWineD3DStateBlockImpl *statebloc
} }
} }
static void state_arb_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
float col[4];
IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
/* Do not overwrite pixel shader constants if a pshader is in use */
if(use_ps(device)) return;
if(stateblock->renderState[WINED3DRS_SPECULARENABLE]) {
/* The specular color has no alpha */
col[0] = 1.0; col[1] = 1.0;
col[2] = 1.0; col[3] = 0.0;
} else {
col[0] = 0.0; col[1] = 0.0;
col[2] = 0.0; col[3] = 0.0;
}
GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_SPECULAR_ENABLE, col));
checkGLcall("glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_SPECULAR_ENABLE, col)");
if(device->shader_backend == &arb_program_shader_backend) {
device = stateblock->wineD3DDevice;
device->activeContext->pshader_const_dirty[ARB_FFP_CONST_SPECULAR_ENABLE] = 1;
device->highest_dirty_ps_const = max(device->highest_dirty_ps_const, ARB_FFP_CONST_SPECULAR_ENABLE + 1);
}
}
static void set_bumpmat_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { static void set_bumpmat_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE; DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
IWineD3DDeviceImpl *device = stateblock->wineD3DDevice; IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
...@@ -2474,7 +2500,7 @@ static const char *get_argreg(SHADER_BUFFER *buffer, DWORD argnum, unsigned int ...@@ -2474,7 +2500,7 @@ static const char *get_argreg(SHADER_BUFFER *buffer, DWORD argnum, unsigned int
return ret; return ret;
} }
static void gen_ffp_instr(SHADER_BUFFER *buffer, unsigned int stage, BOOL color, BOOL alpha, BOOL last, static void gen_ffp_instr(SHADER_BUFFER *buffer, unsigned int stage, BOOL color, BOOL alpha,
DWORD dst, DWORD op, DWORD dw_arg0, DWORD dw_arg1, DWORD dw_arg2) { DWORD dst, DWORD op, DWORD dw_arg0, DWORD dw_arg1, DWORD dw_arg2) {
const char *dstmask, *dstreg, *arg0, *arg1, *arg2; const char *dstmask, *dstreg, *arg0, *arg1, *arg2;
unsigned int mul = 1; unsigned int mul = 1;
...@@ -2484,9 +2510,7 @@ static void gen_ffp_instr(SHADER_BUFFER *buffer, unsigned int stage, BOOL color, ...@@ -2484,9 +2510,7 @@ static void gen_ffp_instr(SHADER_BUFFER *buffer, unsigned int stage, BOOL color,
else if(color) dstmask = ".rgb"; else if(color) dstmask = ".rgb";
else dstmask = ".a"; else dstmask = ".a";
if(dst == tempreg && last) FIXME("Last texture stage writes to D3DTA_TEMP\n");
if(dst == tempreg) dstreg = "tempreg"; if(dst == tempreg) dstreg = "tempreg";
else if(last) dstreg = "result.color";
else dstreg = "ret"; else dstreg = "ret";
arg0 = get_argreg(buffer, 0, stage, dw_arg0); arg0 = get_argreg(buffer, 0, stage, dw_arg0);
...@@ -2627,8 +2651,8 @@ static GLuint gen_arbfp_ffp_shader(struct ffp_settings *settings, IWineD3DStateB ...@@ -2627,8 +2651,8 @@ static GLuint gen_arbfp_ffp_shader(struct ffp_settings *settings, IWineD3DStateB
GLuint ret; GLuint ret;
DWORD arg0, arg1, arg2; DWORD arg0, arg1, arg2;
BOOL tempreg_used = FALSE, tfactor_used = FALSE; BOOL tempreg_used = FALSE, tfactor_used = FALSE;
BOOL last = FALSE;
BOOL op_equal; BOOL op_equal;
const char *final_combiner_src = "ret";
/* Find out which textures are read */ /* Find out which textures are read */
for(stage = 0; stage < MAX_TEXTURES; stage++) { for(stage = 0; stage < MAX_TEXTURES; stage++) {
...@@ -2712,6 +2736,7 @@ static GLuint gen_arbfp_ffp_shader(struct ffp_settings *settings, IWineD3DStateB ...@@ -2712,6 +2736,7 @@ static GLuint gen_arbfp_ffp_shader(struct ffp_settings *settings, IWineD3DStateB
if(tfactor_used) { if(tfactor_used) {
shader_addline(&buffer, "PARAM tfactor = program.env[%u];\n", ARB_FFP_CONST_TFACTOR); shader_addline(&buffer, "PARAM tfactor = program.env[%u];\n", ARB_FFP_CONST_TFACTOR);
} }
shader_addline(&buffer, "PARAM specular_enable = program.env[%u];\n", ARB_FFP_CONST_SPECULAR_ENABLE);
if(settings->sRGB_write) { if(settings->sRGB_write) {
shader_addline(&buffer, "PARAM srgb_mul_low = {%f, %f, %f, 1.0};\n", shader_addline(&buffer, "PARAM srgb_mul_low = {%f, %f, %f, 1.0};\n",
...@@ -2808,15 +2833,9 @@ static GLuint gen_arbfp_ffp_shader(struct ffp_settings *settings, IWineD3DStateB ...@@ -2808,15 +2833,9 @@ static GLuint gen_arbfp_ffp_shader(struct ffp_settings *settings, IWineD3DStateB
for(stage = 0; stage < MAX_TEXTURES; stage++) { for(stage = 0; stage < MAX_TEXTURES; stage++) {
if(settings->op[stage].cop == WINED3DTOP_DISABLE) { if(settings->op[stage].cop == WINED3DTOP_DISABLE) {
if(stage == 0) { if(stage == 0) {
shader_addline(&buffer, "MOV result.color, fragment.color.primary;\n"); final_combiner_src = "fragment.color.primary";
} }
break; break;
} else if(settings->sRGB_write) {
last = FALSE;
} else if(stage == (MAX_TEXTURES - 1)) {
last = TRUE;
} else if(settings->op[stage + 1].cop == WINED3DTOP_DISABLE) {
last = TRUE;
} }
if(settings->op[stage].cop == WINED3DTOP_SELECTARG1 && if(settings->op[stage].cop == WINED3DTOP_SELECTARG1 &&
...@@ -2839,33 +2858,32 @@ static GLuint gen_arbfp_ffp_shader(struct ffp_settings *settings, IWineD3DStateB ...@@ -2839,33 +2858,32 @@ static GLuint gen_arbfp_ffp_shader(struct ffp_settings *settings, IWineD3DStateB
} }
if(settings->op[stage].aop == WINED3DTOP_DISABLE) { if(settings->op[stage].aop == WINED3DTOP_DISABLE) {
gen_ffp_instr(&buffer, stage, TRUE, FALSE, last, settings->op[stage].dst, gen_ffp_instr(&buffer, stage, TRUE, FALSE, settings->op[stage].dst,
settings->op[stage].cop, settings->op[stage].carg0, settings->op[stage].cop, settings->op[stage].carg0,
settings->op[stage].carg1, settings->op[stage].carg2); settings->op[stage].carg1, settings->op[stage].carg2);
if(last && stage == 0) { if(stage == 0) {
shader_addline(&buffer, "MOV result.color.a, fragment.color.primary.a;\n");
} else if(last) {
shader_addline(&buffer, "MOV result.color.a, ret.a;\n");
} else if(stage == 0) {
shader_addline(&buffer, "MOV ret.a, fragment.color.primary.a;\n"); shader_addline(&buffer, "MOV ret.a, fragment.color.primary.a;\n");
} }
} else if(op_equal) { } else if(op_equal) {
gen_ffp_instr(&buffer, stage, TRUE, TRUE, last, settings->op[stage].dst, gen_ffp_instr(&buffer, stage, TRUE, TRUE, settings->op[stage].dst,
settings->op[stage].cop, settings->op[stage].carg0, settings->op[stage].cop, settings->op[stage].carg0,
settings->op[stage].carg1, settings->op[stage].carg2); settings->op[stage].carg1, settings->op[stage].carg2);
} else { } else {
gen_ffp_instr(&buffer, stage, TRUE, FALSE, last, settings->op[stage].dst, gen_ffp_instr(&buffer, stage, TRUE, FALSE, settings->op[stage].dst,
settings->op[stage].cop, settings->op[stage].carg0, settings->op[stage].cop, settings->op[stage].carg0,
settings->op[stage].carg1, settings->op[stage].carg2); settings->op[stage].carg1, settings->op[stage].carg2);
gen_ffp_instr(&buffer, stage, FALSE, TRUE, last, settings->op[stage].dst, gen_ffp_instr(&buffer, stage, FALSE, TRUE, settings->op[stage].dst,
settings->op[stage].aop, settings->op[stage].aarg0, settings->op[stage].aop, settings->op[stage].aarg0,
settings->op[stage].aarg1, settings->op[stage].aarg2); settings->op[stage].aarg1, settings->op[stage].aarg2);
} }
} }
if(settings->sRGB_write) { if(settings->sRGB_write) {
shader_addline(&buffer, "MAD ret, fragment.color.secondary, specular_enable, %s;\n", final_combiner_src);
arbfp_add_sRGB_correction(&buffer, "ret", "arg0", "arg1", "arg2", "tempreg"); arbfp_add_sRGB_correction(&buffer, "ret", "arg0", "arg1", "arg2", "tempreg");
shader_addline(&buffer, "MOV result.color.a, ret.a;\n"); shader_addline(&buffer, "MOV result.color.a, ret.a;\n");
} else {
shader_addline(&buffer, "MAD result.color, fragment.color.secondary, specular_enable, %s;\n", final_combiner_src);
} }
/* Footer */ /* Footer */
...@@ -2938,6 +2956,7 @@ static void fragment_prog_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock, ...@@ -2938,6 +2956,7 @@ static void fragment_prog_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock,
set_bumpmat_arbfp(STATE_TEXTURESTAGE(i, WINED3DTSS_BUMPENVMAT00), stateblock, context); set_bumpmat_arbfp(STATE_TEXTURESTAGE(i, WINED3DTSS_BUMPENVMAT00), stateblock, context);
} }
state_texfactor_arbfp(STATE_RENDER(WINED3DRS_TEXTUREFACTOR), stateblock, context); state_texfactor_arbfp(STATE_RENDER(WINED3DRS_TEXTUREFACTOR), stateblock, context);
state_arb_specularenable(STATE_RENDER(WINED3DRS_SPECULARENABLE), stateblock, context);
} }
} }
...@@ -3125,6 +3144,7 @@ static const struct StateEntryTemplate arbfp_fragmentstate_template[] = { ...@@ -3125,6 +3144,7 @@ static const struct StateEntryTemplate arbfp_fragmentstate_template[] = {
{STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(5, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform }, 0 }, {STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(5, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform }, 0 },
{STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(6, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform }, 0 }, {STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(6, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform }, 0 },
{STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(7, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform }, 0 }, {STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(7, WINED3DTSS_TEXTURETRANSFORMFLAGS), textransform }, 0 },
{ STATE_RENDER(WINED3DRS_SPECULARENABLE), { STATE_RENDER(WINED3DRS_SPECULARENABLE), state_arb_specularenable}, 0 },
{0 /* Terminate */, { 0, 0 }, 0 }, {0 /* Terminate */, { 0, 0 }, 0 },
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment