1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 #include "glheader.h"
26 #include "imports.h"
27 #include "blend.h"
28 #include "bufferobj.h"
29 #include "context.h"
30 #include "enums.h"
31 #include "readpix.h"
32 #include "framebuffer.h"
33 #include "formats.h"
34 #include "format_unpack.h"
35 #include "image.h"
36 #include "mtypes.h"
37 #include "pack.h"
38 #include "pbo.h"
39 #include "state.h"
40 #include "glformats.h"
41 #include "fbobject.h"
42 #include "format_utils.h"
43 #include "pixeltransfer.h"
44
45
46 /**
47 * Return true if the conversion L=R+G+B is needed.
48 */
49 GLboolean
_mesa_need_rgb_to_luminance_conversion(GLenum srcBaseFormat,GLenum dstBaseFormat)50 _mesa_need_rgb_to_luminance_conversion(GLenum srcBaseFormat,
51 GLenum dstBaseFormat)
52 {
53 return (srcBaseFormat == GL_RG ||
54 srcBaseFormat == GL_RGB ||
55 srcBaseFormat == GL_RGBA) &&
56 (dstBaseFormat == GL_LUMINANCE ||
57 dstBaseFormat == GL_LUMINANCE_ALPHA);
58 }
59
60 /**
61 * Return true if the conversion L,I to RGB conversion is needed.
62 */
63 GLboolean
_mesa_need_luminance_to_rgb_conversion(GLenum srcBaseFormat,GLenum dstBaseFormat)64 _mesa_need_luminance_to_rgb_conversion(GLenum srcBaseFormat,
65 GLenum dstBaseFormat)
66 {
67 return (srcBaseFormat == GL_LUMINANCE ||
68 srcBaseFormat == GL_LUMINANCE_ALPHA ||
69 srcBaseFormat == GL_INTENSITY) &&
70 (dstBaseFormat == GL_GREEN ||
71 dstBaseFormat == GL_BLUE ||
72 dstBaseFormat == GL_RG ||
73 dstBaseFormat == GL_RGB ||
74 dstBaseFormat == GL_BGR ||
75 dstBaseFormat == GL_RGBA ||
76 dstBaseFormat == GL_BGRA);
77 }
78
79 /**
80 * Return transfer op flags for this ReadPixels operation.
81 */
82 GLbitfield
_mesa_get_readpixels_transfer_ops(const struct gl_context * ctx,mesa_format texFormat,GLenum format,GLenum type,GLboolean uses_blit)83 _mesa_get_readpixels_transfer_ops(const struct gl_context *ctx,
84 mesa_format texFormat,
85 GLenum format, GLenum type,
86 GLboolean uses_blit)
87 {
88 GLbitfield transferOps = ctx->_ImageTransferState;
89 GLenum srcBaseFormat = _mesa_get_format_base_format(texFormat);
90 GLenum dstBaseFormat = _mesa_unpack_format_to_base_format(format);
91
92 if (format == GL_DEPTH_COMPONENT ||
93 format == GL_DEPTH_STENCIL ||
94 format == GL_STENCIL_INDEX) {
95 return 0;
96 }
97
98 /* Pixel transfer ops (scale, bias, table lookup) do not apply
99 * to integer formats.
100 */
101 if (_mesa_is_enum_format_integer(format)) {
102 return 0;
103 }
104
105 if (uses_blit) {
106 /* For blit-based ReadPixels packing, the clamping is done automatically
107 * unless the type is float. */
108 if (_mesa_get_clamp_read_color(ctx, ctx->ReadBuffer) &&
109 (type == GL_FLOAT || type == GL_HALF_FLOAT)) {
110 transferOps |= IMAGE_CLAMP_BIT;
111 }
112 }
113 else {
114 /* For CPU-based ReadPixels packing, the clamping must always be done
115 * for non-float types, */
116 if (_mesa_get_clamp_read_color(ctx, ctx->ReadBuffer) ||
117 (type != GL_FLOAT && type != GL_HALF_FLOAT)) {
118 transferOps |= IMAGE_CLAMP_BIT;
119 }
120 }
121
122 /* If the format is unsigned normalized, we can ignore clamping
123 * because the values are already in the range [0,1] so it won't
124 * have any effect anyway.
125 */
126 if (_mesa_get_format_datatype(texFormat) == GL_UNSIGNED_NORMALIZED &&
127 !_mesa_need_rgb_to_luminance_conversion(srcBaseFormat, dstBaseFormat)) {
128 transferOps &= ~IMAGE_CLAMP_BIT;
129 }
130
131 return transferOps;
132 }
133
134
135 /**
136 * Return true if memcpy cannot be used for ReadPixels.
137 *
138 * If uses_blit is true, the function returns true if a simple 3D engine blit
139 * cannot be used for ReadPixels packing.
140 *
141 * NOTE: This doesn't take swizzling and format conversions between
142 * the readbuffer and the pixel pack buffer into account.
143 */
144 GLboolean
_mesa_readpixels_needs_slow_path(const struct gl_context * ctx,GLenum format,GLenum type,GLboolean uses_blit)145 _mesa_readpixels_needs_slow_path(const struct gl_context *ctx, GLenum format,
146 GLenum type, GLboolean uses_blit)
147 {
148 struct gl_renderbuffer *rb =
149 _mesa_get_read_renderbuffer_for_format(ctx, format);
150 GLenum dstBaseFormat = _mesa_unpack_format_to_base_format(format);
151
152 assert(rb);
153
154 /* There are different rules depending on the base format. */
155 switch (format) {
156 case GL_DEPTH_STENCIL:
157 return !_mesa_has_depthstencil_combined(ctx->ReadBuffer) ||
158 ctx->Pixel.DepthScale != 1.0f || ctx->Pixel.DepthBias != 0.0f ||
159 ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset ||
160 ctx->Pixel.MapStencilFlag;
161
162 case GL_DEPTH_COMPONENT:
163 return ctx->Pixel.DepthScale != 1.0f || ctx->Pixel.DepthBias != 0.0f;
164
165 case GL_STENCIL_INDEX:
166 return ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset ||
167 ctx->Pixel.MapStencilFlag;
168
169 default:
170 /* Color formats. */
171 if (_mesa_need_rgb_to_luminance_conversion(rb->_BaseFormat,
172 dstBaseFormat)) {
173 return GL_TRUE;
174 }
175
176 /* And finally, see if there are any transfer ops. */
177 return _mesa_get_readpixels_transfer_ops(ctx, rb->Format, format, type,
178 uses_blit) != 0;
179 }
180 return GL_FALSE;
181 }
182
183
184 static GLboolean
readpixels_can_use_memcpy(const struct gl_context * ctx,GLenum format,GLenum type,const struct gl_pixelstore_attrib * packing)185 readpixels_can_use_memcpy(const struct gl_context *ctx, GLenum format, GLenum type,
186 const struct gl_pixelstore_attrib *packing)
187 {
188 struct gl_renderbuffer *rb =
189 _mesa_get_read_renderbuffer_for_format(ctx, format);
190
191 assert(rb);
192
193 if (_mesa_readpixels_needs_slow_path(ctx, format, type, GL_FALSE)) {
194 return GL_FALSE;
195 }
196
197 /* The base internal format and the base Mesa format must match. */
198 if (rb->_BaseFormat != _mesa_get_format_base_format(rb->Format)) {
199 return GL_FALSE;
200 }
201
202 /* The Mesa format must match the input format and type. */
203 if (!_mesa_format_matches_format_and_type(rb->Format, format, type,
204 packing->SwapBytes, NULL)) {
205 return GL_FALSE;
206 }
207
208 return GL_TRUE;
209 }
210
211
212 static GLboolean
readpixels_memcpy(struct gl_context * ctx,GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLvoid * pixels,const struct gl_pixelstore_attrib * packing)213 readpixels_memcpy(struct gl_context *ctx,
214 GLint x, GLint y,
215 GLsizei width, GLsizei height,
216 GLenum format, GLenum type,
217 GLvoid *pixels,
218 const struct gl_pixelstore_attrib *packing)
219 {
220 struct gl_renderbuffer *rb =
221 _mesa_get_read_renderbuffer_for_format(ctx, format);
222 GLubyte *dst, *map;
223 int dstStride, stride, j, texelBytes, bytesPerRow;
224
225 /* Fail if memcpy cannot be used. */
226 if (!readpixels_can_use_memcpy(ctx, format, type, packing)) {
227 return GL_FALSE;
228 }
229
230 dstStride = _mesa_image_row_stride(packing, width, format, type);
231 dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
232 format, type, 0, 0);
233
234 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
235 &map, &stride);
236 if (!map) {
237 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
238 return GL_TRUE; /* don't bother trying the slow path */
239 }
240
241 texelBytes = _mesa_get_format_bytes(rb->Format);
242 bytesPerRow = texelBytes * width;
243
244 /* memcpy*/
245 if (dstStride == stride && dstStride == bytesPerRow) {
246 memcpy(dst, map, bytesPerRow * height);
247 } else {
248 for (j = 0; j < height; j++) {
249 memcpy(dst, map, bytesPerRow);
250 dst += dstStride;
251 map += stride;
252 }
253 }
254
255 ctx->Driver.UnmapRenderbuffer(ctx, rb);
256 return GL_TRUE;
257 }
258
259
260 /**
261 * Optimized path for conversion of depth values to GL_DEPTH_COMPONENT,
262 * GL_UNSIGNED_INT.
263 */
264 static GLboolean
read_uint_depth_pixels(struct gl_context * ctx,GLint x,GLint y,GLsizei width,GLsizei height,GLenum type,GLvoid * pixels,const struct gl_pixelstore_attrib * packing)265 read_uint_depth_pixels( struct gl_context *ctx,
266 GLint x, GLint y,
267 GLsizei width, GLsizei height,
268 GLenum type, GLvoid *pixels,
269 const struct gl_pixelstore_attrib *packing )
270 {
271 struct gl_framebuffer *fb = ctx->ReadBuffer;
272 struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
273 GLubyte *map, *dst;
274 int stride, dstStride, j;
275
276 if (ctx->Pixel.DepthScale != 1.0F || ctx->Pixel.DepthBias != 0.0F)
277 return GL_FALSE;
278
279 if (packing->SwapBytes)
280 return GL_FALSE;
281
282 if (_mesa_get_format_datatype(rb->Format) != GL_UNSIGNED_NORMALIZED)
283 return GL_FALSE;
284
285 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
286 &map, &stride);
287
288 if (!map) {
289 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
290 return GL_TRUE; /* don't bother trying the slow path */
291 }
292
293 dstStride = _mesa_image_row_stride(packing, width, GL_DEPTH_COMPONENT, type);
294 dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
295 GL_DEPTH_COMPONENT, type, 0, 0);
296
297 for (j = 0; j < height; j++) {
298 _mesa_unpack_uint_z_row(rb->Format, width, map, (GLuint *)dst);
299
300 map += stride;
301 dst += dstStride;
302 }
303 ctx->Driver.UnmapRenderbuffer(ctx, rb);
304
305 return GL_TRUE;
306 }
307
308 /**
309 * Read pixels for format=GL_DEPTH_COMPONENT.
310 */
311 static void
read_depth_pixels(struct gl_context * ctx,GLint x,GLint y,GLsizei width,GLsizei height,GLenum type,GLvoid * pixels,const struct gl_pixelstore_attrib * packing)312 read_depth_pixels( struct gl_context *ctx,
313 GLint x, GLint y,
314 GLsizei width, GLsizei height,
315 GLenum type, GLvoid *pixels,
316 const struct gl_pixelstore_attrib *packing )
317 {
318 struct gl_framebuffer *fb = ctx->ReadBuffer;
319 struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
320 GLint j;
321 GLubyte *dst, *map;
322 int dstStride, stride;
323 GLfloat *depthValues;
324
325 if (!rb)
326 return;
327
328 /* clipping should have been done already */
329 assert(x >= 0);
330 assert(y >= 0);
331 assert(x + width <= (GLint) rb->Width);
332 assert(y + height <= (GLint) rb->Height);
333
334 if (type == GL_UNSIGNED_INT &&
335 read_uint_depth_pixels(ctx, x, y, width, height, type, pixels, packing)) {
336 return;
337 }
338
339 dstStride = _mesa_image_row_stride(packing, width, GL_DEPTH_COMPONENT, type);
340 dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
341 GL_DEPTH_COMPONENT, type, 0, 0);
342
343 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
344 &map, &stride);
345 if (!map) {
346 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
347 return;
348 }
349
350 depthValues = malloc(width * sizeof(GLfloat));
351
352 if (depthValues) {
353 /* General case (slower) */
354 for (j = 0; j < height; j++, y++) {
355 _mesa_unpack_float_z_row(rb->Format, width, map, depthValues);
356 _mesa_pack_depth_span(ctx, width, dst, type, depthValues, packing);
357
358 dst += dstStride;
359 map += stride;
360 }
361 }
362 else {
363 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
364 }
365
366 free(depthValues);
367
368 ctx->Driver.UnmapRenderbuffer(ctx, rb);
369 }
370
371
372 /**
373 * Read pixels for format=GL_STENCIL_INDEX.
374 */
375 static void
read_stencil_pixels(struct gl_context * ctx,GLint x,GLint y,GLsizei width,GLsizei height,GLenum type,GLvoid * pixels,const struct gl_pixelstore_attrib * packing)376 read_stencil_pixels( struct gl_context *ctx,
377 GLint x, GLint y,
378 GLsizei width, GLsizei height,
379 GLenum type, GLvoid *pixels,
380 const struct gl_pixelstore_attrib *packing )
381 {
382 struct gl_framebuffer *fb = ctx->ReadBuffer;
383 struct gl_renderbuffer *rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
384 GLint j;
385 GLubyte *map, *stencil;
386 GLint stride;
387
388 if (!rb)
389 return;
390
391 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
392 &map, &stride);
393 if (!map) {
394 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
395 return;
396 }
397
398 stencil = malloc(width * sizeof(GLubyte));
399
400 if (stencil) {
401 /* process image row by row */
402 for (j = 0; j < height; j++) {
403 GLvoid *dest;
404
405 _mesa_unpack_ubyte_stencil_row(rb->Format, width, map, stencil);
406 dest = _mesa_image_address2d(packing, pixels, width, height,
407 GL_STENCIL_INDEX, type, j, 0);
408
409 _mesa_pack_stencil_span(ctx, width, type, dest, stencil, packing);
410
411 map += stride;
412 }
413 }
414 else {
415 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
416 }
417
418 free(stencil);
419
420 ctx->Driver.UnmapRenderbuffer(ctx, rb);
421 }
422
423 /*
424 * Read R, G, B, A, RGB, L, or LA pixels.
425 */
426 static void
read_rgba_pixels(struct gl_context * ctx,GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLvoid * pixels,const struct gl_pixelstore_attrib * packing)427 read_rgba_pixels( struct gl_context *ctx,
428 GLint x, GLint y,
429 GLsizei width, GLsizei height,
430 GLenum format, GLenum type, GLvoid *pixels,
431 const struct gl_pixelstore_attrib *packing )
432 {
433 GLbitfield transferOps;
434 bool dst_is_integer, convert_rgb_to_lum, needs_rebase;
435 int dst_stride, src_stride, rb_stride;
436 uint32_t dst_format, src_format;
437 GLubyte *dst, *map;
438 mesa_format rb_format;
439 bool needs_rgba;
440 void *rgba, *src;
441 bool src_is_uint = false;
442 uint8_t rebase_swizzle[4];
443 struct gl_framebuffer *fb = ctx->ReadBuffer;
444 struct gl_renderbuffer *rb = fb->_ColorReadBuffer;
445 GLenum dstBaseFormat = _mesa_unpack_format_to_base_format(format);
446
447 if (!rb)
448 return;
449
450 transferOps = _mesa_get_readpixels_transfer_ops(ctx, rb->Format, format,
451 type, GL_FALSE);
452 /* Describe the dst format */
453 dst_is_integer = _mesa_is_enum_format_integer(format);
454 dst_stride = _mesa_image_row_stride(packing, width, format, type);
455 dst_format = _mesa_format_from_format_and_type(format, type);
456 convert_rgb_to_lum =
457 _mesa_need_rgb_to_luminance_conversion(rb->_BaseFormat, dstBaseFormat);
458 dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
459 format, type, 0, 0);
460
461 /* Map the source render buffer */
462 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
463 &map, &rb_stride);
464 if (!map) {
465 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
466 return;
467 }
468 rb_format = _mesa_get_srgb_format_linear(rb->Format);
469
470 /*
471 * Depending on the base formats involved in the conversion we might need to
472 * rebase some values, so for these formats we compute a rebase swizzle.
473 */
474 if (rb->_BaseFormat == GL_LUMINANCE || rb->_BaseFormat == GL_INTENSITY) {
475 needs_rebase = true;
476 rebase_swizzle[0] = MESA_FORMAT_SWIZZLE_X;
477 rebase_swizzle[1] = MESA_FORMAT_SWIZZLE_ZERO;
478 rebase_swizzle[2] = MESA_FORMAT_SWIZZLE_ZERO;
479 rebase_swizzle[3] = MESA_FORMAT_SWIZZLE_ONE;
480 } else if (rb->_BaseFormat == GL_LUMINANCE_ALPHA) {
481 needs_rebase = true;
482 rebase_swizzle[0] = MESA_FORMAT_SWIZZLE_X;
483 rebase_swizzle[1] = MESA_FORMAT_SWIZZLE_ZERO;
484 rebase_swizzle[2] = MESA_FORMAT_SWIZZLE_ZERO;
485 rebase_swizzle[3] = MESA_FORMAT_SWIZZLE_W;
486 } else if (_mesa_get_format_base_format(rb_format) != rb->_BaseFormat) {
487 needs_rebase =
488 _mesa_compute_rgba2base2rgba_component_mapping(rb->_BaseFormat,
489 rebase_swizzle);
490 } else {
491 needs_rebase = false;
492 }
493
494 /* Since _mesa_format_convert does not handle transferOps we need to handle
495 * them before we call the function. This requires to convert to RGBA float
496 * first so we can call _mesa_apply_rgba_transfer_ops. If the dst format is
497 * integer transferOps do not apply.
498 *
499 * Converting to luminance also requires converting to RGBA first, so we can
500 * then compute luminance values as L=R+G+B. Notice that this is different
501 * from GetTexImage, where we compute L=R.
502 */
503 assert(!transferOps || (transferOps && !dst_is_integer));
504
505 needs_rgba = transferOps || convert_rgb_to_lum;
506 rgba = NULL;
507 if (needs_rgba) {
508 uint32_t rgba_format;
509 int rgba_stride;
510 bool need_convert;
511
512 /* Convert to RGBA float or int/uint depending on the type of the src */
513 if (dst_is_integer) {
514 src_is_uint = _mesa_is_format_unsigned(rb_format);
515 if (src_is_uint) {
516 rgba_format = RGBA32_UINT;
517 rgba_stride = width * 4 * sizeof(GLuint);
518 } else {
519 rgba_format = RGBA32_INT;
520 rgba_stride = width * 4 * sizeof(GLint);
521 }
522 } else {
523 rgba_format = RGBA32_FLOAT;
524 rgba_stride = width * 4 * sizeof(GLfloat);
525 }
526
527 /* If we are lucky and the dst format matches the RGBA format we need to
528 * convert to, then we can convert directly into the dst buffer and avoid
529 * the final conversion/copy from the rgba buffer to the dst buffer.
530 */
531 if (dst_format == rgba_format &&
532 dst_stride == rgba_stride) {
533 need_convert = false;
534 rgba = dst;
535 } else {
536 need_convert = true;
537 rgba = malloc(height * rgba_stride);
538 if (!rgba) {
539 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
540 goto done_unmap;
541 }
542 }
543
544 /* Convert to RGBA now */
545 _mesa_format_convert(rgba, rgba_format, rgba_stride,
546 map, rb_format, rb_stride,
547 width, height,
548 needs_rebase ? rebase_swizzle : NULL);
549
550 /* Handle transfer ops if necessary */
551 if (transferOps)
552 _mesa_apply_rgba_transfer_ops(ctx, transferOps, width * height, rgba);
553
554 /* If we had to rebase, we have already taken care of that */
555 needs_rebase = false;
556
557 /* If we were lucky and our RGBA conversion matches the dst format, then
558 * we are done.
559 */
560 if (!need_convert)
561 goto done_swap;
562
563 /* Otherwise, we need to convert from RGBA to dst next */
564 src = rgba;
565 src_format = rgba_format;
566 src_stride = rgba_stride;
567 } else {
568 /* No RGBA conversion needed, convert directly to dst */
569 src = map;
570 src_format = rb_format;
571 src_stride = rb_stride;
572 }
573
574 /* Do the conversion.
575 *
576 * If the dst format is Luminance, we need to do the conversion by computing
577 * L=R+G+B values.
578 */
579 if (!convert_rgb_to_lum) {
580 _mesa_format_convert(dst, dst_format, dst_stride,
581 src, src_format, src_stride,
582 width, height,
583 needs_rebase ? rebase_swizzle : NULL);
584 } else if (!dst_is_integer) {
585 /* Compute float Luminance values from RGBA float */
586 int luminance_stride, luminance_bytes;
587 void *luminance;
588 uint32_t luminance_format;
589
590 luminance_stride = width * sizeof(GLfloat);
591 if (format == GL_LUMINANCE_ALPHA)
592 luminance_stride *= 2;
593 luminance_bytes = height * luminance_stride;
594 luminance = malloc(luminance_bytes);
595 if (!luminance) {
596 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
597 free(rgba);
598 goto done_unmap;
599 }
600 _mesa_pack_luminance_from_rgba_float(width * height, src,
601 luminance, format, transferOps);
602
603 /* Convert from Luminance float to dst (this will hadle type conversion
604 * from float to the type of dst if necessary)
605 */
606 luminance_format = _mesa_format_from_format_and_type(format, GL_FLOAT);
607 _mesa_format_convert(dst, dst_format, dst_stride,
608 luminance, luminance_format, luminance_stride,
609 width, height, NULL);
610 free(luminance);
611 } else {
612 _mesa_pack_luminance_from_rgba_integer(width * height, src, !src_is_uint,
613 dst, format, type);
614 }
615
616 free(rgba);
617
618 done_swap:
619 /* Handle byte swapping if required */
620 if (packing->SwapBytes) {
621 _mesa_swap_bytes_2d_image(format, type, packing,
622 width, height, dst, dst);
623 }
624
625 done_unmap:
626 ctx->Driver.UnmapRenderbuffer(ctx, rb);
627 }
628
629 /**
630 * For a packed depth/stencil buffer being read as depth/stencil, just memcpy the
631 * data (possibly swapping 8/24 vs 24/8 as we go).
632 */
633 static GLboolean
fast_read_depth_stencil_pixels(struct gl_context * ctx,GLint x,GLint y,GLsizei width,GLsizei height,GLubyte * dst,int dstStride)634 fast_read_depth_stencil_pixels(struct gl_context *ctx,
635 GLint x, GLint y,
636 GLsizei width, GLsizei height,
637 GLubyte *dst, int dstStride)
638 {
639 struct gl_framebuffer *fb = ctx->ReadBuffer;
640 struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
641 struct gl_renderbuffer *stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
642 GLubyte *map;
643 int stride, i;
644
645 if (rb != stencilRb)
646 return GL_FALSE;
647
648 if (rb->Format != MESA_FORMAT_S8_UINT_Z24_UNORM &&
649 rb->Format != MESA_FORMAT_Z24_UNORM_S8_UINT)
650 return GL_FALSE;
651
652 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
653 &map, &stride);
654 if (!map) {
655 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
656 return GL_TRUE; /* don't bother trying the slow path */
657 }
658
659 for (i = 0; i < height; i++) {
660 _mesa_unpack_uint_24_8_depth_stencil_row(rb->Format, width,
661 map, (GLuint *)dst);
662 map += stride;
663 dst += dstStride;
664 }
665
666 ctx->Driver.UnmapRenderbuffer(ctx, rb);
667
668 return GL_TRUE;
669 }
670
671
672 /**
673 * For non-float-depth and stencil buffers being read as 24/8 depth/stencil,
674 * copy the integer data directly instead of converting depth to float and
675 * re-packing.
676 */
677 static GLboolean
fast_read_depth_stencil_pixels_separate(struct gl_context * ctx,GLint x,GLint y,GLsizei width,GLsizei height,uint32_t * dst,int dstStride)678 fast_read_depth_stencil_pixels_separate(struct gl_context *ctx,
679 GLint x, GLint y,
680 GLsizei width, GLsizei height,
681 uint32_t *dst, int dstStride)
682 {
683 struct gl_framebuffer *fb = ctx->ReadBuffer;
684 struct gl_renderbuffer *depthRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
685 struct gl_renderbuffer *stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
686 GLubyte *depthMap, *stencilMap, *stencilVals;
687 int depthStride, stencilStride, i, j;
688
689 if (_mesa_get_format_datatype(depthRb->Format) != GL_UNSIGNED_NORMALIZED)
690 return GL_FALSE;
691
692 ctx->Driver.MapRenderbuffer(ctx, depthRb, x, y, width, height,
693 GL_MAP_READ_BIT, &depthMap, &depthStride);
694 if (!depthMap) {
695 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
696 return GL_TRUE; /* don't bother trying the slow path */
697 }
698
699 ctx->Driver.MapRenderbuffer(ctx, stencilRb, x, y, width, height,
700 GL_MAP_READ_BIT, &stencilMap, &stencilStride);
701 if (!stencilMap) {
702 ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
703 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
704 return GL_TRUE; /* don't bother trying the slow path */
705 }
706
707 stencilVals = malloc(width * sizeof(GLubyte));
708
709 if (stencilVals) {
710 for (j = 0; j < height; j++) {
711 _mesa_unpack_uint_z_row(depthRb->Format, width, depthMap, dst);
712 _mesa_unpack_ubyte_stencil_row(stencilRb->Format, width,
713 stencilMap, stencilVals);
714
715 for (i = 0; i < width; i++) {
716 dst[i] = (dst[i] & 0xffffff00) | stencilVals[i];
717 }
718
719 depthMap += depthStride;
720 stencilMap += stencilStride;
721 dst += dstStride / 4;
722 }
723 }
724 else {
725 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
726 }
727
728 free(stencilVals);
729
730 ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
731 ctx->Driver.UnmapRenderbuffer(ctx, stencilRb);
732
733 return GL_TRUE;
734 }
735
736 static void
slow_read_depth_stencil_pixels_separate(struct gl_context * ctx,GLint x,GLint y,GLsizei width,GLsizei height,GLenum type,const struct gl_pixelstore_attrib * packing,GLubyte * dst,int dstStride)737 slow_read_depth_stencil_pixels_separate(struct gl_context *ctx,
738 GLint x, GLint y,
739 GLsizei width, GLsizei height,
740 GLenum type,
741 const struct gl_pixelstore_attrib *packing,
742 GLubyte *dst, int dstStride)
743 {
744 struct gl_framebuffer *fb = ctx->ReadBuffer;
745 struct gl_renderbuffer *depthRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
746 struct gl_renderbuffer *stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
747 GLubyte *depthMap, *stencilMap;
748 int depthStride, stencilStride, j;
749 GLubyte *stencilVals;
750 GLfloat *depthVals;
751
752
753 /* The depth and stencil buffers might be separate, or a single buffer.
754 * If one buffer, only map it once.
755 */
756 ctx->Driver.MapRenderbuffer(ctx, depthRb, x, y, width, height,
757 GL_MAP_READ_BIT, &depthMap, &depthStride);
758 if (!depthMap) {
759 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
760 return;
761 }
762
763 if (stencilRb != depthRb) {
764 ctx->Driver.MapRenderbuffer(ctx, stencilRb, x, y, width, height,
765 GL_MAP_READ_BIT, &stencilMap,
766 &stencilStride);
767 if (!stencilMap) {
768 ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
769 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
770 return;
771 }
772 }
773 else {
774 stencilMap = depthMap;
775 stencilStride = depthStride;
776 }
777
778 stencilVals = malloc(width * sizeof(GLubyte));
779 depthVals = malloc(width * sizeof(GLfloat));
780
781 if (stencilVals && depthVals) {
782 for (j = 0; j < height; j++) {
783 _mesa_unpack_float_z_row(depthRb->Format, width, depthMap, depthVals);
784 _mesa_unpack_ubyte_stencil_row(stencilRb->Format, width,
785 stencilMap, stencilVals);
786
787 _mesa_pack_depth_stencil_span(ctx, width, type, (GLuint *)dst,
788 depthVals, stencilVals, packing);
789
790 depthMap += depthStride;
791 stencilMap += stencilStride;
792 dst += dstStride;
793 }
794 }
795 else {
796 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
797 }
798
799 free(stencilVals);
800 free(depthVals);
801
802 ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
803 if (stencilRb != depthRb) {
804 ctx->Driver.UnmapRenderbuffer(ctx, stencilRb);
805 }
806 }
807
808
809 /**
810 * Read combined depth/stencil values.
811 * We'll have already done error checking to be sure the expected
812 * depth and stencil buffers really exist.
813 */
814 static void
read_depth_stencil_pixels(struct gl_context * ctx,GLint x,GLint y,GLsizei width,GLsizei height,GLenum type,GLvoid * pixels,const struct gl_pixelstore_attrib * packing)815 read_depth_stencil_pixels(struct gl_context *ctx,
816 GLint x, GLint y,
817 GLsizei width, GLsizei height,
818 GLenum type, GLvoid *pixels,
819 const struct gl_pixelstore_attrib *packing )
820 {
821 const GLboolean scaleOrBias
822 = ctx->Pixel.DepthScale != 1.0F || ctx->Pixel.DepthBias != 0.0F;
823 const GLboolean stencilTransfer = ctx->Pixel.IndexShift
824 || ctx->Pixel.IndexOffset || ctx->Pixel.MapStencilFlag;
825 GLubyte *dst;
826 int dstStride;
827
828 dst = (GLubyte *) _mesa_image_address2d(packing, pixels,
829 width, height,
830 GL_DEPTH_STENCIL_EXT,
831 type, 0, 0);
832 dstStride = _mesa_image_row_stride(packing, width,
833 GL_DEPTH_STENCIL_EXT, type);
834
835 /* Fast 24/8 reads. */
836 if (type == GL_UNSIGNED_INT_24_8 &&
837 !scaleOrBias && !stencilTransfer && !packing->SwapBytes) {
838 if (fast_read_depth_stencil_pixels(ctx, x, y, width, height,
839 dst, dstStride))
840 return;
841
842 if (fast_read_depth_stencil_pixels_separate(ctx, x, y, width, height,
843 (uint32_t *)dst, dstStride))
844 return;
845 }
846
847 slow_read_depth_stencil_pixels_separate(ctx, x, y, width, height,
848 type, packing,
849 dst, dstStride);
850 }
851
852
853
854 /**
855 * Software fallback routine for ctx->Driver.ReadPixels().
856 * By time we get here, all error checking will have been done.
857 */
858 void
_mesa_readpixels(struct gl_context * ctx,GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,const struct gl_pixelstore_attrib * packing,GLvoid * pixels)859 _mesa_readpixels(struct gl_context *ctx,
860 GLint x, GLint y, GLsizei width, GLsizei height,
861 GLenum format, GLenum type,
862 const struct gl_pixelstore_attrib *packing,
863 GLvoid *pixels)
864 {
865 if (ctx->NewState)
866 _mesa_update_state(ctx);
867
868 pixels = _mesa_map_pbo_dest(ctx, packing, pixels);
869
870 if (pixels) {
871 /* Try memcpy first. */
872 if (readpixels_memcpy(ctx, x, y, width, height, format, type,
873 pixels, packing)) {
874 _mesa_unmap_pbo_dest(ctx, packing);
875 return;
876 }
877
878 /* Otherwise take the slow path. */
879 switch (format) {
880 case GL_STENCIL_INDEX:
881 read_stencil_pixels(ctx, x, y, width, height, type, pixels,
882 packing);
883 break;
884 case GL_DEPTH_COMPONENT:
885 read_depth_pixels(ctx, x, y, width, height, type, pixels,
886 packing);
887 break;
888 case GL_DEPTH_STENCIL_EXT:
889 read_depth_stencil_pixels(ctx, x, y, width, height, type, pixels,
890 packing);
891 break;
892 default:
893 /* all other formats should be color formats */
894 read_rgba_pixels(ctx, x, y, width, height, format, type, pixels,
895 packing);
896 }
897
898 _mesa_unmap_pbo_dest(ctx, packing);
899 }
900 }
901
902
903 static GLenum
read_pixels_es3_error_check(GLenum format,GLenum type,const struct gl_renderbuffer * rb)904 read_pixels_es3_error_check(GLenum format, GLenum type,
905 const struct gl_renderbuffer *rb)
906 {
907 const GLenum internalFormat = rb->InternalFormat;
908 const GLenum data_type = _mesa_get_format_datatype(rb->Format);
909 GLboolean is_unsigned_int = GL_FALSE;
910 GLboolean is_signed_int = GL_FALSE;
911 GLboolean is_float_depth = (internalFormat == GL_DEPTH_COMPONENT32F) ||
912 (internalFormat == GL_DEPTH32F_STENCIL8);
913
914 is_unsigned_int = _mesa_is_enum_format_unsigned_int(internalFormat);
915 if (!is_unsigned_int) {
916 is_signed_int = _mesa_is_enum_format_signed_int(internalFormat);
917 }
918
919 switch (format) {
920 case GL_RGBA:
921 if (type == GL_FLOAT && data_type == GL_FLOAT)
922 return GL_NO_ERROR; /* EXT_color_buffer_float */
923 if (type == GL_UNSIGNED_BYTE && data_type == GL_UNSIGNED_NORMALIZED)
924 return GL_NO_ERROR;
925 if (internalFormat == GL_RGB10_A2 &&
926 type == GL_UNSIGNED_INT_2_10_10_10_REV)
927 return GL_NO_ERROR;
928 if (internalFormat == GL_RGB10_A2UI && type == GL_UNSIGNED_BYTE)
929 return GL_NO_ERROR;
930 break;
931 case GL_BGRA:
932 /* GL_EXT_read_format_bgra */
933 if (type == GL_UNSIGNED_BYTE ||
934 type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
935 type == GL_UNSIGNED_SHORT_1_5_5_5_REV)
936 return GL_NO_ERROR;
937 break;
938 case GL_RGBA_INTEGER:
939 if ((is_signed_int && type == GL_INT) ||
940 (is_unsigned_int && type == GL_UNSIGNED_INT))
941 return GL_NO_ERROR;
942 break;
943 case GL_DEPTH_STENCIL:
944 switch (type) {
945 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
946 if (is_float_depth)
947 return GL_NO_ERROR;
948 break;
949 case GL_UNSIGNED_INT_24_8:
950 if (!is_float_depth)
951 return GL_NO_ERROR;
952 break;
953 default:
954 return GL_INVALID_ENUM;
955 }
956 break;
957 case GL_DEPTH_COMPONENT:
958 switch (type) {
959 case GL_FLOAT:
960 if (is_float_depth)
961 return GL_NO_ERROR;
962 break;
963 case GL_UNSIGNED_SHORT:
964 case GL_UNSIGNED_INT:
965 case GL_UNSIGNED_INT_24_8:
966 if (!is_float_depth)
967 return GL_NO_ERROR;
968 break;
969 default:
970 return GL_INVALID_ENUM;
971 }
972 break;
973 case GL_STENCIL_INDEX:
974 switch (type) {
975 case GL_UNSIGNED_BYTE:
976 return GL_NO_ERROR;
977 default:
978 return GL_INVALID_ENUM;
979 }
980 break;
981 }
982
983 return GL_INVALID_OPERATION;
984 }
985
986
987 static ALWAYS_INLINE void
read_pixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,GLvoid * pixels,bool no_error)988 read_pixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
989 GLenum type, GLsizei bufSize, GLvoid *pixels, bool no_error)
990 {
991 GLenum err = GL_NO_ERROR;
992 struct gl_renderbuffer *rb;
993 struct gl_pixelstore_attrib clippedPacking;
994
995 GET_CURRENT_CONTEXT(ctx);
996
997 FLUSH_VERTICES(ctx, 0);
998 FLUSH_CURRENT(ctx, 0);
999
1000 if (MESA_VERBOSE & VERBOSE_API)
1001 _mesa_debug(ctx, "glReadPixels(%d, %d, %s, %s, %p)\n",
1002 width, height,
1003 _mesa_enum_to_string(format),
1004 _mesa_enum_to_string(type),
1005 pixels);
1006
1007 if (!no_error && (width < 0 || height < 0)) {
1008 _mesa_error( ctx, GL_INVALID_VALUE,
1009 "glReadPixels(width=%d height=%d)", width, height );
1010 return;
1011 }
1012
1013 if (ctx->NewState)
1014 _mesa_update_state(ctx);
1015
1016 if (!no_error && ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
1017 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
1018 "glReadPixels(incomplete framebuffer)" );
1019 return;
1020 }
1021
1022 rb = _mesa_get_read_renderbuffer_for_format(ctx, format);
1023 if (!no_error) {
1024 if (rb == NULL) {
1025 _mesa_error(ctx, GL_INVALID_OPERATION,
1026 "glReadPixels(read buffer)");
1027 return;
1028 }
1029
1030 /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
1031 * combinations of format and type that can be used.
1032 *
1033 * Technically, only two combinations are actually allowed:
1034 * GL_RGBA/GL_UNSIGNED_BYTE, and some implementation-specific internal
1035 * preferred combination. This code doesn't know what that preferred
1036 * combination is, and Mesa can handle anything valid. Just work instead.
1037 */
1038 if (_mesa_is_gles(ctx)) {
1039 if (ctx->API == API_OPENGLES2 &&
1040 _mesa_is_color_format(format) &&
1041 _mesa_get_color_read_format(ctx, NULL, "glReadPixels") == format &&
1042 _mesa_get_color_read_type(ctx, NULL, "glReadPixels") == type) {
1043 err = GL_NO_ERROR;
1044 } else if (ctx->Version < 30) {
1045 err = _mesa_es_error_check_format_and_type(ctx, format, type, 2);
1046 if (err == GL_NO_ERROR) {
1047 if (type == GL_FLOAT || type == GL_HALF_FLOAT_OES) {
1048 err = GL_INVALID_OPERATION;
1049 }
1050 }
1051 } else {
1052 err = read_pixels_es3_error_check(format, type, rb);
1053 }
1054
1055 if (err != GL_NO_ERROR) {
1056 _mesa_error(ctx, err, "glReadPixels(invalid format %s and/or type %s)",
1057 _mesa_enum_to_string(format),
1058 _mesa_enum_to_string(type));
1059 return;
1060 }
1061 }
1062
1063 err = _mesa_error_check_format_and_type(ctx, format, type);
1064 if (err != GL_NO_ERROR) {
1065 _mesa_error(ctx, err, "glReadPixels(invalid format %s and/or type %s)",
1066 _mesa_enum_to_string(format),
1067 _mesa_enum_to_string(type));
1068 return;
1069 }
1070
1071 if (_mesa_is_user_fbo(ctx->ReadBuffer) &&
1072 ctx->ReadBuffer->Visual.samples > 0) {
1073 _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(multisample FBO)");
1074 return;
1075 }
1076
1077 if (!_mesa_source_buffer_exists(ctx, format)) {
1078 _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(no readbuffer)");
1079 return;
1080 }
1081
1082 /* Check that the destination format and source buffer are both
1083 * integer-valued or both non-integer-valued.
1084 */
1085 if (ctx->Extensions.EXT_texture_integer && _mesa_is_color_format(format)) {
1086 const struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
1087 const GLboolean srcInteger = _mesa_is_format_integer_color(rb->Format);
1088 const GLboolean dstInteger = _mesa_is_enum_format_integer(format);
1089 if (dstInteger != srcInteger) {
1090 _mesa_error(ctx, GL_INVALID_OPERATION,
1091 "glReadPixels(integer / non-integer format mismatch");
1092 return;
1093 }
1094 }
1095 }
1096
1097 /* Do all needed clipping here, so that we can forget about it later */
1098 clippedPacking = ctx->Pack;
1099 if (!_mesa_clip_readpixels(ctx, &x, &y, &width, &height, &clippedPacking))
1100 return; /* nothing to do */
1101
1102 if (!no_error) {
1103 if (!_mesa_validate_pbo_access(2, &ctx->Pack, width, height, 1,
1104 format, type, bufSize, pixels)) {
1105 if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
1106 _mesa_error(ctx, GL_INVALID_OPERATION,
1107 "glReadPixels(out of bounds PBO access)");
1108 } else {
1109 _mesa_error(ctx, GL_INVALID_OPERATION,
1110 "glReadnPixelsARB(out of bounds access:"
1111 " bufSize (%d) is too small)", bufSize);
1112 }
1113 return;
1114 }
1115
1116 if (_mesa_is_bufferobj(ctx->Pack.BufferObj) &&
1117 _mesa_check_disallowed_mapping(ctx->Pack.BufferObj)) {
1118 /* buffer is mapped - that's an error */
1119 _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(PBO is mapped)");
1120 return;
1121 }
1122 }
1123
1124 ctx->Driver.ReadPixels(ctx, x, y, width, height,
1125 format, type, &clippedPacking, pixels);
1126 }
1127
1128 void GLAPIENTRY
_mesa_ReadnPixelsARB_no_error(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,GLvoid * pixels)1129 _mesa_ReadnPixelsARB_no_error(GLint x, GLint y, GLsizei width, GLsizei height,
1130 GLenum format, GLenum type, GLsizei bufSize,
1131 GLvoid *pixels)
1132 {
1133 read_pixels(x, y, width, height, format, type, bufSize, pixels, true);
1134 }
1135
1136 void GLAPIENTRY
_mesa_ReadnPixelsARB(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,GLvoid * pixels)1137 _mesa_ReadnPixelsARB(GLint x, GLint y, GLsizei width, GLsizei height,
1138 GLenum format, GLenum type, GLsizei bufSize,
1139 GLvoid *pixels)
1140 {
1141 read_pixels(x, y, width, height, format, type, bufSize, pixels, false);
1142 }
1143
1144 void GLAPIENTRY
_mesa_ReadPixels_no_error(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLvoid * pixels)1145 _mesa_ReadPixels_no_error(GLint x, GLint y, GLsizei width, GLsizei height,
1146 GLenum format, GLenum type, GLvoid *pixels)
1147 {
1148 _mesa_ReadnPixelsARB_no_error(x, y, width, height, format, type, INT_MAX,
1149 pixels);
1150 }
1151
1152 void GLAPIENTRY
_mesa_ReadPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLvoid * pixels)1153 _mesa_ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
1154 GLenum format, GLenum type, GLvoid *pixels)
1155 {
1156 _mesa_ReadnPixelsARB(x, y, width, height, format, type, INT_MAX, pixels);
1157 }
1158