#include "hash.h"
-/* XXX these are temporary here! */
-#define GL_FRAMEBUFFER_EXT 0x8D40
-#define GL_RENDERBUFFER_EXT 0x8D41
-#define GL_STENCIL_INDEX_EXT 0x8D45
-#define GL_STENCIL_INDEX1_EXT 0x8D46
-#define GL_STENCIL_INDEX4_EXT 0x8D47
-#define GL_STENCIL_INDEX8_EXT 0x8D48
-#define GL_STENCIL_INDEX16_EXT 0x8D49
-#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42
-#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43
-#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44
-#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0
-#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1
-#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2
-#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3
-#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4
-#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0
-#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1
-#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2
-#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3
-#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4
-#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5
-#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6
-#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7
-#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8
-#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9
-#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA
-#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB
-#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC
-#define GL_COLOR_ATTACHMENT13_EXT 0x8CED
-#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE
-#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF
-#define GL_DEPTH_ATTACHMENT_EXT 0x8D00
-#define GL_STENCIL_ATTACHMENT_EXT 0x8D20
-#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5
-#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6
-#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7
-#define GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT 0x8CD8
-#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9
-#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA
-#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB
-#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC
-#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD
-#define GL_FRAMEBUFFER_STATUS_ERROR_EXT 0x8CDE
-#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6
-#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7
-#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF
-#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8
-#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506
-
-
-struct gl_render_buffer_object
-{
- GLint RefCount;
- GLuint Name;
-
- GLuint width, height;
-};
-
-
-struct gl_frame_buffer_object
-{
- GLint RefCount;
- GLuint Name;
-
-};
-
+#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_render_buffer_object.
*/
static struct gl_render_buffer_object *
-LookupRenderbuffer(GLcontext *ctx, GLuint id)
+lookup_renderbuffer(GLcontext *ctx, GLuint id)
{
struct gl_render_buffer_object *rb;
* Helper routine for getting a gl_frame_buffer_object.
*/
static struct gl_frame_buffer_object *
-LookupFramebuffer(GLcontext *ctx, GLuint id)
+lookup_framebuffer(GLcontext *ctx, GLuint id)
{
struct gl_frame_buffer_object *rb;
* XXX make this a device driver function.
*/
static struct gl_render_buffer_object *
-NewRenderBuffer(GLcontext *ctx, GLuint name)
+new_renderbuffer(GLcontext *ctx, GLuint name)
{
struct gl_render_buffer_object *rb = CALLOC_STRUCT(gl_render_buffer_object);
if (rb) {
rb->Name = name;
rb->RefCount = 1;
+ /* other fields are zero */
}
return rb;
}
* XXX make this a device driver function.
*/
static struct gl_frame_buffer_object *
-NewFrameBuffer(GLcontext *ctx, GLuint name)
+new_framebuffer(GLcontext *ctx, GLuint name)
{
struct gl_frame_buffer_object *fb = CALLOC_STRUCT(gl_frame_buffer_object);
if (fb) {
}
+static struct gl_render_buffer_attachment *
+get_attachment(GLcontext *ctx, 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 &ctx->CurrentFramebuffer->ColorAttachment[i];
+ case GL_DEPTH_ATTACHMENT_EXT:
+ return &ctx->CurrentFramebuffer->DepthAttachment;
+ case GL_STENCIL_ATTACHMENT_EXT:
+ return &ctx->CurrentFramebuffer->StencilAttachment;
+ default:
+ return NULL;
+ }
+}
+
+
+static void
+remove_attachment(GLcontext *ctx, struct gl_render_buffer_attachment *att)
+{
+ if (att->Type == GL_TEXTURE) {
+ ASSERT(att->Texture);
+ ASSERT(!att->Renderbuffer);
+ 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) {
+ _mesa_free(att->Renderbuffer); /* XXX driver free */
+ }
+ att->Renderbuffer = NULL;
+ }
+ att->Type = GL_NONE;
+}
+
+
+static void
+set_texture_attachment(GLcontext *ctx,
+ struct gl_render_buffer_attachment *att,
+ struct gl_texture_object *texObj,
+ GLenum texTarget, GLuint level, GLuint zoffset)
+{
+ 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;
+ texObj->RefCount++;
+}
+
+
+static void
+set_renderbuffer_attachment(GLcontext *ctx,
+ struct gl_render_buffer_attachment *att,
+ struct gl_render_buffer_object *rb)
+{
+ remove_attachment(ctx, att);
+ att->Type = GL_RENDERBUFFER_EXT;
+ att->Renderbuffer = rb;
+ rb->RefCount++;
+}
+
GLboolean
_mesa_IsRenderbufferEXT(GLuint renderbuffer)
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
- rb = LookupRenderbuffer(ctx, renderbuffer);
+ rb = lookup_renderbuffer(ctx, renderbuffer);
return rb ? GL_TRUE : GL_FALSE;
}
void
_mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer)
{
- struct gl_render_buffer_object *rb;
+ struct gl_render_buffer_object *newRb, *oldRb;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
- switch (target) {
- case GL_RENDERBUFFER_EXT:
- break;
- case GL_FRAMEBUFFER_EXT:
- break;
- default:
- _mesa_error(ctx, GL_INVALID_ENUM, "glBindRenderbufferEXT(target)");
+ if (target != GL_RENDERBUFFER_EXT) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glBindRenderbufferEXT(target)");
return;
}
- rb = LookupRenderbuffer(ctx, renderbuffer);
- if (!rb) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glIsRenderbufferEXT(renderbuffer)");
- return;
+ if (renderbuffer) {
+ newRb = lookup_renderbuffer(ctx, renderbuffer);
+ if (!newRb) {
+ /* create new renderbuffer object */
+ newRb = new_renderbuffer(ctx, renderbuffer);
+ if (!newRb) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindRenderbufferEXT");
+ return;
+ }
+ }
+ newRb->RefCount++;
}
+ oldRb = ctx->CurrentRenderbuffer;
+ if (oldRb) {
+ oldRb->RefCount--;
+ if (oldRb->RefCount == 0) {
+ _mesa_free(oldRb); /* XXX device driver function */
+ }
+ }
+ ctx->CurrentRenderbuffer = newRb;
}
ASSERT_OUTSIDE_BEGIN_END(ctx);
for (i = 0; i < n; i++) {
- struct gl_render_buffer_object *rb;
- rb = LookupRenderbuffer(ctx, renderbuffers[i]);
- if (rb) {
- /* remove from hash table immediately, to free the ID */
- _mesa_HashRemove(ctx->Shared->RenderBuffers, renderbuffers[i]);
-
- /* But the object will not be freed until it's no longer bound in
- * any context.
- */
- rb->RefCount--;
- if (rb->RefCount == 0) {
- _mesa_free(rb); /* XXX call device driver function */
- }
+ if (renderbuffers[i]) {
+ struct gl_render_buffer_object *rb;
+ rb = lookup_renderbuffer(ctx, renderbuffers[i]);
+ if (rb) {
+ /* remove from hash table immediately, to free the ID */
+ _mesa_HashRemove(ctx->Shared->RenderBuffers, renderbuffers[i]);
+
+ /* But the object will not be freed until it's no longer bound in
+ * any context.
+ */
+ rb->RefCount--;
+ if (rb->RefCount == 0) {
+ _mesa_free(rb); /* XXX call device driver function */
+ }
+ }
}
}
}
for (i = 0; i < n; i++) {
struct gl_render_buffer_object *rb;
GLuint name = first + i;
- rb = NewRenderBuffer(ctx, name);
+ rb = new_renderbuffer(ctx, name);
if (!rb) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenRenderbuffersEXT");
return;
}
-
void
_mesa_RenderbufferStorageEXT(GLenum target, GLenum internalFormat,
GLsizei width, GLsizei height)
return;
}
-
if (width > 0 /*value of MAX_RENDERBUFFER_SIZE_EXT*/) {
_mesa_error(ctx, GL_INVALID_VALUE, "glRenderbufferStorageEXT(width)");
return;
return;
}
-
-
}
-
void
_mesa_GetRenderbufferParameterivEXT(GLenum target, GLenum pname, GLint *params)
{
}
-
GLboolean
_mesa_IsFramebufferEXT(GLuint framebuffer)
{
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
- fb = LookupFramebuffer(ctx, framebuffer);
+ fb = lookup_framebuffer(ctx, framebuffer);
return fb ? GL_TRUE : GL_FALSE;
}
void
_mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer)
{
+ struct gl_frame_buffer_object *newFb, *oldFb;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
- switch (target) {
- case GL_FRAMEBUFFER_EXT:
- break;
- default:
- _mesa_error(ctx, GL_INVALID_ENUM,
+ if (target != GL_FRAMEBUFFER_EXT) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
"glBindFramebufferEXT(target)");
return;
}
+ if (framebuffer) {
+ newFb = lookup_framebuffer(ctx, framebuffer);
+ if (!newFb) {
+ /* create new framebuffer object */
+ newFb = new_framebuffer(ctx, framebuffer);
+ if (!newFb) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindFramebufferEXT");
+ return;
+ }
+ }
+ newFb->RefCount++;
+ }
+
+ oldFb = ctx->CurrentFramebuffer;
+ if (oldFb) {
+ oldFb->RefCount--;
+ if (oldFb->RefCount == 0) {
+ _mesa_free(oldFb); /* XXX device driver function */
+ }
+ }
+ ctx->CurrentFramebuffer = newFb;
}
ASSERT_OUTSIDE_BEGIN_END(ctx);
for (i = 0; i < n; i++) {
- struct gl_frame_buffer_object *fb;
- fb = LookupFramebuffer(ctx, framebuffers[i]);
- if (fb) {
- /* remove from hash table immediately, to free the ID */
- _mesa_HashRemove(ctx->Shared->FrameBuffers, framebuffers[i]);
-
- /* But the object will not be freed until it's no longer bound in
- * any context.
- */
- fb->RefCount--;
- if (fb->RefCount == 0) {
- _mesa_free(fb); /* XXX call device driver function */
- }
+ if (framebuffers[i]) {
+ struct gl_frame_buffer_object *fb;
+ fb = lookup_framebuffer(ctx, framebuffers[i]);
+ if (fb) {
+ /* remove from hash table immediately, to free the ID */
+ _mesa_HashRemove(ctx->Shared->FrameBuffers, framebuffers[i]);
+
+ /* But the object will not be freed until it's no longer bound in
+ * any context.
+ */
+ fb->RefCount--;
+ if (fb->RefCount == 0) {
+ _mesa_free(fb); /* XXX call device driver function */
+ }
+ }
}
}
}
for (i = 0; i < n; i++) {
struct gl_frame_buffer_object *fb;
GLuint name = first + i;
- fb = NewFrameBuffer(ctx, name);
+ fb = new_framebuffer(ctx, name);
if (!fb) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenFramebuffersEXT");
return;
* \return GL_TRUE if any error, GL_FALSE otherwise
*/
static GLboolean
-error_check_framebuffer_texture(GLcontext *ctx,
- GLuint dims, GLenum target, GLenum attachment,
- GLint level)
+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;
}
- 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:
- case GL_DEPTH_ATTACHMENT_EXT:
- case GL_STENCIL_ATTACHMENT_EXT:
- break;
- default:
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glFramebufferTexture%dDEXT(level)", dims);
+ if (ctx->CurrentFramebuffer == NULL) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glFramebufferTexture%dDEXT", dims);
return GL_TRUE;
}
- if (level < 0 /* || level too large */) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glFramebufferTexture%dDEXT(level)", 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 (target == GL_TEXTURE_RECTANGLE_ARB && level != 0) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glFramebufferTexture%dDEXT(level)", dims);
- return GL_TRUE;
+ if ((level < 0)
+ || (textarget == GL_TEXTURE_1D
+ && level >= ctx->Const.MaxTextureLevels)
+ || (textarget == GL_TEXTURE_2D
+ && level >= ctx->Const.MaxTextureLevels)
+ || (textarget == GL_TEXTURE_3D
+ && level >= ctx->Const.Max3DTextureLevels)
+ || (textarget == GL_TEXTURE_RECTANGLE_ARB
+ && level != 0)
+ || (IS_CUBE_FACE(textarget)
+ && level >= ctx->Const.MaxCubeTextureLevels)) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glFramebufferTexture%dDEXT(level)", dims);
+ return GL_TRUE;
+ }
}
return GL_FALSE;
_mesa_FramebufferTexture1DEXT(GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level)
{
+ struct gl_render_buffer_attachment *att;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
- if (error_check_framebuffer_texture(ctx, 1, target, attachment, level))
+ if (error_check_framebuffer_texture(ctx, 1, target, attachment,
+ textarget, texture, level))
return;
+ ASSERT(textarget == GL_TEXTURE_1D);
+
+ att = get_attachment(ctx, attachment);
+ if (att == NULL) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glFramebufferTexture1DEXT(attachment)");
+ return;
+ }
+
+ if (texture) {
+ struct gl_texture_object *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;
+ }
+ set_texture_attachment(ctx, att, texObj, textarget, level, 0);
+ }
+ else {
+ remove_attachment(ctx, att);
+ }
+
+ /* XXX call a driver function to signal new attachment? */
}
_mesa_FramebufferTexture2DEXT(GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level)
{
+ struct gl_render_buffer_attachment *att;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
- if (error_check_framebuffer_texture(ctx, 1, target, attachment, level))
+ 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, attachment);
+ if (att == NULL) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glFramebufferTexture2DEXT(attachment)");
return;
+ }
+
+ if (texture) {
+ struct gl_texture_object *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;
+ }
+ set_texture_attachment(ctx, att, texObj, textarget, level, 0);
+ }
+ else {
+ remove_attachment(ctx, att);
+ }
+
}
GLenum textarget, GLuint texture,
GLint level, GLint zoffset)
{
+ struct gl_render_buffer_attachment *att;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
- if (error_check_framebuffer_texture(ctx, 1, target, attachment, level))
+ if (error_check_framebuffer_texture(ctx, 3, target, attachment,
+ textarget, texture, level))
return;
- /* check that zoffset isn't too large */
+ ASSERT(textarget == GL_TEXTURE_3D);
+
+ att = get_attachment(ctx, attachment);
+ if (att == NULL) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glFramebufferTexture1DEXT(attachment)");
+ return;
+ }
+
+ if (texture) {
+ struct gl_texture_object *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 >= texObj->Image[0][level]->Depth) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glFramebufferTexture3DEXT(zoffset)");
+ return;
+ }
+ set_texture_attachment(ctx, att, texObj, textarget, level, zoffset);
+ }
+ else {
+ remove_attachment(ctx, att);
+ }
}
GLenum renderbufferTarget,
GLuint renderbuffer)
{
+ struct gl_render_buffer_object *rb;
+ struct gl_render_buffer_attachment *att;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
return;
}
- 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:
- case GL_DEPTH_ATTACHMENT_EXT:
- case GL_STENCIL_ATTACHMENT_EXT:
- break;
- default:
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glFramebufferRenderbufferEXT(attachment)");
+ if (renderbufferTarget != GL_RENDERBUFFER_EXT) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glFramebufferRenderbufferEXT(renderbufferTarget)");
return;
}
- if (renderbufferTarget != GL_RENDERBUFFER_EXT) {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glFramebufferRenderbufferEXT(renderbufferTarget)");
+ if (ctx->CurrentFramebuffer == NULL) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glFramebufferRenderbufferEXT");
return;
}
+ if (renderbuffer) {
+ rb = lookup_renderbuffer(ctx, renderbuffer);
+ if (!rb) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glFramebufferRenderbufferEXT(renderbuffer)");
+ return;
+ }
+ }
+ else {
+ rb = NULL; /* default renderbuffer */
+ }
+
+ att = get_attachment(ctx, attachment);
+ if (att == NULL) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glFramebufferRenderbufferEXT(attachment)");
+ return;
+ }
+ remove_attachment(ctx, att);
+ set_renderbuffer_attachment(ctx, att, rb);
}
_mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
GLenum pname, GLint *params)
{
+ const struct gl_render_buffer_attachment *att;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
return;
}
- 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:
- case GL_DEPTH_ATTACHMENT_EXT:
- case GL_STENCIL_ATTACHMENT_EXT:
- break;
- default:
+ if (ctx->CurrentFramebuffer == NULL) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetFramebufferAttachmentParameterivEXT");
+ return;
+ }
+
+ att = get_attachment(ctx, attachment);
+ if (att == NULL) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glGetFramebufferAttachmentParameterivEXT(attachment)");
return;
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:
- break;
+ 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;
}
-
- *params = 0;
}
struct ati_fragment_shader
{
- struct program Base;
- struct atifs_instruction *Instructions;
- GLfloat Constants[8][4];
- GLint NumPasses;
- GLint cur_pass;
+ struct program Base;
+ struct atifs_instruction *Instructions;
+ GLfloat Constants[8][4];
+ GLint NumPasses;
+ GLint cur_pass;
};
/**
*/
struct gl_ati_fragment_shader_state
{
- GLboolean Enabled;
- GLboolean _Enabled;
- GLboolean Compiling;
- struct atifs_machine Machine; /* machine state */
- struct ati_fragment_shader *Current;
+ GLboolean Enabled;
+ GLboolean _Enabled;
+ GLboolean Compiling;
+ struct atifs_machine Machine; /* machine state */
+ struct ati_fragment_shader *Current;
};
/*
*/
enum gl2_uiid
{
- UIID_UNKNOWN, /* supported by all objects */
- UIID_GENERIC, /* generic object */
- UIID_CONTAINER, /* contains generic objects */
- UIID_SHADER, /* shader object */
- UIID_FRAGMENT_SHADER, /* fragment shader */
- UIID_VERTEX_SHADER, /* vertex shader */
- UIID_PROGRAM, /* program object */
- UIID_3DLABS_SHHANDLE /* encapsulates 3dlabs' ShHandle */
+ UIID_UNKNOWN, /* supported by all objects */
+ UIID_GENERIC, /* generic object */
+ UIID_CONTAINER, /* contains generic objects */
+ UIID_SHADER, /* shader object */
+ UIID_FRAGMENT_SHADER, /* fragment shader */
+ UIID_VERTEX_SHADER, /* vertex shader */
+ UIID_PROGRAM, /* program object */
+ UIID_3DLABS_SHHANDLE /* encapsulates 3dlabs' ShHandle */
};
struct gl2_unknown_intf
{
- GLvoid (* AddRef) (struct gl2_unknown_intf **);
- GLvoid (* Release) (struct gl2_unknown_intf **);
- struct gl2_unknown_intf **(* QueryInterface) (struct gl2_unknown_intf **, enum gl2_uiid uiid);
+ GLvoid (* AddRef) (struct gl2_unknown_intf **);
+ GLvoid (* Release) (struct gl2_unknown_intf **);
+ struct gl2_unknown_intf **(* QueryInterface) (struct gl2_unknown_intf **, enum gl2_uiid uiid);
};
struct gl2_generic_intf
{
- struct gl2_unknown_intf _unknown;
- GLvoid (* Delete) (struct gl2_generic_intf **);
- GLenum (* GetType) (struct gl2_generic_intf **);
- GLhandleARB (* GetName) (struct gl2_generic_intf **);
- GLboolean (* GetDeleteStatus) (struct gl2_generic_intf **);
- const GLcharARB *(* GetInfoLog) (struct gl2_generic_intf **);
+ struct gl2_unknown_intf _unknown;
+ GLvoid (* Delete) (struct gl2_generic_intf **);
+ GLenum (* GetType) (struct gl2_generic_intf **);
+ GLhandleARB (* GetName) (struct gl2_generic_intf **);
+ GLboolean (* GetDeleteStatus) (struct gl2_generic_intf **);
+ const GLcharARB *(* GetInfoLog) (struct gl2_generic_intf **);
};
struct gl2_container_intf
{
- struct gl2_generic_intf _generic;
- GLboolean (* Attach) (struct gl2_container_intf **, struct gl2_generic_intf **);
- GLboolean (* Detach) (struct gl2_container_intf **, struct gl2_generic_intf **);
- GLsizei (* GetAttachedCount) (struct gl2_container_intf **);
- struct gl2_generic_intf **(* GetAttached) (struct gl2_container_intf **, GLuint);
+ struct gl2_generic_intf _generic;
+ GLboolean (* Attach) (struct gl2_container_intf **, struct gl2_generic_intf **);
+ GLboolean (* Detach) (struct gl2_container_intf **, struct gl2_generic_intf **);
+ GLsizei (* GetAttachedCount) (struct gl2_container_intf **);
+ struct gl2_generic_intf **(* GetAttached) (struct gl2_container_intf **, GLuint);
};
struct gl2_shader_intf
{
- struct gl2_generic_intf _generic;
- GLenum (* GetSubType) (struct gl2_shader_intf **);
- GLboolean (* GetCompileStatus) (struct gl2_shader_intf **);
- GLvoid (* SetSource) (struct gl2_shader_intf **, GLcharARB *, GLint *, GLsizei);
- const GLcharARB *(* GetSource) (struct gl2_shader_intf **);
- GLvoid (* Compile) (struct gl2_shader_intf **);
+ struct gl2_generic_intf _generic;
+ GLenum (* GetSubType) (struct gl2_shader_intf **);
+ GLboolean (* GetCompileStatus) (struct gl2_shader_intf **);
+ GLvoid (* SetSource) (struct gl2_shader_intf **, GLcharARB *, GLint *, GLsizei);
+ const GLcharARB *(* GetSource) (struct gl2_shader_intf **);
+ GLvoid (* Compile) (struct gl2_shader_intf **);
};
struct gl2_program_intf
{
- struct gl2_container_intf _container;
- GLboolean (* GetLinkStatus) (struct gl2_program_intf **);
- GLboolean (* GetValidateStatus) (struct gl2_program_intf **);
- GLvoid (* Link) (struct gl2_program_intf **);
- GLvoid (* Validate) (struct gl2_program_intf **);
+ struct gl2_container_intf _container;
+ GLboolean (* GetLinkStatus) (struct gl2_program_intf **);
+ GLboolean (* GetValidateStatus) (struct gl2_program_intf **);
+ GLvoid (* Link) (struct gl2_program_intf **);
+ GLvoid (* Validate) (struct gl2_program_intf **);
};
struct gl2_fragment_shader_intf
{
- struct gl2_shader_intf _shader;
+ struct gl2_shader_intf _shader;
};
struct gl2_vertex_shader_intf
{
- struct gl2_shader_intf _shader;
+ struct gl2_shader_intf _shader;
};
struct gl2_3dlabs_shhandle_intf
{
- struct gl2_unknown_intf _unknown;
- GLvoid *(* GetShHandle) (struct gl2_3dlabs_shhandle_intf **);
+ struct gl2_unknown_intf _unknown;
+ GLvoid *(* GetShHandle) (struct gl2_3dlabs_shhandle_intf **);
};
struct gl_shader_objects_state
{
- struct gl2_program_intf **current_program;
+ struct gl2_program_intf **current_program;
};
/*@}*/
/**
- * \name GL_NV_vertex/_program
+ * \name Vertex/fragment programs
*/
/*@{*/
struct _mesa_HashTable *Programs;
#endif
/*@}*/
-#if FEATURE_ARB_vertex_buffer_object
+#if FEATURE_ARB_vertex_buffer_object || FEATURE_ARB_pixel_buffer_object
struct _mesa_HashTable *BufferObjects;
#endif
/* GL_OES_read_format */
GLenum ColorReadFormat;
GLenum ColorReadType;
+ /* GL_EXT_framebuffer_object */
+ GLuint MaxColorAttachments;
+ GLuint MaxRenderbufferSize;
};
GLboolean EXT_copy_texture;
GLboolean EXT_depth_bounds_test;
GLboolean EXT_draw_range_elements;
+ GLboolean EXT_framebuffer_object;
GLboolean EXT_fog_coord;
GLboolean EXT_histogram;
GLboolean EXT_multi_draw_arrays;
struct gl_shader_objects_state ShaderObjects; /* GL_ARB_shader_objects */
/*@}*/
+#if FEATURE_EXT_framebuffer_object
+ struct gl_frame_buffer_object *CurrentFramebuffer;
+ struct gl_render_buffer_object *CurrentRenderbuffer;
+#endif
+
GLenum ErrorValue; /**< Last error code */
GLenum RenderMode; /**< either GL_RENDER, GL_SELECT, GL_FEEDBACK */
GLuint NewState; /**< bitwise-or of _NEW_* flags */