Esempio n. 1
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);
   }
}
Esempio n. 2
0
/**
 * Bind a renderbuffer to an attachment point.
 * The previous binding, if any, will be removed first.
 */
void
_mesa_set_renderbuffer_attachment(GLcontext *ctx,
                                  struct gl_renderbuffer_attachment *att,
                                  struct gl_renderbuffer *rb)
{
   /* XXX check if re-doing same attachment, exit early */
   _mesa_remove_attachment(ctx, att);
   att->Type = GL_RENDERBUFFER_EXT;
   att->Texture = NULL; /* just to be safe */
   att->Complete = GL_FALSE;
   _mesa_reference_renderbuffer(&att->Renderbuffer, rb);
}
Esempio n. 3
0
/**
 * Fallback for ctx->Driver.FramebufferRenderbuffer()
 * Attach a renderbuffer object to a framebuffer object.
 */
void
_mesa_framebuffer_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
                               GLenum attachment, struct gl_renderbuffer *rb)
{
   struct gl_renderbuffer_attachment *att;

   _glthread_LOCK_MUTEX(fb->Mutex);

   att = _mesa_get_attachment(ctx, fb, attachment);
   ASSERT(att);
   if (rb) {
      _mesa_set_renderbuffer_attachment(ctx, att, rb);
   }
   else {
      _mesa_remove_attachment(ctx, att);
   }

   _glthread_UNLOCK_MUTEX(fb->Mutex);
}
Esempio n. 4
0
/**
 * Check if the given texture object is bound to the current draw or
 * read framebuffer.  If so, Unbind it.
 */
static void
unbind_texobj_from_fbo(struct gl_context *ctx,
                       struct gl_texture_object *texObj)
{
   const GLuint n = (ctx->DrawBuffer == ctx->ReadBuffer) ? 1 : 2;
   GLuint i;

   for (i = 0; i < n; i++) {
      struct gl_framebuffer *fb = (i == 0) ? ctx->DrawBuffer : ctx->ReadBuffer;
      if (_mesa_is_user_fbo(fb)) {
         GLuint j;
         for (j = 0; j < BUFFER_COUNT; j++) {
            if (fb->Attachment[j].Type == GL_TEXTURE &&
                fb->Attachment[j].Texture == texObj) {
	       /* Vertices are already flushed by _mesa_DeleteTextures */
	       ctx->NewState |= _NEW_BUFFERS;
               _mesa_remove_attachment(ctx, fb->Attachment + j);         
            }
         }
      }
   }
}
Esempio n. 5
0
/**
 * Common code called by glFramebufferTexture1D/2D/3DEXT().
 */
static void
framebuffer_texture(GLcontext *ctx, const char *caller, GLenum target, 
                    GLenum attachment, GLenum textarget, GLuint texture,
                    GLint level, GLint zoffset)
{
   struct gl_renderbuffer_attachment *att;
   struct gl_texture_object *texObj = NULL;
   struct gl_framebuffer *fb;

   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (target != GL_FRAMEBUFFER_EXT) {
      _mesa_error(ctx, GL_INVALID_ENUM,
                  "glFramebufferTexture%sEXT(target)", caller);
      return;
   }

   fb = ctx->DrawBuffer;
   ASSERT(fb);

   /* check framebuffer binding */
   if (fb->Name == 0) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "glFramebufferTexture%sEXT", caller);
      return;
   }


   /* The textarget, level, and zoffset parameters are only validated if
    * texture is non-zero.
    */
   if (texture) {
      GLboolean err = GL_TRUE;

      texObj = _mesa_lookup_texture(ctx, texture);
      if (texObj != NULL) {
         if (textarget == 0) {
            err = (texObj->Target != GL_TEXTURE_3D) &&
                (texObj->Target != GL_TEXTURE_1D_ARRAY_EXT) &&
                (texObj->Target != GL_TEXTURE_2D_ARRAY_EXT);
         }
         else {
            err = (texObj->Target == GL_TEXTURE_CUBE_MAP)
                ? !IS_CUBE_FACE(textarget)
                : (texObj->Target != textarget);
         }
      }

      if (err) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "glFramebufferTexture%sEXT(texture target mismatch)",
                     caller);
         return;
      }

      if (texObj->Target == GL_TEXTURE_3D) {
         const GLint maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
         if (zoffset < 0 || zoffset >= maxSize) {
            _mesa_error(ctx, GL_INVALID_VALUE,
                        "glFramebufferTexture%sEXT(zoffset)", caller);
            return;
         }
      }
      else if ((texObj->Target == GL_TEXTURE_1D_ARRAY_EXT) ||
               (texObj->Target == GL_TEXTURE_2D_ARRAY_EXT)) {
         if (zoffset < 0 || zoffset >= ctx->Const.MaxArrayTextureLayers) {
            _mesa_error(ctx, GL_INVALID_VALUE,
                        "glFramebufferTexture%sEXT(layer)", caller);
            return;
         }
      }


      if ((level < 0) || 
          (level >= _mesa_max_texture_levels(ctx, texObj->Target))) {
         _mesa_error(ctx, GL_INVALID_VALUE,
                     "glFramebufferTexture%sEXT(level)", caller);
         return;
      }
   }

   att = _mesa_get_attachment(ctx, fb, attachment);
   if (att == NULL) {
      _mesa_error(ctx, GL_INVALID_ENUM,
                  "glFramebufferTexture%sEXT(attachment)", caller);
      return;
   }

   FLUSH_VERTICES(ctx, _NEW_BUFFERS);
   /* The above doesn't fully flush the drivers in the way that a
    * glFlush does, but that is required here:
    */
   if (ctx->Driver.Flush)
      ctx->Driver.Flush(ctx);

   _glthread_LOCK_MUTEX(fb->Mutex);
   if (texObj) {
      _mesa_set_texture_attachment(ctx, fb, att, texObj, textarget,
                                   level, zoffset);
   }
   else {
      _mesa_remove_attachment(ctx, att);
   }
   _glthread_UNLOCK_MUTEX(fb->Mutex);
}