* Later, when the object ID is first bound, we replace the placeholder
* with the real frame/renderbuffer.
*/
-static struct gl_frame_buffer_object DummyFramebuffer;
-static struct gl_render_buffer_object DummyRenderbuffer;
+static struct gl_framebuffer DummyFramebuffer;
+static struct gl_renderbuffer DummyRenderbuffer;
#define IS_CUBE_FACE(TARGET) \
/**
- * Helper routine for getting a gl_render_buffer_object.
+ * Helper routine for getting a gl_renderbuffer.
*/
-static struct gl_render_buffer_object *
+static struct gl_renderbuffer *
lookup_renderbuffer(GLcontext *ctx, GLuint id)
{
- struct gl_render_buffer_object *rb;
+ struct gl_renderbuffer *rb;
if (id == 0)
return NULL;
- rb = (struct gl_render_buffer_object *)
+ rb = (struct gl_renderbuffer *)
_mesa_HashLookup(ctx->Shared->RenderBuffers, id);
return rb;
}
/**
- * Helper routine for getting a gl_frame_buffer_object.
+ * Helper routine for getting a gl_framebuffer.
*/
-static struct gl_frame_buffer_object *
+static struct gl_framebuffer *
lookup_framebuffer(GLcontext *ctx, GLuint id)
{
- struct gl_frame_buffer_object *fb;
+ struct gl_framebuffer *fb;
if (id == 0)
return NULL;
- fb = (struct gl_frame_buffer_object *)
+ fb = (struct gl_framebuffer *)
_mesa_HashLookup(ctx->Shared->FrameBuffers, id);
return fb;
}
/**
- * Allocate a new gl_render_buffer_object.
- * XXX make this a device driver function.
+ * Allocate a new gl_framebuffer.
+ * This is the default function for ctx->Driver.NewFramebuffer().
*/
-static struct gl_render_buffer_object *
-new_renderbuffer(GLcontext *ctx, GLuint name)
+struct gl_framebuffer *
+_mesa_new_framebuffer(GLcontext *ctx, GLuint name)
{
- struct gl_render_buffer_object *rb = CALLOC_STRUCT(gl_render_buffer_object);
+ struct gl_framebuffer *fb = CALLOC_STRUCT(gl_framebuffer);
+ if (fb) {
+ fb->Name = name;
+ fb->RefCount = 1;
+ fb->Delete = _mesa_delete_framebuffer;
+ }
+ return fb;
+}
+
+
+/**
+ * Delete a gl_framebuffer.
+ * This is the default function for framebuffer->Delete().
+ */
+void
+_mesa_delete_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb)
+{
+ (void) ctx;
+ _mesa_free(fb);
+}
+
+
+/**
+ * Allocate the actual storage for a renderbuffer with the given format
+ * and dimensions.
+ * This is the default function for gl_renderbuffer->AllocStorage().
+ * All incoming parameters will have already been checked for errors.
+ * If memory allocate fails, the function must call
+ * _mesa_error(GL_OUT_OF_MEMORY) and then return.
+ * \return GL_TRUE for success, GL_FALSE for failure.
+ */
+static GLboolean
+alloc_renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLenum internalFormat, GLuint width, GLuint height)
+{
+ /* First, free any existing storage */
+ if (rb->Data) {
+ _mesa_free(rb->Data);
+ }
+
+ /* Now, allocate new storage */
+ rb->Data = _mesa_malloc(width * height * 4); /* XXX fix size! */
+ if (rb->Data == NULL) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glRenderbufferStorageEXT");
+ return GL_FALSE;
+ }
+
+ /* We set these fields now if the allocation worked */
+ rb->Width = width;
+ rb->Height = height;
+ rb->InternalFormat = internalFormat;
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Allocate a new gl_renderbuffer.
+ * This is the default function for ctx->Driver.NewRenderbuffer().
+ */
+struct gl_renderbuffer *
+_mesa_new_renderbuffer(GLcontext *ctx, GLuint name)
+{
+ struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer);
if (rb) {
rb->Name = name;
rb->RefCount = 1;
+ rb->Delete = _mesa_delete_renderbuffer;
+ rb->AllocStorage = alloc_renderbuffer_storage;
/* other fields are zero */
}
return rb;
/**
- * Allocate a new gl_frame_buffer_object.
- * XXX make this a device driver function.
+ * Delete a gl_framebuffer.
+ * This is the default function for framebuffer->Delete().
*/
-static struct gl_frame_buffer_object *
-new_framebuffer(GLcontext *ctx, GLuint name)
+void
+_mesa_delete_renderbuffer(GLcontext *ctx, struct gl_renderbuffer *rb)
{
- struct gl_frame_buffer_object *fb = CALLOC_STRUCT(gl_frame_buffer_object);
- if (fb) {
- fb->Name = name;
- fb->RefCount = 1;
+ (void) ctx;
+ if (rb->Data) {
+ _mesa_free(rb->Data);
}
- return fb;
+ _mesa_free(rb);
}
/**
* Given a GL_*_ATTACHMENTn token, return a pointer to the corresponding
- * gl_render_buffer_attachment object.
+ * gl_renderbuffer_attachment object.
*/
-static struct gl_render_buffer_attachment *
-get_attachment(GLcontext *ctx, GLenum attachment)
+static struct gl_renderbuffer_attachment *
+get_attachment(GLcontext *ctx, struct gl_framebuffer *fb, GLenum attachment)
{
GLuint i;
if (i >= ctx->Const.MaxColorAttachments) {
return NULL;
}
- return &ctx->CurrentFramebuffer->ColorAttachment[i];
+ return &fb->ColorAttachment[i];
case GL_DEPTH_ATTACHMENT_EXT:
- return &ctx->CurrentFramebuffer->DepthAttachment;
+ return &fb->DepthAttachment;
case GL_STENCIL_ATTACHMENT_EXT:
- return &ctx->CurrentFramebuffer->StencilAttachment;
+ return &fb->StencilAttachment;
default:
return NULL;
}
* point. Update reference counts, etc.
*/
static void
-remove_attachment(GLcontext *ctx, struct gl_render_buffer_attachment *att)
+remove_attachment(GLcontext *ctx, struct gl_renderbuffer_attachment *att)
{
if (att->Type == GL_TEXTURE) {
ASSERT(att->Texture);
ASSERT(!att->Texture);
att->Renderbuffer->RefCount--;
if (att->Renderbuffer->RefCount == 0) {
- _mesa_free(att->Renderbuffer); /* XXX driver free */
+ att->Renderbuffer->Delete(ctx, att->Renderbuffer);
}
att->Renderbuffer = NULL;
}
*/
static void
set_texture_attachment(GLcontext *ctx,
- struct gl_render_buffer_attachment *att,
+ struct gl_renderbuffer_attachment *att,
struct gl_texture_object *texObj,
GLenum texTarget, GLuint level, GLuint zoffset)
{
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.
+ */
}
*/
static void
set_renderbuffer_attachment(GLcontext *ctx,
- struct gl_render_buffer_attachment *att,
- struct gl_render_buffer_object *rb)
+ struct gl_renderbuffer_attachment *att,
+ struct gl_renderbuffer *rb)
{
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++;
}
*/
static void
test_attachment_completeness(const GLcontext *ctx, GLenum format,
- struct gl_render_buffer_attachment *att)
+ struct gl_renderbuffer_attachment *att)
{
assert(format == GL_COLOR || format == GL_DEPTH || format == GL_STENCIL);
*/
static void
test_framebuffer_completeness(GLcontext *ctx,
- struct gl_frame_buffer_object *fb)
+ struct gl_framebuffer *fb)
{
GLint i;
GLuint numImages, width, height;
/* Start at -2 to more easily loop over all attachment points */
for (i = -2; i < ctx->Const.MaxColorAttachments; i++) {
- struct gl_render_buffer_attachment *att;
+ struct gl_renderbuffer_attachment *att;
GLuint w, h;
GLenum f;
/* Check that all DrawBuffers are present */
for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
if (fb->DrawBuffer[i] != GL_NONE) {
- struct gl_render_buffer_attachment *att
- = get_attachment(ctx, fb->DrawBuffer[i]);
+ struct gl_renderbuffer_attachment *att
+ = get_attachment(ctx, fb, fb->DrawBuffer[i]);
if (att->Type == GL_NONE) {
fb->Status = GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT;
return;
/* Check that the ReadBuffer is present */
if (fb->ReadBuffer != GL_NONE) {
- struct gl_render_buffer_attachment *att
- = get_attachment(ctx, fb->ReadBuffer);
+ struct gl_renderbuffer_attachment *att
+ = get_attachment(ctx, fb, fb->ReadBuffer);
if (att->Type == GL_NONE) {
fb->Status = GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT;
return;
GLboolean GLAPIENTRY
_mesa_IsRenderbufferEXT(GLuint renderbuffer)
{
- const struct gl_render_buffer_object *rb;
+ const struct gl_renderbuffer *rb;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
void GLAPIENTRY
_mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer)
{
- struct gl_render_buffer_object *newRb, *oldRb;
+ struct gl_renderbuffer *newRb, *oldRb;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
}
if (!newRb) {
/* create new renderbuffer object */
- newRb = new_renderbuffer(ctx, renderbuffer);
+ 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++;
if (oldRb) {
oldRb->RefCount--;
if (oldRb->RefCount == 0) {
- _mesa_free(oldRb); /* XXX device driver function */
+ oldRb->Delete(ctx, oldRb);
}
}
ASSERT_OUTSIDE_BEGIN_END(ctx);
for (i = 0; i < n; i++) {
- if (renderbuffers[i]) {
- struct gl_render_buffer_object *rb;
+ if (renderbuffers[i] > 0) {
+ struct gl_renderbuffer *rb;
rb = lookup_renderbuffer(ctx, renderbuffers[i]);
if (rb) {
/* remove from hash table immediately, to free the ID */
*/
rb->RefCount--;
if (rb->RefCount == 0) {
- _mesa_free(rb); /* XXX call device driver function */
+ rb->Delete(ctx, rb);
}
}
}
case GL_STENCIL_INDEX16_EXT:
return GL_STENCIL_INDEX;
case GL_DEPTH_COMPONENT:
- case GL_DEPTH_COMPONENT16_SGIX:
- case GL_DEPTH_COMPONENT24_SGIX:
- case GL_DEPTH_COMPONENT32_SGIX:
+ case GL_DEPTH_COMPONENT16:
+ case GL_DEPTH_COMPONENT24:
+ case GL_DEPTH_COMPONENT32:
return GL_DEPTH_COMPONENT;
/* XXX add floating point formats eventually */
default:
_mesa_RenderbufferStorageEXT(GLenum target, GLenum internalFormat,
GLsizei width, GLsizei height)
{
+ struct gl_renderbuffer *rb;
GLenum baseFormat;
GET_CURRENT_CONTEXT(ctx);
return;
}
- /* XXX this check isn't in the spec, but seems necessary */
- if (!ctx->CurrentRenderbuffer) {
+ rb = ctx->CurrentRenderbuffer;
+
+ if (!rb) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glRenderbufferStorageEXT");
return;
}
- if (ctx->CurrentRenderbuffer->Data) {
- /* XXX device driver free */
- _mesa_free(ctx->CurrentRenderbuffer->Data);
+ /* 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;
}
-
- /* XXX device driver allocate, fix size */
- ctx->CurrentRenderbuffer->Data = _mesa_malloc(width * height * 4);
- if (ctx->CurrentRenderbuffer->Data == NULL) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glRenderbufferStorageEXT");
- return;
+ else {
+ /* Probably ran out of memory - clear the fields */
+ rb->Width = 0;
+ rb->Height = 0;
+ rb->InternalFormat = GL_NONE;
+ rb->_BaseFormat = GL_NONE;
}
- ctx->CurrentRenderbuffer->InternalFormat = internalFormat;
- ctx->CurrentRenderbuffer->Width = width;
- ctx->CurrentRenderbuffer->Height = height;
- ctx->CurrentRenderbuffer->_BaseFormat = baseFormat;
+
+ /* XXX if this renderbuffer is attached anywhere, invalidate attachment
+ * points???
+ */
}
GLboolean GLAPIENTRY
_mesa_IsFramebufferEXT(GLuint framebuffer)
{
- const struct gl_frame_buffer_object *fb;
+ const struct gl_framebuffer *fb;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
void GLAPIENTRY
_mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)
{
- struct gl_frame_buffer_object *newFb, *oldFb;
+ struct gl_framebuffer *newFb, *oldFb;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
}
if (!newFb) {
/* create new framebuffer object */
- newFb = new_framebuffer(ctx, framebuffer);
+ newFb = ctx->Driver.NewFramebuffer(ctx, framebuffer);
if (!newFb) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindFramebufferEXT");
return;
if (oldFb) {
oldFb->RefCount--;
if (oldFb->RefCount == 0) {
- _mesa_free(oldFb); /* XXX device driver function */
+ oldFb->Delete(ctx, oldFb);
}
}
ASSERT_OUTSIDE_BEGIN_END(ctx);
for (i = 0; i < n; i++) {
- if (framebuffers[i]) {
- struct gl_frame_buffer_object *fb;
+ if (framebuffers[i] > 0) {
+ struct gl_framebuffer *fb;
fb = lookup_framebuffer(ctx, framebuffers[i]);
if (fb) {
/* remove from hash table immediately, to free the ID */
*/
fb->RefCount--;
if (fb->RefCount == 0) {
- _mesa_free(fb); /* XXX call device driver function */
+ fb->Delete(ctx, fb);
}
}
}
_mesa_FramebufferTexture1DEXT(GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level)
{
- struct gl_render_buffer_attachment *att;
+ struct gl_renderbuffer_attachment *att;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
ASSERT(textarget == GL_TEXTURE_1D);
- att = get_attachment(ctx, attachment);
+ att = get_attachment(ctx, ctx->CurrentFramebuffer, attachment);
if (att == NULL) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glFramebufferTexture1DEXT(attachment)");
_mesa_FramebufferTexture2DEXT(GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level)
{
- struct gl_render_buffer_attachment *att;
+ struct gl_renderbuffer_attachment *att;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
textarget == GL_TEXTURE_RECTANGLE_ARB ||
IS_CUBE_FACE(textarget));
- att = get_attachment(ctx, attachment);
+ att = get_attachment(ctx, ctx->CurrentFramebuffer, attachment);
if (att == NULL) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glFramebufferTexture2DEXT(attachment)");
GLenum textarget, GLuint texture,
GLint level, GLint zoffset)
{
- struct gl_render_buffer_attachment *att;
+ struct gl_renderbuffer_attachment *att;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
ASSERT(textarget == GL_TEXTURE_3D);
- att = get_attachment(ctx, attachment);
+ att = get_attachment(ctx, ctx->CurrentFramebuffer, attachment);
if (att == NULL) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glFramebufferTexture1DEXT(attachment)");
GLenum renderbufferTarget,
GLuint renderbuffer)
{
- struct gl_render_buffer_attachment *att;
+ struct gl_renderbuffer_attachment *att;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
return;
}
- att = get_attachment(ctx, attachment);
+ att = get_attachment(ctx, ctx->CurrentFramebuffer, attachment);
if (att == NULL) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glFramebufferRenderbufferEXT(attachment)");
}
if (renderbuffer) {
- struct gl_render_buffer_object *rb;
+ struct gl_renderbuffer *rb;
rb = lookup_renderbuffer(ctx, renderbuffer);
if (!rb) {
_mesa_error(ctx, GL_INVALID_VALUE,
_mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
GLenum pname, GLint *params)
{
- const struct gl_render_buffer_attachment *att;
+ const struct gl_renderbuffer_attachment *att;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
return;
}
- att = get_attachment(ctx, attachment);
+ att = get_attachment(ctx, ctx->CurrentFramebuffer, attachment);
if (att == NULL) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glGetFramebufferAttachmentParameterivEXT(attachment)");
#define FBOBJECT_H
-struct gl_render_buffer_object
+/**
+ * A renderbuffer stores colors or depth values or stencil values.
+ * A framebuffer object will have a collection of these.
+ * Data are read/written to the buffer with a handful of Get/Put functions.
+ *
+ * Instances of this object are allocated with the Driver's NewRenderbuffer
+ * hook. Drivers will likely wrap this class inside a driver-specific
+ * class to simulate inheritance.
+ */
+struct gl_renderbuffer
{
- GLint RefCount;
GLuint Name;
+ GLint RefCount;
GLuint Width, Height;
GLenum InternalFormat;
GLenum _BaseFormat; /* Either GL_RGB, GL_RGBA, GL_DEPTH_COMPONENT or */
/* GL_STENCIL_INDEX. */
+
+ GLenum DataType; /* GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, etc */
GLvoid *Data;
+
+ /* Delete this renderbuffer */
+ void (*Delete)(GLcontext *ctx, struct gl_renderbuffer *rb);
+
+ /* Allocate new storage for this renderbuffer */
+ GLboolean (*AllocStorage)(GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLenum internalFormat,
+ GLuint width, GLuint height);
+
+ /* Return a pointer to the element/pixel at (x,y).
+ * Should return NULL if the buffer memory can't be directly addressed.
+ */
+ void *(*GetPointer)(struct gl_renderbuffer *rb, GLint x, GLint y);
+
+ /* Get/Read a row of values.
+ * The values will be of format _BaseFormat and type DataType.
+ */
+ void (*GetRow)(struct gl_renderbuffer *rb,
+ GLint x, GLint y, GLuint count, void *values);
+
+ /* Get/Read values at arbitrary locations
+ * The values will be of format _BaseFormat and type DataType.
+ */
+ void (*GetValues)(struct gl_renderbuffer *rb,
+ const GLint x[], const GLint y[],
+ GLuint count, void *values);
+
+ /* Put/Write a row of values
+ * The values will be of format _BaseFormat and type DataType.
+ */
+ void (*PutRow)(struct gl_renderbuffer *rb,
+ GLint x, GLint y, GLuint count,
+ const void *values, const GLubyte *maek);
+
+ /* Put/Write values at arbitrary locations
+ * The values will be of format _BaseFormat and type DataType.
+ */
+ void (*PutValues)(struct gl_renderbuffer *rb,
+ const GLint x[], const GLint y[], GLuint count,
+ const void *values, const GLubyte *mask);
};
-struct gl_render_buffer_attachment
+/**
+ * A renderbuffer attachment point points to either a texture object
+ * (and specifies a mipmap level, cube face or 3D texture slice) or
+ * points to a renderbuffer.
+ */
+struct gl_renderbuffer_attachment
{
GLenum Type; /* GL_NONE or GL_TEXTURE or GL_RENDERBUFFER_EXT */
+ GLboolean Complete;
+
/* IF Type == GL_RENDERBUFFER_EXT: */
- struct gl_render_buffer_object *Renderbuffer;
+ struct gl_renderbuffer *Renderbuffer;
+
/* IF Type == GL_TEXTURE: */
struct gl_texture_object *Texture;
GLuint TextureLevel;
GLuint CubeMapFace; /* 0 .. 5, for cube map textures */
GLuint Zoffset; /* for 3D textures */
- GLboolean Complete;
};
-struct gl_frame_buffer_object
+/**
+ * A framebuffer object is basically a collection of rendering buffers.
+ * (Though, a rendering buffer might actually be a texture image.)
+ * All the renderbuffers/textures which we reference must have the same
+ * width and height (and meet a few other requirements) in order for the
+ * framebufffer object to be "complete".
+ *
+ * Instances of this object are allocated with the Driver's Newframebuffer
+ * hook. Drivers will likely wrap this class inside a driver-specific
+ * class to simulate inheritance.
+ */
+struct gl_framebuffer
{
- GLint RefCount;
GLuint Name;
+ GLint RefCount;
- GLenum Status;
+ GLenum Status; /* One of the GL_FRAMEBUFFER_(IN)COMPLETE_* tokens */
- struct gl_render_buffer_attachment ColorAttachment[MAX_COLOR_ATTACHMENTS];
- struct gl_render_buffer_attachment DepthAttachment;
- struct gl_render_buffer_attachment StencilAttachment;
+ struct gl_renderbuffer_attachment ColorAttachment[MAX_COLOR_ATTACHMENTS];
+ struct gl_renderbuffer_attachment DepthAttachment;
+ struct gl_renderbuffer_attachment StencilAttachment;
/* In unextended OpenGL, these vars are part of the GL_COLOR_BUFFER
* attribute group and GL_PIXEL attribute group, respectively.
*/
GLenum DrawBuffer[MAX_DRAW_BUFFERS];
GLenum ReadBuffer;
+
+ GLuint _Width, _Height;
+
+ /** Delete this framebuffer */
+ void (*Delete)(GLcontext *ctx, struct gl_framebuffer *fb);
};
+extern struct gl_framebuffer *
+_mesa_new_framebuffer(GLcontext *ctx, GLuint name);
+
+extern void
+_mesa_delete_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb);
+
+extern struct gl_renderbuffer *
+_mesa_new_renderbuffer(GLcontext *ctx, GLuint name);
+
+extern void
+_mesa_delete_renderbuffer(GLcontext *ctx, struct gl_renderbuffer *rb);
+
+
extern GLboolean GLAPIENTRY
_mesa_IsRenderbufferEXT(GLuint renderbuffer);
GLsizei width, GLsizei height);
extern void GLAPIENTRY
-_mesa_GetRenderbufferParameterivEXT(GLenum target, GLenum pname, GLint *params);
+_mesa_GetRenderbufferParameterivEXT(GLenum target, GLenum pname,
+ GLint *params);
extern GLboolean GLAPIENTRY
_mesa_IsFramebufferEXT(GLuint framebuffer);