[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