Ejemplo n.º 1
0
/**
 * Free dynamically-allocted texture data attached to the given context.
 */
void
_mesa_free_texture_data(struct gl_context *ctx)
{
    GLuint u, tgt;

    /* unreference current textures */
    for (u = 0; u < ARRAY_SIZE(ctx->Texture.Unit); u++) {
        /* The _Current texture could account for another reference */
        _mesa_reference_texobj(&ctx->Texture.Unit[u]._Current, NULL);

        for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
            _mesa_reference_texobj(&ctx->Texture.Unit[u].CurrentTex[tgt], NULL);
        }
    }

    /* Free proxy texture objects */
    for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++)
        ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]);

    /* GL_ARB_texture_buffer_object */
    _mesa_reference_buffer_object(ctx, &ctx->Texture.BufferObject, NULL);

    for (u = 0; u < ARRAY_SIZE(ctx->Texture.Unit); u++) {
        _mesa_reference_sampler_object(ctx, &ctx->Texture.Unit[u].Sampler, NULL);
    }
}
Ejemplo n.º 2
0
void GLAPIENTRY
_mesa_BindImageTexture(GLuint unit, GLuint texture, GLint level,
                       GLboolean layered, GLint layer, GLenum access,
                       GLenum format)
{
   GET_CURRENT_CONTEXT(ctx);
   struct gl_image_unit *u;

   if (!validate_bind_image_texture(ctx, unit, texture, level,
                                    layered, layer, access, format))
      return;

   u = &ctx->ImageUnits[unit];

   FLUSH_VERTICES(ctx, 0);
   ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits;

   if (texture) {
      struct gl_texture_object *t = _mesa_lookup_texture(ctx, texture);

      if (!t) {
         _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(texture)");
         return;
      }

      /* From section 8.22 "Texture Image Loads and Stores" of the OpenGL ES
       * 3.1 spec:
       *
       * "An INVALID_OPERATION error is generated if texture is not the name
       *  of an immutable texture object."
       */
      if (_mesa_is_gles(ctx) && !t->Immutable) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "glBindImageTexture(!immutable)");
         return;
      }

      _mesa_reference_texobj(&u->TexObj, t);
   } else {
      _mesa_reference_texobj(&u->TexObj, NULL);
   }

   u->Level = level;
   u->Access = access;
   u->Format = format;
   u->_ActualFormat = _mesa_get_shader_image_format(format);

   if (u->TexObj && _mesa_tex_target_is_layered(u->TexObj->Target)) {
      u->Layered = layered;
      u->Layer = layer;
      u->_Layer = (u->Layered ? 0 : u->Layer);
   } else {
      u->Layered = GL_FALSE;
      u->Layer = 0;
   }

   if (ctx->Driver.BindImageTexture)
      ctx->Driver.BindImageTexture(ctx, u, u->TexObj, level, layered,
                                   layer, access, format);
}
Ejemplo n.º 3
0
/**
 * \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);
}
Ejemplo n.º 4
0
/**
 * \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);
}
Ejemplo n.º 5
0
void GLAPIENTRY
_mesa_BindImageTexture(GLuint unit, GLuint texture, GLint level,
                       GLboolean layered, GLint layer, GLenum access,
                       GLenum format)
{
   GET_CURRENT_CONTEXT(ctx);
   struct gl_texture_object *t = NULL;
   struct gl_image_unit *u;

   if (!validate_bind_image_texture(ctx, unit, texture, level,
                                    layered, layer, access, format))
      return;

   u = &ctx->ImageUnits[unit];

   FLUSH_VERTICES(ctx, 0);
   ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits;

   if (texture) {
      t = _mesa_lookup_texture(ctx, texture);
      if (!t) {
         _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(texture)");
         return;
      }

      _mesa_reference_texobj(&u->TexObj, t);
      u->Level = level;
      u->Access = access;
      u->Format = format;
      u->_ActualFormat = get_image_format(format);

      if (_mesa_tex_target_is_layered(t->Target)) {
         u->Layered = layered;
         u->Layer = (layered ? 0 : layer);
      } else {
         u->Layered = GL_FALSE;
         u->Layer = 0;
      }

   } else {
      _mesa_reference_texobj(&u->TexObj, NULL);
   }

   u->_Valid = validate_image_unit(ctx, u);

   if (ctx->Driver.BindImageTexture)
      ctx->Driver.BindImageTexture(ctx, u, t, level, layered,
                                   layer, access, format);
}
Ejemplo n.º 6
0
/**
 * Free all the data hanging off the given gl_framebuffer, but don't free
 * the gl_framebuffer object itself.
 */
void
_mesa_free_framebuffer_data(struct gl_framebuffer *fb)
{
   GLuint i;

   assert(fb);
   assert(fb->RefCount == 0);

   _glthread_DESTROY_MUTEX(fb->Mutex);

   for (i = 0; i < BUFFER_COUNT; i++) {
      struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
      if (att->Renderbuffer) {
         _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
      }
      if (att->Texture) {
         _mesa_reference_texobj(&att->Texture, NULL);
      }
      ASSERT(!att->Renderbuffer);
      ASSERT(!att->Texture);
      att->Type = GL_NONE;
   }

   /* unbind _Depth/_StencilBuffer to decr ref counts */
   _mesa_reference_renderbuffer(&fb->_DepthBuffer, NULL);
   _mesa_reference_renderbuffer(&fb->_StencilBuffer, NULL);
}
Ejemplo n.º 7
0
/**
 * Bind a texture object to an attachment point.
 * The previous binding, if any, will be removed first.
 */
void
_mesa_set_texture_attachment(GLcontext *ctx,
                             struct gl_framebuffer *fb,
                             struct gl_renderbuffer_attachment *att,
                             struct gl_texture_object *texObj,
                             GLenum texTarget, GLuint level, GLuint zoffset)
{
   if (att->Texture == texObj) {
      /* re-attaching same texture */
      ASSERT(att->Type == GL_TEXTURE);
   }
   else {
      /* new attachment */
      _mesa_remove_attachment(ctx, att);
      att->Type = GL_TEXTURE;
      assert(!att->Texture);
      _mesa_reference_texobj(&att->Texture, texObj);
   }

   /* always update these fields */
   att->TextureLevel = level;
   if (IS_CUBE_FACE(texTarget)) {
      att->CubeMapFace = texTarget - GL_TEXTURE_CUBE_MAP_POSITIVE_X;
   }
   else {
      att->CubeMapFace = 0;
   }
   att->Zoffset = zoffset;
   att->Complete = GL_FALSE;

   if (att->Texture->Image[att->CubeMapFace][att->TextureLevel]) {
      ctx->Driver.RenderTexture(ctx, fb, att);
   }
}
Ejemplo n.º 8
0
void GLAPIENTRY
_mesa_VDPAUUnregisterSurfaceNV(GLintptr surface)
{
   struct vdp_surface *surf = (struct vdp_surface *)surface;
   struct set_entry *entry;
   int i;
   GET_CURRENT_CONTEXT(ctx);

   if (!ctx->vdpDevice || !ctx->vdpGetProcAddress || !ctx->vdpSurfaces) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAUUnregisterSurfaceNV");
      return;
   }

   /* according to the spec it's ok when this is zero */
   if (surface == 0)
      return;

   entry = _mesa_set_search(ctx->vdpSurfaces, surf);
   if (!entry) {
      _mesa_error(ctx, GL_INVALID_VALUE, "VDPAUUnregisterSurfaceNV");
      return;
   }

   for (i = 0; i < MAX_TEXTURES; i++) {
      if (surf->textures[i]) {
         surf->textures[i]->Immutable = GL_FALSE;
         _mesa_reference_texobj(&surf->textures[i], NULL);
      }
   }

   _mesa_set_remove(ctx->vdpSurfaces, entry);
   free(surf);
}
Ejemplo n.º 9
0
/**
 * Used by glXCopyContext to copy texture state from one context to another.
 */
void
_mesa_copy_texture_state( const struct gl_context *src, struct gl_context *dst )
{
   GLuint u, tex;

   assert(src);
   assert(dst);

   dst->Texture.CurrentUnit = src->Texture.CurrentUnit;
   dst->Texture._GenFlags = src->Texture._GenFlags;
   dst->Texture._TexGenEnabled = src->Texture._TexGenEnabled;
   dst->Texture._TexMatEnabled = src->Texture._TexMatEnabled;

   /* per-unit state */
   for (u = 0; u < src->Const.MaxCombinedTextureImageUnits; u++) {
      dst->Texture.Unit[u].LodBias = src->Texture.Unit[u].LodBias;

      /*
       * XXX strictly speaking, we should compare texture names/ids and
       * bind textures in the dest context according to id.  For now, only
       * copy bindings if the contexts share the same pool of textures to
       * avoid refcounting bugs.
       */
      if (dst->Shared == src->Shared) {
         /* copy texture object bindings, not contents of texture objects */
         _mesa_lock_context_textures(dst);

         for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
            _mesa_reference_texobj(&dst->Texture.Unit[u].CurrentTex[tex],
                                   src->Texture.Unit[u].CurrentTex[tex]);
            if (src->Texture.Unit[u].CurrentTex[tex]) {
               dst->Texture.NumCurrentTexUsed =
                  MAX2(dst->Texture.NumCurrentTexUsed, u + 1);
            }
         }
         dst->Texture.Unit[u]._BoundTextures = src->Texture.Unit[u]._BoundTextures;
         _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;
   }
}
Ejemplo n.º 10
0
Archivo: texobj.c Proyecto: RAOF/mesa
/**
 * Delete named textures.
 *
 * \param n number of textures to be deleted.
 * \param textures array of texture IDs to be deleted.
 *
 * \sa glDeleteTextures().
 *
 * If we're about to delete a texture that's currently bound to any
 * texture unit, unbind the texture first.  Decrement the reference
 * count on the texture object and delete it if it's zero.
 * Recall that texture objects can be shared among several rendering
 * contexts.
 */
void GLAPIENTRY
_mesa_DeleteTextures( GLsizei n, const GLuint *textures)
{
   GET_CURRENT_CONTEXT(ctx);
   GLint i;

   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
      _mesa_debug(ctx, "glDeleteTextures %d\n", n);

   FLUSH_VERTICES(ctx, 0); /* too complex */

   if (!textures)
      return;

   for (i = 0; i < n; i++) {
      if (textures[i] > 0) {
         struct gl_texture_object *delObj
            = _mesa_lookup_texture(ctx, textures[i]);

         if (delObj) {
            _mesa_lock_texture(ctx, delObj);

            /* Check if texture is bound to any framebuffer objects.
             * If so, unbind.
             * See section 4.4.2.3 of GL_EXT_framebuffer_object.
             */
            unbind_texobj_from_fbo(ctx, delObj);

            /* Check if this texture is currently bound to any texture units.
             * If so, unbind it.
             */
            unbind_texobj_from_texunits(ctx, delObj);

            _mesa_unlock_texture(ctx, delObj);

            ctx->NewState |= _NEW_TEXTURE;

            /* The texture _name_ is now free for re-use.
             * Remove it from the hash table now.
             */
            _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
            _mesa_HashRemove(ctx->Shared->TexObjects, delObj->Name);
            _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);

            /* Unreference the texobj.  If refcount hits zero, the texture
             * will be deleted.
             */
            _mesa_reference_texobj(&delObj, NULL);
         }
      }
   }
}
Ejemplo n.º 11
0
/**
 * Update the default texture objects in the given context to reference those
 * specified in the shared state and release those referencing the old
 * shared state.
 */
void
_mesa_update_default_objects_texture(struct gl_context *ctx)
{
    GLuint u, tex;

    for (u = 0; u < ARRAY_SIZE(ctx->Texture.Unit); u++) {
        struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u];
        for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
            _mesa_reference_texobj(&texUnit->CurrentTex[tex],
                                   ctx->Shared->DefaultTex[tex]);
        }
    }
}
Ejemplo n.º 12
0
/**
 * Used by glXCopyContext to copy texture state from one context to another.
 */
void
_mesa_copy_texture_state( const GLcontext *src, GLcontext *dst )
{
   GLuint u, tex;

   ASSERT(src);
   ASSERT(dst);

   dst->Texture.CurrentUnit = src->Texture.CurrentUnit;
   dst->Texture._GenFlags = src->Texture._GenFlags;
   dst->Texture._TexGenEnabled = src->Texture._TexGenEnabled;
   dst->Texture._TexMatEnabled = src->Texture._TexMatEnabled;
   dst->Texture.SharedPalette = src->Texture.SharedPalette;

   /* per-unit state */
   for (u = 0; u < src->Const.MaxTextureImageUnits; 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;

      /* GL_ATI_envmap_bumpmap - need this? */
      dst->Texture.Unit[u].BumpTarget = src->Texture.Unit[u].BumpTarget;
      COPY_4V(dst->Texture.Unit[u].RotMatrix, src->Texture.Unit[u].RotMatrix);

      /*
       * XXX strictly speaking, we should compare texture names/ids and
       * bind textures in the dest context according to id.  For now, only
       * copy bindings if the contexts share the same pool of textures to
       * avoid refcounting bugs.
       */
      if (dst->Shared == src->Shared) {
         /* copy texture object bindings, not contents of texture objects */
         _mesa_lock_context_textures(dst);

         for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
            _mesa_reference_texobj(&dst->Texture.Unit[u].CurrentTex[tex],
                                   src->Texture.Unit[u].CurrentTex[tex]);
         }
         _mesa_unlock_context_textures(dst);
      }
   }
}
Ejemplo n.º 13
0
static inline void
update_single_program_texture_state(struct gl_context *ctx,
                                    struct gl_program *prog,
                                    int unit,
                                    BITSET_WORD *enabled_texture_units)
{
   struct gl_texture_object *texObj;

   texObj = update_single_program_texture(ctx, prog, unit);

   _mesa_reference_texobj(&ctx->Texture.Unit[unit]._Current, texObj);
   BITSET_SET(enabled_texture_units, unit);
   ctx->Texture._MaxEnabledTexImageUnit =
      MAX2(ctx->Texture._MaxEnabledTexImageUnit, (int)unit);
}
Ejemplo n.º 14
0
/**
 * Check if the given texture object is bound to any texture image units and
 * unbind it if so (revert to default textures).
 */
static void
unbind_texobj_from_texunits(struct gl_context *ctx,
                            struct gl_texture_object *texObj)
{
   GLuint tex;
   struct gl_texture_unit *unit = &ctx->Texture.Unit;
   for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
      if (texObj == unit->CurrentTex[tex]) {
         _mesa_reference_texobj(&unit->CurrentTex[tex],
                                ctx->Shared->DefaultTex[tex]);
         ASSERT(unit->CurrentTex[tex]);
         break;
      }
   }
}
Ejemplo n.º 15
0
/**
 * Used by glXCopyContext to copy texture state from one context to another.
 */
void
_mesa_copy_texture_state( const GLcontext *src, GLcontext *dst )
{
   GLuint u, tex;

   ASSERT(src);
   ASSERT(dst);

   dst->Texture.CurrentUnit = src->Texture.CurrentUnit;
   dst->Texture._GenFlags = src->Texture._GenFlags;
   dst->Texture._TexGenEnabled = src->Texture._TexGenEnabled;
   dst->Texture._TexMatEnabled = src->Texture._TexMatEnabled;
   dst->Texture.SharedPalette = src->Texture.SharedPalette;

   /* per-unit state */
   for (u = 0; u < src->Const.MaxTextureImageUnits; 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;

      /* GL_ATI_envmap_bumpmap - need this? */
      dst->Texture.Unit[u].BumpTarget = src->Texture.Unit[u].BumpTarget;
      COPY_4V(dst->Texture.Unit[u].RotMatrix, src->Texture.Unit[u].RotMatrix);


      /* copy texture object bindings, not contents of texture objects */
      _mesa_lock_context_textures(dst);

      for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
         _mesa_reference_texobj(&dst->Texture.Unit[u].CurrentTex[tex],
                                src->Texture.Unit[u].CurrentTex[tex]);
      }

      _mesa_unlock_context_textures(dst);
   }
}
Ejemplo n.º 16
0
/**
 * Delete named textures.
 *
 * \param n number of textures to be deleted.
 * \param textures array of texture IDs to be deleted.
 *
 * \sa glDeleteTextures().
 *
 * If we're about to delete a texture that's currently bound to any
 * texture unit, unbind the texture first.  Decrement the reference
 * count on the texture object and delete it if it's zero.
 * Recall that texture objects can be shared among several rendering
 * contexts.
 */
void GLAPIENTRY
_mesa_DeleteTextures( GLsizei n, const GLuint *textures)
{
   GET_CURRENT_CONTEXT(ctx);
   GLint i;
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex */

   if (!textures)
      return;

   for (i = 0; i < n; i++) {
      if (textures[i] > 0) {
         struct gl_texture_object *delObj
            = _mesa_lookup_texture(ctx, textures[i]);

         if (delObj) {
            _mesa_lock_texture(ctx, delObj);

            /* Check if this texture is currently bound to any texture units.
             * If so, unbind it.
             */
            unbind_texobj_from_texunits(ctx, delObj);

            _mesa_unlock_texture(ctx, delObj);

            ctx->NewState |= _NEW_TEXTURE;

            /* The texture _name_ is now free for re-use.
             * Remove it from the hash table now.
             */
            _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
            _mesa_HashRemove(ctx->Shared->TexObjects, delObj->Name);
            _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);

            /* Unreference the texobj.  If refcount hits zero, the texture
             * will be deleted.
             */
            _mesa_reference_texobj(&delObj, NULL);
         }
      }
   }
}
Ejemplo n.º 17
0
/**
 * Remove any texture or renderbuffer attached to the given attachment
 * point.  Update reference counts, etc.
 */
void
_mesa_remove_attachment(GLcontext *ctx, struct gl_renderbuffer_attachment *att)
{
   if (att->Type == GL_TEXTURE) {
      ASSERT(att->Texture);
      if (ctx->Driver.FinishRenderTexture) {
         /* tell driver we're done rendering to this texobj */
         ctx->Driver.FinishRenderTexture(ctx, att);
      }
      _mesa_reference_texobj(&att->Texture, NULL); /* unbind */
      ASSERT(!att->Texture);
   }
   if (att->Type == GL_TEXTURE || att->Type == GL_RENDERBUFFER_EXT) {
      ASSERT(!att->Texture);
      _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); /* unbind */
      ASSERT(!att->Renderbuffer);
   }
   att->Type = GL_NONE;
   att->Complete = GL_TRUE;
}
Ejemplo n.º 18
0
/**
 * 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;
}
Ejemplo n.º 19
0
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);
      }
   }
}
/**
 * Free all the data hanging off the given gl_framebuffer, but don't free
 * the gl_framebuffer object itself.
 */
void
_mesa_free_framebuffer_data(struct gl_framebuffer *fb)
{
   GLuint i;

   assert(fb);
   assert(fb->RefCount == 0);

   mtx_destroy(&fb->Mutex);

   for (i = 0; i < BUFFER_COUNT; i++) {
      struct gl_renderbuffer_attachment *att = &fb->Attachment[i];
      if (att->Renderbuffer) {
         _mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
      }
      if (att->Texture) {
         _mesa_reference_texobj(&att->Texture, NULL);
      }
      assert(!att->Renderbuffer);
      assert(!att->Texture);
      att->Type = GL_NONE;
   }
}
Ejemplo n.º 21
0
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]->InputsRead >> VARYING_SLOT_TEX0) &
            coordMask;
    }
}
Ejemplo n.º 22
0
static GLintptr
register_surface(struct gl_context *ctx, GLboolean isOutput,
                 const GLvoid *vdpSurface, GLenum target,
                 GLsizei numTextureNames, const GLuint *textureNames)
{
   struct vdp_surface *surf;
   int i;

   if (!ctx->vdpDevice || !ctx->vdpGetProcAddress || !ctx->vdpSurfaces) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "VDPAURegisterSurfaceNV");
      return (GLintptr)NULL;
   }

   if (target != GL_TEXTURE_2D && target != GL_TEXTURE_RECTANGLE) {
      _mesa_error(ctx, GL_INVALID_ENUM, "VDPAURegisterSurfaceNV");
      return (GLintptr)NULL;
   }

   if (target == GL_TEXTURE_RECTANGLE && !ctx->Extensions.NV_texture_rectangle) {
      _mesa_error(ctx, GL_INVALID_ENUM, "VDPAURegisterSurfaceNV");
      return (GLintptr)NULL;
   }

   surf = CALLOC_STRUCT( vdp_surface );
   if (surf == NULL) {
      _mesa_error_no_memory("VDPAURegisterSurfaceNV");
      return (GLintptr)NULL;
   }

   surf->vdpSurface = vdpSurface;
   surf->target = target;
   surf->access = GL_READ_WRITE;
   surf->state = GL_SURFACE_REGISTERED_NV;
   surf->output = isOutput;
   for (i = 0; i < numTextureNames; ++i) {
      struct gl_texture_object *tex;
      tex  = _mesa_lookup_texture(ctx, textureNames[i]);
      if (tex == NULL) {
         free(surf);
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "VDPAURegisterSurfaceNV(texture ID not found)");
         return (GLintptr)NULL;
      }

      _mesa_lock_texture(ctx, tex);

      if (tex->Immutable) {
         _mesa_unlock_texture(ctx, tex);
         free(surf);
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "VDPAURegisterSurfaceNV(texture is immutable)");
         return (GLintptr)NULL;
      }

      if (tex->Target == 0)
         tex->Target = target;
      else if (tex->Target != target) {
         _mesa_unlock_texture(ctx, tex);
         free(surf);
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "VDPAURegisterSurfaceNV(target mismatch)");
         return (GLintptr)NULL;
      }

      /* This will disallow respecifying the storage. */
      tex->Immutable = GL_TRUE;
      _mesa_unlock_texture(ctx, tex);

      _mesa_reference_texobj(&surf->textures[i], tex);
   }

   _mesa_set_add(ctx->vdpSurfaces, surf);

   return (GLintptr)surf;
}
Ejemplo n.º 23
0
void GLAPIENTRY
_mesa_BindImageTextures(GLuint first, GLsizei count, const GLuint *textures)
{
   GET_CURRENT_CONTEXT(ctx);
   int i;

   if (!ctx->Extensions.ARB_shader_image_load_store) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glBindImageTextures()");
      return;
   }

   if (first + count > ctx->Const.MaxImageUnits) {
      /* The ARB_multi_bind spec says:
       *
       *    "An INVALID_OPERATION error is generated if <first> + <count>
       *     is greater than the number of image units supported by
       *     the implementation."
       */
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "glBindImageTextures(first=%u + count=%d > the value of "
                  "GL_MAX_IMAGE_UNITS=%u)",
                  first, count, ctx->Const.MaxImageUnits);
      return;
   }

   /* Assume that at least one binding will be changed */
   FLUSH_VERTICES(ctx, 0);
   ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits;

   /* Note that the error semantics for multi-bind commands differ from
    * those of other GL commands.
    *
    * The Issues section in the ARB_multi_bind spec says:
    *
    *    "(11) Typically, OpenGL specifies that if an error is generated by
    *          a command, that command has no effect.  This is somewhat
    *          unfortunate for multi-bind commands, because it would require
    *          a first pass to scan the entire list of bound objects for
    *          errors and then a second pass to actually perform the
    *          bindings.  Should we have different error semantics?
    *
    *       RESOLVED:  Yes.  In this specification, when the parameters for
    *       one of the <count> binding points are invalid, that binding
    *       point is not updated and an error will be generated.  However,
    *       other binding points in the same command will be updated if
    *       their parameters are valid and no other error occurs."
    */

   _mesa_begin_texture_lookups(ctx);

   for (i = 0; i < count; i++) {
      struct gl_image_unit *u = &ctx->ImageUnits[first + i];
      const GLuint texture = textures ? textures[i] : 0;

      if (texture != 0) {
         struct gl_texture_object *texObj;
         GLenum tex_format;

         if (!u->TexObj || u->TexObj->Name != texture) {
            texObj = _mesa_lookup_texture_locked(ctx, texture);
            if (!texObj) {
               /* The ARB_multi_bind spec says:
                *
                *    "An INVALID_OPERATION error is generated if any value
                *     in <textures> is not zero or the name of an existing
                *     texture object (per binding)."
                */
               _mesa_error(ctx, GL_INVALID_OPERATION,
                           "glBindImageTextures(textures[%d]=%u "
                           "is not zero or the name of an existing texture "
                           "object)", i, texture);
               continue;
            }
         } else {
            texObj = u->TexObj;
         }

         if (texObj->Target == GL_TEXTURE_BUFFER) {
            tex_format = texObj->BufferObjectFormat;
         } else {
            struct gl_texture_image *image = texObj->Image[0][0];

            if (!image || image->Width == 0 || image->Height == 0 ||
                image->Depth == 0) {
               /* The ARB_multi_bind spec says:
                *
                *    "An INVALID_OPERATION error is generated if the width,
                *     height, or depth of the level zero texture image of
                *     any texture in <textures> is zero (per binding)."
                */
               _mesa_error(ctx, GL_INVALID_OPERATION,
                           "glBindImageTextures(the width, height or depth "
                           "of the level zero texture image of "
                           "textures[%d]=%u is zero)", i, texture);
               continue;
            }

            tex_format = image->InternalFormat;
         }

         if (_mesa_get_shader_image_format(tex_format) == MESA_FORMAT_NONE) {
            /* The ARB_multi_bind spec says:
             *
             *   "An INVALID_OPERATION error is generated if the internal
             *    format of the level zero texture image of any texture
             *    in <textures> is not found in table 8.33 (per binding)."
             */
            _mesa_error(ctx, GL_INVALID_OPERATION,
                        "glBindImageTextures(the internal format %s of "
                        "the level zero texture image of textures[%d]=%u "
                        "is not supported)",
                        _mesa_lookup_enum_by_nr(tex_format),
                        i, texture);
            continue;
         }

         /* Update the texture binding */
         _mesa_reference_texobj(&u->TexObj, texObj);
         u->Level = 0;
         u->Layered = _mesa_tex_target_is_layered(texObj->Target);
         u->Layer = 0;
         u->Access = GL_READ_WRITE;
         u->Format = tex_format;
         u->_ActualFormat = _mesa_get_shader_image_format(tex_format);
         u->_Valid = validate_image_unit(ctx, u);
      } else {
         /* Unbind the texture from the unit */
         _mesa_reference_texobj(&u->TexObj, NULL);
         u->Level = 0;
         u->Layered = GL_FALSE;
         u->Layer = 0;
         u->Access = GL_READ_ONLY;
         u->Format = GL_R8;
         u->_ActualFormat = MESA_FORMAT_R_UNORM8;
         u->_Valid = GL_FALSE;
      }

      /* Pass the BindImageTexture call down to the device driver */
      if (ctx->Driver.BindImageTexture)
         ctx->Driver.BindImageTexture(ctx, u, u->TexObj, u->Level, u->Layered,
                                      u->Layer, u->Access, u->Format);
   }

   _mesa_end_texture_lookups(ctx);
}
Ejemplo n.º 24
0
Archivo: meta.c Proyecto: GYGit/reactos
/**
 * Enter meta state.  This is like a light-weight version of glPushAttrib
 * but it also resets most GL state back to default values.
 *
 * \param state  bitmask of MESA_META_* flags indicating which attribute groups
 *               to save and reset to their defaults
 */
void
_mesa_meta_begin(struct gl_context *ctx, GLbitfield state)
{
   struct save_state *save;

   /* hope MAX_META_OPS_DEPTH is large enough */
   assert(ctx->Meta->SaveStackDepth < MAX_META_OPS_DEPTH);

   save = &ctx->Meta->Save[ctx->Meta->SaveStackDepth++];
   memset(save, 0, sizeof(*save));
   save->SavedState = state;

   if (state & MESA_META_ALPHA_TEST) {
      save->AlphaEnabled = ctx->Color.AlphaEnabled;
      save->AlphaFunc = ctx->Color.AlphaFunc;
      save->AlphaRef = ctx->Color.AlphaRef;
      if (ctx->Color.AlphaEnabled)
         _mesa_set_enable(ctx, GL_ALPHA_TEST, GL_FALSE);
   }

   if (state & MESA_META_BLEND) {
      save->BlendEnabled = ctx->Color.BlendEnabled;
      if (ctx->Color.BlendEnabled) {
         _mesa_set_enable(ctx, GL_BLEND, GL_FALSE);
      }
      save->ColorLogicOpEnabled = ctx->Color.ColorLogicOpEnabled;
      if (ctx->Color.ColorLogicOpEnabled)
         _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, GL_FALSE);
   }

   if (state & MESA_META_COLOR_MASK) {
      memcpy(save->ColorMask, ctx->Color.ColorMask,
             sizeof(ctx->Color.ColorMask));
      if (!ctx->Color.ColorMask[0] ||
          !ctx->Color.ColorMask[1] ||
          !ctx->Color.ColorMask[2] ||
          !ctx->Color.ColorMask[3])
         _mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
   }

   if (state & MESA_META_DEPTH_TEST) {
      save->Depth = ctx->Depth; /* struct copy */
      if (ctx->Depth.Test)
         _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_FALSE);
   }

   if (state & MESA_META_FOG) {
      save->Fog = ctx->Fog.Enabled;
      if (ctx->Fog.Enabled)
         _mesa_set_enable(ctx, GL_FOG, GL_FALSE);
   }

   if (state & MESA_META_PIXEL_STORE) {
      save->Pack = ctx->Pack;
      save->Unpack = ctx->Unpack;
      ctx->Pack = ctx->DefaultPacking;
      ctx->Unpack = ctx->DefaultPacking;
   }

   if (state & MESA_META_PIXEL_TRANSFER) {
      save->RedScale = ctx->Pixel.RedScale;
      save->RedBias = ctx->Pixel.RedBias;
      save->GreenScale = ctx->Pixel.GreenScale;
      save->GreenBias = ctx->Pixel.GreenBias;
      save->BlueScale = ctx->Pixel.BlueScale;
      save->BlueBias = ctx->Pixel.BlueBias;
      save->AlphaScale = ctx->Pixel.AlphaScale;
      save->AlphaBias = ctx->Pixel.AlphaBias;
      save->MapColorFlag = ctx->Pixel.MapColorFlag;
      ctx->Pixel.RedScale = 1.0F;
      ctx->Pixel.RedBias = 0.0F;
      ctx->Pixel.GreenScale = 1.0F;
      ctx->Pixel.GreenBias = 0.0F;
      ctx->Pixel.BlueScale = 1.0F;
      ctx->Pixel.BlueBias = 0.0F;
      ctx->Pixel.AlphaScale = 1.0F;
      ctx->Pixel.AlphaBias = 0.0F;
      ctx->Pixel.MapColorFlag = GL_FALSE;
      /* XXX more state */
      ctx->NewState |=_NEW_PIXEL;
   }

   if (state & MESA_META_RASTERIZATION) {
      save->FrontPolygonMode = ctx->Polygon.FrontMode;
      save->BackPolygonMode = ctx->Polygon.BackMode;
      save->PolygonOffset = ctx->Polygon.OffsetFill;
      save->PolygonSmooth = ctx->Polygon.SmoothFlag;
      save->PolygonStipple = ctx->Polygon.StippleFlag;
      save->PolygonCull = ctx->Polygon.CullFlag;
      _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
      _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, GL_FALSE);
      _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, GL_FALSE);
      _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, GL_FALSE);
      _mesa_set_enable(ctx, GL_CULL_FACE, GL_FALSE);
   }

   if (state & MESA_META_SCISSOR) {
      save->Scissor = ctx->Scissor; /* struct copy */
      _mesa_set_enable(ctx, GL_SCISSOR_TEST, GL_FALSE);
   }

   if (state & MESA_META_STENCIL_TEST) {
      save->Stencil = ctx->Stencil; /* struct copy */
      if (ctx->Stencil.Enabled)
         _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_FALSE);
      /* NOTE: other stencil state not reset */
   }

   if (state & MESA_META_TEXTURE) {
      GLuint tgt;

      save->EnvMode = ctx->Texture.Unit.EnvMode;

      /* Disable all texture units */
      save->TexEnabled = ctx->Texture.Unit.Enabled;
      save->TexGenEnabled = ctx->Texture.Unit.TexGenEnabled;
      if (ctx->Texture.Unit.Enabled ||
          ctx->Texture.Unit.TexGenEnabled) {
         _mesa_set_enable(ctx, GL_TEXTURE_1D, GL_FALSE);
         _mesa_set_enable(ctx, GL_TEXTURE_2D, GL_FALSE);
         if (ctx->Extensions.ARB_texture_cube_map)
            _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE);
         _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, GL_FALSE);
         _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, GL_FALSE);
         _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, GL_FALSE);
         _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, GL_FALSE);
      }

      /* save current texture objects for unit[0] only */
      for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
         _mesa_reference_texobj(&save->CurrentTexture[tgt],
                                ctx->Texture.Unit.CurrentTex[tgt]);
      }
      _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
   }

   if (state & MESA_META_TRANSFORM) {
      memcpy(save->ModelviewMatrix, ctx->ModelviewMatrixStack.Top->m,
             16 * sizeof(GLfloat));
      memcpy(save->ProjectionMatrix, ctx->ProjectionMatrixStack.Top->m,
             16 * sizeof(GLfloat));
      memcpy(save->TextureMatrix, ctx->TextureMatrixStack.Top->m,
             16 * sizeof(GLfloat));
      save->MatrixMode = ctx->Transform.MatrixMode;
      /* set 1:1 vertex:pixel coordinate transform */
      _mesa_MatrixMode(GL_TEXTURE);
      _mesa_LoadIdentity();
      _mesa_MatrixMode(GL_MODELVIEW);
      _mesa_LoadIdentity();
      _mesa_MatrixMode(GL_PROJECTION);
      _mesa_LoadIdentity();
      _mesa_Ortho(0.0, ctx->DrawBuffer->Width,
                  0.0, ctx->DrawBuffer->Height,
                  -1.0, 1.0);
   }

   if (state & MESA_META_CLIP) {
      save->ClipPlanesEnabled = ctx->Transform.ClipPlanesEnabled;
      if (ctx->Transform.ClipPlanesEnabled) {
         GLuint i;
         for (i = 0; i < ctx->Const.MaxClipPlanes; i++) {
            _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_FALSE);
         }
      }
   }

   if (state & MESA_META_VIEWPORT) {
      /* save viewport state */
      save->ViewportX = ctx->Viewport.X;
      save->ViewportY = ctx->Viewport.Y;
      save->ViewportW = ctx->Viewport.Width;
      save->ViewportH = ctx->Viewport.Height;
      /* set viewport to match window size */
      if (ctx->Viewport.X != 0 ||
          ctx->Viewport.Y != 0 ||
          ctx->Viewport.Width != ctx->DrawBuffer->Width ||
          ctx->Viewport.Height != ctx->DrawBuffer->Height) {
         _mesa_set_viewport(ctx, 0, 0,
                            ctx->DrawBuffer->Width, ctx->DrawBuffer->Height);
      }
      /* save depth range state */
      save->DepthNear = ctx->Viewport.Near;
      save->DepthFar = ctx->Viewport.Far;
      /* set depth range to default */
      _mesa_DepthRange(0.0, 1.0);
   }

   if (state & MESA_META_SELECT_FEEDBACK) {
      save->RenderMode = ctx->RenderMode;
      if (ctx->RenderMode == GL_SELECT) {
	 save->Select = ctx->Select; /* struct copy */
	 _mesa_RenderMode(GL_RENDER);
      } else if (ctx->RenderMode == GL_FEEDBACK) {
	 save->Feedback = ctx->Feedback; /* struct copy */
	 _mesa_RenderMode(GL_RENDER);
      }
   }

   /* misc */
   {
      save->Lighting = ctx->Light.Enabled;
      if (ctx->Light.Enabled)
         _mesa_set_enable(ctx, GL_LIGHTING, GL_FALSE);
      save->RasterDiscard = ctx->RasterDiscard;
      if (ctx->RasterDiscard)
         _mesa_set_enable(ctx, GL_RASTERIZER_DISCARD, GL_FALSE);
   }
}
Ejemplo n.º 25
0
Archivo: meta.c Proyecto: GYGit/reactos
/**
 * Leave meta state.  This is like a light-weight version of glPopAttrib().
 */
void
_mesa_meta_end(struct gl_context *ctx)
{
   struct save_state *save = &ctx->Meta->Save[--ctx->Meta->SaveStackDepth];
   const GLbitfield state = save->SavedState;

   if (state & MESA_META_ALPHA_TEST) {
      if (ctx->Color.AlphaEnabled != save->AlphaEnabled)
         _mesa_set_enable(ctx, GL_ALPHA_TEST, save->AlphaEnabled);
      _mesa_AlphaFunc(save->AlphaFunc, save->AlphaRef);
   }

   if (state & MESA_META_BLEND) {
      if (ctx->Color.BlendEnabled != save->BlendEnabled) {
         _mesa_set_enable(ctx, GL_BLEND, (save->BlendEnabled & 1));
      }
      if (ctx->Color.ColorLogicOpEnabled != save->ColorLogicOpEnabled)
         _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, save->ColorLogicOpEnabled);
   }

   if (state & MESA_META_COLOR_MASK) {
      if (!TEST_EQ_4V(ctx->Color.ColorMask, save->ColorMask)) {
         _mesa_ColorMask(save->ColorMask[0], save->ColorMask[1],
                         save->ColorMask[2], save->ColorMask[3]);         
      }
   }

   if (state & MESA_META_DEPTH_TEST) {
      if (ctx->Depth.Test != save->Depth.Test)
         _mesa_set_enable(ctx, GL_DEPTH_TEST, save->Depth.Test);
      _mesa_DepthFunc(save->Depth.Func);
      _mesa_DepthMask(save->Depth.Mask);
   }

   if (state & MESA_META_FOG) {
      _mesa_set_enable(ctx, GL_FOG, save->Fog);
   }

   if (state & MESA_META_PIXEL_STORE) {
      ctx->Pack = save->Pack;
      ctx->Unpack = save->Unpack;
   }

   if (state & MESA_META_PIXEL_TRANSFER) {
      ctx->Pixel.RedScale = save->RedScale;
      ctx->Pixel.RedBias = save->RedBias;
      ctx->Pixel.GreenScale = save->GreenScale;
      ctx->Pixel.GreenBias = save->GreenBias;
      ctx->Pixel.BlueScale = save->BlueScale;
      ctx->Pixel.BlueBias = save->BlueBias;
      ctx->Pixel.AlphaScale = save->AlphaScale;
      ctx->Pixel.AlphaBias = save->AlphaBias;
      ctx->Pixel.MapColorFlag = save->MapColorFlag;
      /* XXX more state */
      ctx->NewState |=_NEW_PIXEL;
   }

   if (state & MESA_META_RASTERIZATION) {
      _mesa_PolygonMode(GL_FRONT, save->FrontPolygonMode);
      _mesa_PolygonMode(GL_BACK, save->BackPolygonMode);
      _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, save->PolygonStipple);
      _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, save->PolygonOffset);
      _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, save->PolygonSmooth);
      _mesa_set_enable(ctx, GL_CULL_FACE, save->PolygonCull);
   }

   if (state & MESA_META_SCISSOR) {
      _mesa_set_enable(ctx, GL_SCISSOR_TEST, save->Scissor.Enabled);
      _mesa_Scissor(save->Scissor.X, save->Scissor.Y,
                    save->Scissor.Width, save->Scissor.Height);
   }

   if (state & MESA_META_STENCIL_TEST) {
      const struct gl_stencil_attrib *stencil = &save->Stencil;

      _mesa_set_enable(ctx, GL_STENCIL_TEST, stencil->Enabled);
      _mesa_ClearStencil(stencil->Clear);
      _mesa_StencilFunc(stencil->Function,
                        stencil->Ref,
                        stencil->ValueMask);
      _mesa_StencilMask(stencil->WriteMask);
      _mesa_StencilOp(stencil->FailFunc, stencil->ZFailFunc, stencil->ZPassFunc);
   }

   if (state & MESA_META_TEXTURE) {
      GLuint tgt;

      /* restore texenv for unit[0] */
      _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, save->EnvMode);

      /* restore texture objects for unit[0] only */
      for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
	 if (ctx->Texture.Unit.CurrentTex[tgt] != save->CurrentTexture[tgt]) {
	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
	    _mesa_reference_texobj(&ctx->Texture.Unit.CurrentTex[tgt],
				   save->CurrentTexture[tgt]);
	 }
         _mesa_reference_texobj(&save->CurrentTexture[tgt], NULL);
      }

      /* Restore fixed function texture enables, texgen */
	 if (ctx->Texture.Unit.Enabled != save->TexEnabled) {
	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
	    ctx->Texture.Unit.Enabled = save->TexEnabled;
	 }

	 if (ctx->Texture.Unit.TexGenEnabled != save->TexGenEnabled) {
	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
	    ctx->Texture.Unit.TexGenEnabled = save->TexGenEnabled;
	 }
   }

   if (state & MESA_META_TRANSFORM) {
      _mesa_MatrixMode(GL_TEXTURE);
      _mesa_LoadMatrixf(save->TextureMatrix);

      _mesa_MatrixMode(GL_MODELVIEW);
      _mesa_LoadMatrixf(save->ModelviewMatrix);

      _mesa_MatrixMode(GL_PROJECTION);
      _mesa_LoadMatrixf(save->ProjectionMatrix);

      _mesa_MatrixMode(save->MatrixMode);
   }

   if (state & MESA_META_CLIP) {
      if (save->ClipPlanesEnabled) {
         GLuint i;
         for (i = 0; i < ctx->Const.MaxClipPlanes; i++) {
            if (save->ClipPlanesEnabled & (1 << i)) {
               _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_TRUE);
            }
         }
      }
   }

   if (state & MESA_META_VIEWPORT) {
      if (save->ViewportX != ctx->Viewport.X ||
          save->ViewportY != ctx->Viewport.Y ||
          save->ViewportW != ctx->Viewport.Width ||
          save->ViewportH != ctx->Viewport.Height) {
         _mesa_set_viewport(ctx, save->ViewportX, save->ViewportY,
                            save->ViewportW, save->ViewportH);
      }
      _mesa_DepthRange(save->DepthNear, save->DepthFar);
   }

   /* misc */
   if (save->Lighting) {
      _mesa_set_enable(ctx, GL_LIGHTING, GL_TRUE);
   }
   if (save->RasterDiscard) {
      _mesa_set_enable(ctx, GL_RASTERIZER_DISCARD, GL_TRUE);
   }
}
Ejemplo n.º 26
0
/**
 * \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 )
{
   GLuint unit;
   struct gl_program *fprog = NULL;
   struct gl_program *vprog = NULL;
   struct gl_program *gprog = NULL;
   GLbitfield enabledFragUnits = 0x0;

   if (ctx->Shader.CurrentVertexProgram &&
       ctx->Shader.CurrentVertexProgram->LinkStatus) {
      vprog = ctx->Shader.CurrentVertexProgram->_LinkedShaders[MESA_SHADER_VERTEX]->Program;
   }

   if (ctx->Shader.CurrentGeometryProgram &&
       ctx->Shader.CurrentGeometryProgram->LinkStatus) {
      gprog = ctx->Shader.CurrentGeometryProgram->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program;
   }

   if (ctx->Shader.CurrentFragmentProgram &&
       ctx->Shader.CurrentFragmentProgram->LinkStatus) {
      fprog = ctx->Shader.CurrentFragmentProgram->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program;
   }
   else if (ctx->FragmentProgram._Enabled) {
      fprog = &ctx->FragmentProgram.Current->Base;
   }

   /* TODO: only set this if there are actual changes */
   ctx->NewState |= _NEW_TEXTURE;

   ctx->Texture._EnabledUnits = 0x0;
   ctx->Texture._GenFlags = 0x0;
   ctx->Texture._TexMatEnabled = 0x0;
   ctx->Texture._TexGenEnabled = 0x0;

   /*
    * Update texture unit state.
    */
   for (unit = 0; unit < ctx->Const.MaxCombinedTextureImageUnits; unit++) {
      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
      GLbitfield enabledVertTargets = 0x0;
      GLbitfield enabledFragTargets = 0x0;
      GLbitfield enabledGeomTargets = 0x0;
      GLbitfield enabledTargets = 0x0;
      GLuint texIndex;

      /* Get the bitmask of texture target enables.
       * enableBits will be a mask of the TEXTURE_*_BIT flags indicating
       * which texture targets are enabled (fixed function) or referenced
       * by a fragment program/program.  When multiple flags are set, we'll
       * settle on the one with highest priority (see below).
       */
      if (vprog) {
         enabledVertTargets |= vprog->TexturesUsed[unit];
      }

      if (gprog) {
         enabledGeomTargets |= gprog->TexturesUsed[unit];
      }

      if (fprog) {
         enabledFragTargets |= fprog->TexturesUsed[unit];
      }
      else {
         /* fixed-function fragment program */
         enabledFragTargets |= texUnit->Enabled;
      }

      enabledTargets = enabledVertTargets | enabledFragTargets |
                       enabledGeomTargets;

      texUnit->_ReallyEnabled = 0x0;

      if (enabledTargets == 0x0) {
         /* neither vertex nor fragment processing uses this unit */
         continue;
      }

      /* Look for the highest priority texture target that's enabled (or used
       * by the vert/frag shaders) and "complete".  That's the one we'll use
       * for texturing.
       *
       * Note that the TEXTURE_x_INDEX values are in high to low priority.
       */
      for (texIndex = 0; texIndex < NUM_TEXTURE_TARGETS; texIndex++) {
         if (enabledTargets & (1 << texIndex)) {
            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)) {
               texUnit->_ReallyEnabled = 1 << texIndex;
               _mesa_reference_texobj(&texUnit->_Current, texObj);
               break;
            }
         }
      }

      if (!texUnit->_ReallyEnabled) {
         if (fprog) {
            /* If we get here it means the shader is expecting a texture
             * object, but there isn't one (or it's incomplete).  Use the
             * fallback texture.
             */
            struct gl_texture_object *texObj;
            gl_texture_index texTarget;

            texTarget = (gl_texture_index) (ffs(enabledTargets) - 1);
            texObj = _mesa_get_fallback_texture(ctx, texTarget);
            
            assert(texObj);
            if (!texObj) {
               /* invalid fallback texture: don't enable the texture unit */
               continue;
            }

            _mesa_reference_texobj(&texUnit->_Current, texObj);
            texUnit->_ReallyEnabled = 1 << texTarget;
         }
         else {
            /* fixed-function: texture unit is really disabled */
            continue;
         }
      }

      /* if we get here, we know this texture unit is enabled */

      ctx->Texture._EnabledUnits |= (1 << unit);

      if (enabledFragTargets)
         enabledFragUnits |= (1 << unit);

      if (!fprog)
         update_tex_combine(ctx, texUnit);
   }


   /* Determine which texture coordinate sets are actually needed */
   if (fprog) {
      const GLuint coordMask = (1 << MAX_TEXTURE_COORD_UNITS) - 1;
      ctx->Texture._EnabledCoordUnits
         = (fprog->InputsRead >> VARYING_SLOT_TEX0) & coordMask;
   }
   else {
Ejemplo n.º 27
0
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);
    }
}
Ejemplo n.º 28
0
/**
 * \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( GLcontext *ctx )
{
   GLuint unit;
   struct gl_fragment_program *fprog = NULL;
   struct gl_vertex_program *vprog = NULL;
   GLbitfield enabledFragUnits = 0x0;

   if (ctx->Shader.CurrentProgram &&
       ctx->Shader.CurrentProgram->LinkStatus) {
      fprog = ctx->Shader.CurrentProgram->FragmentProgram;
      vprog = ctx->Shader.CurrentProgram->VertexProgram;
   }
   else {
      if (ctx->FragmentProgram._Enabled) {
         fprog = ctx->FragmentProgram.Current;
      }
      if (ctx->VertexProgram._Enabled) {
         /* XXX enable this if/when non-shader vertex programs get
          * texture fetches:
         vprog = ctx->VertexProgram.Current;
         */
      }
   }

   /* TODO: only set this if there are actual changes */
   ctx->NewState |= _NEW_TEXTURE;

   ctx->Texture._EnabledUnits = 0x0;
   ctx->Texture._GenFlags = 0x0;
   ctx->Texture._TexMatEnabled = 0x0;
   ctx->Texture._TexGenEnabled = 0x0;

   /*
    * Update texture unit state.
    */
   for (unit = 0; unit < ctx->Const.MaxTextureImageUnits; unit++) {
      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
      GLbitfield enabledVertTargets = 0x0;
      GLbitfield enabledFragTargets = 0x0;
      GLbitfield enabledTargets = 0x0;
      GLuint texIndex;

      /* Get the bitmask of texture target enables.
       * enableBits will be a mask of the TEXTURE_*_BIT flags indicating
       * which texture targets are enabled (fixed function) or referenced
       * by a fragment shader/program.  When multiple flags are set, we'll
       * settle on the one with highest priority (see below).
       */
      if (vprog) {
         enabledVertTargets |= vprog->Base.TexturesUsed[unit];
      }

      if (fprog) {
         enabledFragTargets |= fprog->Base.TexturesUsed[unit];
      }
      else {
         /* fixed-function fragment program */
         enabledFragTargets |= texUnit->Enabled;
      }

      enabledTargets = enabledVertTargets | enabledFragTargets;

      texUnit->_ReallyEnabled = 0x0;

      if (enabledTargets == 0x0) {
         /* neither vertex nor fragment processing uses this unit */
         continue;
      }

      /* Look for the highest priority texture target that's enabled (or used
       * by the vert/frag shaders) and "complete".  That's the one we'll use
       * for texturing.  If we're using vert/frag program we're guaranteed
       * that bitcount(enabledBits) <= 1.
       * Note that the TEXTURE_x_INDEX values are in high to low priority.
       */
      for (texIndex = 0; texIndex < NUM_TEXTURE_TARGETS; texIndex++) {
         if (enabledTargets & (1 << texIndex)) {
            struct gl_texture_object *texObj = texUnit->CurrentTex[texIndex];
            if (!texObj->_Complete) {
               _mesa_test_texobj_completeness(ctx, texObj);
            }
            if (texObj->_Complete) {
               texUnit->_ReallyEnabled = 1 << texIndex;
               _mesa_reference_texobj(&texUnit->_Current, texObj);
               break;
            }
         }
      }

      if (!texUnit->_ReallyEnabled) {
         if (fprog) {
            /* If we get here it means the shader is expecting a texture
             * object, but there isn't one (or it's incomplete).  Use the
             * fallback texture.
             */
            struct gl_texture_object *texObj = _mesa_get_fallback_texture(ctx);
            texUnit->_ReallyEnabled = 1 << TEXTURE_2D_INDEX;
            _mesa_reference_texobj(&texUnit->_Current, texObj);
         }
         else {
            /* fixed-function: texture unit is really disabled */
            continue;
         }
      }

      /* if we get here, we know this texture unit is enabled */

      ctx->Texture._EnabledUnits |= (1 << unit);

      if (enabledFragTargets)
         enabledFragUnits |= (1 << unit);

      update_tex_combine(ctx, texUnit);
   }


   /* Determine which texture coordinate sets are actually needed */
   if (fprog) {
      const GLuint coordMask = (1 << MAX_TEXTURE_COORD_UNITS) - 1;
      ctx->Texture._EnabledCoordUnits
         = (fprog->Base.InputsRead >> FRAG_ATTRIB_TEX0) & coordMask;
   }
   else {
Ejemplo n.º 29
0
/**
 * Bind a named texture to a texturing target.
 * 
 * \param target texture target.
 * \param texName texture name.
 * 
 * \sa glBindTexture().
 *
 * Determines the old texture object bound and returns immediately if rebinding
 * the same texture.  Get the current texture which is either a default texture
 * if name is null, a named texture from the hash, or a new texture if the
 * given texture name is new. Increments its reference count, binds it, and
 * calls dd_function_table::BindTexture. Decrements the old texture reference
 * count and deletes it if it reaches zero.
 */
void GLAPIENTRY
_mesa_BindTexture( GLenum target, GLuint texName )
{
   GET_CURRENT_CONTEXT(ctx);
   struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
   struct gl_texture_object *newTexObj = NULL;
   GLint targetIndex;
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
      _mesa_debug(ctx, "glBindTexture %s %d\n",
                  _mesa_lookup_enum_by_nr(target), (GLint) texName);

   targetIndex = target_enum_to_index(ctx, target);
   if (targetIndex < 0) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glBindTexture(target)");
      return;
   }
   assert(targetIndex < NUM_TEXTURE_TARGETS);

   /*
    * Get pointer to new texture object (newTexObj)
    */
   if (texName == 0) {
      /* Use a default texture object */
      newTexObj = ctx->Shared->DefaultTex[targetIndex];
   }
   else {
      /* non-default texture object */
      newTexObj = _mesa_lookup_texture(ctx, texName);
      if (newTexObj) {
         /* error checking */
         if (newTexObj->Target != 0 && newTexObj->Target != target) {
            /* the named texture object's target doesn't match the given target */
            _mesa_error( ctx, GL_INVALID_OPERATION,
                         "glBindTexture(target mismatch)" );
            return;
         }
         if (newTexObj->Target == 0) {
            finish_texture_init(ctx, target, newTexObj);
         }
      }
      else {
         if (ctx->API == API_OPENGL_CORE) {
            _mesa_error(ctx, GL_INVALID_OPERATION, "glBindTexture");
            return;
         }

         /* if this is a new texture id, allocate a texture object now */
         newTexObj = ctx->Driver.NewTextureObject(ctx, texName, target);
         if (!newTexObj) {
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindTexture");
            return;
         }

         /* and insert it into hash table */
         _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
         _mesa_HashInsert(ctx->Shared->TexObjects, texName, newTexObj);
         _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
      }
      newTexObj->Target = target;
   }

   assert(valid_texture_object(newTexObj));

   /* Check if this texture is only used by this context and is already bound.
    * If so, just return.
    */
   {
      GLboolean early_out;
      _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
      early_out = ((ctx->Shared->RefCount == 1)
                   && (newTexObj == texUnit->CurrentTex[targetIndex]));
      _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
      if (early_out) {
         return;
      }
   }

   /* flush before changing binding */
   FLUSH_VERTICES(ctx, _NEW_TEXTURE);

   /* Do the actual binding.  The refcount on the previously bound
    * texture object will be decremented.  It'll be deleted if the
    * count hits zero.
    */
   _mesa_reference_texobj(&texUnit->CurrentTex[targetIndex], newTexObj);
   ASSERT(texUnit->CurrentTex[targetIndex]);

   /* Pass BindTexture call to device driver */
   if (ctx->Driver.BindTexture)
      ctx->Driver.BindTexture(ctx, target, newTexObj);
}
Ejemplo n.º 30
0
/**
 * Initialize texture state for the given context.
 */
GLboolean
_mesa_init_texture(struct gl_context *ctx)
{
   GLuint u;

   /* Texture group */
   ctx->Texture.CurrentUnit = 0;      /* multitexture */

   /* Appendix F.2 of the OpenGL ES 3.0 spec says:
    *
    *     "OpenGL ES 3.0 requires that all cube map filtering be
    *     seamless. OpenGL ES 2.0 specified that a single cube map face be
    *     selected and used for filtering."
    *
    * Unfortunatley, a call to _mesa_is_gles3 below will only work if
    * the driver has already computed and set ctx->Version, however drivers
    * seem to call _mesa_initialize_context (which calls this) early
    * in the CreateContext hook and _mesa_compute_version much later (since
    * it needs information about available extensions). So, we will
    * enable seamless cubemaps by default since GLES2. This should work
    * for most implementations and drivers that don't support seamless
    * cubemaps for GLES2 can still disable it.
    */
   ctx->Texture.CubeMapSeamless = ctx->API == API_OPENGLES2;

   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
    * MAX_COMBINED_TEXTURE_IMAGE_UNITS + 1.
    */
   assert(ctx->Shared->DefaultTex[TEXTURE_1D_INDEX]->RefCount
          >= MAX_COMBINED_TEXTURE_IMAGE_UNITS + 1);

   /* Allocate proxy textures */
   if (!alloc_proxy_textures( ctx ))
      return GL_FALSE;

   /* GL_ARB_texture_buffer_object */
   _mesa_reference_buffer_object(ctx, &ctx->Texture.BufferObject,
                                 ctx->Shared->NullBufferObj);

   ctx->Texture.NumCurrentTexUsed = 0;

   return GL_TRUE;
}