/** * \note This routine refers to derived texture matrix values to * compute the ENABLE_TEXMAT flags, but is only called on * _NEW_TEXTURE_OBJECT/STATE. On changes to _NEW_TEXTURE_MATRIX, * the ENABLE_TEXMAT flags are updated by _mesa_update_texture_matrices, * above. * * \param ctx GL context. */ void _mesa_update_texture_state(struct gl_context *ctx) { struct gl_program *prog[MESA_SHADER_STAGES]; int i; int old_max_unit = ctx->Texture._MaxEnabledTexImageUnit; BITSET_DECLARE(enabled_texture_units, MAX_COMBINED_TEXTURE_IMAGE_UNITS); memcpy(prog, ctx->_Shader->CurrentProgram, sizeof(prog)); if (prog[MESA_SHADER_FRAGMENT] == NULL && _mesa_arb_fragment_program_enabled(ctx)) { prog[MESA_SHADER_FRAGMENT] = ctx->FragmentProgram.Current; } /* TODO: only set this if there are actual changes */ ctx->NewState |= _NEW_TEXTURE_OBJECT | _NEW_TEXTURE_STATE; ctx->Texture._GenFlags = 0x0; ctx->Texture._TexMatEnabled = 0x0; ctx->Texture._TexGenEnabled = 0x0; ctx->Texture._MaxEnabledTexImageUnit = -1; ctx->Texture._EnabledCoordUnits = 0x0; memset(&enabled_texture_units, 0, sizeof(enabled_texture_units)); /* First, walk over our programs pulling in all the textures for them. * Programs dictate specific texture targets to be enabled, and for a draw * call to be valid they can't conflict about which texture targets are * used. */ update_program_texture_state(ctx, prog, enabled_texture_units); /* Also pull in any textures necessary for fixed function fragment shading. */ if (!prog[MESA_SHADER_FRAGMENT]) update_ff_texture_state(ctx, enabled_texture_units); /* Now, clear out the _Current of any disabled texture units. */ for (i = 0; i <= ctx->Texture._MaxEnabledTexImageUnit; i++) { if (!BITSET_TEST(enabled_texture_units, i)) _mesa_reference_texobj(&ctx->Texture.Unit[i]._Current, NULL); } for (i = ctx->Texture._MaxEnabledTexImageUnit + 1; i <= old_max_unit; i++) { _mesa_reference_texobj(&ctx->Texture.Unit[i]._Current, NULL); } /* add fallback texture for SampleMapATI if there is nothing */ if (_mesa_ati_fragment_shader_enabled(ctx) && ctx->ATIFragmentShader.Current->Program) fix_missing_textures_for_atifs(ctx, ctx->ATIFragmentShader.Current->Program, enabled_texture_units); if (!prog[MESA_SHADER_FRAGMENT] || !prog[MESA_SHADER_VERTEX]) update_texgen(ctx); }
/** * \note This routine refers to derived texture matrix values to * compute the ENABLE_TEXMAT flags, but is only called on * _NEW_TEXTURE. On changes to _NEW_TEXTURE_MATRIX, the ENABLE_TEXMAT * flags are updated by _mesa_update_texture_matrices, above. * * \param ctx GL context. */ static void update_texture_state( struct gl_context *ctx ) { struct gl_program *prog[MESA_SHADER_STAGES]; int i; int old_max_unit = ctx->Texture._MaxEnabledTexImageUnit; BITSET_DECLARE(enabled_texture_units, MAX_COMBINED_TEXTURE_IMAGE_UNITS); for (i = 0; i < MESA_SHADER_STAGES; i++) { if (ctx->_Shader->CurrentProgram[i] && ctx->_Shader->CurrentProgram[i]->LinkStatus) { prog[i] = ctx->_Shader->CurrentProgram[i]->_LinkedShaders[i]->Program; } else { if (i == MESA_SHADER_FRAGMENT && ctx->FragmentProgram._Enabled) prog[i] = &ctx->FragmentProgram.Current->Base; else prog[i] = NULL; } } /* TODO: only set this if there are actual changes */ ctx->NewState |= _NEW_TEXTURE; ctx->Texture._GenFlags = 0x0; ctx->Texture._TexMatEnabled = 0x0; ctx->Texture._TexGenEnabled = 0x0; ctx->Texture._MaxEnabledTexImageUnit = -1; ctx->Texture._EnabledCoordUnits = 0x0; memset(&enabled_texture_units, 0, sizeof(enabled_texture_units)); /* First, walk over our programs pulling in all the textures for them. * Programs dictate specific texture targets to be enabled, and for a draw * call to be valid they can't conflict about which texture targets are * used. */ update_program_texture_state(ctx, prog, enabled_texture_units); /* Also pull in any textures necessary for fixed function fragment shading. */ if (!prog[MESA_SHADER_FRAGMENT]) update_ff_texture_state(ctx, enabled_texture_units); /* Now, clear out the _Current of any disabled texture units. */ for (i = 0; i <= ctx->Texture._MaxEnabledTexImageUnit; i++) { if (!BITSET_TEST(enabled_texture_units, i)) _mesa_reference_texobj(&ctx->Texture.Unit[i]._Current, NULL); } for (i = ctx->Texture._MaxEnabledTexImageUnit + 1; i <= old_max_unit; i++) { _mesa_reference_texobj(&ctx->Texture.Unit[i]._Current, NULL); } if (!prog[MESA_SHADER_FRAGMENT] || !prog[MESA_SHADER_VERTEX]) update_texgen(ctx); }