#include "pack.h"
#include "pbo.h"
#include "state.h"
+#include "glformats.h"
+#include "fbobject.h"
/**
return;
}
- depthValues = (GLfloat *) malloc(width * sizeof(GLfloat));
+ depthValues = malloc(width * sizeof(GLfloat));
if (depthValues) {
/* General case (slower) */
return;
}
- stencil = (GLubyte *) malloc(width * sizeof(GLubyte));
+ stencil = malloc(width * sizeof(GLubyte));
if (stencil) {
/* process image row by row */
void *rgba;
GLubyte *dst, *map;
int dstStride, stride, j;
+ GLboolean dst_is_integer = _mesa_is_enum_format_integer(format);
+ GLboolean dst_is_uint = _mesa_is_format_unsigned(rbFormat);
dstStride = _mesa_image_row_stride(packing, width, format, type);
dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
goto done;
for (j = 0; j < height; j++) {
- if (_mesa_is_integer_format(format)) {
+ if (dst_is_integer) {
_mesa_unpack_uint_rgba_row(rbFormat, width, map, (GLuint (*)[4]) rgba);
_mesa_rebase_rgba_uint(width, (GLuint (*)[4]) rgba,
rb->_BaseFormat);
- _mesa_pack_rgba_span_int(ctx, width, (GLuint (*)[4]) rgba, format,
- type, dst);
+ if (dst_is_uint) {
+ _mesa_pack_rgba_span_from_uints(ctx, width, (GLuint (*)[4]) rgba, format,
+ type, dst);
+ } else {
+ _mesa_pack_rgba_span_from_ints(ctx, width, (GLint (*)[4]) rgba, format,
+ type, dst);
+ }
} else {
_mesa_unpack_rgba_row(rbFormat, width, map, (GLfloat (*)[4]) rgba);
_mesa_rebase_rgba_float(width, (GLfloat (*)[4]) rgba,
return;
if ((ctx->Color._ClampReadColor == GL_TRUE || type != GL_FLOAT) &&
- !_mesa_is_integer_format(format)) {
+ !_mesa_is_enum_format_integer(format)) {
transferOps |= IMAGE_CLAMP_BIT;
}
return GL_TRUE; /* don't bother trying the slow path */
}
- stencilVals = (GLubyte *) malloc(width * sizeof(GLubyte));
+ stencilVals = malloc(width * sizeof(GLubyte));
if (stencilVals) {
for (j = 0; j < height; j++) {
stencilStride = depthStride;
}
- stencilVals = (GLubyte *) malloc(width * sizeof(GLubyte));
- depthVals = (GLfloat *) malloc(width * sizeof(GLfloat));
+ stencilVals = malloc(width * sizeof(GLubyte));
+ depthVals = malloc(width * sizeof(GLfloat));
if (stencilVals && depthVals) {
for (j = 0; j < height; j++) {
return;
}
+ /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
+ * combinations of format and type that can be used.
+ *
+ * Technically, only two combinations are actually allowed:
+ * GL_RGBA/GL_UNSIGNED_BYTE, and some implementation-specific internal
+ * 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 (err != GL_NO_ERROR) {
+ _mesa_error(ctx, err, "glReadPixels(invalid format %s and/or type %s)",
+ _mesa_lookup_enum_by_nr(format),
+ _mesa_lookup_enum_by_nr(type));
+ return;
+ }
+ }
+
if (ctx->NewState)
_mesa_update_state(ctx);
return;
}
+ if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
+ "glReadPixels(incomplete framebuffer)" );
+ return;
+ }
+
/* Check that the destination format and source buffer are both
* integer-valued or both non-integer-valued.
*/
if (ctx->Extensions.EXT_texture_integer && _mesa_is_color_format(format)) {
const struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
const GLboolean srcInteger = _mesa_is_format_integer_color(rb->Format);
- const GLboolean dstInteger = _mesa_is_integer_format(format);
+ const GLboolean dstInteger = _mesa_is_enum_format_integer(format);
if (dstInteger != srcInteger) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glReadPixels(integer / non-integer format mismatch");
}
}
- if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
- "glReadPixels(incomplete framebuffer)" );
- return;
- }
-
- if (ctx->ReadBuffer->Name != 0 && ctx->ReadBuffer->Visual.samples > 0) {
+ if (_mesa_is_user_fbo(ctx->ReadBuffer) &&
+ ctx->ReadBuffer->Visual.samples > 0) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(multisample FBO)");
return;
}