+static struct gl_texture_object *
+update_single_program_texture(struct gl_context *ctx, struct gl_program *prog,
+ int s)
+{
+ gl_texture_index target_index;
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_sampler_object *sampler;
+ int unit;
+
+ if (!(prog->SamplersUsed & (1 << s)))
+ return NULL;
+
+ unit = prog->SamplerUnits[s];
+ texUnit = &ctx->Texture.Unit[unit];
+
+ /* Note: If more than one bit was set in TexturesUsed[unit], then we should
+ * have had the draw call rejected already. From the GL 4.4 specification,
+ * section 7.10 ("Samplers"):
+ *
+ * "It is not allowed to have variables of different sampler types
+ * pointing to the same texture image unit within a program
+ * object. This situation can only be detected at the next rendering
+ * command issued which triggers shader invocations, and an
+ * INVALID_OPERATION error will then be generated."
+ */
+ target_index = ffs(prog->TexturesUsed[unit]) - 1;
+ texObj = texUnit->CurrentTex[target_index];
+
+ sampler = texUnit->Sampler ?
+ texUnit->Sampler : &texObj->Sampler;
+
+ if (likely(texObj)) {
+ if (_mesa_is_texture_complete(texObj, sampler))
+ return texObj;
+
+ _mesa_test_texobj_completeness(ctx, texObj);
+ if (_mesa_is_texture_complete(texObj, sampler))
+ return texObj;
+ }
+
+ /* If we've reached this point, we didn't find a complete texture of the
+ * shader's target. From the GL 4.4 core specification, section 11.1.3.5
+ * ("Texture Access"):
+ *
+ * "If a sampler is used in a shader and the sampler’s associated
+ * texture is not complete, as defined in section 8.17, (0, 0, 0, 1)
+ * will be returned for a non-shadow sampler and 0 for a shadow
+ * sampler."
+ *
+ * Mesa implements this by creating a hidden texture object with a pixel of
+ * that value.
+ */
+ texObj = _mesa_get_fallback_texture(ctx, target_index);
+ assert(texObj);
+
+ return texObj;
+}
+
+static void
+update_program_texture_state(struct gl_context *ctx, struct gl_program **prog,
+ BITSET_WORD *enabled_texture_units)
+{
+ int i;
+
+ for (i = 0; i < MESA_SHADER_STAGES; i++) {
+ int s;
+
+ if (!prog[i])
+ continue;
+
+ /* We can't only do the shifting trick as the loop condition because if
+ * sampler 31 is active, the next iteration tries to shift by 32, which is
+ * undefined.
+ */
+ for (s = 0; s < MAX_SAMPLERS && (1 << s) <= prog[i]->SamplersUsed; s++) {
+ struct gl_texture_object *texObj;
+
+ texObj = update_single_program_texture(ctx, prog[i], s);
+ if (texObj) {
+ int unit = prog[i]->SamplerUnits[s];
+ _mesa_reference_texobj(&ctx->Texture.Unit[unit]._Current, texObj);
+ BITSET_SET(enabled_texture_units, unit);
+ ctx->Texture._MaxEnabledTexImageUnit =
+ MAX2(ctx->Texture._MaxEnabledTexImageUnit, (int)unit);
+ }
+ }
+ }
+
+ if (prog[MESA_SHADER_FRAGMENT]) {
+ const GLuint coordMask = (1 << MAX_TEXTURE_COORD_UNITS) - 1;
+ ctx->Texture._EnabledCoordUnits |=
+ (prog[MESA_SHADER_FRAGMENT]->info.inputs_read >> VARYING_SLOT_TEX0) &
+ coordMask;
+ }
+}
+
+static void
+update_ff_texture_state(struct gl_context *ctx,
+ BITSET_WORD *enabled_texture_units)
+{
+ int unit;
+
+ for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ GLbitfield mask;
+ bool complete;
+
+ if (texUnit->Enabled == 0x0)
+ continue;
+
+ /* If a shader already dictated what texture target was used for this
+ * unit, just go along with it.
+ */
+ if (BITSET_TEST(enabled_texture_units, unit))
+ continue;
+
+ /* From the GL 4.4 compat specification, section 16.2 ("Texture Application"):
+ *
+ * "Texturing is enabled or disabled using the generic Enable and
+ * Disable commands, respectively, with the symbolic constants
+ * TEXTURE_1D, TEXTURE_2D, TEXTURE_RECTANGLE, TEXTURE_3D, or
+ * TEXTURE_CUBE_MAP to enable the one-, two-, rectangular,
+ * three-dimensional, or cube map texture, respectively. If more
+ * than one of these textures is enabled, the first one enabled
+ * from the following list is used:
+ *
+ * • cube map texture
+ * • three-dimensional texture
+ * • rectangular texture
+ * • two-dimensional texture
+ * • one-dimensional texture"
+ *
+ * Note that the TEXTURE_x_INDEX values are in high to low priority.
+ * Also:
+ *
+ * "If a texture unit is disabled or has an invalid or incomplete
+ * texture (as defined in section 8.17) bound to it, then blending
+ * is disabled for that texture unit. If the texture environment
+ * for a given enabled texture unit references a disabled texture
+ * unit, or an invalid or incomplete texture that is bound to
+ * another unit, then the results of texture blending are
+ * undefined."
+ */
+ complete = false;
+ mask = texUnit->Enabled;
+ while (mask) {
+ const int texIndex = u_bit_scan(&mask);
+ struct gl_texture_object *texObj = texUnit->CurrentTex[texIndex];
+ struct gl_sampler_object *sampler = texUnit->Sampler ?
+ texUnit->Sampler : &texObj->Sampler;
+
+ if (!_mesa_is_texture_complete(texObj, sampler)) {
+ _mesa_test_texobj_completeness(ctx, texObj);
+ }
+ if (_mesa_is_texture_complete(texObj, sampler)) {
+ _mesa_reference_texobj(&texUnit->_Current, texObj);
+ complete = true;
+ break;
+ }
+ }
+
+ if (!complete)
+ continue;
+
+ /* if we get here, we know this texture unit is enabled */
+ BITSET_SET(enabled_texture_units, unit);
+ ctx->Texture._MaxEnabledTexImageUnit =
+ MAX2(ctx->Texture._MaxEnabledTexImageUnit, (int)unit);
+
+ ctx->Texture._EnabledCoordUnits |= 1 << unit;
+
+ update_tex_combine(ctx, texUnit);
+ }
+}
+