wined3d: Add fog and tex types to the ffp fragment description.

This commit is contained in:
Stefan Dösinger 2008-07-11 21:18:06 -05:00 committed by Alexandre Julliard
parent 40cfec2582
commit 294f1b4aad
3 changed files with 111 additions and 59 deletions

View File

@ -780,13 +780,13 @@ static GLuint gen_ati_shader(struct texture_stage_op op[MAX_TEXTURES], WineD3D_G
static void set_tex_op_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
IWineD3DDeviceImpl *This = stateblock->wineD3DDevice;
struct atifs_ffp_desc *desc;
struct texture_stage_op op[MAX_TEXTURES];
struct ffp_settings settings;
struct atifs_private_data *priv = (struct atifs_private_data *) This->fragment_priv;
DWORD mapped_stage;
unsigned int i;
gen_ffp_op(stateblock, op);
desc = (struct atifs_ffp_desc *) find_ffp_shader(&priv->fragment_shaders, op);
gen_ffp_op(stateblock, &settings, TRUE);
desc = (struct atifs_ffp_desc *) find_ffp_shader(&priv->fragment_shaders, &settings);
if(!desc) {
desc = HeapAlloc(GetProcessHeap(), 0, sizeof(*desc));
if(!desc) {
@ -795,12 +795,12 @@ static void set_tex_op_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, Wi
}
desc->num_textures_used = 0;
for(i = 0; i < GL_LIMITS(texture_stages); i++) {
if(op[i].cop == WINED3DTOP_DISABLE) break;
if(settings.op[i].cop == WINED3DTOP_DISABLE) break;
desc->num_textures_used = i;
}
memcpy(desc->parent.op, op, sizeof(op));
desc->shader = gen_ati_shader(op, &GLINFO_LOCATION);
memcpy(&desc->parent.settings, &settings, sizeof(settings));
desc->shader = gen_ati_shader(settings.op, &GLINFO_LOCATION);
add_ffp_shader(&priv->fragment_shaders, &desc->parent);
TRACE("Allocated fixed function replacement shader descriptor %p\n", desc);
}

View File

@ -1750,7 +1750,7 @@ void *hash_table_get(hash_table_t *table, void *key)
}
#define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
void gen_ffp_op(IWineD3DStateBlockImpl *stateblock, struct texture_stage_op op[MAX_TEXTURES]) {
void gen_ffp_op(IWineD3DStateBlockImpl *stateblock, struct ffp_settings *settings, BOOL ignore_textype) {
#define ARG1 0x01
#define ARG2 0x02
#define ARG0 0x04
@ -1789,42 +1789,54 @@ void gen_ffp_op(IWineD3DStateBlockImpl *stateblock, struct texture_stage_op op[M
for(i = 0; i < GL_LIMITS(texture_stages); i++) {
IWineD3DBaseTextureImpl *texture;
if(stateblock->textureState[i][WINED3DTSS_COLOROP] == WINED3DTOP_DISABLE) {
op[i].cop = WINED3DTOP_DISABLE;
op[i].aop = WINED3DTOP_DISABLE;
op[i].carg0 = op[i].carg1 = op[i].carg2 = 0xffffffff;
op[i].aarg0 = op[i].aarg1 = op[i].aarg2 = 0xffffffff;
op[i].color_correction = WINED3DFMT_UNKNOWN;
op[i].dst = 0xffffffff;
settings->op[i].cop = WINED3DTOP_DISABLE;
settings->op[i].aop = WINED3DTOP_DISABLE;
settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = 0xffffffff;
settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = 0xffffffff;
settings->op[i].color_correction = WINED3DFMT_UNKNOWN;
settings->op[i].dst = 0xffffffff;
i++;
break;
}
texture = (IWineD3DBaseTextureImpl *) stateblock->textures[i];
op[i].color_correction = texture ? texture->baseTexture.shader_conversion_group : WINED3DFMT_UNKNOWN;
op[i].cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
op[i].aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
op[i].carg1 = (args[op[i].cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : 0xffffffff;
op[i].carg2 = (args[op[i].cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : 0xffffffff;
op[i].carg0 = (args[op[i].cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : 0xffffffff;
if(is_invalid_op(stateblock->wineD3DDevice, i, op[i].cop, op[i].carg1, op[i].carg2, op[i].carg0)) {
op[i].carg0 = 0xffffffff;
op[i].carg2 = 0xffffffff;
op[i].carg1 = WINED3DTA_CURRENT;
op[i].cop = WINED3DTOP_SELECTARG1;
if(texture) {
settings->op[i].color_correction = texture->baseTexture.shader_conversion_group;
if(ignore_textype) {
settings->op[i].tex_type = 0;
} else {
settings->op[i].tex_type = stateblock->textureDimensions[i];
}
} else {
settings->op[i].color_correction = WINED3DFMT_UNKNOWN;
settings->op[i].tex_type = 0;
}
op[i].aarg1 = (args[op[i].aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : 0xffffffff;
op[i].aarg2 = (args[op[i].aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : 0xffffffff;
op[i].aarg0 = (args[op[i].aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : 0xffffffff;
settings->op[i].cop = stateblock->textureState[i][WINED3DTSS_COLOROP];
settings->op[i].aop = stateblock->textureState[i][WINED3DTSS_ALPHAOP];
if(is_invalid_op(stateblock->wineD3DDevice, i, op[i].aop, op[i].aarg1, op[i].aarg2, op[i].aarg0)) {
op[i].aarg0 = 0xffffffff;
op[i].aarg2 = 0xffffffff;
op[i].aarg1 = WINED3DTA_CURRENT;
op[i].aop = WINED3DTOP_SELECTARG1;
settings->op[i].carg1 = (args[settings->op[i].cop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_COLORARG1] : 0xffffffff;
settings->op[i].carg2 = (args[settings->op[i].cop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_COLORARG2] : 0xffffffff;
settings->op[i].carg0 = (args[settings->op[i].cop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_COLORARG0] : 0xffffffff;
if(is_invalid_op(stateblock->wineD3DDevice, i,settings->op[i].cop,
settings->op[i].carg1, settings->op[i].carg2, settings->op[i].carg0)) {
settings->op[i].carg0 = 0xffffffff;
settings->op[i].carg2 = 0xffffffff;
settings->op[i].carg1 = WINED3DTA_CURRENT;
settings->op[i].cop = WINED3DTOP_SELECTARG1;
}
settings->op[i].aarg1 = (args[settings->op[i].aop] & ARG1) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG1] : 0xffffffff;
settings->op[i].aarg2 = (args[settings->op[i].aop] & ARG2) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG2] : 0xffffffff;
settings->op[i].aarg0 = (args[settings->op[i].aop] & ARG0) ? stateblock->textureState[i][WINED3DTSS_ALPHAARG0] : 0xffffffff;
if(is_invalid_op(stateblock->wineD3DDevice, i, settings->op[i].aop,
settings->op[i].aarg1, settings->op[i].aarg2, settings->op[i].aarg0)) {
settings->op[i].aarg0 = 0xffffffff;
settings->op[i].aarg2 = 0xffffffff;
settings->op[i].aarg1 = WINED3DTA_CURRENT;
settings->op[i].aop = WINED3DTOP_SELECTARG1;
} else if(i == 0 && stateblock->textures[0] &&
stateblock->renderState[WINED3DRS_COLORKEYENABLE] &&
(stateblock->textureDimensions[0] == GL_TEXTURE_2D ||
@ -1834,52 +1846,81 @@ void gen_ffp_op(IWineD3DStateBlockImpl *stateblock, struct texture_stage_op op[M
if(surf->CKeyFlags & WINEDDSD_CKSRCBLT &&
getFormatDescEntry(surf->resource.format, NULL, NULL)->alphaMask == 0x00000000) {
if(op[0].aop == WINED3DTOP_DISABLE) {
op[0].aarg1 = WINED3DTA_TEXTURE;
op[0].aop = WINED3DTOP_SELECTARG1;
if(settings->op[0].aop == WINED3DTOP_DISABLE) {
settings->op[0].aarg1 = WINED3DTA_TEXTURE;
settings->op[0].aop = WINED3DTOP_SELECTARG1;
}
else if(op[0].aop == WINED3DTOP_SELECTARG1 && op[0].aarg1 != WINED3DTA_TEXTURE) {
else if(settings->op[0].aop == WINED3DTOP_SELECTARG1 && settings->op[0].aarg1 != WINED3DTA_TEXTURE) {
if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE]) {
op[0].aarg2 = WINED3DTA_TEXTURE;
op[0].aop = WINED3DTOP_MODULATE;
settings->op[0].aarg2 = WINED3DTA_TEXTURE;
settings->op[0].aop = WINED3DTOP_MODULATE;
}
else op[0].aarg1 = WINED3DTA_TEXTURE;
else settings->op[0].aarg1 = WINED3DTA_TEXTURE;
}
else if(op[0].aop == WINED3DTOP_SELECTARG2 && op[0].aarg2 != WINED3DTA_TEXTURE) {
else if(settings->op[0].aop == WINED3DTOP_SELECTARG2 && settings->op[0].aarg2 != WINED3DTA_TEXTURE) {
if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE]) {
op[0].aarg1 = WINED3DTA_TEXTURE;
op[0].aop = WINED3DTOP_MODULATE;
settings->op[0].aarg1 = WINED3DTA_TEXTURE;
settings->op[0].aop = WINED3DTOP_MODULATE;
}
else op[0].aarg2 = WINED3DTA_TEXTURE;
else settings->op[0].aarg2 = WINED3DTA_TEXTURE;
}
}
}
if(op[i].carg1 == WINED3DTA_TEXTURE || op[i].carg2 == WINED3DTA_TEXTURE || op[i].carg0 == WINED3DTA_TEXTURE ||
op[i].aarg1 == WINED3DTA_TEXTURE || op[i].aarg2 == WINED3DTA_TEXTURE || op[i].aarg0 == WINED3DTA_TEXTURE) {
if(settings->op[i].carg1 == WINED3DTA_TEXTURE || settings->op[i].carg2 == WINED3DTA_TEXTURE || settings->op[i].carg0 == WINED3DTA_TEXTURE ||
settings->op[i].aarg1 == WINED3DTA_TEXTURE || settings->op[i].aarg2 == WINED3DTA_TEXTURE || settings->op[i].aarg0 == WINED3DTA_TEXTURE) {
ttff = stateblock->textureState[i][WINED3DTSS_TEXTURETRANSFORMFLAGS];
if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT3)) {
op[i].projected = proj_count3;
settings->op[i].projected = proj_count3;
} else if(ttff == (WINED3DTTFF_PROJECTED | WINED3DTTFF_COUNT4)) {
op[i].projected = proj_count4;
settings->op[i].projected = proj_count4;
} else {
op[i].projected = proj_none;
settings->op[i].projected = proj_none;
}
} else {
op[i].projected = proj_none;
settings->op[i].projected = proj_none;
}
op[i].dst = stateblock->textureState[i][WINED3DTSS_RESULTARG];
settings->op[i].dst = stateblock->textureState[i][WINED3DTSS_RESULTARG];
}
/* Clear unsupported stages */
for(; i < MAX_TEXTURES; i++) {
memset(&op[i], 0xff, sizeof(op[i]));
memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
}
if(stateblock->renderState[WINED3DRS_FOGENABLE] == FALSE) {
settings->fog = FOG_OFF;
} else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
switch(stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
case WINED3DFOG_NONE:
case WINED3DFOG_LINEAR:
settings->fog = FOG_LINEAR;
break;
case WINED3DFOG_EXP:
settings->fog = FOG_EXP;
break;
case WINED3DFOG_EXP2:
settings->fog = FOG_EXP2;
break;
}
} else {
switch(stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
case WINED3DFOG_LINEAR:
settings->fog = FOG_LINEAR;
break;
case WINED3DFOG_EXP:
settings->fog = FOG_EXP;
break;
case WINED3DFOG_EXP2:
settings->fog = FOG_EXP2;
break;
}
}
}
#undef GLINFO_LOCATION
struct ffp_desc *find_ffp_shader(struct list *shaders, struct texture_stage_op op[MAX_TEXTURES])
struct ffp_desc *find_ffp_shader(struct list *shaders, struct ffp_settings *settings)
{
struct ffp_desc *entry;
@ -1887,7 +1928,7 @@ struct ffp_desc *find_ffp_shader(struct list *shaders, struct texture_stage_op o
* or maybe consider using hashtables
*/
LIST_FOR_EACH_ENTRY(entry, shaders, struct ffp_desc, entry) {
if(memcmp(op, entry->op, sizeof(struct texture_stage_op) * MAX_TEXTURES) == 0) {
if(memcmp(settings, &entry->settings, sizeof(*settings)) == 0) {
TRACE("Found shader entry %p\n", entry);
return entry;
}

View File

@ -728,18 +728,29 @@ struct texture_stage_op
DWORD carg1, carg2, carg0;
DWORD aarg1, aarg2, aarg0;
WINED3DFORMAT color_correction;
DWORD tex_type;
DWORD dst;
enum projection_types projected;
};
struct ffp_settings {
struct texture_stage_op op[MAX_TEXTURES];
enum {
FOG_OFF,
FOG_LINEAR,
FOG_EXP,
FOG_EXP2
} fog;
};
struct ffp_desc
{
struct texture_stage_op op[MAX_TEXTURES];
struct ffp_settings settings;
struct list entry;
};
void gen_ffp_op(IWineD3DStateBlockImpl *stateblock,struct texture_stage_op op[MAX_TEXTURES]);
struct ffp_desc *find_ffp_shader(struct list *shaders, struct texture_stage_op op[MAX_TEXTURES]);
void gen_ffp_op(IWineD3DStateBlockImpl *stateblock, struct ffp_settings *settings, BOOL ignore_textype);
struct ffp_desc *find_ffp_shader(struct list *shaders, struct ffp_settings *settings);
void add_ffp_shader(struct list *shaders, struct ffp_desc *desc);
/*****************************************************************************