wined3d: Call activate_dimensions from the atifs code.

This commit is contained in:
Stefan Dösinger 2008-04-23 22:23:57 +02:00 committed by Alexandre Julliard
parent c6d04ea9d5
commit 9ee7e42de8
4 changed files with 141 additions and 116 deletions

View File

@ -45,6 +45,7 @@ struct atifs_ffp_desc
{
struct ffp_desc parent;
GLuint shader;
unsigned int num_textures_used;
};
struct atifs_private_data
@ -782,6 +783,8 @@ static void set_tex_op_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, Wi
struct atifs_ffp_desc *desc;
struct texture_stage_op op[MAX_TEXTURES];
struct atifs_private_data *priv = (struct atifs_private_data *) This->shader_priv;
DWORD mapped_stage;
unsigned int i;
gen_ffp_op(stateblock, op);
desc = (struct atifs_ffp_desc *) find_ffp_shader(&priv->fragment_shaders, op);
@ -791,12 +794,31 @@ static void set_tex_op_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, Wi
ERR("Out of memory\n");
return;
}
desc->num_textures_used = 0;
for(i = 0; i < GL_LIMITS(texture_stages); i++) {
if(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);
add_ffp_shader(&priv->fragment_shaders, &desc->parent);
TRACE("Allocated fixed function replacement shader descriptor %p\n", desc);
}
/* GL_ATI_fragment_shader depends on the GL_TEXTURE_xD enable settings. Update the texture stages
* used by this shader
*/
for(i = 0; i < desc->num_textures_used; i++) {
mapped_stage = This->texUnitMap[i];
if(mapped_stage != -1) {
const struct StateEntry *StateTable = stateblock->wineD3DDevice->shader_backend->StateTable;
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
checkGLcall("glActiveTextureARB");
texture_activate_dimensions(i, stateblock, context);
}
}
GL_EXTCALL(glBindFragmentShaderATI(desc->shader));
}

View File

@ -1810,118 +1810,6 @@ static void state_ckeyblend(DWORD state, IWineD3DStateBlockImpl *stateblock, Win
}
}
/* Activates the texture dimension according to the bound D3D texture.
* Does not care for the colorop or correct gl texture unit(when using nvrc)
* Requires the caller to activate the correct unit before
*/
static void activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
BOOL bumpmap = FALSE;
if(stage > 0 && (stateblock->textureState[stage - 1][WINED3DTSS_COLOROP] == WINED3DTOP_BUMPENVMAPLUMINANCE ||
stateblock->textureState[stage - 1][WINED3DTSS_COLOROP] == WINED3DTOP_BUMPENVMAP)) {
bumpmap = TRUE;
context->texShaderBumpMap |= (1 << stage);
} else {
context->texShaderBumpMap &= ~(1 << stage);
}
if(stateblock->textures[stage]) {
switch(stateblock->textureDimensions[stage]) {
case GL_TEXTURE_2D:
if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, bumpmap ? GL_OFFSET_TEXTURE_2D_NV : GL_TEXTURE_2D);
checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, ...)");
} else {
glDisable(GL_TEXTURE_3D);
checkGLcall("glDisable(GL_TEXTURE_3D)");
if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
}
if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
glDisable(GL_TEXTURE_RECTANGLE_ARB);
checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
}
glEnable(GL_TEXTURE_2D);
checkGLcall("glEnable(GL_TEXTURE_2D)");
}
break;
case GL_TEXTURE_RECTANGLE_ARB:
if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, bumpmap ? GL_OFFSET_TEXTURE_2D_NV : GL_TEXTURE_RECTANGLE_ARB);
checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, ...)");
} else {
glDisable(GL_TEXTURE_2D);
checkGLcall("glDisable(GL_TEXTURE_2D)");
glDisable(GL_TEXTURE_3D);
checkGLcall("glDisable(GL_TEXTURE_3D)");
if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
}
glEnable(GL_TEXTURE_RECTANGLE_ARB);
checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
}
break;
case GL_TEXTURE_3D:
if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_3D);
checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_3D)");
} else {
if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
}
if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
glDisable(GL_TEXTURE_RECTANGLE_ARB);
checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
}
glDisable(GL_TEXTURE_2D);
checkGLcall("glDisable(GL_TEXTURE_2D)");
glEnable(GL_TEXTURE_3D);
checkGLcall("glEnable(GL_TEXTURE_3D)");
}
break;
case GL_TEXTURE_CUBE_MAP_ARB:
if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_CUBE_MAP_ARB);
checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_CUBE_MAP_ARB)");
} else {
glDisable(GL_TEXTURE_2D);
checkGLcall("glDisable(GL_TEXTURE_2D)");
glDisable(GL_TEXTURE_3D);
checkGLcall("glDisable(GL_TEXTURE_3D)");
if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
glDisable(GL_TEXTURE_RECTANGLE_ARB);
checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
}
glEnable(GL_TEXTURE_CUBE_MAP_ARB);
checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
}
break;
}
} else {
if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE);
checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE)");
} else {
glEnable(GL_TEXTURE_2D);
checkGLcall("glEnable(GL_TEXTURE_2D)");
glDisable(GL_TEXTURE_3D);
checkGLcall("glDisable(GL_TEXTURE_3D)");
if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
}
if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
glDisable(GL_TEXTURE_RECTANGLE_ARB);
checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
}
/* Binding textures is done by samplers. A dummy texture will be bound */
}
}
}
static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
@ -1987,7 +1875,7 @@ static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
* if the sampler for this stage is dirty
*/
if(!isStateDirty(context, STATE_SAMPLER(stage))) {
if (tex_used) activate_dimensions(stage, stateblock, context);
if (tex_used) texture_activate_dimensions(stage, stateblock, context);
}
/* Set the texture combiners */
@ -2010,7 +1898,7 @@ static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
if(usesBump != usedBump) {
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage + 1));
checkGLcall("glActiveTextureARB");
activate_dimensions(stage + 1, stateblock, context);
texture_activate_dimensions(stage + 1, stateblock, context);
GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
checkGLcall("glActiveTextureARB");
}
@ -2539,7 +2427,7 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont
checkGLcall("glEnable(stateblock->textureDimensions[sampler])");
} else if(sampler < stateblock->lowest_disabled_stage) {
if(!isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) {
activate_dimensions(sampler, stateblock, context);
texture_activate_dimensions(sampler, stateblock, context);
}
if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && sampler == 0) {
@ -2553,7 +2441,7 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont
if(sampler < stateblock->lowest_disabled_stage) {
/* TODO: What should I do with pixel shaders here ??? */
if(!isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) {
activate_dimensions(sampler, stateblock, context);
texture_activate_dimensions(sampler, stateblock, context);
}
if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && sampler == 0) {

View File

@ -3384,3 +3384,117 @@ struct ffp_desc *find_ffp_shader(struct list *shaders, struct texture_stage_op o
void add_ffp_shader(struct list *shaders, struct ffp_desc *desc) {
list_add_head(shaders, &desc->entry);
}
/* Activates the texture dimension according to the bound D3D texture.
* Does not care for the colorop or correct gl texture unit(when using nvrc)
* Requires the caller to activate the correct unit before
*/
#define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
BOOL bumpmap = FALSE;
if(stage > 0 && (stateblock->textureState[stage - 1][WINED3DTSS_COLOROP] == WINED3DTOP_BUMPENVMAPLUMINANCE ||
stateblock->textureState[stage - 1][WINED3DTSS_COLOROP] == WINED3DTOP_BUMPENVMAP)) {
bumpmap = TRUE;
context->texShaderBumpMap |= (1 << stage);
} else {
context->texShaderBumpMap &= ~(1 << stage);
}
if(stateblock->textures[stage]) {
switch(stateblock->textureDimensions[stage]) {
case GL_TEXTURE_2D:
if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, bumpmap ? GL_OFFSET_TEXTURE_2D_NV : GL_TEXTURE_2D);
checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, ...)");
} else {
glDisable(GL_TEXTURE_3D);
checkGLcall("glDisable(GL_TEXTURE_3D)");
if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
}
if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
glDisable(GL_TEXTURE_RECTANGLE_ARB);
checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
}
glEnable(GL_TEXTURE_2D);
checkGLcall("glEnable(GL_TEXTURE_2D)");
}
break;
case GL_TEXTURE_RECTANGLE_ARB:
if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, bumpmap ? GL_OFFSET_TEXTURE_2D_NV : GL_TEXTURE_RECTANGLE_ARB);
checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, ...)");
} else {
glDisable(GL_TEXTURE_2D);
checkGLcall("glDisable(GL_TEXTURE_2D)");
glDisable(GL_TEXTURE_3D);
checkGLcall("glDisable(GL_TEXTURE_3D)");
if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
}
glEnable(GL_TEXTURE_RECTANGLE_ARB);
checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
}
break;
case GL_TEXTURE_3D:
if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_3D);
checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_3D)");
} else {
if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
}
if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
glDisable(GL_TEXTURE_RECTANGLE_ARB);
checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
}
glDisable(GL_TEXTURE_2D);
checkGLcall("glDisable(GL_TEXTURE_2D)");
glEnable(GL_TEXTURE_3D);
checkGLcall("glEnable(GL_TEXTURE_3D)");
}
break;
case GL_TEXTURE_CUBE_MAP_ARB:
if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_CUBE_MAP_ARB);
checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_CUBE_MAP_ARB)");
} else {
glDisable(GL_TEXTURE_2D);
checkGLcall("glDisable(GL_TEXTURE_2D)");
glDisable(GL_TEXTURE_3D);
checkGLcall("glDisable(GL_TEXTURE_3D)");
if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
glDisable(GL_TEXTURE_RECTANGLE_ARB);
checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
}
glEnable(GL_TEXTURE_CUBE_MAP_ARB);
checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
}
break;
}
} else {
if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE);
checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE)");
} else {
glEnable(GL_TEXTURE_2D);
checkGLcall("glEnable(GL_TEXTURE_2D)");
glDisable(GL_TEXTURE_3D);
checkGLcall("glDisable(GL_TEXTURE_3D)");
if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
}
if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
glDisable(GL_TEXTURE_RECTANGLE_ARB);
checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
}
/* Binding textures is done by samplers. A dummy texture will be bound */
}
}
}
#undef GLINFO_LOCATION

View File

@ -1737,6 +1737,7 @@ GLenum CompareFunc(DWORD func);
void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3);
void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3, INT texture_idx, DWORD dst);
void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed, DWORD coordtype);
void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context);
void surface_set_compatible_renderbuffer(IWineD3DSurface *iface, unsigned int width, unsigned int height);
GLenum surface_get_gl_buffer(IWineD3DSurface *iface, IWineD3DSwapChain *swapchain);