#include "framebuffer.h"
#include "hash.h"
#include "macros.h"
+#include "mfeatures.h"
+#include "mtypes.h"
#include "renderbuffer.h"
#include "state.h"
#include "teximage.h"
/**
* Is the given base format a legal format for a color renderbuffer?
*/
-static GLboolean
-is_legal_color_format(const struct gl_context *ctx, GLenum baseFormat)
+GLboolean
+_mesa_is_legal_color_format(const struct gl_context *ctx, GLenum baseFormat)
{
switch (baseFormat) {
case GL_RGB:
case GL_RGBA:
return GL_TRUE;
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
case GL_ALPHA:
return ctx->Extensions.ARB_framebuffer_object;
case GL_RED:
baseFormat = _mesa_get_format_base_format(texImage->TexFormat);
if (format == GL_COLOR) {
- if (!is_legal_color_format(ctx, baseFormat)) {
+ if (!_mesa_is_legal_color_format(ctx, baseFormat)) {
att_incomplete("bad format");
att->Complete = GL_FALSE;
return;
return;
}
if (format == GL_COLOR) {
- if (baseFormat != GL_RGB &&
- baseFormat != GL_RGBA) {
+ if (!_mesa_is_legal_color_format(ctx, baseFormat)) {
att_incomplete("bad renderbuffer color format");
att->Complete = GL_FALSE;
return;
f = texImg->_BaseFormat;
mesaFormat = texImg->TexFormat;
numImages++;
- if (!is_legal_color_format(ctx, f) &&
+ if (!_mesa_is_legal_color_format(ctx, f) &&
!is_legal_depth_format(ctx, f)) {
fb->_Status = GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT;
fbo_incomplete("texture attachment incomplete", -1);
}
/* check if integer color */
- fb->_IntegerColor = _mesa_is_format_integer(mesaFormat);
+ fb->_IntegerColor = _mesa_is_format_integer_color(mesaFormat);
/* Error-check width, height, format, samples
*/
fb->Height = minHeight;
/* finally, update the visual info for the framebuffer */
- _mesa_update_framebuffer_visual(fb);
+ _mesa_update_framebuffer_visual(ctx, fb);
}
}
/**
- * Given an internal format token for a render buffer, return the
+ * Given an internal format token for a renderbuffer, return the
* corresponding base format.
- * This is very similar to _mesa_base_tex_format() but the set of valid
- * internal formats is somewhat different.
- *
- * \return one of GL_RGB, GL_RGBA, GL_STENCIL_INDEX, GL_DEPTH_COMPONENT
- * GL_DEPTH_STENCIL_EXT or zero if error.
- *
- * XXX in the future when we support red-only and red-green formats
- * we'll also return GL_RED and GL_RG.
*/
GLenum
_mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat)
{
+ GLenum baseFormat;
+
switch (internalFormat) {
- case GL_ALPHA:
- case GL_ALPHA4:
- case GL_ALPHA8:
- case GL_ALPHA12:
- case GL_ALPHA16:
- return GL_ALPHA;
- 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:
case GL_RGBA16_SNORM:
+ /* This is used internally by Mesa for accum buffers. */
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:
+ /* This is not a valid texture internalFormat, but valid for
+ * renderbuffers.
+ */
return GL_STENCIL_INDEX;
case GL_DEPTH_COMPONENT:
case GL_DEPTH_COMPONENT16:
case GL_DEPTH_COMPONENT24:
case GL_DEPTH_COMPONENT32:
+ /* This is an override of _mesa_base_tex_format's check that
+ * ARB_depth_texture is present. We allow depth RBs without it.
+ */
return GL_DEPTH_COMPONENT;
- case GL_DEPTH_STENCIL_EXT:
- case GL_DEPTH24_STENCIL8_EXT:
- if (ctx->Extensions.EXT_packed_depth_stencil)
- return GL_DEPTH_STENCIL_EXT;
- else
- return 0;
- /* XXX add floating point formats eventually */
- default:
- return 0;
}
+
+ baseFormat = _mesa_base_tex_format(ctx, internalFormat);
+ if (baseFormat < 0)
+ return 0;
+
+ return baseFormat;
}
return;
}
+ if (baseFormat != GL_DEPTH_COMPONENT &&
+ baseFormat != GL_STENCIL_INDEX &&
+ baseFormat != GL_DEPTH_STENCIL &&
+ !_mesa_is_legal_color_format(ctx, baseFormat)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "%s(internalFormat)", func);
+ return;
+ }
+
if (width < 1 || width > (GLsizei) ctx->Const.MaxRenderbufferSize) {
_mesa_error(ctx, GL_INVALID_VALUE, "%s(width)", func);
return;
switch (pname) {
case GL_RENDERBUFFER_RED_SIZE_EXT:
case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
+ if (baseFormat == GL_RGB || baseFormat == GL_RGBA ||
+ baseFormat == GL_RG || baseFormat == GL_RED)
+ return _mesa_get_format_bits(format, pname);
+ else
+ return 0;
case GL_RENDERBUFFER_GREEN_SIZE_EXT:
case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
+ if (baseFormat == GL_RGB || baseFormat == GL_RGBA || baseFormat == GL_RG)
+ return _mesa_get_format_bits(format, pname);
+ else
+ return 0;
case GL_RENDERBUFFER_BLUE_SIZE_EXT:
case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
if (baseFormat == GL_RGB || baseFormat == GL_RGBA)
return 0;
case GL_RENDERBUFFER_ALPHA_SIZE_EXT:
case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
- if (baseFormat == GL_RGBA || baseFormat == GL_ALPHA)
+ if (baseFormat == GL_RGBA || baseFormat == GL_ALPHA ||
+ baseFormat == GL_LUMINANCE_ALPHA)
return _mesa_get_format_bits(format, pname);
else
return 0;
" renderbuffer %u)", renderbuffer);
return;
}
+ else if (rb == &DummyRenderbuffer) {
+ /* This is what NVIDIA does */
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glFramebufferRenderbufferEXT(renderbuffer %u)",
+ renderbuffer);
+ return;
+ }
}
else {
/* remove renderbuffer attachment */
/* Some subsequent GL commands may depend on the framebuffer's visual
* after the binding is updated. Update visual info now.
*/
- _mesa_update_framebuffer_visual(fb);
+ _mesa_update_framebuffer_visual(ctx, fb);
}
switch (pname) {
case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT:
- *params = att->Type;
+ *params = buffer->Name == 0 ? GL_FRAMEBUFFER_DEFAULT : att->Type;
return;
case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT:
if (att->Type == GL_RENDERBUFFER_EXT) {
*params = att->Texture->Name;
}
else {
- _mesa_error(ctx, GL_INVALID_ENUM,
- "glGetFramebufferAttachmentParameterivEXT(pname)");
+ assert(att->Type == GL_NONE);
+ *params = 0;
}
return;
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT:
/* OK, legal value */
break;
default:
+ /* XXX need to implement GL_TEXTURE_1D_ARRAY and GL_TEXTURE_2D_ARRAY */
_mesa_error(ctx, GL_INVALID_ENUM, "glGenerateMipmapEXT(target)");
return;
}
return;
}
+ if (texObj->Target == GL_TEXTURE_CUBE_MAP &&
+ !_mesa_cube_complete(texObj)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGenerateMipmap(incomplete cube map)");
+ return;
+ }
+
_mesa_lock_texture(ctx, texObj);
if (target == GL_TEXTURE_CUBE_MAP) {
GLuint face;