wined3d: Add fixed function sRGB write correction.

This commit is contained in:
Stefan Dösinger 2008-08-20 10:15:31 -05:00 committed by Alexandre Julliard
parent 6c87a66355
commit f39e122477
3 changed files with 50 additions and 20 deletions

View File

@ -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 },
};

View File

@ -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

View File

@ -785,6 +785,7 @@ struct ffp_settings {
FOG_EXP,
FOG_EXP2
} fog;
unsigned char sRGB_write;
};
struct ffp_desc