aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/extras/Mesa/src/mesa/main/fbobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'nx-X11/extras/Mesa/src/mesa/main/fbobject.c')
-rw-r--r--nx-X11/extras/Mesa/src/mesa/main/fbobject.c1357
1 files changed, 0 insertions, 1357 deletions
diff --git a/nx-X11/extras/Mesa/src/mesa/main/fbobject.c b/nx-X11/extras/Mesa/src/mesa/main/fbobject.c
deleted file mode 100644
index b16e13a22..000000000
--- a/nx-X11/extras/Mesa/src/mesa/main/fbobject.c
+++ /dev/null
@@ -1,1357 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.3
- *
- * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-/*
- * Authors:
- * Brian Paul
- */
-
-
-#include "context.h"
-#include "fbobject.h"
-#include "framebuffer.h"
-#include "hash.h"
-#include "renderbuffer.h"
-#include "teximage.h"
-#include "texstore.h"
-
-
-/**
- * Notes:
- *
- * None of the GL_EXT_framebuffer_object functions are compiled into
- * display lists.
- */
-
-
-
-/*
- * When glGenRender/FramebuffersEXT() is called we insert pointers to
- * these placeholder objects into the hash table.
- * Later, when the object ID is first bound, we replace the placeholder
- * with the real frame/renderbuffer.
- */
-static struct gl_framebuffer DummyFramebuffer;
-static struct gl_renderbuffer DummyRenderbuffer;
-
-
-#define IS_CUBE_FACE(TARGET) \
- ((TARGET) >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && \
- (TARGET) <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z)
-
-
-/**
- * Helper routine for getting a gl_renderbuffer.
- */
-static struct gl_renderbuffer *
-lookup_renderbuffer(GLcontext *ctx, GLuint id)
-{
- struct gl_renderbuffer *rb;
-
- if (id == 0)
- return NULL;
-
- rb = (struct gl_renderbuffer *)
- _mesa_HashLookup(ctx->Shared->RenderBuffers, id);
- return rb;
-}
-
-
-/**
- * Helper routine for getting a gl_framebuffer.
- */
-static struct gl_framebuffer *
-lookup_framebuffer(GLcontext *ctx, GLuint id)
-{
- struct gl_framebuffer *fb;
-
- if (id == 0)
- return NULL;
-
- fb = (struct gl_framebuffer *)
- _mesa_HashLookup(ctx->Shared->FrameBuffers, id);
- return fb;
-}
-
-
-/**
- * Given a GL_*_ATTACHMENTn token, return a pointer to the corresponding
- * gl_renderbuffer_attachment object.
- */
-static struct gl_renderbuffer_attachment *
-get_attachment(GLcontext *ctx, struct gl_framebuffer *fb, GLenum attachment)
-{
- GLuint i;
-
- switch (attachment) {
- case GL_COLOR_ATTACHMENT0_EXT:
- case GL_COLOR_ATTACHMENT1_EXT:
- case GL_COLOR_ATTACHMENT2_EXT:
- case GL_COLOR_ATTACHMENT3_EXT:
- case GL_COLOR_ATTACHMENT4_EXT:
- case GL_COLOR_ATTACHMENT5_EXT:
- case GL_COLOR_ATTACHMENT6_EXT:
- case GL_COLOR_ATTACHMENT7_EXT:
- case GL_COLOR_ATTACHMENT8_EXT:
- case GL_COLOR_ATTACHMENT9_EXT:
- case GL_COLOR_ATTACHMENT10_EXT:
- case GL_COLOR_ATTACHMENT11_EXT:
- case GL_COLOR_ATTACHMENT12_EXT:
- case GL_COLOR_ATTACHMENT13_EXT:
- case GL_COLOR_ATTACHMENT14_EXT:
- case GL_COLOR_ATTACHMENT15_EXT:
- i = attachment - GL_COLOR_ATTACHMENT0_EXT;
- if (i >= ctx->Const.MaxColorAttachments) {
- return NULL;
- }
- return &fb->Attachment[BUFFER_COLOR0 + i];
- case GL_DEPTH_ATTACHMENT_EXT:
- return &fb->Attachment[BUFFER_DEPTH];
- case GL_STENCIL_ATTACHMENT_EXT:
- return &fb->Attachment[BUFFER_STENCIL];
- default:
- return NULL;
- }
-}
-
-
-/**
- * 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 (att->Renderbuffer) {
- /* delete/remove the 'wrapper' renderbuffer */
- /* XXX do we really want to do this??? */
- att->Renderbuffer->Delete(att->Renderbuffer);
- att->Renderbuffer = NULL;
- }
- att->Texture->RefCount--;
- if (att->Texture->RefCount == 0) {
- ctx->Driver.DeleteTexture(ctx, att->Texture);
- }
- att->Texture = NULL;
- }
- else if (att->Type == GL_RENDERBUFFER_EXT) {
- ASSERT(att->Renderbuffer);
- ASSERT(!att->Texture);
- att->Renderbuffer->RefCount--;
- if (att->Renderbuffer->RefCount == 0) {
- att->Renderbuffer->Delete(att->Renderbuffer);
- }
- att->Renderbuffer = NULL;
- }
- att->Type = GL_NONE;
- att->Complete = GL_TRUE;
-}
-
-
-/**
- * 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_renderbuffer_attachment *att,
- struct gl_texture_object *texObj,
- GLenum texTarget, GLuint level, GLuint zoffset)
-{
- _mesa_remove_attachment(ctx, att);
- att->Type = GL_TEXTURE;
- att->Texture = texObj;
- 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;
-
- texObj->RefCount++;
-
- /* XXX when we attach to a texture, we should probably set the
- * att->Renderbuffer pointer to a "wrapper renderbuffer" which
- * makes the texture image look like renderbuffer.
- */
-}
-
-
-/**
- * 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)
-{
- _mesa_remove_attachment(ctx, att);
- att->Type = GL_RENDERBUFFER_EXT;
- att->Renderbuffer = rb;
- att->Texture = NULL; /* just to be safe */
- att->Complete = GL_FALSE;
- rb->RefCount++;
-}
-
-
-/**
- * Fallback for ctx->Driver.FramebufferRenderbuffer()
- * Sets a framebuffer attachment to a particular renderbuffer.
- * The framebuffer in question is ctx->DrawBuffer.
- * \sa _mesa_renderbuffer_texture
- */
-void
-_mesa_framebuffer_renderbuffer(GLcontext *ctx,
- struct gl_renderbuffer_attachment *att,
- struct gl_renderbuffer *rb)
-{
- if (rb) {
- _mesa_set_renderbuffer_attachment(ctx, att, rb);
- }
- else {
- _mesa_remove_attachment(ctx, att);
- }
-}
-
-
-/**
- * Test if an attachment point is complete and update its Complete field.
- * \param format if GL_COLOR, this is a color attachment point,
- * if GL_DEPTH, this is a depth component attachment point,
- * if GL_STENCIL, this is a stencil component attachment point.
- */
-static void
-test_attachment_completeness(const GLcontext *ctx, GLenum format,
- struct gl_renderbuffer_attachment *att)
-{
- assert(format == GL_COLOR || format == GL_DEPTH || format == GL_STENCIL);
-
- /* assume complete */
- att->Complete = GL_TRUE;
-
- /* Look for reasons why the attachment might be incomplete */
- if (att->Type == GL_TEXTURE) {
- const struct gl_texture_object *texObj = att->Texture;
- struct gl_texture_image *texImage;
-
- if (!texObj) {
- att->Complete = GL_FALSE;
- return;
- }
-
- texImage = texObj->Image[att->CubeMapFace][att->TextureLevel];
- if (!texImage) {
- att->Complete = GL_FALSE;
- return;
- }
- if (texImage->Width < 1 || texImage->Height < 1) {
- att->Complete = GL_FALSE;
- return;
- }
- if (texObj->Target == GL_TEXTURE_3D && att->Zoffset >= texImage->Depth) {
- att->Complete = GL_FALSE;
- return;
- }
-
- if (format == GL_COLOR) {
- if (texImage->TexFormat->BaseFormat != GL_RGB &&
- texImage->TexFormat->BaseFormat != GL_RGBA) {
- att->Complete = GL_FALSE;
- return;
- }
- }
- else if (format == GL_DEPTH) {
- if (texImage->TexFormat->BaseFormat != GL_DEPTH_COMPONENT) {
- att->Complete = GL_FALSE;
- return;
- }
- }
- else {
- /* no such thing as stencil textures */
- att->Complete = GL_FALSE;
- return;
- }
- }
- else if (att->Type == GL_RENDERBUFFER_EXT) {
- if (att->Renderbuffer->Width < 1 || att->Renderbuffer->Height < 1) {
- att->Complete = GL_FALSE;
- return;
- }
- if (format == GL_COLOR) {
- if (att->Renderbuffer->_BaseFormat != GL_RGB &&
- att->Renderbuffer->_BaseFormat != GL_RGBA) {
- att->Complete = GL_FALSE;
- return;
- }
- }
- else if (format == GL_DEPTH) {
- if (att->Renderbuffer->_BaseFormat != GL_DEPTH_COMPONENT) {
- att->Complete = GL_FALSE;
- return;
- }
- }
- else {
- assert(format == GL_STENCIL);
- if (att->Renderbuffer->_BaseFormat != GL_STENCIL_INDEX) {
- att->Complete = GL_FALSE;
- return;
- }
- }
- }
- else {
- ASSERT(att->Type == GL_NONE);
- /* complete */
- return;
- }
-}
-
-
-/**
- * Test if the given framebuffer object is complete and update its
- * Status field with the results.
- * Also update the framebuffer's Width and Height fields if the
- * framebuffer is complete.
- */
-void
-_mesa_test_framebuffer_completeness(GLcontext *ctx, struct gl_framebuffer *fb)
-{
- GLuint numImages, width = 0, height = 0;
- GLenum intFormat = GL_NONE;
- GLuint w = 0, h = 0;
- GLint i;
-
- assert(fb->Name != 0);
-
- numImages = 0;
- fb->Width = 0;
- fb->Height = 0;
-
- /* Start at -2 to more easily loop over all attachment points */
- for (i = -2; i < (GLint) ctx->Const.MaxColorAttachments; i++) {
- struct gl_renderbuffer_attachment *att;
- GLenum f;
-
- if (i == -2) {
- att = &fb->Attachment[BUFFER_DEPTH];
- test_attachment_completeness(ctx, GL_DEPTH, att);
- if (!att->Complete) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT;
- return;
- }
- }
- else if (i == -1) {
- att = &fb->Attachment[BUFFER_STENCIL];
- test_attachment_completeness(ctx, GL_STENCIL, att);
- if (!att->Complete) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT;
- return;
- }
- }
- else {
- att = &fb->Attachment[BUFFER_COLOR0 + i];
- test_attachment_completeness(ctx, GL_COLOR, att);
- if (!att->Complete) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT;
- return;
- }
- }
-
- if (att->Type == GL_TEXTURE) {
- w = att->Texture->Image[att->CubeMapFace][att->TextureLevel]->Width;
- h = att->Texture->Image[att->CubeMapFace][att->TextureLevel]->Height;
- f = att->Texture->Image[att->CubeMapFace][att->TextureLevel]->Format;
- numImages++;
- if (f != GL_RGB && f != GL_RGBA && f != GL_DEPTH_COMPONENT) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT;
- return;
- }
- }
- else if (att->Type == GL_RENDERBUFFER_EXT) {
- w = att->Renderbuffer->Width;
- h = att->Renderbuffer->Height;
- f = att->Renderbuffer->InternalFormat;
- numImages++;
- }
- else {
- assert(att->Type == GL_NONE);
- continue;
- }
-
- if (numImages == 1) {
- /* set required width, height and format */
- width = w;
- height = h;
- if (i >= 0)
- intFormat = f;
- }
- else {
- /* check that width, height, format are same */
- if (w != width || h != height) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT;
- return;
- }
- if (intFormat != GL_NONE && f != intFormat) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT;
- return;
- }
- }
- }
-
- /* Check that all DrawBuffers are present */
- for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
- if (fb->ColorDrawBuffer[i] != GL_NONE) {
- const struct gl_renderbuffer_attachment *att
- = get_attachment(ctx, fb, fb->ColorDrawBuffer[i]);
- assert(att);
- if (att->Type == GL_NONE) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT;
- return;
- }
- }
- }
-
- /* Check that the ReadBuffer is present */
- if (fb->ColorReadBuffer != GL_NONE) {
- const struct gl_renderbuffer_attachment *att
- = get_attachment(ctx, fb, fb->ColorReadBuffer);
- assert(att);
- if (att->Type == GL_NONE) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT;
- return;
- }
- }
-
- /* Check if any renderbuffer is attached more than once */
- for (i = 0; i < BUFFER_COUNT - 1; i++) {
- struct gl_renderbuffer *rb_i = fb->Attachment[i].Renderbuffer;
- if (rb_i) {
- GLint j;
- for (j = i + 1; j < BUFFER_COUNT; j++) {
- struct gl_renderbuffer *rb_j = fb->Attachment[j].Renderbuffer;
- if (rb_i == rb_j) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT;
- return;
- }
- }
- }
- }
-
-
- if (numImages == 0) {
- fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT;
- return;
- }
-
- /*
- * If we get here, the framebuffer is complete!
- */
- fb->_Status = GL_FRAMEBUFFER_COMPLETE_EXT;
- fb->Width = w;
- fb->Height = h;
-}
-
-
-GLboolean GLAPIENTRY
-_mesa_IsRenderbufferEXT(GLuint renderbuffer)
-{
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
- if (renderbuffer) {
- struct gl_renderbuffer *rb = lookup_renderbuffer(ctx, renderbuffer);
- if (rb != NULL && rb != &DummyRenderbuffer)
- return GL_TRUE;
- }
- return GL_FALSE;
-}
-
-
-void GLAPIENTRY
-_mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer)
-{
- struct gl_renderbuffer *newRb, *oldRb;
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (target != GL_RENDERBUFFER_EXT) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glBindRenderbufferEXT(target)");
- return;
- }
-
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- if (renderbuffer) {
- newRb = lookup_renderbuffer(ctx, renderbuffer);
- if (newRb == &DummyRenderbuffer) {
- /* ID was reserved, but no real renderbuffer object made yet */
- newRb = NULL;
- }
- if (!newRb) {
- /* create new renderbuffer object */
- newRb = ctx->Driver.NewRenderbuffer(ctx, renderbuffer);
- if (!newRb) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindRenderbufferEXT");
- return;
- }
- ASSERT(newRb->AllocStorage);
- _mesa_HashInsert(ctx->Shared->RenderBuffers, renderbuffer, newRb);
- }
- newRb->RefCount++;
- }
- else {
- newRb = NULL;
- }
-
- oldRb = ctx->CurrentRenderbuffer;
- if (oldRb) {
- oldRb->RefCount--;
- if (oldRb->RefCount == 0) {
- oldRb->Delete(oldRb);
- }
- }
-
- ASSERT(newRb != &DummyRenderbuffer);
-
- ctx->CurrentRenderbuffer = newRb;
-}
-
-
-void GLAPIENTRY
-_mesa_DeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers)
-{
- GLint i;
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- for (i = 0; i < n; i++) {
- if (renderbuffers[i] > 0) {
- struct gl_renderbuffer *rb;
- rb = lookup_renderbuffer(ctx, renderbuffers[i]);
- if (rb) {
- /* check if deleting currently bound renderbuffer object */
- if (rb == ctx->CurrentRenderbuffer) {
- /* bind default */
- ASSERT(rb->RefCount >= 2);
- _mesa_BindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
- }
-
- /* remove from hash table immediately, to free the ID */
- _mesa_HashRemove(ctx->Shared->RenderBuffers, renderbuffers[i]);
-
- if (rb != &DummyRenderbuffer) {
- /* But the object will not be freed until it's no longer
- * bound in any context.
- */
- rb->RefCount--;
- if (rb->RefCount == 0) {
- rb->Delete(rb);
- }
- }
- }
- }
- }
-}
-
-
-void GLAPIENTRY
-_mesa_GenRenderbuffersEXT(GLsizei n, GLuint *renderbuffers)
-{
- GET_CURRENT_CONTEXT(ctx);
- GLuint first;
- GLint i;
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (n < 0) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGenRenderbuffersEXT(n)");
- return;
- }
-
- if (!renderbuffers)
- return;
-
- first = _mesa_HashFindFreeKeyBlock(ctx->Shared->RenderBuffers, n);
-
- for (i = 0; i < n; i++) {
- GLuint name = first + i;
- renderbuffers[i] = name;
- /* insert dummy placeholder into hash table */
- _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
- _mesa_HashInsert(ctx->Shared->RenderBuffers, name, &DummyRenderbuffer);
- _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
- }
-}
-
-
-/**
- * Given an internal format token for a render buffer, return the
- * corresponding base format.
- * \return one of GL_RGB, GL_RGBA, GL_STENCIL_INDEX, GL_DEPTH_COMPONENT
- * or zero if error.
- */
-static GLenum
-base_internal_format(GLcontext *ctx, GLenum internalFormat)
-{
- switch (internalFormat) {
- case GL_RGB:
- case GL_R3_G3_B2:
- case GL_RGB4:
- case GL_RGB5:
- case GL_RGB8:
- case GL_RGB10:
- case GL_RGB12:
- case GL_RGB16:
- return GL_RGB;
- case GL_RGBA:
- case GL_RGBA2:
- case GL_RGBA4:
- case GL_RGB5_A1:
- case GL_RGBA8:
- case GL_RGB10_A2:
- case GL_RGBA12:
- case GL_RGBA16:
- return GL_RGBA;
- case GL_STENCIL_INDEX:
- case GL_STENCIL_INDEX1_EXT:
- case GL_STENCIL_INDEX4_EXT:
- case GL_STENCIL_INDEX8_EXT:
- case GL_STENCIL_INDEX16_EXT:
- return GL_STENCIL_INDEX;
- case GL_DEPTH_COMPONENT:
- case GL_DEPTH_COMPONENT16:
- case GL_DEPTH_COMPONENT24:
- case GL_DEPTH_COMPONENT32:
- return GL_DEPTH_COMPONENT;
- /* XXX add floating point formats eventually */
- default:
- return 0;
- }
-}
-
-
-void GLAPIENTRY
-_mesa_RenderbufferStorageEXT(GLenum target, GLenum internalFormat,
- GLsizei width, GLsizei height)
-{
- struct gl_renderbuffer *rb;
- GLenum baseFormat;
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (target != GL_RENDERBUFFER_EXT) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glRenderbufferStorageEXT(target)");
- return;
- }
-
- baseFormat = base_internal_format(ctx, internalFormat);
- if (baseFormat == 0) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glRenderbufferStorageEXT(internalFormat)");
- return;
- }
-
- if (width < 1 || width > ctx->Const.MaxRenderbufferSize) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glRenderbufferStorageEXT(width)");
- return;
- }
-
- if (height < 1 || height > ctx->Const.MaxRenderbufferSize) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glRenderbufferStorageEXT(height)");
- return;
- }
-
- rb = ctx->CurrentRenderbuffer;
-
- if (!rb) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glRenderbufferStorageEXT");
- return;
- }
-
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- /* Now allocate the storage */
- ASSERT(rb->AllocStorage);
- if (rb->AllocStorage(ctx, rb, internalFormat, width, height)) {
- /* No error - check/set fields now */
- assert(rb->Width == width);
- assert(rb->Height == height);
- assert(rb->InternalFormat);
- rb->_BaseFormat = baseFormat;
- }
- else {
- /* Probably ran out of memory - clear the fields */
- rb->Width = 0;
- rb->Height = 0;
- rb->InternalFormat = GL_NONE;
- rb->_BaseFormat = GL_NONE;
- }
-
- /*
- test_framebuffer_completeness(ctx, fb);
- */
- /* XXX if this renderbuffer is attached anywhere, invalidate attachment
- * points???
- */
-}
-
-
-void GLAPIENTRY
-_mesa_GetRenderbufferParameterivEXT(GLenum target, GLenum pname, GLint *params)
-{
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (target != GL_RENDERBUFFER_EXT) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetRenderbufferParameterivEXT(target)");
- return;
- }
-
- if (!ctx->CurrentRenderbuffer) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetRenderbufferParameterivEXT");
- return;
- }
-
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- switch (pname) {
- case GL_RENDERBUFFER_WIDTH_EXT:
- *params = ctx->CurrentRenderbuffer->Width;
- return;
- case GL_RENDERBUFFER_HEIGHT_EXT:
- *params = ctx->CurrentRenderbuffer->Height;
- return;
- case GL_RENDERBUFFER_INTERNAL_FORMAT_EXT:
- *params = ctx->CurrentRenderbuffer->InternalFormat;
- return;
- case GL_RENDERBUFFER_RED_SIZE_EXT:
- if (ctx->CurrentRenderbuffer->_BaseFormat == GL_RGB ||
- ctx->CurrentRenderbuffer->_BaseFormat == GL_RGBA) {
- *params = ctx->CurrentRenderbuffer->ComponentSizes[0];
- }
- else {
- *params = 0;
- }
- break;
- case GL_RENDERBUFFER_GREEN_SIZE_EXT:
- if (ctx->CurrentRenderbuffer->_BaseFormat == GL_RGB ||
- ctx->CurrentRenderbuffer->_BaseFormat == GL_RGBA) {
- *params = ctx->CurrentRenderbuffer->ComponentSizes[1];
- }
- else {
- *params = 0;
- }
- break;
- case GL_RENDERBUFFER_BLUE_SIZE_EXT:
- if (ctx->CurrentRenderbuffer->_BaseFormat == GL_RGB ||
- ctx->CurrentRenderbuffer->_BaseFormat == GL_RGBA) {
- *params = ctx->CurrentRenderbuffer->ComponentSizes[2];
- }
- else {
- *params = 0;
- }
- break;
- case GL_RENDERBUFFER_ALPHA_SIZE_EXT:
- if (ctx->CurrentRenderbuffer->_BaseFormat == GL_RGB ||
- ctx->CurrentRenderbuffer->_BaseFormat == GL_RGBA) {
- *params = ctx->CurrentRenderbuffer->ComponentSizes[3];
- }
- else {
- *params = 0;
- }
- break;
- case GL_RENDERBUFFER_DEPTH_SIZE_EXT:
- if (ctx->CurrentRenderbuffer->_BaseFormat == GL_DEPTH_COMPONENT) {
- *params = ctx->CurrentRenderbuffer->ComponentSizes[0];
- }
- else {
- *params = 0;
- }
- break;
- case GL_RENDERBUFFER_STENCIL_SIZE_EXT:
- if (ctx->CurrentRenderbuffer->_BaseFormat == GL_STENCIL_INDEX) {
- *params = ctx->CurrentRenderbuffer->ComponentSizes[0];
- }
- else {
- *params = 0;
- }
- break;
-
- default:
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetRenderbufferParameterivEXT(target)");
- return;
- }
-}
-
-
-GLboolean GLAPIENTRY
-_mesa_IsFramebufferEXT(GLuint framebuffer)
-{
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
- if (framebuffer) {
- struct gl_framebuffer *rb = lookup_framebuffer(ctx, framebuffer);
- if (rb != NULL && rb != &DummyFramebuffer)
- return GL_TRUE;
- }
- return GL_FALSE;
-}
-
-
-void GLAPIENTRY
-_mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)
-{
- struct gl_framebuffer *newFb, *newReadFb, *oldFb;
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (target != GL_FRAMEBUFFER_EXT) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glBindFramebufferEXT(target)");
- return;
- }
-
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- if (framebuffer) {
- /* Binding a user-created framebuffer object */
- newFb = lookup_framebuffer(ctx, framebuffer);
- if (newFb == &DummyFramebuffer) {
- /* ID was reserved, but no real framebuffer object made yet */
- newFb = NULL;
- }
- if (!newFb) {
- /* create new framebuffer object */
- newFb = ctx->Driver.NewFramebuffer(ctx, framebuffer);
- if (!newFb) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindFramebufferEXT");
- return;
- }
- _mesa_HashInsert(ctx->Shared->FrameBuffers, framebuffer, newFb);
- }
- newFb->RefCount++;
- newReadFb = newFb;
- }
- else {
- /* Binding the window system framebuffer (which was originally set
- * with MakeCurrent).
- */
- newFb = ctx->WinSysDrawBuffer;
- newReadFb = ctx->WinSysReadBuffer;
- }
-
- oldFb = ctx->DrawBuffer;
- if (oldFb && oldFb->Name != 0) {
- oldFb->RefCount--;
- if (oldFb->RefCount == 0) {
- oldFb->Delete(oldFb);
- }
- }
-
- ASSERT(newFb != &DummyFramebuffer);
-
- /* Note, we set both the GL_DRAW_BUFFER and GL_READ_BUFFER state: */
- ctx->DrawBuffer = newFb;
- ctx->ReadBuffer = newReadFb;
-}
-
-
-void GLAPIENTRY
-_mesa_DeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers)
-{
- GLint i;
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- for (i = 0; i < n; i++) {
- if (framebuffers[i] > 0) {
- struct gl_framebuffer *fb;
- fb = lookup_framebuffer(ctx, framebuffers[i]);
- if (fb) {
- ASSERT(fb == &DummyFramebuffer || fb->Name == framebuffers[i]);
-
- /* check if deleting currently bound framebuffer object */
- if (fb == ctx->DrawBuffer) {
- /* bind default */
- ASSERT(fb->RefCount >= 2);
- _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
- }
-
- /* remove from hash table immediately, to free the ID */
- _mesa_HashRemove(ctx->Shared->FrameBuffers, framebuffers[i]);
-
- if (fb != &DummyFramebuffer) {
- /* But the object will not be freed until it's no longer
- * bound in any context.
- */
- fb->RefCount--;
- if (fb->RefCount == 0) {
- fb->Delete(fb);
- }
- }
- }
- }
- }
-}
-
-
-void GLAPIENTRY
-_mesa_GenFramebuffersEXT(GLsizei n, GLuint *framebuffers)
-{
- GET_CURRENT_CONTEXT(ctx);
- GLuint first;
- GLint i;
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (n < 0) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGenFramebuffersEXT(n)");
- return;
- }
-
- if (!framebuffers)
- return;
-
- first = _mesa_HashFindFreeKeyBlock(ctx->Shared->FrameBuffers, n);
-
- for (i = 0; i < n; i++) {
- GLuint name = first + i;
- framebuffers[i] = name;
- /* insert dummy placeholder into hash table */
- _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
- _mesa_HashInsert(ctx->Shared->FrameBuffers, name, &DummyFramebuffer);
- _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
- }
-}
-
-
-
-GLenum GLAPIENTRY
-_mesa_CheckFramebufferStatusEXT(GLenum target)
-{
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
-
- if (target != GL_FRAMEBUFFER_EXT) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glCheckFramebufferStatus(target)");
- return 0; /* formerly GL_FRAMEBUFFER_STATUS_ERROR_EXT */
- }
-
- if (ctx->DrawBuffer->Name == 0) {
- /* The window system / default framebuffer is always complete */
- return GL_FRAMEBUFFER_COMPLETE_EXT;
- }
-
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- _mesa_test_framebuffer_completeness(ctx, ctx->DrawBuffer);
- return ctx->DrawBuffer->_Status;
-}
-
-
-
-/**
- * Do error checking common to glFramebufferTexture1D/2D/3DEXT.
- * \return GL_TRUE if any error, GL_FALSE otherwise
- */
-static GLboolean
-error_check_framebuffer_texture(GLcontext *ctx, GLuint dims,
- GLenum target, GLenum attachment,
- GLenum textarget, GLuint texture, GLint level)
-{
- ASSERT(dims >= 1 && dims <= 3);
-
- if (target != GL_FRAMEBUFFER_EXT) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glFramebufferTexture%dDEXT(target)", dims);
- return GL_TRUE;
- }
-
- /* check framebuffer binding */
- if (ctx->DrawBuffer->Name == 0) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glFramebufferTexture%dDEXT", dims);
- return GL_TRUE;
- }
-
- /* only check textarget, level if texture ID is non-zero */
- if (texture) {
- if ((dims == 1 && textarget != GL_TEXTURE_1D) ||
- (dims == 3 && textarget != GL_TEXTURE_3D) ||
- (dims == 2 && textarget != GL_TEXTURE_2D &&
- textarget != GL_TEXTURE_RECTANGLE_ARB &&
- !IS_CUBE_FACE(textarget))) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glFramebufferTexture%dDEXT(textarget)", dims);
- return GL_TRUE;
- }
-
- if ((level < 0) || level >= _mesa_max_texture_levels(ctx, textarget)) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glFramebufferTexture%dDEXT(level)", dims);
- return GL_TRUE;
- }
- }
-
- return GL_FALSE;
-}
-
-
-void GLAPIENTRY
-_mesa_FramebufferTexture1DEXT(GLenum target, GLenum attachment,
- GLenum textarget, GLuint texture, GLint level)
-{
- struct gl_renderbuffer_attachment *att;
- struct gl_texture_object *texObj;
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (error_check_framebuffer_texture(ctx, 1, target, attachment,
- textarget, texture, level))
- return;
-
- ASSERT(textarget == GL_TEXTURE_1D);
-
- att = get_attachment(ctx, ctx->DrawBuffer, attachment);
- if (att == NULL) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glFramebufferTexture1DEXT(attachment)");
- return;
- }
-
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- if (texture) {
- texObj = (struct gl_texture_object *)
- _mesa_HashLookup(ctx->Shared->TexObjects, texture);
- if (!texObj) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glFramebufferTexture1DEXT(texture)");
- return;
- }
- if (texObj->Target != textarget) {
- _mesa_error(ctx, GL_INVALID_OPERATION, /* XXX correct error? */
- "glFramebufferTexture1DEXT(texture target)");
- return;
- }
- }
- else {
- /* remove texture attachment */
- texObj = NULL;
- }
- ctx->Driver.RenderbufferTexture(ctx, att, texObj, textarget, level, 0);
-}
-
-
-void GLAPIENTRY
-_mesa_FramebufferTexture2DEXT(GLenum target, GLenum attachment,
- GLenum textarget, GLuint texture, GLint level)
-{
- struct gl_renderbuffer_attachment *att;
- struct gl_texture_object *texObj;
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (error_check_framebuffer_texture(ctx, 2, target, attachment,
- textarget, texture, level))
- return;
-
- ASSERT(textarget == GL_TEXTURE_2D ||
- textarget == GL_TEXTURE_RECTANGLE_ARB ||
- IS_CUBE_FACE(textarget));
-
- att = get_attachment(ctx, ctx->DrawBuffer, attachment);
- if (att == NULL) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glFramebufferTexture2DEXT(attachment)");
- return;
- }
-
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- if (texture) {
- texObj = (struct gl_texture_object *)
- _mesa_HashLookup(ctx->Shared->TexObjects, texture);
- if (!texObj) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glFramebufferTexture2DEXT(texture)");
- return;
- }
- if ((texObj->Target == GL_TEXTURE_2D && textarget != GL_TEXTURE_2D) ||
- (texObj->Target == GL_TEXTURE_RECTANGLE_ARB
- && textarget != GL_TEXTURE_RECTANGLE_ARB) ||
- (texObj->Target == GL_TEXTURE_CUBE_MAP
- && !IS_CUBE_FACE(textarget))) {
- _mesa_error(ctx, GL_INVALID_OPERATION, /* XXX correct error? */
- "glFramebufferTexture2DEXT(texture target)");
- return;
- }
- }
- else {
- /* remove texture attachment */
- texObj = NULL;
- }
- ctx->Driver.RenderbufferTexture(ctx, att, texObj, textarget, level, 0);
-}
-
-
-void GLAPIENTRY
-_mesa_FramebufferTexture3DEXT(GLenum target, GLenum attachment,
- GLenum textarget, GLuint texture,
- GLint level, GLint zoffset)
-{
- struct gl_renderbuffer_attachment *att;
- struct gl_texture_object *texObj;
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (error_check_framebuffer_texture(ctx, 3, target, attachment,
- textarget, texture, level))
- return;
-
- ASSERT(textarget == GL_TEXTURE_3D);
-
- att = get_attachment(ctx, ctx->DrawBuffer, attachment);
- if (att == NULL) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glFramebufferTexture1DEXT(attachment)");
- return;
- }
-
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- if (texture) {
- const GLint maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
- texObj = (struct gl_texture_object *)
- _mesa_HashLookup(ctx->Shared->TexObjects, texture);
- if (!texObj) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glFramebufferTexture3DEXT(texture)");
- return;
- }
- if (texObj->Target != textarget) {
- _mesa_error(ctx, GL_INVALID_OPERATION, /* XXX correct error? */
- "glFramebufferTexture3DEXT(texture target)");
- return;
- }
- if (zoffset < 0 || zoffset >= maxSize) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glFramebufferTexture3DEXT(zoffset)");
- return;
- }
- }
- else {
- /* remove texture attachment */
- texObj = NULL;
- }
- ctx->Driver.RenderbufferTexture(ctx, att, texObj, textarget,
- level, zoffset);
-}
-
-
-void GLAPIENTRY
-_mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment,
- GLenum renderbufferTarget,
- GLuint renderbuffer)
-{
- struct gl_renderbuffer_attachment *att;
- struct gl_renderbuffer *rb;
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (target != GL_FRAMEBUFFER_EXT) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glFramebufferRenderbufferEXT(target)");
- return;
- }
-
- if (renderbufferTarget != GL_RENDERBUFFER_EXT) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glFramebufferRenderbufferEXT(renderbufferTarget)");
- return;
- }
-
- if (ctx->DrawBuffer->Name == 0) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glFramebufferRenderbufferEXT");
- return;
- }
-
- att = get_attachment(ctx, ctx->DrawBuffer, attachment);
- if (att == NULL) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glFramebufferRenderbufferEXT(attachment)");
- return;
- }
-
- if (renderbuffer) {
- rb = lookup_renderbuffer(ctx, renderbuffer);
- if (!rb) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glFramebufferRenderbufferEXT(renderbuffer)");
- return;
- }
- }
- else {
- /* remove renderbuffer attachment */
- rb = NULL;
- }
-
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- assert(ctx->Driver.FramebufferRenderbuffer);
- ctx->Driver.FramebufferRenderbuffer(ctx, att, rb);
-}
-
-
-void GLAPIENTRY
-_mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
- GLenum pname, GLint *params)
-{
- const struct gl_renderbuffer_attachment *att;
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
-
- if (target != GL_FRAMEBUFFER_EXT) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameterivEXT(target)");
- return;
- }
-
- if (ctx->DrawBuffer->Name == 0) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetFramebufferAttachmentParameterivEXT");
- return;
- }
-
- att = get_attachment(ctx, ctx->DrawBuffer, attachment);
- if (att == NULL) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameterivEXT(attachment)");
- return;
- }
-
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- switch (pname) {
- case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT:
- *params = att->Type;
- return;
- case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT:
- if (att->Type == GL_RENDERBUFFER_EXT) {
- *params = att->Renderbuffer->Name;
- }
- else if (att->Type == GL_TEXTURE) {
- *params = att->Texture->Name;
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameterivEXT(pname)");
- }
- return;
- case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT:
- if (att->Type == GL_TEXTURE) {
- *params = att->TextureLevel;
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameterivEXT(pname)");
- }
- return;
- case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT:
- if (att->Type == GL_TEXTURE) {
- *params = GL_TEXTURE_CUBE_MAP_POSITIVE_X + att->CubeMapFace;
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameterivEXT(pname)");
- }
- return;
- case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT:
- if (att->Type == GL_TEXTURE) {
- *params = att->Zoffset;
- }
- else {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameterivEXT(pname)");
- }
- return;
- default:
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameterivEXT(pname)");
- return;
- }
-}
-
-
-void GLAPIENTRY
-_mesa_GenerateMipmapEXT(GLenum target)
-{
- struct gl_texture_unit *texUnit;
- struct gl_texture_object *texObj;
- GET_CURRENT_CONTEXT(ctx);
-
- ASSERT_OUTSIDE_BEGIN_END(ctx);
- FLUSH_VERTICES(ctx, _NEW_BUFFERS);
-
- switch (target) {
- case GL_TEXTURE_1D:
- case GL_TEXTURE_2D:
- case GL_TEXTURE_3D:
- case GL_TEXTURE_CUBE_MAP:
- /* OK, legal value */
- break;
- default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glGenerateMipmapEXT(target)");
- return;
- }
-
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
-
- /* XXX this might not handle cube maps correctly */
- _mesa_generate_mipmap(ctx, target, texUnit, texObj);
-}