aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/main
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2013-01-16 08:45:43 +0100
committermarha <marha@users.sourceforge.net>2013-01-16 08:45:43 +0100
commitb8219a4680768e14b7fe4930adf86e9be261b31f (patch)
tree193855ef8d48765d67cc11153a15e3c1e2568e50 /mesalib/src/mesa/main
parent15cdb95b194cb051a5d469cc9eb73eb0eed4db41 (diff)
parent811d1bcf6d61ea49551abdd7f2294c5af2776913 (diff)
downloadvcxsrv-b8219a4680768e14b7fe4930adf86e9be261b31f.tar.gz
vcxsrv-b8219a4680768e14b7fe4930adf86e9be261b31f.tar.bz2
vcxsrv-b8219a4680768e14b7fe4930adf86e9be261b31f.zip
Merge remote-tracking branch 'origin/released'
* origin/released: Switched to xcalc-1.0.5 Switched to bdftopcf-1.0.4 libxtrans fontconfig glproto libX11 libXau libXext libXft libXinerama libXmu libfontenc mesa xkeyboard-config
Diffstat (limited to 'mesalib/src/mesa/main')
-rw-r--r--mesalib/src/mesa/main/bufferobj.c53
-rw-r--r--mesalib/src/mesa/main/buffers.c101
-rw-r--r--mesalib/src/mesa/main/dd.h16
-rw-r--r--mesalib/src/mesa/main/extensions.c1
-rw-r--r--mesalib/src/mesa/main/fbobject.c244
-rw-r--r--mesalib/src/mesa/main/formatquery.c147
-rw-r--r--mesalib/src/mesa/main/formatquery.h35
-rw-r--r--mesalib/src/mesa/main/framebuffer.c21
-rw-r--r--mesalib/src/mesa/main/framebuffer.h5
-rw-r--r--mesalib/src/mesa/main/glformats.c459
-rw-r--r--mesalib/src/mesa/main/glformats.h5
-rw-r--r--mesalib/src/mesa/main/mtypes.h2
-rw-r--r--mesalib/src/mesa/main/pack.c12
-rw-r--r--mesalib/src/mesa/main/queryobj.c28
-rw-r--r--mesalib/src/mesa/main/readpix.c22
-rw-r--r--mesalib/src/mesa/main/teximage.c55
-rw-r--r--mesalib/src/mesa/main/texparam.c13
-rw-r--r--mesalib/src/mesa/main/varray.c14
18 files changed, 1076 insertions, 157 deletions
diff --git a/mesalib/src/mesa/main/bufferobj.c b/mesalib/src/mesa/main/bufferobj.c
index 107711560..a9cd7382e 100644
--- a/mesalib/src/mesa/main/bufferobj.c
+++ b/mesalib/src/mesa/main/bufferobj.c
@@ -136,10 +136,24 @@ get_buffer(struct gl_context *ctx, const char *func, GLenum target)
}
-static inline GLbitfield
-default_access_mode(const struct gl_context *ctx)
+/**
+ * Convert a GLbitfield describing the mapped buffer access flags
+ * into one of GL_READ_WRITE, GL_READ_ONLY, or GL_WRITE_ONLY.
+ */
+static GLenum
+simplified_access_mode(struct gl_context *ctx, GLbitfield access)
{
- /* Table 2.6 on page 31 (page 44 of the PDF) of the OpenGL 1.5 spec says:
+ const GLbitfield rwFlags = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT;
+ if ((access & rwFlags) == rwFlags)
+ return GL_READ_WRITE;
+ if ((access & GL_MAP_READ_BIT) == GL_MAP_READ_BIT)
+ return GL_READ_ONLY;
+ if ((access & GL_MAP_WRITE_BIT) == GL_MAP_WRITE_BIT)
+ return GL_WRITE_ONLY;
+
+ /* Otherwise, AccessFlags is zero (the default state).
+ *
+ * Table 2.6 on page 31 (page 44 of the PDF) of the OpenGL 1.5 spec says:
*
* Name Type Initial Value Legal Values
* ... ... ... ...
@@ -155,26 +169,9 @@ default_access_mode(const struct gl_context *ctx)
* The difference is because GL_OES_mapbuffer only supports mapping buffers
* write-only.
*/
- return _mesa_is_gles(ctx)
- ? GL_MAP_WRITE_BIT : (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
-}
+ assert(access == 0);
-
-/**
- * Convert a GLbitfield describing the mapped buffer access flags
- * into one of GL_READ_WRITE, GL_READ_ONLY, or GL_WRITE_ONLY.
- */
-static GLenum
-simplified_access_mode(GLbitfield access)
-{
- const GLbitfield rwFlags = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT;
- if ((access & rwFlags) == rwFlags)
- return GL_READ_WRITE;
- if ((access & GL_MAP_READ_BIT) == GL_MAP_READ_BIT)
- return GL_READ_ONLY;
- if ((access & GL_MAP_WRITE_BIT) == GL_MAP_WRITE_BIT)
- return GL_WRITE_ONLY;
- return GL_READ_WRITE; /* this should never happen, but no big deal */
+ return _mesa_is_gles(ctx) ? GL_WRITE_ONLY : GL_READ_WRITE;
}
@@ -354,7 +351,7 @@ _mesa_initialize_buffer_object( struct gl_context *ctx,
obj->RefCount = 1;
obj->Name = name;
obj->Usage = GL_STATIC_DRAW_ARB;
- obj->AccessFlags = default_access_mode(ctx);
+ obj->AccessFlags = 0;
}
@@ -864,7 +861,7 @@ _mesa_DeleteBuffers(GLsizei n, const GLuint *ids)
if (_mesa_bufferobj_mapped(bufObj)) {
/* if mapped, unmap it now */
ctx->Driver.UnmapBuffer(ctx, bufObj);
- bufObj->AccessFlags = default_access_mode(ctx);
+ bufObj->AccessFlags = 0;
bufObj->Pointer = NULL;
}
@@ -1064,7 +1061,7 @@ _mesa_BufferData(GLenum target, GLsizeiptrARB size,
if (_mesa_bufferobj_mapped(bufObj)) {
/* Unmap the existing buffer. We'll replace it now. Not an error. */
ctx->Driver.UnmapBuffer(ctx, bufObj);
- bufObj->AccessFlags = default_access_mode(ctx);
+ bufObj->AccessFlags = 0;
ASSERT(bufObj->Pointer == NULL);
}
@@ -1282,7 +1279,7 @@ _mesa_UnmapBuffer(GLenum target)
#endif
status = ctx->Driver.UnmapBuffer( ctx, bufObj );
- bufObj->AccessFlags = default_access_mode(ctx);
+ bufObj->AccessFlags = 0;
ASSERT(bufObj->Pointer == NULL);
ASSERT(bufObj->Offset == 0);
ASSERT(bufObj->Length == 0);
@@ -1310,7 +1307,7 @@ _mesa_GetBufferParameteriv(GLenum target, GLenum pname, GLint *params)
*params = bufObj->Usage;
return;
case GL_BUFFER_ACCESS_ARB:
- *params = simplified_access_mode(bufObj->AccessFlags);
+ *params = simplified_access_mode(ctx, bufObj->AccessFlags);
return;
case GL_BUFFER_MAPPED_ARB:
*params = _mesa_bufferobj_mapped(bufObj);
@@ -1364,7 +1361,7 @@ _mesa_GetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)
*params = bufObj->Usage;
return;
case GL_BUFFER_ACCESS_ARB:
- *params = simplified_access_mode(bufObj->AccessFlags);
+ *params = simplified_access_mode(ctx, bufObj->AccessFlags);
return;
case GL_BUFFER_ACCESS_FLAGS:
if (!ctx->Extensions.ARB_map_buffer_range)
diff --git a/mesalib/src/mesa/main/buffers.c b/mesalib/src/mesa/main/buffers.c
index d10a57394..87848fb93 100644
--- a/mesalib/src/mesa/main/buffers.c
+++ b/mesalib/src/mesa/main/buffers.c
@@ -94,7 +94,7 @@ supported_buffer_bitmask(const struct gl_context *ctx,
* GL_FRONT_AND_BACK), return the corresponding bitmask of BUFFER_BIT_* flags.
*/
static GLbitfield
-draw_buffer_enum_to_bitmask(GLenum buffer)
+draw_buffer_enum_to_bitmask(const struct gl_context *ctx, GLenum buffer)
{
switch (buffer) {
case GL_NONE:
@@ -102,6 +102,21 @@ draw_buffer_enum_to_bitmask(GLenum buffer)
case GL_FRONT:
return BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT;
case GL_BACK:
+ if (_mesa_is_gles3(ctx)) {
+ /* Page 181 (page 192 of the PDF) in section 4.2.1 of the OpenGL
+ * ES 3.0.1 specification says:
+ *
+ * "When draw buffer zero is BACK, color values are written
+ * into the sole buffer for single-buffered contexts, or into
+ * the back buffer for double-buffered contexts."
+ *
+ * Since there is no stereo rendering in ES 3.0, only return the
+ * LEFT bits. This also satisfies the "n must be 1" requirement.
+ */
+ if (ctx->DrawBuffer->Visual.doubleBufferMode)
+ return BUFFER_BIT_BACK_LEFT;
+ return BUFFER_BIT_FRONT_LEFT;
+ }
return BUFFER_BIT_BACK_LEFT | BUFFER_BIT_BACK_RIGHT;
case GL_RIGHT:
return BUFFER_BIT_FRONT_RIGHT | BUFFER_BIT_BACK_RIGHT;
@@ -241,7 +256,7 @@ _mesa_DrawBuffer(GLenum buffer)
else {
const GLbitfield supportedMask
= supported_buffer_bitmask(ctx, ctx->DrawBuffer);
- destMask = draw_buffer_enum_to_bitmask(buffer);
+ destMask = draw_buffer_enum_to_bitmask(ctx, buffer);
if (destMask == BAD_MASK) {
/* totally bogus buffer */
_mesa_error(ctx, GL_INVALID_ENUM,
@@ -290,6 +305,10 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers)
/* Turns out n==0 is a valid input that should not produce an error.
* The remaining code below correctly handles the n==0 case.
+ *
+ * From the OpenGL 3.0 specification, page 258:
+ * "An INVALID_VALUE error is generated if n is greater than
+ * MAX_DRAW_BUFFERS."
*/
if (n < 0 || n > (GLsizei) ctx->Const.MaxDrawBuffers) {
_mesa_error(ctx, GL_INVALID_VALUE, "glDrawBuffersARB(n)");
@@ -299,26 +318,94 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers)
supportedMask = supported_buffer_bitmask(ctx, ctx->DrawBuffer);
usedBufferMask = 0x0;
+ /* From the ES 3.0 specification, page 180:
+ * "If the GL is bound to the default framebuffer, then n must be 1
+ * and the constant must be BACK or NONE."
+ */
+ if (_mesa_is_gles3(ctx) && _mesa_is_winsys_fbo(ctx->DrawBuffer) &&
+ (n != 1 || (buffers[0] != GL_NONE && buffers[0] != GL_BACK))) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffers(buffer)");
+ return;
+ }
+
/* complicated error checking... */
for (output = 0; output < n; output++) {
if (buffers[output] == GL_NONE) {
destMask[output] = 0x0;
}
else {
- destMask[output] = draw_buffer_enum_to_bitmask(buffers[output]);
- if (destMask[output] == BAD_MASK
- || _mesa_bitcount(destMask[output]) > 1) {
+ /* Page 259 (page 275 of the PDF) in section 4.2.1 of the OpenGL 3.0
+ * spec (20080923) says:
+ *
+ * "If the GL is bound to a framebuffer object and DrawBuffers is
+ * supplied with [...] COLOR_ATTACHMENTm where m is greater than
+ * or equal to the value of MAX_COLOR_ATTACHMENTS, then the error
+ * INVALID_OPERATION results."
+ */
+ if (_mesa_is_user_fbo(ctx->DrawBuffer) && buffers[output] >=
+ GL_COLOR_ATTACHMENT0 + ctx->Const.MaxDrawBuffers) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffersARB(buffer)");
+ return;
+ }
+
+ destMask[output] = draw_buffer_enum_to_bitmask(ctx, buffers[output]);
+
+ /* From the OpenGL 3.0 specification, page 258:
+ * "Each buffer listed in bufs must be one of the values from tables
+ * 4.5 or 4.6. Otherwise, an INVALID_ENUM error is generated.
+ */
+ if (destMask[output] == BAD_MASK) {
_mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffersARB(buffer)");
return;
}
+
+ /* From the OpenGL 3.0 specification, page 259:
+ * "For both the default framebuffer and framebuffer objects, the
+ * constants FRONT, BACK, LEFT, RIGHT, and FRONT_AND_BACK are not
+ * valid in the bufs array passed to DrawBuffers, and will result in
+ * the error INVALID_OPERATION. This restriction is because these
+ * constants may themselves refer to multiple buffers, as shown in
+ * table 4.4."
+ */
+ if (_mesa_bitcount(destMask[output]) > 1) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffersARB(buffer)");
+ return;
+ }
+
+ /* From the OpenGL 3.0 specification, page 259:
+ * "If the GL is bound to the default framebuffer and DrawBuffers is
+ * supplied with a constant (other than NONE) that does not indicate
+ * any of the color buffers allocated to the GL context by the window
+ * system, the error INVALID_OPERATION will be generated.
+ *
+ * If the GL is bound to a framebuffer object and DrawBuffers is
+ * supplied with a constant from table 4.6 [...] then the error
+ * INVALID_OPERATION results."
+ */
destMask[output] &= supportedMask;
if (destMask[output] == 0) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glDrawBuffersARB(unsupported buffer)");
return;
}
+
+ /* ES 3.0 is even more restrictive. From the ES 3.0 spec, page 180:
+ * "If the GL is bound to a framebuffer object, the ith buffer listed
+ * in bufs must be COLOR_ATTACHMENTi or NONE. [...] INVALID_OPERATION."
+ */
+ if (_mesa_is_gles3(ctx) && _mesa_is_user_fbo(ctx->DrawBuffer) &&
+ buffers[output] != GL_NONE &&
+ buffers[output] != GL_COLOR_ATTACHMENT0 + output) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffers(buffer)");
+ return;
+ }
+
+ /* From the OpenGL 3.0 specification, page 258:
+ * "Except for NONE, a buffer may not appear more than once in the
+ * array pointed to by bufs. Specifying a buffer more then once will
+ * result in the error INVALID_OPERATION."
+ */
if (destMask[output] & usedBufferMask) {
- /* can't specify a dest buffer more than once! */
_mesa_error(ctx, GL_INVALID_OPERATION,
"glDrawBuffersARB(duplicated buffer)");
return;
@@ -391,7 +478,7 @@ _mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers,
const GLbitfield supportedMask = supported_buffer_bitmask(ctx, fb);
GLuint output;
for (output = 0; output < n; output++) {
- mask[output] = draw_buffer_enum_to_bitmask(buffers[output]);
+ mask[output] = draw_buffer_enum_to_bitmask(ctx, buffers[output]);
ASSERT(mask[output] != BAD_MASK);
mask[output] &= supportedMask;
}
diff --git a/mesalib/src/mesa/main/dd.h b/mesalib/src/mesa/main/dd.h
index 70c53240e..07787d41d 100644
--- a/mesalib/src/mesa/main/dd.h
+++ b/mesalib/src/mesa/main/dd.h
@@ -201,6 +201,22 @@ struct dd_function_table {
GLenum srcFormat, GLenum srcType );
/**
+ * Determine sample counts support for a particular format
+ *
+ * \param ctx GL context
+ * \param internalFormat GL format enum
+ * \param samples Buffer to hold the returned sample counts.
+ * Drivers \b must \b not return more than 16 counts.
+ *
+ * \returns
+ * The number of sample counts actually written to \c samples. If
+ * \c internaFormat is not renderable, zero is returned.
+ */
+ size_t (*QuerySamplesForFormat)(struct gl_context *ctx,
+ GLenum internalFormat,
+ int samples[16]);
+
+ /**
* Called by glTexImage[123]D() and glCopyTexImage[12]D()
* Allocate texture memory and copy the user's image to the buffer.
* The gl_texture_image fields, etc. will be fully initialized.
diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c
index c3c73fc26..23b494836 100644
--- a/mesalib/src/mesa/main/extensions.c
+++ b/mesalib/src/mesa/main/extensions.c
@@ -104,6 +104,7 @@ static const struct extension extension_table[] = {
{ "GL_ARB_half_float_pixel", o(ARB_half_float_pixel), GL, 2003 },
{ "GL_ARB_half_float_vertex", o(ARB_half_float_vertex), GL, 2008 },
{ "GL_ARB_instanced_arrays", o(ARB_instanced_arrays), GL, 2008 },
+ { "GL_ARB_internalformat_query", o(ARB_internalformat_query), GL, 2011 },
{ "GL_ARB_invalidate_subdata", o(dummy_true), GL, 2012 },
{ "GL_ARB_map_buffer_alignment", o(ARB_map_buffer_alignment), GL, 2011 },
{ "GL_ARB_map_buffer_range", o(ARB_map_buffer_range), GL, 2008 },
diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c
index 50ad84c56..9db5035d1 100644
--- a/mesalib/src/mesa/main/fbobject.c
+++ b/mesalib/src/mesa/main/fbobject.c
@@ -245,6 +245,25 @@ _mesa_get_fb0_attachment(struct gl_context *ctx, struct gl_framebuffer *fb,
{
assert(_mesa_is_winsys_fbo(fb));
+ if (_mesa_is_gles3(ctx)) {
+ assert(attachment == GL_BACK ||
+ attachment == GL_DEPTH ||
+ attachment == GL_STENCIL);
+ switch (attachment) {
+ case GL_BACK:
+ /* Since there is no stereo rendering in ES 3.0, only return the
+ * LEFT bits.
+ */
+ if (ctx->DrawBuffer->Visual.doubleBufferMode)
+ return &fb->Attachment[BUFFER_BACK_LEFT];
+ return &fb->Attachment[BUFFER_FRONT_LEFT];
+ case GL_DEPTH:
+ return &fb->Attachment[BUFFER_DEPTH];
+ case GL_STENCIL:
+ return &fb->Attachment[BUFFER_STENCIL];
+ }
+ }
+
switch (attachment) {
case GL_FRONT_LEFT:
return &fb->Attachment[BUFFER_FRONT_LEFT];
@@ -492,7 +511,8 @@ _mesa_is_legal_color_format(const struct gl_context *ctx, GLenum baseFormat)
case GL_LUMINANCE_ALPHA:
case GL_INTENSITY:
case GL_ALPHA:
- return ctx->Extensions.ARB_framebuffer_object;
+ return ctx->API == API_OPENGL_COMPAT &&
+ ctx->Extensions.ARB_framebuffer_object;
case GL_RED:
case GL_RG:
return ctx->Extensions.ARB_texture_rg;
@@ -1110,7 +1130,7 @@ _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat)
case GL_RGB16:
return _mesa_is_desktop_gl(ctx) ? GL_RGB : 0;
case GL_SRGB8_EXT:
- return _mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx) ? GL_RGB : 0;
+ return _mesa_is_desktop_gl(ctx) ? GL_RGB : 0;
case GL_RGBA4:
case GL_RGB5_A1:
case GL_RGBA8:
@@ -1197,25 +1217,21 @@ _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat)
ctx->Extensions.ARB_framebuffer_object ? GL_ALPHA : 0;
case GL_R16F:
case GL_R32F:
- return ctx->Version >= 30
- || (ctx->API == API_OPENGL_COMPAT &&
+ return (_mesa_is_desktop_gl(ctx) &&
ctx->Extensions.ARB_texture_rg &&
ctx->Extensions.ARB_texture_float) ? GL_RED : 0;
case GL_RG16F:
case GL_RG32F:
- return ctx->Version >= 30
- || (ctx->API == API_OPENGL_COMPAT &&
+ return (_mesa_is_desktop_gl(ctx) &&
ctx->Extensions.ARB_texture_rg &&
ctx->Extensions.ARB_texture_float) ? GL_RG : 0;
case GL_RGB16F:
case GL_RGB32F:
return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_float)
- || _mesa_is_gles3(ctx)
? GL_RGB : 0;
case GL_RGBA16F:
case GL_RGBA32F:
return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_float)
- || _mesa_is_gles3(ctx)
? GL_RGBA : 0;
case GL_ALPHA16F_ARB:
case GL_ALPHA32F_ARB:
@@ -1240,10 +1256,10 @@ _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat)
case GL_RGB9_E5:
return (_mesa_is_desktop_gl(ctx)
&& ctx->Extensions.EXT_texture_shared_exponent)
- || _mesa_is_gles3(ctx) ? GL_RGB : 0;
+ ? GL_RGB : 0;
case GL_R11F_G11F_B10F:
return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_packed_float)
- || _mesa_is_gles3(ctx) ? GL_RGB : 0;
+ ? GL_RGB : 0;
case GL_RGBA8UI_EXT:
case GL_RGBA16UI_EXT:
@@ -1378,13 +1394,28 @@ renderbuffer_storage(GLenum target, GLenum internalFormat,
GLsizei width, GLsizei height, GLsizei samples)
{
const char *func = samples == NO_SAMPLES ?
- "glRenderbufferStorage" : "RenderbufferStorageMultisample";
+ "glRenderbufferStorage" : "glRenderbufferStorageMultisample";
struct gl_renderbuffer *rb;
GLenum baseFormat;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
+ if (MESA_VERBOSE & VERBOSE_API) {
+ if (samples == NO_SAMPLES)
+ _mesa_debug(ctx, "%s(%s, %s, %d, %d)\n",
+ func,
+ _mesa_lookup_enum_by_nr(target),
+ _mesa_lookup_enum_by_nr(internalFormat),
+ width, height);
+ else
+ _mesa_debug(ctx, "%s(%s, %s, %d, %d, %d)\n",
+ func,
+ _mesa_lookup_enum_by_nr(target),
+ _mesa_lookup_enum_by_nr(internalFormat),
+ width, height, samples);
+ }
+
if (target != GL_RENDERBUFFER_EXT) {
_mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", func);
return;
@@ -1904,6 +1935,10 @@ _mesa_CheckFramebufferStatus(GLenum target)
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx, "glCheckFramebufferStatus(%s)\n",
+ _mesa_lookup_enum_by_nr(target));
+
buffer = get_framebuffer_target(ctx, target);
if (!buffer) {
_mesa_error(ctx, GL_INVALID_ENUM, "glCheckFramebufferStatus(target)");
@@ -2347,11 +2382,19 @@ _mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
* OES_framebuffer_object spec refers to the EXT_framebuffer_object
* spec.
*/
- if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_framebuffer_object) {
+ if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_framebuffer_object)
+ && !_mesa_is_gles3(ctx)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glGetFramebufferAttachmentParameteriv(bound FBO = 0)");
return;
}
+
+ if (_mesa_is_gles3(ctx) && attachment != GL_BACK &&
+ attachment != GL_DEPTH && attachment != GL_STENCIL) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetFramebufferAttachmentParameteriv(attachment)");
+ return;
+ }
/* the default / window-system FBO */
att = _mesa_get_fb0_attachment(ctx, buffer, attachment);
}
@@ -2739,7 +2782,6 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GL_DEPTH_BUFFER_BIT |
GL_STENCIL_BUFFER_BIT);
const struct gl_framebuffer *readFb, *drawFb;
- const struct gl_renderbuffer *colorReadRb, *colorDrawRb;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
@@ -2794,8 +2836,10 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
/* get color read/draw renderbuffers */
if (mask & GL_COLOR_BUFFER_BIT) {
- colorReadRb = readFb->_ColorReadBuffer;
- colorDrawRb = drawFb->_ColorDrawBuffers[0];
+ const GLuint numColorDrawBuffers = ctx->DrawBuffer->_NumColorDrawBuffers;
+ const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer;
+ const struct gl_renderbuffer *colorDrawRb = NULL;
+ GLuint i;
/* From the EXT_framebuffer_object spec:
*
@@ -2803,20 +2847,45 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
* the read and draw framebuffers, the corresponding bit is silently
* ignored."
*/
- if ((colorReadRb == NULL) || (colorDrawRb == NULL)) {
- colorReadRb = colorDrawRb = NULL;
- mask &= ~GL_COLOR_BUFFER_BIT;
+ if (!colorReadRb || numColorDrawBuffers == 0) {
+ mask &= ~GL_COLOR_BUFFER_BIT;
}
- else if (!compatible_color_datatypes(colorReadRb->Format,
- colorDrawRb->Format)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebufferEXT(color buffer datatypes mismatch)");
- return;
+ else {
+ for (i = 0; i < numColorDrawBuffers; i++) {
+ colorDrawRb = ctx->DrawBuffer->_ColorDrawBuffers[i];
+ if (!colorDrawRb)
+ continue;
+
+ if (!compatible_color_datatypes(colorReadRb->Format,
+ colorDrawRb->Format)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBlitFramebufferEXT(color buffer datatypes mismatch)");
+ return;
+ }
+ /* extra checks for multisample copies... */
+ if (readFb->Visual.samples > 0 || drawFb->Visual.samples > 0) {
+ /* color formats must match */
+ if (!compatible_resolve_formats(colorReadRb, colorDrawRb)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBlitFramebufferEXT(bad src/dst multisample pixel formats)");
+ return;
+ }
+ }
+ }
+ if (filter == GL_LINEAR) {
+ /* 3.1 spec, page 199:
+ * "Calling BlitFramebuffer will result in an INVALID_OPERATION error
+ * if filter is LINEAR and read buffer contains integer data."
+ */
+ GLenum type = _mesa_get_format_datatype(colorReadRb->Format);
+ if (type == GL_INT || type == GL_UNSIGNED_INT) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBlitFramebufferEXT(integer color type)");
+ return;
+ }
+ }
}
}
- else {
- colorReadRb = colorDrawRb = NULL;
- }
if (mask & GL_STENCIL_BUFFER_BIT) {
struct gl_renderbuffer *readRb =
@@ -2833,14 +2902,35 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
if ((readRb == NULL) || (drawRb == NULL)) {
mask &= ~GL_STENCIL_BUFFER_BIT;
}
- else if (_mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS) !=
- _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS)) {
- /* There is no need to check the stencil datatype here, because
- * there is only one: GL_UNSIGNED_INT.
- */
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebufferEXT(stencil buffer size mismatch)");
- return;
+ else {
+ int read_z_bits, draw_z_bits;
+
+ if (_mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS) !=
+ _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS)) {
+ /* There is no need to check the stencil datatype here, because
+ * there is only one: GL_UNSIGNED_INT.
+ */
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBlitFramebuffer(stencil attachment format mismatch)");
+ return;
+ }
+
+ read_z_bits = _mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS);
+ draw_z_bits = _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS);
+
+ /* If both buffers also have depth data, the depth formats must match
+ * as well. If one doesn't have depth, it's not blitted, so we should
+ * ignore the depth format check.
+ */
+ if (read_z_bits > 0 && draw_z_bits > 0 &&
+ (read_z_bits != draw_z_bits ||
+ _mesa_get_format_datatype(readRb->Format) !=
+ _mesa_get_format_datatype(drawRb->Format))) {
+
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebuffer"
+ "(stencil attachment depth format mismatch)");
+ return;
+ }
}
}
@@ -2859,13 +2949,30 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
if ((readRb == NULL) || (drawRb == NULL)) {
mask &= ~GL_DEPTH_BUFFER_BIT;
}
- else if ((_mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS) !=
- _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS)) ||
- (_mesa_get_format_datatype(readRb->Format) !=
- _mesa_get_format_datatype(drawRb->Format))) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebufferEXT(depth buffer format mismatch)");
- return;
+ else {
+ int read_s_bit, draw_s_bit;
+
+ if ((_mesa_get_format_bits(readRb->Format, GL_DEPTH_BITS) !=
+ _mesa_get_format_bits(drawRb->Format, GL_DEPTH_BITS)) ||
+ (_mesa_get_format_datatype(readRb->Format) !=
+ _mesa_get_format_datatype(drawRb->Format))) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBlitFramebuffer(depth attachment format mismatch)");
+ return;
+ }
+
+ read_s_bit = _mesa_get_format_bits(readRb->Format, GL_STENCIL_BITS);
+ draw_s_bit = _mesa_get_format_bits(drawRb->Format, GL_STENCIL_BITS);
+
+ /* If both buffers also have stencil data, the stencil formats must
+ * match as well. If one doesn't have stencil, it's not blitted, so
+ * we should ignore the stencil format check.
+ */
+ if (read_s_bit > 0 && draw_s_bit > 0 && read_s_bit != draw_s_bit) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glBlitFramebuffer"
+ "(depth attachment stencil bits mismatch)");
+ return;
+ }
}
}
@@ -2886,28 +2993,6 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
"glBlitFramebufferEXT(bad src/dst multisample region sizes)");
return;
}
-
- /* color formats must match */
- if (colorReadRb &&
- colorDrawRb &&
- !compatible_resolve_formats(colorReadRb, colorDrawRb)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebufferEXT(bad src/dst multisample pixel formats)");
- return;
- }
- }
-
- if (filter == GL_LINEAR && (mask & GL_COLOR_BUFFER_BIT)) {
- /* 3.1 spec, page 199:
- * "Calling BlitFramebuffer will result in an INVALID_OPERATION error
- * if filter is LINEAR and read buffer contains integer data."
- */
- GLenum type = _mesa_get_format_datatype(colorReadRb->Format);
- if (type == GL_INT || type == GL_UNSIGNED_INT) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBlitFramebufferEXT(integer color type)");
- return;
- }
}
if (!ctx->Extensions.EXT_framebuffer_blit) {
@@ -2917,6 +3002,10 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
/* Debug code */
if (DEBUG_BLIT) {
+ const struct gl_renderbuffer *colorReadRb = readFb->_ColorReadBuffer;
+ const struct gl_renderbuffer *colorDrawRb = NULL;
+ GLuint i = 0;
+
printf("glBlitFramebuffer(%d, %d, %d, %d, %d, %d, %d, %d,"
" 0x%x, 0x%x)\n",
srcX0, srcY0, srcX1, srcY1,
@@ -2938,18 +3027,25 @@ _mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
}
printf("\n");
- att = find_attachment(drawFb, colorDrawRb);
- printf(" Dst FBO %u RB %u (%dx%d) ",
- drawFb->Name, colorDrawRb->Name,
- colorDrawRb->Width, colorDrawRb->Height);
- if (att && att->Texture) {
- printf("Tex %u tgt 0x%x level %u face %u",
- att->Texture->Name,
- att->Texture->Target,
- att->TextureLevel,
- att->CubeMapFace);
+ /* Print all active color render buffers */
+ for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
+ colorDrawRb = ctx->DrawBuffer->_ColorDrawBuffers[i];
+ if (!colorDrawRb)
+ continue;
+
+ att = find_attachment(drawFb, colorDrawRb);
+ printf(" Dst FBO %u RB %u (%dx%d) ",
+ drawFb->Name, colorDrawRb->Name,
+ colorDrawRb->Width, colorDrawRb->Height);
+ if (att && att->Texture) {
+ printf("Tex %u tgt 0x%x level %u face %u",
+ att->Texture->Name,
+ att->Texture->Target,
+ att->TextureLevel,
+ att->CubeMapFace);
+ }
+ printf("\n");
}
- printf("\n");
}
}
diff --git a/mesalib/src/mesa/main/formatquery.c b/mesalib/src/mesa/main/formatquery.c
new file mode 100644
index 000000000..f08ab66f0
--- /dev/null
+++ b/mesalib/src/mesa/main/formatquery.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ */
+
+#include "mtypes.h"
+#include "glformats.h"
+#include "macros.h"
+#include "mfeatures.h"
+#include "enums.h"
+#include "fbobject.h"
+#include "formatquery.h"
+
+void GLAPIENTRY
+_mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname,
+ GLsizei bufSize, GLint *params)
+{
+ GLint buffer[16];
+ GLsizei count = 0;
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!ctx->Extensions.ARB_internalformat_query) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInternalformativ");
+ return;
+ }
+
+ assert(ctx->Driver.QuerySamplesForFormat != NULL);
+
+ /* The ARB_internalformat_query spec says:
+ *
+ * "If the <target> parameter to GetInternalformativ is not one of
+ * TEXTURE_2D_MULTISAMPLE, TEXTURE_2D_MULTISAMPLE_ARRAY or RENDERBUFFER
+ * then an INVALID_ENUM error is generated."
+ */
+ switch (target) {
+ case GL_RENDERBUFFER:
+ break;
+
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ /* Mesa does not currently support GL_ARB_texture_multisample, so these
+ * enums are not valid on this implementation either.
+ */
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetInternalformativ(target=%s)",
+ _mesa_lookup_enum_by_nr(target));
+ return;
+ }
+
+ /* The ARB_internalformat_query spec says:
+ *
+ * "If the <internalformat> parameter to GetInternalformativ is not
+ * color-, depth- or stencil-renderable, then an INVALID_ENUM error is
+ * generated."
+ */
+ if (_mesa_base_fbo_format(ctx, internalformat) == 0) {
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetInternalformativ(internalformat=%s)",
+ _mesa_lookup_enum_by_nr(internalformat));
+ return;
+ }
+
+ /* The ARB_internalformat_query spec says:
+ *
+ * "If the <bufSize> parameter to GetInternalformativ is negative, then
+ * an INVALID_VALUE error is generated."
+ */
+ if (bufSize < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glGetInternalformativ(target=%s)",
+ _mesa_lookup_enum_by_nr(target));
+ return;
+ }
+
+ switch (pname) {
+ case GL_SAMPLES:
+ count = ctx->Driver.QuerySamplesForFormat(ctx, internalformat, buffer);
+ break;
+ case GL_NUM_SAMPLE_COUNTS: {
+ /* The driver can return 0, and we should pass that along to the
+ * application. The ARB decided that ARB_internalformat_query should
+ * behave as ARB_internalformat_query2 in this situation.
+ *
+ * The ARB_internalformat_query2 spec says:
+ *
+ * "- NUM_SAMPLE_COUNTS: The number of sample counts that would be
+ * returned by querying SAMPLES is returned in <params>.
+ * * If <internalformat> is not color-renderable,
+ * depth-renderable, or stencil-renderable (as defined in
+ * section 4.4.4), or if <target> does not support multiple
+ * samples (ie other than TEXTURE_2D_MULTISAMPLE,
+ * TEXTURE_2D_MULTISAMPLE_ARRAY, or RENDERBUFFER), 0 is
+ * returned."
+ */
+ const size_t num_samples =
+ ctx->Driver.QuerySamplesForFormat(ctx, internalformat, buffer);
+
+ /* QuerySamplesForFormat writes some stuff to buffer, so we have to
+ * separately over-write it with the requested value.
+ */
+ buffer[0] = (GLint) num_samples;
+ count = 1;
+ break;
+ }
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetInternalformativ(pname=%s)",
+ _mesa_lookup_enum_by_nr(pname));
+ return;
+ }
+
+ if (bufSize != 0 && params == NULL) {
+ /* Emit a warning to aid application debugging, but go ahead and do the
+ * memcpy (and probably crash) anyway.
+ */
+ _mesa_warning(ctx,
+ "glGetInternalformativ(bufSize = %d, but params = NULL)",
+ bufSize);
+ }
+
+ /* Copy the data from the temporary buffer to the buffer supplied by the
+ * application. Clamp the size of the copy to the size supplied by the
+ * application.
+ */
+ memcpy(params, buffer, MIN2(count, bufSize) * sizeof(GLint));
+
+ return;
+}
diff --git a/mesalib/src/mesa/main/formatquery.h b/mesalib/src/mesa/main/formatquery.h
new file mode 100644
index 000000000..585c3eb64
--- /dev/null
+++ b/mesalib/src/mesa/main/formatquery.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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.
+ */
+
+#pragma once
+#ifndef FORMATQUERY_H
+#define FORMATQUERY_H
+
+#include "compiler.h"
+#include "glheader.h"
+
+extern void GLAPIENTRY
+_mesa_GetInternalformativ(GLenum target, GLenum internalformat,
+ GLenum pname, GLsizei bufSize, GLint *params);
+
+#endif /* FORMATQUERY_H */
diff --git a/mesalib/src/mesa/main/framebuffer.c b/mesalib/src/mesa/main/framebuffer.c
index 13887f8f5..8cbfbd6bc 100644
--- a/mesalib/src/mesa/main/framebuffer.c
+++ b/mesalib/src/mesa/main/framebuffer.c
@@ -42,6 +42,7 @@
#include "framebuffer.h"
#include "renderbuffer.h"
#include "texobj.h"
+#include "glformats.h"
@@ -899,6 +900,26 @@ _mesa_get_color_read_type(struct gl_context *ctx)
/**
+ * Returns the read renderbuffer for the specified format.
+ */
+struct gl_renderbuffer *
+_mesa_get_read_renderbuffer_for_format(struct gl_context *ctx,
+ GLenum format)
+{
+ struct gl_framebuffer *rfb = ctx->ReadBuffer;
+
+ if (_mesa_is_color_format(format)) {
+ return rfb->Attachment[rfb->_ColorReadBufferIndex].Renderbuffer;
+ } else if (_mesa_is_depth_format(format) ||
+ _mesa_is_depthstencil_format(format)) {
+ return rfb->Attachment[BUFFER_DEPTH].Renderbuffer;
+ } else {
+ return rfb->Attachment[BUFFER_STENCIL].Renderbuffer;
+ }
+}
+
+
+/**
* Print framebuffer info to stderr, for debugging.
*/
void
diff --git a/mesalib/src/mesa/main/framebuffer.h b/mesalib/src/mesa/main/framebuffer.h
index ad53d8cbe..06db04925 100644
--- a/mesalib/src/mesa/main/framebuffer.h
+++ b/mesalib/src/mesa/main/framebuffer.h
@@ -30,6 +30,7 @@
struct gl_config;
struct gl_context;
+struct gl_renderbuffer;
extern struct gl_framebuffer *
_mesa_create_framebuffer(const struct gl_config *visual);
@@ -96,6 +97,10 @@ _mesa_get_color_read_type(struct gl_context *ctx);
extern GLenum
_mesa_get_color_read_format(struct gl_context *ctx);
+extern struct gl_renderbuffer *
+_mesa_get_read_renderbuffer_for_format(struct gl_context *ctx,
+ GLenum format);
+
extern void
_mesa_print_framebuffer(const struct gl_framebuffer *fb);
diff --git a/mesalib/src/mesa/main/glformats.c b/mesalib/src/mesa/main/glformats.c
index ff56ffad0..7969f77a4 100644
--- a/mesalib/src/mesa/main/glformats.c
+++ b/mesalib/src/mesa/main/glformats.c
@@ -1289,6 +1289,10 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx,
ctx->Extensions.ARB_texture_rgb10_a2ui) {
break; /* OK */
}
+ if (type == GL_UNSIGNED_INT_2_10_10_10_REV && format == GL_RGB &&
+ ctx->API == API_OPENGLES2) {
+ break; /* OK by GL_EXT_texture_type_2_10_10_10_REV */
+ }
return GL_INVALID_OPERATION;
case GL_UNSIGNED_INT_24_8:
@@ -1402,6 +1406,10 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx,
case GL_UNSIGNED_SHORT_5_6_5:
case GL_UNSIGNED_SHORT_5_6_5_REV:
return GL_NO_ERROR;
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ /* OK by GL_EXT_texture_type_2_10_10_10_REV */
+ return (ctx->API == API_OPENGLES2)
+ ? GL_NO_ERROR : GL_INVALID_ENUM;
case GL_HALF_FLOAT:
return ctx->Extensions.ARB_half_float_pixel
? GL_NO_ERROR : GL_INVALID_ENUM;
@@ -1478,8 +1486,18 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx,
else if (ctx->Extensions.ARB_depth_buffer_float &&
type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV)
return GL_NO_ERROR;
- else
+ switch (type) {
+ case GL_BYTE:
+ case GL_UNSIGNED_BYTE:
+ case GL_SHORT:
+ case GL_UNSIGNED_SHORT:
+ case GL_INT:
+ case GL_UNSIGNED_INT:
+ case GL_FLOAT:
+ return GL_INVALID_OPERATION;
+ default:
return GL_INVALID_ENUM;
+ }
case GL_DUDV_ATI:
case GL_DU8DV8_ATI:
@@ -1670,3 +1688,442 @@ _mesa_es_error_check_format_and_type(GLenum format, GLenum type,
return type_valid ? GL_NO_ERROR : GL_INVALID_OPERATION;
}
+
+
+/**
+ * Do error checking of format/type combinations for OpenGL ES 3
+ * glTex[Sub]Image.
+ * \return error code, or GL_NO_ERROR.
+ */
+GLenum
+_mesa_es3_error_check_format_and_type(GLenum format, GLenum type,
+ GLenum internalFormat,
+ unsigned dimensions)
+{
+ GLboolean type_valid = GL_TRUE;
+
+ switch (format) {
+ case GL_RGBA:
+ switch (type) {
+ case GL_UNSIGNED_BYTE:
+ switch (internalFormat) {
+ case GL_RGBA:
+ case GL_RGBA8:
+ case GL_RGB5_A1:
+ case GL_RGBA4:
+ case GL_SRGB8_ALPHA8_EXT:
+ break;
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+
+ case GL_BYTE:
+ if (internalFormat != GL_RGBA8_SNORM)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ switch (internalFormat) {
+ case GL_RGBA:
+ case GL_RGBA4:
+ break;
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ switch (internalFormat) {
+ case GL_RGBA:
+ case GL_RGB5_A1:
+ break;
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ switch (internalFormat) {
+ case GL_RGBA: /* GL_EXT_texture_type_2_10_10_10_REV */
+ case GL_RGB10_A2:
+ case GL_RGB5_A1:
+ break;
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+
+ case GL_HALF_FLOAT:
+ if (internalFormat != GL_RGBA16F)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_FLOAT:
+ switch (internalFormat) {
+ case GL_RGBA16F:
+ case GL_RGBA32F:
+ break;
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+
+ case GL_RGBA_INTEGER:
+ switch (type) {
+ case GL_UNSIGNED_BYTE:
+ if (internalFormat != GL_RGBA8UI)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_BYTE:
+ if (internalFormat != GL_RGBA8I)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_UNSIGNED_SHORT:
+ if (internalFormat != GL_RGBA16UI)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_SHORT:
+ if (internalFormat != GL_RGBA16I)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_UNSIGNED_INT:
+ if (internalFormat != GL_RGBA32UI)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_INT:
+ if (internalFormat != GL_RGBA32I)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ if (internalFormat != GL_RGB10_A2UI)
+ return GL_INVALID_OPERATION;
+ break;
+
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+
+ case GL_RGB:
+ switch (type) {
+ case GL_UNSIGNED_BYTE:
+ switch (internalFormat) {
+ case GL_RGB:
+ case GL_RGB8:
+ case GL_RGB565:
+ case GL_SRGB8:
+ break;
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+
+ case GL_BYTE:
+ if (internalFormat != GL_RGB8_SNORM)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_UNSIGNED_SHORT_5_6_5:
+ switch (internalFormat) {
+ case GL_RGB:
+ case GL_RGB565:
+ break;
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+
+ case GL_UNSIGNED_INT_10F_11F_11F_REV:
+ if (internalFormat != GL_R11F_G11F_B10F)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_UNSIGNED_INT_5_9_9_9_REV:
+ if (internalFormat != GL_RGB9_E5)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_HALF_FLOAT:
+ switch (internalFormat) {
+ case GL_RGB16F:
+ case GL_R11F_G11F_B10F:
+ case GL_RGB9_E5:
+ break;
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+
+ case GL_FLOAT:
+ switch (internalFormat) {
+ case GL_RGB16F:
+ case GL_RGB32F:
+ case GL_R11F_G11F_B10F:
+ case GL_RGB9_E5:
+ break;
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ switch (internalFormat) {
+ case GL_RGB: /* GL_EXT_texture_type_2_10_10_10_REV */
+ break;
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+
+ case GL_RGB_INTEGER:
+ switch (type) {
+ case GL_UNSIGNED_BYTE:
+ if (internalFormat != GL_RGB8UI)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_BYTE:
+ if (internalFormat != GL_RGB8I)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_UNSIGNED_SHORT:
+ if (internalFormat != GL_RGB16UI)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_SHORT:
+ if (internalFormat != GL_RGB16I)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_UNSIGNED_INT:
+ if (internalFormat != GL_RGB32UI)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_INT:
+ if (internalFormat != GL_RGB32I)
+ return GL_INVALID_OPERATION;
+ break;
+
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+
+ case GL_RG:
+ switch (type) {
+ case GL_UNSIGNED_BYTE:
+ if (internalFormat != GL_RG8)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_BYTE:
+ if (internalFormat != GL_RG8_SNORM)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_HALF_FLOAT:
+ if (internalFormat != GL_RG16F)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_FLOAT:
+ switch (internalFormat) {
+ case GL_RG16F:
+ case GL_RG32F:
+ break;
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+
+ case GL_RG_INTEGER:
+ switch (type) {
+ case GL_UNSIGNED_BYTE:
+ if (internalFormat != GL_RG8UI)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_BYTE:
+ if (internalFormat != GL_RG8I)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_UNSIGNED_SHORT:
+ if (internalFormat != GL_RG16UI)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_SHORT:
+ if (internalFormat != GL_RG16I)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_UNSIGNED_INT:
+ if (internalFormat != GL_RG32UI)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_INT:
+ if (internalFormat != GL_RG32I)
+ return GL_INVALID_OPERATION;
+ break;
+
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+
+ case GL_RED:
+ switch (type) {
+ case GL_UNSIGNED_BYTE:
+ if (internalFormat != GL_R8)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_BYTE:
+ if (internalFormat != GL_R8_SNORM)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_HALF_FLOAT:
+ if (internalFormat != GL_R16F)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_FLOAT:
+ switch (internalFormat) {
+ case GL_R16F:
+ case GL_R32F:
+ break;
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+
+ case GL_RED_INTEGER:
+ switch (type) {
+ case GL_UNSIGNED_BYTE:
+ if (internalFormat != GL_R8UI)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_BYTE:
+ if (internalFormat != GL_R8I)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_UNSIGNED_SHORT:
+ if (internalFormat != GL_R16UI)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_SHORT:
+ if (internalFormat != GL_R16I)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_UNSIGNED_INT:
+ if (internalFormat != GL_R32UI)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_INT:
+ if (internalFormat != GL_R32I)
+ return GL_INVALID_OPERATION;
+ break;
+
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+
+ case GL_DEPTH_COMPONENT:
+ if (dimensions != 2) {
+ return GL_INVALID_OPERATION;
+ }
+ switch (type) {
+ case GL_UNSIGNED_SHORT:
+ if (internalFormat != GL_DEPTH_COMPONENT16)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_UNSIGNED_INT:
+ switch (internalFormat) {
+ case GL_DEPTH_COMPONENT16:
+ case GL_DEPTH_COMPONENT24:
+ break;
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+
+ case GL_FLOAT:
+ if (internalFormat != GL_DEPTH_COMPONENT32F)
+ return GL_INVALID_OPERATION;
+ break;
+
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+
+ case GL_DEPTH_STENCIL:
+ if (dimensions != 2) {
+ return GL_INVALID_OPERATION;
+ }
+ switch (type) {
+ case GL_UNSIGNED_INT_24_8:
+ if (internalFormat != GL_DEPTH24_STENCIL8)
+ return GL_INVALID_OPERATION;
+ break;
+
+ case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
+ if (internalFormat != GL_DEPTH32F_STENCIL8)
+ return GL_INVALID_OPERATION;
+ break;
+
+ default:
+ return GL_INVALID_OPERATION;
+ }
+ break;
+
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ if (type != GL_UNSIGNED_BYTE || format != internalFormat)
+ return GL_INVALID_OPERATION;
+ break;
+ }
+
+ return type_valid ? GL_NO_ERROR : GL_INVALID_OPERATION;
+}
diff --git a/mesalib/src/mesa/main/glformats.h b/mesalib/src/mesa/main/glformats.h
index fe604ddc9..4cbc82f5e 100644
--- a/mesalib/src/mesa/main/glformats.h
+++ b/mesalib/src/mesa/main/glformats.h
@@ -120,6 +120,11 @@ extern GLenum
_mesa_es_error_check_format_and_type(GLenum format, GLenum type,
unsigned dimensions);
+extern GLenum
+_mesa_es3_error_check_format_and_type(GLenum format, GLenum type,
+ GLenum internalFormat,
+ unsigned dimensions);
+
#ifdef __cplusplus
}
diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h
index 8904b13d9..d0c0e24ac 100644
--- a/mesalib/src/mesa/main/mtypes.h
+++ b/mesalib/src/mesa/main/mtypes.h
@@ -2523,6 +2523,7 @@ struct gl_query_object
GLuint64EXT Result; /**< the counter */
GLboolean Active; /**< inside Begin/EndQuery */
GLboolean Ready; /**< result is ready? */
+ GLboolean EverBound;/**< has query object ever been bound */
};
@@ -3030,6 +3031,7 @@ struct gl_extensions
GLboolean ARB_half_float_pixel;
GLboolean ARB_half_float_vertex;
GLboolean ARB_instanced_arrays;
+ GLboolean ARB_internalformat_query;
GLboolean ARB_map_buffer_alignment;
GLboolean ARB_map_buffer_range;
GLboolean ARB_occlusion_query;
diff --git a/mesalib/src/mesa/main/pack.c b/mesalib/src/mesa/main/pack.c
index 4f0caa763..d6a97b35a 100644
--- a/mesalib/src/mesa/main/pack.c
+++ b/mesalib/src/mesa/main/pack.c
@@ -3641,7 +3641,11 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
rgba[i][rDst] = ((p ) & 0x3ff) * rs;
rgba[i][gDst] = ((p >> 10) & 0x3ff) * gs;
rgba[i][bDst] = ((p >> 20) & 0x3ff) * bs;
- rgba[i][aDst] = ((p >> 30) ) * as;
+ if (aSrc < 0) {
+ rgba[i][aDst] = 1.0F;
+ } else {
+ rgba[i][aDst] = (p >> 30) * as;
+ }
}
}
else {
@@ -3652,7 +3656,11 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
rgba[i][rDst] = ((p ) & 0x3ff) * rs;
rgba[i][gDst] = ((p >> 10) & 0x3ff) * gs;
rgba[i][bDst] = ((p >> 20) & 0x3ff) * bs;
- rgba[i][aDst] = ((p >> 30) ) * as;
+ if (aSrc < 0) {
+ rgba[i][aDst] = 1.0F;
+ } else {
+ rgba[i][aDst] = (p >> 30) * as;
+ }
}
}
break;
diff --git a/mesalib/src/mesa/main/queryobj.c b/mesalib/src/mesa/main/queryobj.c
index 054dfbad7..bd7d0d297 100644
--- a/mesalib/src/mesa/main/queryobj.c
+++ b/mesalib/src/mesa/main/queryobj.c
@@ -50,7 +50,20 @@ _mesa_new_query_object(struct gl_context *ctx, GLuint id)
q->Id = id;
q->Result = 0;
q->Active = GL_FALSE;
- q->Ready = GL_TRUE; /* correct, see spec */
+
+ /* This is to satisfy the language of the specification: "In the initial
+ * state of a query object, the result is available" (OpenGL 3.1 §
+ * 2.13).
+ */
+ q->Ready = GL_TRUE;
+
+ /* OpenGL 3.1 § 2.13 says about GenQueries, "These names are marked as
+ * used, but no object is associated with them until the first time they
+ * are used by BeginQuery." Since our implementation actually does
+ * allocate an object at this point, use a flag to indicate that this
+ * object has not yet been bound so should not be considered a query.
+ */
+ q->EverBound = GL_FALSE;
}
return q;
}
@@ -252,16 +265,22 @@ _mesa_DeleteQueries(GLsizei n, const GLuint *ids)
GLboolean GLAPIENTRY
_mesa_IsQuery(GLuint id)
{
+ struct gl_query_object *q;
+
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(ctx, "glIsQuery(%u)\n", id);
- if (id && _mesa_lookup_query_object(ctx, id))
- return GL_TRUE;
- else
+ if (id == 0)
return GL_FALSE;
+
+ q = _mesa_lookup_query_object(ctx, id);
+ if (q == NULL)
+ return GL_FALSE;
+
+ return q->EverBound;
}
static GLboolean
@@ -354,6 +373,7 @@ _mesa_BeginQueryIndexed(GLenum target, GLuint index, GLuint id)
q->Active = GL_TRUE;
q->Result = 0;
q->Ready = GL_FALSE;
+ q->EverBound = GL_TRUE;
/* XXX should probably refcount query objects */
*bindpt = q;
diff --git a/mesalib/src/mesa/main/readpix.c b/mesalib/src/mesa/main/readpix.c
index d6d105bc4..5b80e9a8b 100644
--- a/mesalib/src/mesa/main/readpix.c
+++ b/mesalib/src/mesa/main/readpix.c
@@ -679,7 +679,7 @@ _mesa_ReadnPixelsARB( GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, GLsizei bufSize,
GLvoid *pixels )
{
- GLenum err;
+ GLenum err = GL_NO_ERROR;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
@@ -707,17 +707,21 @@ _mesa_ReadnPixelsARB( GLint x, GLint y, GLsizei width, GLsizei height,
* preferred combination. This code doesn't know what that preferred
* combination is, and Mesa can handle anything valid. Just work instead.
*/
- if (_mesa_is_gles(ctx) && ctx->Version < 30) {
- err = _mesa_es_error_check_format_and_type(format, type, 2);
- if (err == GL_NO_ERROR) {
- if (type == GL_FLOAT || type == GL_HALF_FLOAT_OES) {
- err = GL_INVALID_OPERATION;
- } else if (format == GL_DEPTH_COMPONENT
- || format == GL_DEPTH_STENCIL) {
- err = GL_INVALID_ENUM;
+ if (_mesa_is_gles(ctx)) {
+ if (ctx->Version < 30) {
+ err = _mesa_es_error_check_format_and_type(format, type, 2);
+ if (err == GL_NO_ERROR) {
+ if (type == GL_FLOAT || type == GL_HALF_FLOAT_OES) {
+ err = GL_INVALID_OPERATION;
+ }
}
}
+ if (err == GL_NO_ERROR && (format == GL_DEPTH_COMPONENT
+ || format == GL_DEPTH_STENCIL)) {
+ err = GL_INVALID_ENUM;
+ }
+
if (err != GL_NO_ERROR) {
_mesa_error(ctx, err, "glReadPixels(invalid format %s and/or type %s)",
_mesa_lookup_enum_by_nr(format),
diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c
index 7d3abb7e0..5e451e235 100644
--- a/mesalib/src/mesa/main/teximage.c
+++ b/mesalib/src/mesa/main/teximage.c
@@ -1893,23 +1893,30 @@ texture_error_check( struct gl_context *ctx,
* requires GL_OES_texture_float) are filtered elsewhere.
*/
- if (_mesa_is_gles(ctx) && !_mesa_is_gles3(ctx)) {
- if (format != internalFormat) {
+ if (_mesa_is_gles(ctx)) {
+ if (_mesa_is_gles3(ctx)) {
+ err = _mesa_es3_error_check_format_and_type(format, type,
+ internalFormat,
+ dimensions);
+ } else {
+ if (format != internalFormat) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glTexImage%dD(format = %s, internalFormat = %s)",
dimensions,
_mesa_lookup_enum_by_nr(format),
_mesa_lookup_enum_by_nr(internalFormat));
return GL_TRUE;
- }
+ }
- err = _mesa_es_error_check_format_and_type(format, type, dimensions);
+ err = _mesa_es_error_check_format_and_type(format, type, dimensions);
+ }
if (err != GL_NO_ERROR) {
_mesa_error(ctx, err,
- "glTexImage%dD(format = %s, type = %s)",
+ "glTexImage%dD(format = %s, type = %s, internalFormat = %s)",
dimensions,
_mesa_lookup_enum_by_nr(format),
- _mesa_lookup_enum_by_nr(type));
+ _mesa_lookup_enum_by_nr(type),
+ _mesa_lookup_enum_by_nr(internalFormat));
return GL_TRUE;
}
}
@@ -2340,6 +2347,8 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
GLint width, GLint height, GLint border )
{
GLint baseFormat;
+ struct gl_renderbuffer *rb;
+ GLenum rb_internal_format;
/* check target */
if (!legal_texsubimage_target(ctx, dimensions, target)) {
@@ -2384,6 +2393,13 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
return GL_TRUE;
}
+ rb = _mesa_get_read_renderbuffer_for_format(ctx, internalFormat);
+ if (rb == NULL) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCopyTexImage%dD(read buffer)", dimensions);
+ return GL_TRUE;
+ }
+
/* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
* internalFormat.
*/
@@ -2409,6 +2425,8 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
return GL_TRUE;
}
+ rb_internal_format = rb->InternalFormat;
+
if (!_mesa_source_buffer_exists(ctx, baseFormat)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glCopyTexImage%dD(missing readbuffer)", dimensions);
@@ -2423,13 +2441,20 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
* integer format and the read color buffer is an integer format."
*/
if (_mesa_is_color_format(internalFormat)) {
- struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
-
- if (_mesa_is_enum_format_integer(rb->InternalFormat) !=
- _mesa_is_enum_format_integer(internalFormat)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glCopyTexImage%dD(integer vs non-integer)", dimensions);
- return GL_TRUE;
+ bool is_int = _mesa_is_enum_format_integer(internalFormat);
+ bool is_rbint = _mesa_is_enum_format_integer(rb_internal_format);
+ if (is_int || is_rbint) {
+ if (is_int != is_rbint) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCopyTexImage%dD(integer vs non-integer)", dimensions);
+ return GL_TRUE;
+ } else if (_mesa_is_gles(ctx) &&
+ _mesa_is_enum_format_unsigned_int(internalFormat) !=
+ _mesa_is_enum_format_unsigned_int(rb_internal_format)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glCopyTexImage%dD(signed vs unsigned integer)", dimensions);
+ return GL_TRUE;
+ }
}
}
@@ -3340,9 +3365,7 @@ copyteximage(struct gl_context *ctx, GLuint dims,
border, internalFormat, texFormat);
/* Allocate texture memory (no pixel data yet) */
- ctx->Driver.TexImage(ctx, dims, texImage,
- GL_NONE, GL_NONE,
- NULL, &ctx->Unpack);
+ ctx->Driver.AllocTextureImageBuffer(ctx, texImage);
if (_mesa_clip_copytexsubimage(ctx, &dstX, &dstY, &srcX, &srcY,
&width, &height)) {
diff --git a/mesalib/src/mesa/main/texparam.c b/mesalib/src/mesa/main/texparam.c
index ca5a21f78..4d32fd6dd 100644
--- a/mesalib/src/mesa/main/texparam.c
+++ b/mesalib/src/mesa/main/texparam.c
@@ -662,21 +662,16 @@ _mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param)
case GL_DEPTH_TEXTURE_MODE_ARB:
case GL_TEXTURE_SRGB_DECODE_EXT:
case GL_TEXTURE_CUBE_MAP_SEAMLESS:
- {
- /* convert float param to int */
- GLint p[4];
- p[0] = (GLint) param;
- p[1] = p[2] = p[3] = 0;
- need_update = set_tex_parameteri(ctx, texObj, pname, p);
- }
- break;
case GL_TEXTURE_SWIZZLE_R_EXT:
case GL_TEXTURE_SWIZZLE_G_EXT:
case GL_TEXTURE_SWIZZLE_B_EXT:
case GL_TEXTURE_SWIZZLE_A_EXT:
{
GLint p[4];
- p[0] = (GLint) param;
+ p[0] = (param > 0) ?
+ ((param > INT_MAX) ? INT_MAX : (GLint) (param + 0.5)) :
+ ((param < INT_MIN) ? INT_MIN : (GLint) (param - 0.5));
+
p[1] = p[2] = p[3] = 0;
need_update = set_tex_parameteri(ctx, texObj, pname, p);
}
diff --git a/mesalib/src/mesa/main/varray.c b/mesalib/src/mesa/main/varray.c
index e453b3b0e..0f7e2a69b 100644
--- a/mesalib/src/mesa/main/varray.c
+++ b/mesalib/src/mesa/main/varray.c
@@ -151,21 +151,21 @@ update_array(struct gl_context *ctx,
}
if (_mesa_is_gles(ctx)) {
- /* Once Mesa gets support for GL_OES_vertex_half_float this mask will
- * change. Adding support for this extension isn't quite as trivial as
- * we'd like because ES uses a different enum value for GL_HALF_FLOAT.
- */
- legalTypesMask &= ~(FIXED_GL_BIT | HALF_BIT | DOUBLE_BIT);
+ legalTypesMask &= ~(FIXED_GL_BIT | DOUBLE_BIT);
/* GL_INT and GL_UNSIGNED_INT data is not allowed in OpenGL ES until
* 3.0. The 2_10_10_10 types are added in OpenGL ES 3.0 or
- * GL_OES_vertex_type_10_10_10_2.
+ * GL_OES_vertex_type_10_10_10_2. GL_HALF_FLOAT data is not allowed
+ * until 3.0 or with the GL_OES_vertex_half float extension, which isn't
+ * quite as trivial as we'd like because it uses a different enum value
+ * for GL_HALF_FLOAT_OES.
*/
if (ctx->Version < 30) {
legalTypesMask &= ~(UNSIGNED_INT_BIT
| INT_BIT
| UNSIGNED_INT_2_10_10_10_REV_BIT
- | INT_2_10_10_10_REV_BIT);
+ | INT_2_10_10_10_REV_BIT
+ | HALF_BIT);
}
/* BGRA ordering is not supported in ES contexts.