/* per-unit state */
for (u = 0; u < src->Const.MaxCombinedTextureImageUnits; u++) {
- dst->Texture.Unit[u].Enabled = src->Texture.Unit[u].Enabled;
- dst->Texture.Unit[u].EnvMode = src->Texture.Unit[u].EnvMode;
- COPY_4V(dst->Texture.Unit[u].EnvColor, src->Texture.Unit[u].EnvColor);
- dst->Texture.Unit[u].TexGenEnabled = src->Texture.Unit[u].TexGenEnabled;
- dst->Texture.Unit[u].GenS = src->Texture.Unit[u].GenS;
- dst->Texture.Unit[u].GenT = src->Texture.Unit[u].GenT;
- dst->Texture.Unit[u].GenR = src->Texture.Unit[u].GenR;
- dst->Texture.Unit[u].GenQ = src->Texture.Unit[u].GenQ;
dst->Texture.Unit[u].LodBias = src->Texture.Unit[u].LodBias;
- /* GL_EXT_texture_env_combine */
- dst->Texture.Unit[u].Combine = src->Texture.Unit[u].Combine;
-
/*
* XXX strictly speaking, we should compare texture names/ids and
* bind textures in the dest context according to id. For now, only
_mesa_unlock_context_textures(dst);
}
}
+
+ for (u = 0; u < src->Const.MaxTextureCoordUnits; u++) {
+ dst->Texture.FixedFuncUnit[u].Enabled = src->Texture.FixedFuncUnit[u].Enabled;
+ dst->Texture.FixedFuncUnit[u].EnvMode = src->Texture.FixedFuncUnit[u].EnvMode;
+ COPY_4V(dst->Texture.FixedFuncUnit[u].EnvColor, src->Texture.FixedFuncUnit[u].EnvColor);
+ dst->Texture.FixedFuncUnit[u].TexGenEnabled = src->Texture.FixedFuncUnit[u].TexGenEnabled;
+ dst->Texture.FixedFuncUnit[u].GenS = src->Texture.FixedFuncUnit[u].GenS;
+ dst->Texture.FixedFuncUnit[u].GenT = src->Texture.FixedFuncUnit[u].GenT;
+ dst->Texture.FixedFuncUnit[u].GenR = src->Texture.FixedFuncUnit[u].GenR;
+ dst->Texture.FixedFuncUnit[u].GenQ = src->Texture.FixedFuncUnit[u].GenQ;
+
+ /* GL_EXT_texture_env_combine */
+ dst->Texture.FixedFuncUnit[u].Combine = src->Texture.FixedFuncUnit[u].Combine;
+ }
}
void
_mesa_print_texunit_state( struct gl_context *ctx, GLuint unit )
{
- const struct gl_texture_unit *texUnit = ctx->Texture.Unit + unit;
+ const struct gl_fixedfunc_texture_unit *texUnit = ctx->Texture.FixedFuncUnit + unit;
printf("Texture Unit %d\n", unit);
printf(" GL_TEXTURE_ENV_MODE = %s\n", _mesa_enum_to_string(texUnit->EnvMode));
printf(" GL_COMBINE_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.ModeRGB));
}
}
+
+ /* The below flush call seems useless because
+ * gl_context::Texture::CurrentUnit is not used by
+ * _mesa_update_texture_state() and friends.
+ *
+ * However removing the flush
+ * introduced some blinking textures in UT2004. More investigation is
+ * needed to find the root cause.
+ *
+ * https://bugs.freedesktop.org/show_bug.cgi?id=105436
+ */
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE_STATE);
+
ctx->Texture.CurrentUnit = texUnit;
if (ctx->Transform.MatrixMode == GL_TEXTURE) {
/* update current stack pointer */
static void
-pack_tex_combine(struct gl_texture_unit *texUnit)
+pack_tex_combine(struct gl_fixedfunc_texture_unit *texUnit)
{
struct gl_tex_env_combine_state *state = texUnit->_CurrentCombine;
struct gl_tex_env_combine_packed *packed = &texUnit->_CurrentCombinePacked;
* Examine texture unit's combine/env state to update derived state.
*/
static void
-update_tex_combine(struct gl_context *ctx, struct gl_texture_unit *texUnit)
+update_tex_combine(struct gl_context *ctx,
+ struct gl_texture_unit *texUnit,
+ struct gl_fixedfunc_texture_unit *fftexUnit)
{
struct gl_tex_env_combine_state *combine;
* state, or the combiner state which is derived from traditional texenv
* mode.
*/
- if (texUnit->EnvMode == GL_COMBINE ||
- texUnit->EnvMode == GL_COMBINE4_NV) {
- texUnit->_CurrentCombine = & texUnit->Combine;
+ if (fftexUnit->EnvMode == GL_COMBINE ||
+ fftexUnit->EnvMode == GL_COMBINE4_NV) {
+ fftexUnit->_CurrentCombine = & fftexUnit->Combine;
}
else {
const struct gl_texture_object *texObj = texUnit->_Current;
if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT) {
format = texObj->DepthMode;
}
- calculate_derived_texenv(&texUnit->_EnvMode, texUnit->EnvMode, format);
- texUnit->_CurrentCombine = & texUnit->_EnvMode;
+ calculate_derived_texenv(&fftexUnit->_EnvMode, fftexUnit->EnvMode, format);
+ fftexUnit->_CurrentCombine = & fftexUnit->_EnvMode;
}
- combine = texUnit->_CurrentCombine;
+ combine = fftexUnit->_CurrentCombine;
/* Determine number of source RGB terms in the combiner function */
switch (combine->ModeRGB) {
break;
case GL_ADD:
case GL_ADD_SIGNED:
- if (texUnit->EnvMode == GL_COMBINE4_NV)
+ if (fftexUnit->EnvMode == GL_COMBINE4_NV)
combine->_NumArgsRGB = 4;
else
combine->_NumArgsRGB = 2;
break;
case GL_ADD:
case GL_ADD_SIGNED:
- if (texUnit->EnvMode == GL_COMBINE4_NV)
+ if (fftexUnit->EnvMode == GL_COMBINE4_NV)
combine->_NumArgsA = 4;
else
combine->_NumArgsA = 2;
break;
}
- pack_tex_combine(texUnit);
+ pack_tex_combine(fftexUnit);
}
static void
/* Setup texgen for those texture coordinate sets that are in use */
for (unit = 0; unit < ctx->Const.MaxTextureCoordUnits; unit++) {
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ struct gl_fixedfunc_texture_unit *texUnit =
+ &ctx->Texture.FixedFuncUnit[unit];
texUnit->_GenFlags = 0x0;
texUnit->Sampler : &texObj->Sampler;
if (likely(texObj)) {
- if (_mesa_is_texture_complete(texObj, sampler))
+ if (_mesa_is_texture_complete(texObj, sampler,
+ ctx->Const.ForceIntegerTexNearest))
return texObj;
_mesa_test_texobj_completeness(ctx, texObj);
- if (_mesa_is_texture_complete(texObj, sampler))
+ if (_mesa_is_texture_complete(texObj, sampler,
+ ctx->Const.ForceIntegerTexNearest))
return texObj;
}
struct gl_texture_object *texObj;
texObj = update_single_program_texture(ctx, prog, unit);
- if (!texObj)
- return;
_mesa_reference_texobj(&ctx->Texture.Unit[unit]._Current, texObj);
BITSET_SET(enabled_texture_units, unit);
for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ struct gl_fixedfunc_texture_unit *fftexUnit =
+ &ctx->Texture.FixedFuncUnit[unit];
GLbitfield mask;
bool complete;
- if (texUnit->Enabled == 0x0)
+ if (fftexUnit->Enabled == 0x0)
continue;
/* If a shader already dictated what texture target was used for this
* undefined."
*/
complete = false;
- mask = texUnit->Enabled;
+ mask = fftexUnit->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)) {
+ if (!_mesa_is_texture_complete(texObj, sampler,
+ ctx->Const.ForceIntegerTexNearest)) {
_mesa_test_texobj_completeness(ctx, texObj);
}
- if (_mesa_is_texture_complete(texObj, sampler)) {
+ if (_mesa_is_texture_complete(texObj, sampler,
+ ctx->Const.ForceIntegerTexNearest)) {
_mesa_reference_texobj(&texUnit->_Current, texObj);
complete = true;
break;
ctx->Texture._EnabledCoordUnits |= 1 << unit;
- update_tex_combine(ctx, texUnit);
+ update_tex_combine(ctx, texUnit, fftexUnit);
+ }
+}
+
+static void
+fix_missing_textures_for_atifs(struct gl_context *ctx,
+ struct gl_program *prog,
+ BITSET_WORD *enabled_texture_units)
+{
+ GLbitfield mask = prog->SamplersUsed;
+
+ while (mask) {
+ const int s = u_bit_scan(&mask);
+ const int unit = prog->SamplerUnits[s];
+ const gl_texture_index target_index = ffs(prog->TexturesUsed[unit]) - 1;
+
+ if (!ctx->Texture.Unit[unit]._Current) {
+ struct gl_texture_object *texObj =
+ _mesa_get_fallback_texture(ctx, target_index);
+ _mesa_reference_texobj(&ctx->Texture.Unit[unit]._Current, texObj);
+ BITSET_SET(enabled_texture_units, unit);
+ ctx->Texture._MaxEnabledTexImageUnit =
+ MAX2(ctx->Texture._MaxEnabledTexImageUnit, (int)unit);
+ }
}
}
memcpy(prog, ctx->_Shader->CurrentProgram, sizeof(prog));
- if (prog[MESA_SHADER_FRAGMENT] == NULL) {
- if (_mesa_arb_fragment_program_enabled(ctx))
- prog[MESA_SHADER_FRAGMENT] = ctx->FragmentProgram.Current;
- else if (_mesa_ati_fragment_shader_enabled(ctx))
- prog[MESA_SHADER_FRAGMENT] = ctx->ATIFragmentShader.Current->Program;
+ 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 */
_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);
}
}
-/**
- * Initialize a texture unit.
- *
- * \param ctx GL context.
- * \param unit texture unit number to be initialized.
- */
-static void
-init_texture_unit( struct gl_context *ctx, GLuint unit )
-{
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
- GLuint tex;
-
- texUnit->EnvMode = GL_MODULATE;
- ASSIGN_4V( texUnit->EnvColor, 0.0, 0.0, 0.0, 0.0 );
-
- texUnit->Combine = default_combine_state;
- texUnit->_EnvMode = default_combine_state;
- texUnit->_CurrentCombine = & texUnit->_EnvMode;
-
- texUnit->TexGenEnabled = 0x0;
- texUnit->GenS.Mode = GL_EYE_LINEAR;
- texUnit->GenT.Mode = GL_EYE_LINEAR;
- texUnit->GenR.Mode = GL_EYE_LINEAR;
- texUnit->GenQ.Mode = GL_EYE_LINEAR;
- texUnit->GenS._ModeBit = TEXGEN_EYE_LINEAR;
- texUnit->GenT._ModeBit = TEXGEN_EYE_LINEAR;
- texUnit->GenR._ModeBit = TEXGEN_EYE_LINEAR;
- texUnit->GenQ._ModeBit = TEXGEN_EYE_LINEAR;
-
- /* Yes, these plane coefficients are correct! */
- ASSIGN_4V( texUnit->GenS.ObjectPlane, 1.0, 0.0, 0.0, 0.0 );
- ASSIGN_4V( texUnit->GenT.ObjectPlane, 0.0, 1.0, 0.0, 0.0 );
- ASSIGN_4V( texUnit->GenR.ObjectPlane, 0.0, 0.0, 0.0, 0.0 );
- ASSIGN_4V( texUnit->GenQ.ObjectPlane, 0.0, 0.0, 0.0, 0.0 );
- ASSIGN_4V( texUnit->GenS.EyePlane, 1.0, 0.0, 0.0, 0.0 );
- ASSIGN_4V( texUnit->GenT.EyePlane, 0.0, 1.0, 0.0, 0.0 );
- ASSIGN_4V( texUnit->GenR.EyePlane, 0.0, 0.0, 0.0, 0.0 );
- ASSIGN_4V( texUnit->GenQ.EyePlane, 0.0, 0.0, 0.0, 0.0 );
-
- /* initialize current texture object ptrs to the shared default objects */
- for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
- _mesa_reference_texobj(&texUnit->CurrentTex[tex],
- ctx->Shared->DefaultTex[tex]);
- }
-
- texUnit->_BoundTextures = 0;
-}
-
-
/**
* Initialize texture state for the given context.
*/
*/
ctx->Texture.CubeMapSeamless = ctx->API == API_OPENGLES2;
- for (u = 0; u < ARRAY_SIZE(ctx->Texture.Unit); u++)
- init_texture_unit(ctx, u);
+ for (u = 0; u < ARRAY_SIZE(ctx->Texture.Unit); u++) {
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u];
+ GLuint tex;
+
+ /* initialize current texture object ptrs to the shared default objects */
+ for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
+ _mesa_reference_texobj(&texUnit->CurrentTex[tex],
+ ctx->Shared->DefaultTex[tex]);
+ }
+
+ texUnit->_BoundTextures = 0;
+ }
+
+ for (u = 0; u < ARRAY_SIZE(ctx->Texture.FixedFuncUnit); u++) {
+ struct gl_fixedfunc_texture_unit *texUnit =
+ &ctx->Texture.FixedFuncUnit[u];
+
+ texUnit->EnvMode = GL_MODULATE;
+ ASSIGN_4V( texUnit->EnvColor, 0.0, 0.0, 0.0, 0.0 );
+
+ texUnit->Combine = default_combine_state;
+ texUnit->_EnvMode = default_combine_state;
+ texUnit->_CurrentCombine = & texUnit->_EnvMode;
+
+ texUnit->TexGenEnabled = 0x0;
+ texUnit->GenS.Mode = GL_EYE_LINEAR;
+ texUnit->GenT.Mode = GL_EYE_LINEAR;
+ texUnit->GenR.Mode = GL_EYE_LINEAR;
+ texUnit->GenQ.Mode = GL_EYE_LINEAR;
+ texUnit->GenS._ModeBit = TEXGEN_EYE_LINEAR;
+ texUnit->GenT._ModeBit = TEXGEN_EYE_LINEAR;
+ texUnit->GenR._ModeBit = TEXGEN_EYE_LINEAR;
+ texUnit->GenQ._ModeBit = TEXGEN_EYE_LINEAR;
+
+ /* Yes, these plane coefficients are correct! */
+ ASSIGN_4V( texUnit->GenS.ObjectPlane, 1.0, 0.0, 0.0, 0.0 );
+ ASSIGN_4V( texUnit->GenT.ObjectPlane, 0.0, 1.0, 0.0, 0.0 );
+ ASSIGN_4V( texUnit->GenR.ObjectPlane, 0.0, 0.0, 0.0, 0.0 );
+ ASSIGN_4V( texUnit->GenQ.ObjectPlane, 0.0, 0.0, 0.0, 0.0 );
+ ASSIGN_4V( texUnit->GenS.EyePlane, 1.0, 0.0, 0.0, 0.0 );
+ ASSIGN_4V( texUnit->GenT.EyePlane, 0.0, 1.0, 0.0, 0.0 );
+ ASSIGN_4V( texUnit->GenR.EyePlane, 0.0, 0.0, 0.0, 0.0 );
+ ASSIGN_4V( texUnit->GenQ.EyePlane, 0.0, 0.0, 0.0, 0.0 );
+ }
/* After we're done initializing the context's texture state the default
* texture objects' refcounts should be at least
return GL_FALSE;
/* GL_ARB_texture_buffer_object */
- _mesa_reference_buffer_object(ctx, &ctx->Texture.BufferObject,
- ctx->Shared->NullBufferObj);
+ _mesa_reference_buffer_object(ctx, &ctx->Texture.BufferObject, NULL);
ctx->Texture.NumCurrentTexUsed = 0;