Stefan Dösinger : wined3d: Add fixed function sRGB write correction.
Alexandre Julliard
julliard at winehq.org
Mon Aug 25 06:21:29 CDT 2008
Module: wine
Branch: master
Commit: f39e1224774a4f975951ccbc7dab6dac55e0670b
URL: http://source.winehq.org/git/wine.git/?a=commit;h=f39e1224774a4f975951ccbc7dab6dac55e0670b
Author: Stefan Dösinger <stefan at codeweavers.com>
Date: Wed Aug 20 10:15:31 2008 -0500
wined3d: Add fixed function sRGB write correction.
---
dlls/wined3d/arb_program_shader.c | 64 +++++++++++++++++++++++++-----------
dlls/wined3d/utils.c | 5 +++
dlls/wined3d/wined3d_private.h | 1 +
3 files changed, 50 insertions(+), 20 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index bc8d3b3..a701f36 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -1958,6 +1958,28 @@ static BOOL shader_arb_dirty_const(IWineD3DDevice *iface) {
return TRUE;
}
+static void arbfp_add_sRGB_correction(SHADER_BUFFER *buffer, const char *fragcolor, const char *tmp1,
+ const char *tmp2, const char *tmp3, const char *tmp4) {
+ /* Perform sRGB write correction. See GLX_EXT_framebuffer_sRGB */
+
+ /* Calculate the > 0.0031308 case */
+ shader_addline(buffer, "POW %s.x, %s.x, srgb_pow.x;\n", tmp1, fragcolor);
+ shader_addline(buffer, "POW %s.y, %s.y, srgb_pow.y;\n", tmp1, fragcolor);
+ shader_addline(buffer, "POW %s.z, %s.z, srgb_pow.z;\n", tmp1, fragcolor);
+ shader_addline(buffer, "MUL %s, %s, srgb_mul_hi;\n", tmp1, tmp1);
+ shader_addline(buffer, "SUB %s, %s, srgb_sub_hi;\n", tmp1, tmp1);
+ /* Calculate the < case */
+ shader_addline(buffer, "MUL %s, srgb_mul_low, %s;\n", tmp2, fragcolor);
+ /* Get 1.0 / 0.0 masks for > 0.0031308 and < 0.0031308 */
+ shader_addline(buffer, "SLT %s, srgb_comparison, %s;\n", tmp3, fragcolor);
+ shader_addline(buffer, "SGE %s, srgb_comparison, %s;\n", tmp4, fragcolor);
+ /* Store the components > 0.0031308 in the destination */
+ shader_addline(buffer, "MUL %s, %s, %s;\n", fragcolor, tmp1, tmp3);
+ /* Add the components that are < 0.0031308 */
+ shader_addline(buffer, "MAD result.color.xyz, %s, %s, %s;\n", tmp2, tmp4, fragcolor);
+ /* [0.0;1.0] clamping. Not needed, this is done implicitly */
+}
+
static void shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer) {
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
shader_reg_maps* reg_maps = &This->baseShader.reg_maps;
@@ -2002,24 +2024,7 @@ static void shader_arb_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFFE
fragcolor = "TMP_COLOR";
}
if(This->srgb_enabled) {
- /* Perform sRGB write correction. See GLX_EXT_framebuffer_sRGB */
-
- /* Calculate the > 0.0031308 case */
- shader_addline(buffer, "POW TMP.x, %s.x, srgb_pow.x;\n", fragcolor);
- shader_addline(buffer, "POW TMP.y, %s.y, srgb_pow.y;\n", fragcolor);
- shader_addline(buffer, "POW TMP.z, %s.z, srgb_pow.z;\n", fragcolor);
- shader_addline(buffer, "MUL TMP, TMP, srgb_mul_hi;\n");
- shader_addline(buffer, "SUB TMP, TMP, srgb_sub_hi;\n");
- /* Calculate the < case */
- shader_addline(buffer, "MUL TMP2, srgb_mul_low, %s;\n", fragcolor);
- /* Get 1.0 / 0.0 masks for > 0.0031308 and < 0.0031308 */
- shader_addline(buffer, "SLT TA, srgb_comparison, %s;\n", fragcolor);
- shader_addline(buffer, "SGE TB, srgb_comparison, %s;\n", fragcolor);
- /* Store the components > 0.0031308 in the destination */
- shader_addline(buffer, "MUL %s, TMP, TA;\n", fragcolor);
- /* Add the components that are < 0.0031308 */
- shader_addline(buffer, "MAD result.color.xyz, TMP2, TB, %s;\n", fragcolor);
- /* [0.0;1.0] clamping. Not needed, this is done implicitly */
+ arbfp_add_sRGB_correction(buffer, fragcolor, "TMP", "TMP2", "TA", "TB");
}
if (This->baseShader.hex_version < WINED3DPS_VERSION(3,0)) {
shader_addline(buffer, "LRP result.color.rgb, TMP_FOG.x, %s, state.fog.color;\n", fragcolor);
@@ -2644,7 +2649,7 @@ static GLuint gen_arbfp_ffp_shader(struct ffp_settings *settings, IWineD3DStateB
shader_addline(&buffer, "PARAM const = {1, 2, 4, 0.5};\n");
shader_addline(&buffer, "TEMP ret;\n");
- if(tempreg_used) 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");
@@ -2658,6 +2663,19 @@ static GLuint gen_arbfp_ffp_shader(struct ffp_settings *settings, IWineD3DStateB
shader_addline(&buffer, "PARAM tfactor = program.env[%u];\n", ARB_FFP_CONST_TFACTOR);
}
+ if(settings->sRGB_write) {
+ shader_addline(&buffer, "PARAM srgb_mul_low = {%f, %f, %f, 1.0};\n",
+ srgb_mul_low, srgb_mul_low, srgb_mul_low);
+ shader_addline(&buffer, "PARAM srgb_comparison = {%f, %f, %f, %f};\n",
+ srgb_cmp, srgb_cmp, srgb_cmp, srgb_cmp);
+ shader_addline(&buffer, "PARAM srgb_pow = {%f, %f, %f, 1.0};\n",
+ srgb_pow, srgb_pow, srgb_pow);
+ shader_addline(&buffer, "PARAM srgb_mul_hi = {%f, %f, %f, 1.0};\n",
+ srgb_mul_high, srgb_mul_high, srgb_mul_high);
+ shader_addline(&buffer, "PARAM srgb_sub_hi = {%f, %f, %f, 0.0};\n",
+ srgb_sub_high, srgb_sub_high, srgb_sub_high);
+ }
+
/* Generate texture sampling instructions) */
for(stage = 0; stage < MAX_TEXTURES && settings->op[stage].cop != WINED3DTOP_DISABLE; stage++) {
if(!tex_read[stage]) continue;
@@ -2714,6 +2732,8 @@ static GLuint gen_arbfp_ffp_shader(struct ffp_settings *settings, IWineD3DStateB
shader_addline(&buffer, "MOV result.color, fragment.color.primary;\n");
}
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) {
@@ -2748,7 +2768,10 @@ static GLuint gen_arbfp_ffp_shader(struct ffp_settings *settings, IWineD3DStateB
}
}
- /* TODO: Generate sRGB write color correction */
+ if(settings->sRGB_write) {
+ arbfp_add_sRGB_correction(&buffer, "ret", "arg0", "arg1", "arg2", "tempreg");
+ shader_addline(&buffer, "MOV result.color.a, ret.a;\n");
+ }
/* Footer */
shader_addline(&buffer, "END\n");
@@ -2976,6 +2999,7 @@ static const struct StateEntryTemplate arbfp_fragmentstate_template[] = {
{ STATE_RENDER(WINED3DRS_FOGENABLE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_arbfp_fog }, 0 },
{ STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_arbfp_fog }, 0 },
{ STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_arbfp_fog }, 0 },
+ { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE), { STATE_PIXELSHADER, fragment_prog_arbfp }, 0 },
{0 /* Terminate */, { 0, 0 }, 0 },
};
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 91c8c37..8501544 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -1976,6 +1976,11 @@ void gen_ffp_op(IWineD3DStateBlockImpl *stateblock, struct ffp_settings *setting
break;
}
}
+ if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE]) {
+ settings->sRGB_write = 1;
+ } else {
+ settings->sRGB_write = 0;
+ }
}
#undef GLINFO_LOCATION
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index e67ec38..c72afe6 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -785,6 +785,7 @@ struct ffp_settings {
FOG_EXP,
FOG_EXP2
} fog;
+ unsigned char sRGB_write;
};
struct ffp_desc
More information about the wine-cvs
mailing list