diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 89dece79a4f..8d177887ff2 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -5951,13 +5951,14 @@ static void state_texfactor_arbfp(struct wined3d_context *context, const struct wined3d_gl_info *gl_info = context->gl_info; struct wined3d_color color; - /* Don't load the parameter if we're using an arbfp pixel shader, - * otherwise we'll overwrite application provided constants. */ if (device->shader_backend == &arb_program_shader_backend) { struct shader_arb_priv *priv; - if (use_ps(state)) return; + /* Don't load the parameter if we're using an arbfp pixel shader, + * otherwise we'll overwrite application provided constants. */ + if (use_ps(state)) + return; priv = device->shader_priv; priv->pshader_const_dirty[ARB_FFP_CONST_TFACTOR] = 1; @@ -5969,6 +5970,34 @@ static void state_texfactor_arbfp(struct wined3d_context *context, checkGLcall("glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_TFACTOR, &color.r)"); } +static void state_tss_constant_arbfp(struct wined3d_context *context, + const struct wined3d_state *state, DWORD state_id) +{ + DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); + struct wined3d_device *device = context->swapchain->device; + const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_color color; + + if (device->shader_backend == &arb_program_shader_backend) + { + struct shader_arb_priv *priv; + + /* Don't load the parameter if we're using an arbfp pixel shader, otherwise we'll overwrite + * application provided constants. + */ + if (use_ps(state)) + return; + + priv = device->shader_priv; + priv->pshader_const_dirty[ARB_FFP_CONST_CONSTANT(stage)] = 1; + priv->highest_dirty_ps_const = max(priv->highest_dirty_ps_const, ARB_FFP_CONST_CONSTANT(stage) + 1); + } + + wined3d_color_from_d3dcolor(&color, state->texture_states[stage][WINED3D_TSS_CONSTANT]); + GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_CONSTANT(stage), &color.r)); + checkGLcall("glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, ARB_FFP_CONST_CONSTANT(stage), &color.r)"); +} + static void state_arb_specularenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { @@ -5976,14 +6005,15 @@ static void state_arb_specularenable(struct wined3d_context *context, const struct wined3d_gl_info *gl_info = context->gl_info; float col[4]; - /* Don't load the parameter if we're using an arbfp pixel shader, otherwise we'll overwrite - * application provided constants - */ if (device->shader_backend == &arb_program_shader_backend) { struct shader_arb_priv *priv; - if (use_ps(state)) return; + /* Don't load the parameter if we're using an arbfp pixel shader, otherwise we'll overwrite + * application provided constants. + */ + if (use_ps(state)) + return; priv = device->shader_priv; priv->pshader_const_dirty[ARB_FFP_CONST_SPECULAR_ENABLE] = 1; @@ -6047,7 +6077,7 @@ static void tex_bumpenvlum_arbfp(struct wined3d_context *context, { struct shader_arb_priv *priv = device->shader_priv; - /* Exit now, don't set the bumpmat below, otherwise we may overwrite pixel shader constants. */ + /* Exit now, don't set the luminance below, otherwise we may overwrite pixel shader constants. */ if (use_ps(state)) return; @@ -6104,12 +6134,12 @@ static void color_key_arbfp(struct wined3d_context *context, const struct wined3 if (!texture) return; - /* Don't load the parameter if we're using an arbfp pixel shader, - * otherwise we'll overwrite application provided constants. */ if (device->shader_backend == &arb_program_shader_backend) { struct shader_arb_priv *priv; + /* Don't load the parameter if we're using an arbfp pixel shader, + * otherwise we'll overwrite application provided constants. */ if (use_ps(state)) return; @@ -6165,7 +6195,6 @@ static const char *get_argreg(struct wined3d_string_buffer *buffer, DWORD argnum ret = "tempreg"; break; case WINED3DTA_CONSTANT: - FIXME("Implement perstage constants\n"); switch(stage) { case 0: ret = "const0"; break; case 1: ret = "const1"; break; @@ -6354,6 +6383,7 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con BOOL tex_read[MAX_TEXTURES] = {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}; BOOL bump_used[MAX_TEXTURES] = {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}; BOOL luminance_used[MAX_TEXTURES] = {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}; + BOOL constant_used[MAX_TEXTURES] = {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE}; UINT lowest_disabled_stage; const char *textype; const char *instr; @@ -6388,9 +6418,9 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con arg0 = settings->op[stage].carg0 & WINED3DTA_SELECTMASK; arg1 = settings->op[stage].carg1 & WINED3DTA_SELECTMASK; arg2 = settings->op[stage].carg2 & WINED3DTA_SELECTMASK; - if(arg0 == WINED3DTA_TEXTURE) tex_read[stage] = TRUE; - if(arg1 == WINED3DTA_TEXTURE) tex_read[stage] = TRUE; - if(arg2 == WINED3DTA_TEXTURE) tex_read[stage] = TRUE; + if (arg0 == WINED3DTA_TEXTURE) tex_read[stage] = TRUE; + if (arg1 == WINED3DTA_TEXTURE) tex_read[stage] = TRUE; + if (arg2 == WINED3DTA_TEXTURE) tex_read[stage] = TRUE; if (settings->op[stage].cop == WINED3D_TOP_BLEND_TEXTURE_ALPHA) tex_read[stage] = TRUE; @@ -6412,30 +6442,29 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con tfactor_used = TRUE; } - if(arg0 == WINED3DTA_TFACTOR || arg1 == WINED3DTA_TFACTOR || arg2 == WINED3DTA_TFACTOR) { - tfactor_used = TRUE; - } - - if(settings->op[stage].dst == tempreg) tempreg_used = TRUE; - if(arg0 == WINED3DTA_TEMP || arg1 == WINED3DTA_TEMP || arg2 == WINED3DTA_TEMP) { + if (settings->op[stage].dst == tempreg) tempreg_used = TRUE; + if (arg0 == WINED3DTA_TEMP || arg1 == WINED3DTA_TEMP || arg2 == WINED3DTA_TEMP) tempreg_used = TRUE; - } + if (arg0 == WINED3DTA_TFACTOR || arg1 == WINED3DTA_TFACTOR || arg2 == WINED3DTA_TFACTOR) + tfactor_used = TRUE; + if (arg0 == WINED3DTA_CONSTANT || arg1 == WINED3DTA_CONSTANT || arg2 == WINED3DTA_CONSTANT) + constant_used[stage] = TRUE; if (settings->op[stage].aop == WINED3D_TOP_DISABLE) continue; arg0 = settings->op[stage].aarg0 & WINED3DTA_SELECTMASK; arg1 = settings->op[stage].aarg1 & WINED3DTA_SELECTMASK; arg2 = settings->op[stage].aarg2 & WINED3DTA_SELECTMASK; - if(arg0 == WINED3DTA_TEXTURE) tex_read[stage] = TRUE; - if(arg1 == WINED3DTA_TEXTURE) tex_read[stage] = TRUE; - if(arg2 == WINED3DTA_TEXTURE) tex_read[stage] = TRUE; + if (arg0 == WINED3DTA_TEXTURE) tex_read[stage] = TRUE; + if (arg1 == WINED3DTA_TEXTURE) tex_read[stage] = TRUE; + if (arg2 == WINED3DTA_TEXTURE) tex_read[stage] = TRUE; - if(arg0 == WINED3DTA_TEMP || arg1 == WINED3DTA_TEMP || arg2 == WINED3DTA_TEMP) { + if (arg0 == WINED3DTA_TEMP || arg1 == WINED3DTA_TEMP || arg2 == WINED3DTA_TEMP) tempreg_used = TRUE; - } - if(arg0 == WINED3DTA_TFACTOR || arg1 == WINED3DTA_TFACTOR || arg2 == WINED3DTA_TFACTOR) { + if (arg0 == WINED3DTA_TFACTOR || arg1 == WINED3DTA_TFACTOR || arg2 == WINED3DTA_TFACTOR) tfactor_used = TRUE; - } + if (arg0 == WINED3DTA_CONSTANT || arg1 == WINED3DTA_CONSTANT || arg2 == WINED3DTA_CONSTANT) + constant_used[stage] = TRUE; } lowest_disabled_stage = stage; @@ -6459,16 +6488,26 @@ static GLuint gen_arbfp_ffp_shader(const struct ffp_frag_settings *settings, con shader_addline(&buffer, "PARAM const = {1, 2, 4, 0.5};\n"); shader_addline(&buffer, "TEMP TMP;\n"); shader_addline(&buffer, "TEMP ret;\n"); - if(tempreg_used || settings->sRGB_write) shader_addline(&buffer, "TEMP tempreg;\n"); + if (tempreg_used || settings->sRGB_write) shader_addline(&buffer, "TEMP tempreg;\n"); shader_addline(&buffer, "TEMP arg0;\n"); shader_addline(&buffer, "TEMP arg1;\n"); shader_addline(&buffer, "TEMP arg2;\n"); - for(stage = 0; stage < MAX_TEXTURES; stage++) { - if(!tex_read[stage]) continue; + for (stage = 0; stage < MAX_TEXTURES; ++stage) + { + if (constant_used[stage]) + shader_addline(&buffer, "PARAM const%u = program.env[%u];\n", stage, ARB_FFP_CONST_CONSTANT(stage)); + + if (!tex_read[stage]) + continue; + shader_addline(&buffer, "TEMP tex%u;\n", stage); - if(!bump_used[stage]) continue; + + if (!bump_used[stage]) + continue; shader_addline(&buffer, "PARAM bumpmat%u = program.env[%u];\n", stage, ARB_FFP_CONST_BUMPMAT(stage)); - if(!luminance_used[stage]) continue; + + if (!luminance_used[stage]) + continue; shader_addline(&buffer, "PARAM luminance%u = program.env[%u];\n", stage, ARB_FFP_CONST_LUMINANCE(stage)); } if(tfactor_used) { @@ -6665,6 +6704,7 @@ static void fragment_prog_arbfp(struct wined3d_context *context, const struct wi for (i = 0; i < MAX_TEXTURES; ++i) { set_bumpmat_arbfp(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_BUMPENV_MAT00)); + state_tss_constant_arbfp(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_CONSTANT)); } state_texfactor_arbfp(context, state, STATE_RENDER(WINED3D_RS_TEXTUREFACTOR)); state_arb_specularenable(context, state, STATE_RENDER(WINED3D_RS_SPECULARENABLE)); @@ -6714,6 +6754,7 @@ static void fragment_prog_arbfp(struct wined3d_context *context, const struct wi for (i = 0; i < MAX_TEXTURES; ++i) { set_bumpmat_arbfp(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_BUMPENV_MAT00)); + state_tss_constant_arbfp(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_CONSTANT)); } state_texfactor_arbfp(context, state, STATE_RENDER(WINED3D_RS_TEXTUREFACTOR)); state_arb_specularenable(context, state, STATE_RENDER(WINED3D_RS_SPECULARENABLE)); @@ -6922,14 +6963,22 @@ static const struct StateEntryTemplate arbfp_fragmentstate_template[] = {STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), { STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_FOGCOLOR), { STATE_RENDER(WINED3D_RS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_FOGDENSITY), { STATE_RENDER(WINED3D_RS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(0,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform }, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(3,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(4,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7,WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), textransform}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(0, WINED3D_TSS_CONSTANT), { STATE_TEXTURESTAGE(0, WINED3D_TSS_CONSTANT), state_tss_constant_arbfp}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(1, WINED3D_TSS_CONSTANT), { STATE_TEXTURESTAGE(1, WINED3D_TSS_CONSTANT), state_tss_constant_arbfp}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(2, WINED3D_TSS_CONSTANT), { STATE_TEXTURESTAGE(2, WINED3D_TSS_CONSTANT), state_tss_constant_arbfp}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(3, WINED3D_TSS_CONSTANT), { STATE_TEXTURESTAGE(3, WINED3D_TSS_CONSTANT), state_tss_constant_arbfp}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(4, WINED3D_TSS_CONSTANT), { STATE_TEXTURESTAGE(4, WINED3D_TSS_CONSTANT), state_tss_constant_arbfp}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(5, WINED3D_TSS_CONSTANT), { STATE_TEXTURESTAGE(5, WINED3D_TSS_CONSTANT), state_tss_constant_arbfp}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(6, WINED3D_TSS_CONSTANT), { STATE_TEXTURESTAGE(6, WINED3D_TSS_CONSTANT), state_tss_constant_arbfp}, WINED3D_GL_EXT_NONE }, + {STATE_TEXTURESTAGE(7, WINED3D_TSS_CONSTANT), { STATE_TEXTURESTAGE(7, WINED3D_TSS_CONSTANT), state_tss_constant_arbfp}, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_SPECULARENABLE), { STATE_RENDER(WINED3D_RS_SPECULARENABLE), state_arb_specularenable}, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_SHADEMODE), { STATE_RENDER(WINED3D_RS_SHADEMODE), state_shademode }, WINED3D_GL_EXT_NONE }, {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },