Stefan Dösinger : wined3d: Implement secondary color in the arbfp ffp pipeline.

Alexandre Julliard julliard at winehq.org
Tue Sep 2 08:33:29 CDT 2008


Module: wine
Branch: master
Commit: d60ece20b5fc43ba1e1132ad6d60f48104c081bd
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=d60ece20b5fc43ba1e1132ad6d60f48104c081bd

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Tue Aug 26 15:17:09 2008 -0500

wined3d: Implement secondary color in the arbfp ffp pipeline.

---

 dlls/wined3d/arb_program_shader.c |   68 ++++++++++++++++++++++++-------------
 1 files changed, 44 insertions(+), 24 deletions(-)

diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index c96feec..335e54b 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -2221,10 +2221,11 @@ const shader_backend_t arb_program_shader_backend = {
 };
 
 /* ARB_fragment_program fixed function pipeline replacement definitions */
-#define ARB_FFP_CONST_TFACTOR       0
-#define ARB_FFP_CONST_CONSTANT(i)   ((ARB_FFP_CONST_TFACTOR) + 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)
+#define ARB_FFP_CONST_TFACTOR           0
+#define ARB_FFP_CONST_SPECULAR_ENABLE   ((ARB_FFP_CONST_TFACTOR) + 1)
+#define ARB_FFP_CONST_CONSTANT(i)       ((ARB_FFP_CONST_SPECULAR_ENABLE) + 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
 {
@@ -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) {
     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
     IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
@@ -2474,7 +2500,7 @@ static const char *get_argreg(SHADER_BUFFER *buffer, DWORD argnum, unsigned int
     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) {
     const char *dstmask, *dstreg, *arg0, *arg1, *arg2;
     unsigned int mul = 1;
@@ -2484,9 +2510,7 @@ static void gen_ffp_instr(SHADER_BUFFER *buffer, unsigned int stage, BOOL color,
     else if(color) dstmask = ".rgb";
     else dstmask = ".a";
 
-    if(dst == tempreg && last) FIXME("Last texture stage writes to D3DTA_TEMP\n");
     if(dst == tempreg) dstreg = "tempreg";
-    else if(last) dstreg = "result.color";
     else dstreg = "ret";
 
     arg0 = get_argreg(buffer, 0, stage, dw_arg0);
@@ -2627,8 +2651,8 @@ static GLuint gen_arbfp_ffp_shader(struct ffp_settings *settings, IWineD3DStateB
     GLuint ret;
     DWORD arg0, arg1, arg2;
     BOOL tempreg_used = FALSE, tfactor_used = FALSE;
-    BOOL last = FALSE;
     BOOL op_equal;
+    const char *final_combiner_src = "ret";
 
     /* Find out which textures are read */
     for(stage = 0; stage < MAX_TEXTURES; stage++) {
@@ -2712,6 +2736,7 @@ static GLuint gen_arbfp_ffp_shader(struct ffp_settings *settings, IWineD3DStateB
     if(tfactor_used) {
         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) {
         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
     for(stage = 0; stage < MAX_TEXTURES; stage++) {
         if(settings->op[stage].cop == WINED3DTOP_DISABLE) {
             if(stage == 0) {
-                shader_addline(&buffer, "MOV result.color, fragment.color.primary;\n");
+                final_combiner_src = "fragment.color.primary";
             }
             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 &&
@@ -2839,33 +2858,32 @@ static GLuint gen_arbfp_ffp_shader(struct ffp_settings *settings, IWineD3DStateB
         }
 
         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].carg1, settings->op[stage].carg2);
-            if(last && 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) {
+            if(stage == 0) {
                 shader_addline(&buffer, "MOV ret.a, fragment.color.primary.a;\n");
             }
         } 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].carg1, settings->op[stage].carg2);
         } 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].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].aarg1, settings->op[stage].aarg2);
         }
     }
 
     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");
         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 */
@@ -2938,6 +2956,7 @@ static void fragment_prog_arbfp(DWORD state, IWineD3DStateBlockImpl *stateblock,
                 set_bumpmat_arbfp(STATE_TEXTURESTAGE(i, WINED3DTSS_BUMPENVMAT00), 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[] = {
     {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(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                               },
 };
 




More information about the wine-cvs mailing list