[PATCH] WineD3D: Add fixed function sRGB write correction=0A=

Stefan Doesinger stefan at codeweavers.com
Wed Aug 20 10:15:31 CDT 2008


=0A=
Obviously this only works with the pipeline replacement shader=0A=
---=0A=
 dlls/wined3d/arb_program_shader.c |   64 =
+++++++++++++++++++++++++-----------=0A=
 dlls/wined3d/utils.c              |    5 +++=0A=
 dlls/wined3d/wined3d_private.h    |    1 +=0A=
 3 files changed, 50 insertions(+), 20 deletions(-)=0A=
=0A=
diff --git a/dlls/wined3d/arb_program_shader.c =
b/dlls/wined3d/arb_program_shader.c=0A=
index bc8d3b3..a701f36 100644=0A=
--- a/dlls/wined3d/arb_program_shader.c=0A=
+++ b/dlls/wined3d/arb_program_shader.c=0A=
@@ -1958,6 +1958,28 @@ static BOOL shader_arb_dirty_const(IWineD3DDevice =
*iface) {=0A=
     return TRUE;=0A=
 }=0A=
 =0A=
+static void arbfp_add_sRGB_correction(SHADER_BUFFER *buffer, const char =
*fragcolor, const char *tmp1,=0A=
+                                      const char *tmp2, const char =
*tmp3, const char *tmp4) {=0A=
+    /* Perform sRGB write correction. See GLX_EXT_framebuffer_sRGB */=0A=
+=0A=
+    /* Calculate the > 0.0031308 case */=0A=
+    shader_addline(buffer, "POW %s.x, %s.x, srgb_pow.x;\n", tmp1, =
fragcolor);=0A=
+    shader_addline(buffer, "POW %s.y, %s.y, srgb_pow.y;\n", tmp1, =
fragcolor);=0A=
+    shader_addline(buffer, "POW %s.z, %s.z, srgb_pow.z;\n", tmp1, =
fragcolor);=0A=
+    shader_addline(buffer, "MUL %s, %s, srgb_mul_hi;\n", tmp1, tmp1);=0A=
+    shader_addline(buffer, "SUB %s, %s, srgb_sub_hi;\n", tmp1, tmp1);=0A=
+    /* Calculate the < case */=0A=
+    shader_addline(buffer, "MUL %s, srgb_mul_low, %s;\n", tmp2, =
fragcolor);=0A=
+    /* Get 1.0 / 0.0 masks for > 0.0031308 and < 0.0031308 */=0A=
+    shader_addline(buffer, "SLT %s, srgb_comparison, %s;\n", tmp3, =
fragcolor);=0A=
+    shader_addline(buffer, "SGE %s, srgb_comparison, %s;\n", tmp4, =
fragcolor);=0A=
+    /* Store the components > 0.0031308 in the destination */=0A=
+    shader_addline(buffer, "MUL %s, %s, %s;\n", fragcolor, tmp1, tmp3);=0A=
+    /* Add the components that are < 0.0031308 */=0A=
+    shader_addline(buffer, "MAD result.color.xyz, %s, %s, %s;\n", tmp2, =
tmp4, fragcolor);=0A=
+    /* [0.0;1.0] clamping. Not needed, this is done implicitly */=0A=
+}=0A=
+=0A=
 static void shader_arb_generate_pshader(IWineD3DPixelShader *iface, =
SHADER_BUFFER *buffer) {=0A=
     IWineD3DPixelShaderImpl *This =3D (IWineD3DPixelShaderImpl *)iface;=0A=
     shader_reg_maps* reg_maps =3D &This->baseShader.reg_maps;=0A=
@@ -2002,24 +2024,7 @@ static void =
shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFFE=0A=
         fragcolor =3D "TMP_COLOR";=0A=
     }=0A=
     if(This->srgb_enabled) {=0A=
-        /* Perform sRGB write correction. See GLX_EXT_framebuffer_sRGB =
*/=0A=
-=0A=
-        /* Calculate the > 0.0031308 case */=0A=
-        shader_addline(buffer, "POW TMP.x, %s.x, srgb_pow.x;\n", =
fragcolor);=0A=
-        shader_addline(buffer, "POW TMP.y, %s.y, srgb_pow.y;\n", =
fragcolor);=0A=
-        shader_addline(buffer, "POW TMP.z, %s.z, srgb_pow.z;\n", =
fragcolor);=0A=
-        shader_addline(buffer, "MUL TMP, TMP, srgb_mul_hi;\n");=0A=
-        shader_addline(buffer, "SUB TMP, TMP, srgb_sub_hi;\n");=0A=
-        /* Calculate the < case */=0A=
-        shader_addline(buffer, "MUL TMP2, srgb_mul_low, %s;\n", =
fragcolor);=0A=
-        /* Get 1.0 / 0.0 masks for > 0.0031308 and < 0.0031308 */=0A=
-        shader_addline(buffer, "SLT TA, srgb_comparison, %s;\n", =
fragcolor);=0A=
-        shader_addline(buffer, "SGE TB, srgb_comparison, %s;\n", =
fragcolor);=0A=
-        /* Store the components > 0.0031308 in the destination */=0A=
-        shader_addline(buffer, "MUL %s, TMP, TA;\n", fragcolor);=0A=
-        /* Add the components that are < 0.0031308 */=0A=
-        shader_addline(buffer, "MAD result.color.xyz, TMP2, TB, %s;\n", =
fragcolor);=0A=
-        /* [0.0;1.0] clamping. Not needed, this is done implicitly */=0A=
+        arbfp_add_sRGB_correction(buffer, fragcolor, "TMP", "TMP2", =
"TA", "TB");=0A=
     }=0A=
     if (This->baseShader.hex_version < WINED3DPS_VERSION(3,0)) {=0A=
         shader_addline(buffer, "LRP result.color.rgb, TMP_FOG.x, %s, =
state.fog.color;\n", fragcolor);=0A=
@@ -2644,7 +2649,7 @@ static GLuint gen_arbfp_ffp_shader(struct =
ffp_settings *settings, IWineD3DStateB=0A=
 =0A=
     shader_addline(&buffer, "PARAM const =3D {1, 2, 4, 0.5};\n");=0A=
     shader_addline(&buffer, "TEMP ret;\n");=0A=
-    if(tempreg_used) shader_addline(&buffer, "TEMP tempreg;\n");=0A=
+    if(tempreg_used || settings->sRGB_write) shader_addline(&buffer, =
"TEMP tempreg;\n");=0A=
     shader_addline(&buffer, "TEMP arg0;\n");=0A=
     shader_addline(&buffer, "TEMP arg1;\n");=0A=
     shader_addline(&buffer, "TEMP arg2;\n");=0A=
@@ -2658,6 +2663,19 @@ static GLuint gen_arbfp_ffp_shader(struct =
ffp_settings *settings, IWineD3DStateB=0A=
         shader_addline(&buffer, "PARAM tfactor =3D program.env[%u];\n", =
ARB_FFP_CONST_TFACTOR);=0A=
     }=0A=
 =0A=
+    if(settings->sRGB_write) {=0A=
+        shader_addline(&buffer, "PARAM srgb_mul_low =3D {%f, %f, %f, =
1.0};\n",=0A=
+                       srgb_mul_low, srgb_mul_low, srgb_mul_low);=0A=
+        shader_addline(&buffer, "PARAM srgb_comparison =3D  {%f, %f, =
%f, %f};\n",=0A=
+                       srgb_cmp, srgb_cmp, srgb_cmp, srgb_cmp);=0A=
+        shader_addline(&buffer, "PARAM srgb_pow =3D  {%f, %f, %f, =
1.0};\n",=0A=
+                       srgb_pow, srgb_pow, srgb_pow);=0A=
+        shader_addline(&buffer, "PARAM srgb_mul_hi =3D  {%f, %f, %f, =
1.0};\n",=0A=
+                       srgb_mul_high, srgb_mul_high, srgb_mul_high);=0A=
+        shader_addline(&buffer, "PARAM srgb_sub_hi =3D  {%f, %f, %f, =
0.0};\n",=0A=
+                       srgb_sub_high, srgb_sub_high, srgb_sub_high);=0A=
+    }=0A=
+=0A=
     /* Generate texture sampling instructions) */=0A=
     for(stage =3D 0; stage < MAX_TEXTURES && settings->op[stage].cop =
!=3D WINED3DTOP_DISABLE; stage++) {=0A=
         if(!tex_read[stage]) continue;=0A=
@@ -2714,6 +2732,8 @@ static GLuint gen_arbfp_ffp_shader(struct =
ffp_settings *settings, IWineD3DStateB=0A=
                 shader_addline(&buffer, "MOV result.color, =
fragment.color.primary;\n");=0A=
             }=0A=
             break;=0A=
+        } else if(settings->sRGB_write) {=0A=
+            last =3D FALSE;=0A=
         } else if(stage =3D=3D (MAX_TEXTURES - 1)) {=0A=
             last =3D TRUE;=0A=
         } else if(settings->op[stage + 1].cop =3D=3D =
WINED3DTOP_DISABLE) {=0A=
@@ -2748,7 +2768,10 @@ static GLuint gen_arbfp_ffp_shader(struct =
ffp_settings *settings, IWineD3DStateB=0A=
         }=0A=
     }=0A=
 =0A=
-    /* TODO: Generate sRGB write color correction */=0A=
+    if(settings->sRGB_write) {=0A=
+        arbfp_add_sRGB_correction(&buffer, "ret", "arg0", "arg1", =
"arg2", "tempreg");=0A=
+        shader_addline(&buffer, "MOV result.color.a, ret.a;\n");=0A=
+    }=0A=
 =0A=
     /* Footer */=0A=
     shader_addline(&buffer, "END\n");=0A=
@@ -2976,6 +2999,7 @@ static const struct StateEntryTemplate =
arbfp_fragmentstate_template[] =3D {=0A=
     { STATE_RENDER(WINED3DRS_FOGENABLE),                  { =
STATE_RENDER(WINED3DRS_FOGENABLE),                  state_arbfp_fog      =
   }, 0                               },=0A=
     { STATE_RENDER(WINED3DRS_FOGTABLEMODE),               { =
STATE_RENDER(WINED3DRS_FOGENABLE),                  state_arbfp_fog      =
   }, 0                               },=0A=
     { STATE_RENDER(WINED3DRS_FOGVERTEXMODE),              { =
STATE_RENDER(WINED3DRS_FOGENABLE),                  state_arbfp_fog      =
   }, 0                               },=0A=
+    { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE),            { =
STATE_PIXELSHADER,                                  fragment_prog_arbfp  =
   }, 0                               },=0A=
     {0 /* Terminate */,                                   { 0,          =
                                        0                       }, 0     =
                          },=0A=
 };=0A=
 =0A=
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c=0A=
index 8b3be3f..340c984 100644=0A=
--- a/dlls/wined3d/utils.c=0A=
+++ b/dlls/wined3d/utils.c=0A=
@@ -1976,6 +1976,11 @@ void gen_ffp_op(IWineD3DStateBlockImpl =
*stateblock, struct ffp_settings *setting=0A=
                 break;=0A=
         }=0A=
     }=0A=
+    if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE]) {=0A=
+        settings->sRGB_write =3D 1;=0A=
+    } else {=0A=
+        settings->sRGB_write =3D 0;=0A=
+    }=0A=
 }=0A=
 #undef GLINFO_LOCATION=0A=
 =0A=
diff --git a/dlls/wined3d/wined3d_private.h =
b/dlls/wined3d/wined3d_private.h=0A=
index e67ec38..c72afe6 100644=0A=
--- a/dlls/wined3d/wined3d_private.h=0A=
+++ b/dlls/wined3d/wined3d_private.h=0A=
@@ -785,6 +785,7 @@ struct ffp_settings {=0A=
         FOG_EXP,=0A=
         FOG_EXP2=0A=
     } fog;=0A=
+    unsigned char sRGB_write;=0A=
 };=0A=
 =0A=
 struct ffp_desc=0A=
-- =0A=
1.5.6.4=0A=
=0A=

------=_NextPart_000_0014_01C9046F.851ED0C0--




More information about the wine-patches mailing list