{
struct ffp_desc parent;
GLuint shader;
+ unsigned int num_textures_used;
};
struct atifs_private_data
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);
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));
}
}
}
-/* 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];
* 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 */
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");
}
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) {
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) {
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
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);