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;
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
243 /* memcpy*/
244 for (j = 0; j < height; j++) {
245 memcpy(dst, map, width * texelBytes);
246 dst += dstStride;
247 map += stride;
248 }
249
250 ctx->Driver.UnmapRenderbuffer(ctx, rb);
251 return GL_TRUE;
252 }
253
254
255 /**
256 * Optimized path for conversion of depth values to GL_DEPTH_COMPONENT,
257 * GL_UNSIGNED_INT.
258 */
259 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)260 read_uint_depth_pixels( struct gl_context *ctx,
261 GLint x, GLint y,
262 GLsizei width, GLsizei height,
263 GLenum type, GLvoid *pixels,
264 const struct gl_pixelstore_attrib *packing )
265 {
266 struct gl_framebuffer *fb = ctx->ReadBuffer;
267 struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
268 GLubyte *map, *dst;
269 int stride, dstStride, j;
270
271 if (ctx->Pixel.DepthScale != 1.0F || ctx->Pixel.DepthBias != 0.0F)
272 return GL_FALSE;
273
274 if (packing->SwapBytes)
275 return GL_FALSE;
276
277 if (_mesa_get_format_datatype(rb->Format) != GL_UNSIGNED_NORMALIZED)
278 return GL_FALSE;
279
280 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
281 &map, &stride);
282
283 if (!map) {
284 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
285 return GL_TRUE; /* don't bother trying the slow path */
286 }
287
288 dstStride = _mesa_image_row_stride(packing, width, GL_DEPTH_COMPONENT, type);
289 dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
290 GL_DEPTH_COMPONENT, type, 0, 0);
291
292 for (j = 0; j < height; j++) {
293 _mesa_unpack_uint_z_row(rb->Format, width, map, (GLuint *)dst);
294
295 map += stride;
296 dst += dstStride;
297 }
298 ctx->Driver.UnmapRenderbuffer(ctx, rb);
299
300 return GL_TRUE;
301 }
302
303 /**
304 * Read pixels for format=GL_DEPTH_COMPONENT.
305 */
306 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)307 read_depth_pixels( struct gl_context *ctx,
308 GLint x, GLint y,
309 GLsizei width, GLsizei height,
310 GLenum type, GLvoid *pixels,
311 const struct gl_pixelstore_attrib *packing )
312 {
313 struct gl_framebuffer *fb = ctx->ReadBuffer;
314 struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
315 GLint j;
316 GLubyte *dst, *map;
317 int dstStride, stride;
318 GLfloat *depthValues;
319
320 if (!rb)
321 return;
322
323 /* clipping should have been done already */
324 assert(x >= 0);
325 assert(y >= 0);
326 assert(x + width <= (GLint) rb->Width);
327 assert(y + height <= (GLint) rb->Height);
328
329 if (type == GL_UNSIGNED_INT &&
330 read_uint_depth_pixels(ctx, x, y, width, height, type, pixels, packing)) {
331 return;
332 }
333
334 dstStride = _mesa_image_row_stride(packing, width, GL_DEPTH_COMPONENT, type);
335 dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
336 GL_DEPTH_COMPONENT, type, 0, 0);
337
338 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
339 &map, &stride);
340 if (!map) {
341 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
342 return;
343 }
344
345 depthValues = malloc(width * sizeof(GLfloat));
346
347 if (depthValues) {
348 /* General case (slower) */
349 for (j = 0; j < height; j++, y++) {
350 _mesa_unpack_float_z_row(rb->Format, width, map, depthValues);
351 _mesa_pack_depth_span(ctx, width, dst, type, depthValues, packing);
352
353 dst += dstStride;
354 map += stride;
355 }
356 }
357 else {
358 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
359 }
360
361 free(depthValues);
362
363 ctx->Driver.UnmapRenderbuffer(ctx, rb);
364 }
365
366
367 /**
368 * Read pixels for format=GL_STENCIL_INDEX.
369 */
370 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)371 read_stencil_pixels( struct gl_context *ctx,
372 GLint x, GLint y,
373 GLsizei width, GLsizei height,
374 GLenum type, GLvoid *pixels,
375 const struct gl_pixelstore_attrib *packing )
376 {
377 struct gl_framebuffer *fb = ctx->ReadBuffer;
378 struct gl_renderbuffer *rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
379 GLint j;
380 GLubyte *map, *stencil;
381 GLint stride;
382
383 if (!rb)
384 return;
385
386 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
387 &map, &stride);
388 if (!map) {
389 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
390 return;
391 }
392
393 stencil = malloc(width * sizeof(GLubyte));
394
395 if (stencil) {
396 /* process image row by row */
397 for (j = 0; j < height; j++) {
398 GLvoid *dest;
399
400 _mesa_unpack_ubyte_stencil_row(rb->Format, width, map, stencil);
401 dest = _mesa_image_address2d(packing, pixels, width, height,
402 GL_STENCIL_INDEX, type, j, 0);
403
404 _mesa_pack_stencil_span(ctx, width, type, dest, stencil, packing);
405
406 map += stride;
407 }
408 }
409 else {
410 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
411 }
412
413 free(stencil);
414
415 ctx->Driver.UnmapRenderbuffer(ctx, rb);
416 }
417
418 /*
419 * Read R, G, B, A, RGB, L, or LA pixels.
420 */
421 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)422 read_rgba_pixels( struct gl_context *ctx,
423 GLint x, GLint y,
424 GLsizei width, GLsizei height,
425 GLenum format, GLenum type, GLvoid *pixels,
426 const struct gl_pixelstore_attrib *packing )
427 {
428 GLbitfield transferOps;
429 bool dst_is_integer, convert_rgb_to_lum, needs_rebase;
430 int dst_stride, src_stride, rb_stride;
431 uint32_t dst_format, src_format;
432 GLubyte *dst, *map;
433 mesa_format rb_format;
434 bool needs_rgba;
435 void *rgba, *src;
436 bool src_is_uint = false;
437 uint8_t rebase_swizzle[4];
438 struct gl_framebuffer *fb = ctx->ReadBuffer;
439 struct gl_renderbuffer *rb = fb->_ColorReadBuffer;
440 GLenum dstBaseFormat = _mesa_unpack_format_to_base_format(format);
441
442 if (!rb)
443 return;
444
445 transferOps = _mesa_get_readpixels_transfer_ops(ctx, rb->Format, format,
446 type, GL_FALSE);
447 /* Describe the dst format */
448 dst_is_integer = _mesa_is_enum_format_integer(format);
449 dst_stride = _mesa_image_row_stride(packing, width, format, type);
450 dst_format = _mesa_format_from_format_and_type(format, type);
451 convert_rgb_to_lum =
452 _mesa_need_rgb_to_luminance_conversion(rb->_BaseFormat, dstBaseFormat);
453 dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height,
454 format, type, 0, 0);
455
456 /* Map the source render buffer */
457 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
458 &map, &rb_stride);
459 if (!map) {
460 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
461 return;
462 }
463 rb_format = _mesa_get_srgb_format_linear(rb->Format);
464
465 /*
466 * Depending on the base formats involved in the conversion we might need to
467 * rebase some values, so for these formats we compute a rebase swizzle.
468 */
469 if (rb->_BaseFormat == GL_LUMINANCE || rb->_BaseFormat == GL_INTENSITY) {
470 needs_rebase = true;
471 rebase_swizzle[0] = MESA_FORMAT_SWIZZLE_X;
472 rebase_swizzle[1] = MESA_FORMAT_SWIZZLE_ZERO;
473 rebase_swizzle[2] = MESA_FORMAT_SWIZZLE_ZERO;
474 rebase_swizzle[3] = MESA_FORMAT_SWIZZLE_ONE;
475 } else if (rb->_BaseFormat == GL_LUMINANCE_ALPHA) {
476 needs_rebase = true;
477 rebase_swizzle[0] = MESA_FORMAT_SWIZZLE_X;
478 rebase_swizzle[1] = MESA_FORMAT_SWIZZLE_ZERO;
479 rebase_swizzle[2] = MESA_FORMAT_SWIZZLE_ZERO;
480 rebase_swizzle[3] = MESA_FORMAT_SWIZZLE_W;
481 } else if (_mesa_get_format_base_format(rb_format) != rb->_BaseFormat) {
482 needs_rebase =
483 _mesa_compute_rgba2base2rgba_component_mapping(rb->_BaseFormat,
484 rebase_swizzle);
485 } else {
486 needs_rebase = false;
487 }
488
489 /* Since _mesa_format_convert does not handle transferOps we need to handle
490 * them before we call the function. This requires to convert to RGBA float
491 * first so we can call _mesa_apply_rgba_transfer_ops. If the dst format is
492 * integer transferOps do not apply.
493 *
494 * Converting to luminance also requires converting to RGBA first, so we can
495 * then compute luminance values as L=R+G+B. Notice that this is different
496 * from GetTexImage, where we compute L=R.
497 */
498 assert(!transferOps || (transferOps && !dst_is_integer));
499
500 needs_rgba = transferOps || convert_rgb_to_lum;
501 rgba = NULL;
502 if (needs_rgba) {
503 uint32_t rgba_format;
504 int rgba_stride;
505 bool need_convert;
506
507 /* Convert to RGBA float or int/uint depending on the type of the src */
508 if (dst_is_integer) {
509 src_is_uint = _mesa_is_format_unsigned(rb_format);
510 if (src_is_uint) {
511 rgba_format = RGBA32_UINT;
512 rgba_stride = width * 4 * sizeof(GLuint);
513 } else {
514 rgba_format = RGBA32_INT;
515 rgba_stride = width * 4 * sizeof(GLint);
516 }
517 } else {
518 rgba_format = RGBA32_FLOAT;
519 rgba_stride = width * 4 * sizeof(GLfloat);
520 }
521
522 /* If we are lucky and the dst format matches the RGBA format we need to
523 * convert to, then we can convert directly into the dst buffer and avoid
524 * the final conversion/copy from the rgba buffer to the dst buffer.
525 */
526 if (dst_format == rgba_format &&
527 dst_stride == rgba_stride) {
528 need_convert = false;
529 rgba = dst;
530 } else {
531 need_convert = true;
532 rgba = malloc(height * rgba_stride);
533 if (!rgba) {
534 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
535 goto done_unmap;
536 }
537 }
538
539 /* Convert to RGBA now */
540 _mesa_format_convert(rgba, rgba_format, rgba_stride,
541 map, rb_format, rb_stride,
542 width, height,
543 needs_rebase ? rebase_swizzle : NULL);
544
545 /* Handle transfer ops if necessary */
546 if (transferOps)
547 _mesa_apply_rgba_transfer_ops(ctx, transferOps, width * height, rgba);
548
549 /* If we had to rebase, we have already taken care of that */
550 needs_rebase = false;
551
552 /* If we were lucky and our RGBA conversion matches the dst format, then
553 * we are done.
554 */
555 if (!need_convert)
556 goto done_swap;
557
558 /* Otherwise, we need to convert from RGBA to dst next */
559 src = rgba;
560 src_format = rgba_format;
561 src_stride = rgba_stride;
562 } else {
563 /* No RGBA conversion needed, convert directly to dst */
564 src = map;
565 src_format = rb_format;
566 src_stride = rb_stride;
567 }
568
569 /* Do the conversion.
570 *
571 * If the dst format is Luminance, we need to do the conversion by computing
572 * L=R+G+B values.
573 */
574 if (!convert_rgb_to_lum) {
575 _mesa_format_convert(dst, dst_format, dst_stride,
576 src, src_format, src_stride,
577 width, height,
578 needs_rebase ? rebase_swizzle : NULL);
579 } else if (!dst_is_integer) {
580 /* Compute float Luminance values from RGBA float */
581 int luminance_stride, luminance_bytes;
582 void *luminance;
583 uint32_t luminance_format;
584
585 luminance_stride = width * sizeof(GLfloat);
586 if (format == GL_LUMINANCE_ALPHA)
587 luminance_stride *= 2;
588 luminance_bytes = height * luminance_stride;
589 luminance = malloc(luminance_bytes);
590 if (!luminance) {
591 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
592 free(rgba);
593 goto done_unmap;
594 }
595 _mesa_pack_luminance_from_rgba_float(width * height, src,
596 luminance, format, transferOps);
597
598 /* Convert from Luminance float to dst (this will hadle type conversion
599 * from float to the type of dst if necessary)
600 */
601 luminance_format = _mesa_format_from_format_and_type(format, GL_FLOAT);
602 _mesa_format_convert(dst, dst_format, dst_stride,
603 luminance, luminance_format, luminance_stride,
604 width, height, NULL);
605 free(luminance);
606 } else {
607 _mesa_pack_luminance_from_rgba_integer(width * height, src, !src_is_uint,
608 dst, format, type);
609 }
610
611 free(rgba);
612
613 done_swap:
614 /* Handle byte swapping if required */
615 if (packing->SwapBytes) {
616 _mesa_swap_bytes_2d_image(format, type, packing,
617 width, height, dst, dst);
618 }
619
620 done_unmap:
621 ctx->Driver.UnmapRenderbuffer(ctx, rb);
622 }
623
624 /**
625 * For a packed depth/stencil buffer being read as depth/stencil, just memcpy the
626 * data (possibly swapping 8/24 vs 24/8 as we go).
627 */
628 static GLboolean
fast_read_depth_stencil_pixels(struct gl_context * ctx,GLint x,GLint y,GLsizei width,GLsizei height,GLubyte * dst,int dstStride)629 fast_read_depth_stencil_pixels(struct gl_context *ctx,
630 GLint x, GLint y,
631 GLsizei width, GLsizei height,
632 GLubyte *dst, int dstStride)
633 {
634 struct gl_framebuffer *fb = ctx->ReadBuffer;
635 struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
636 struct gl_renderbuffer *stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
637 GLubyte *map;
638 int stride, i;
639
640 if (rb != stencilRb)
641 return GL_FALSE;
642
643 if (rb->Format != MESA_FORMAT_S8_UINT_Z24_UNORM &&
644 rb->Format != MESA_FORMAT_Z24_UNORM_S8_UINT)
645 return GL_FALSE;
646
647 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT,
648 &map, &stride);
649 if (!map) {
650 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
651 return GL_TRUE; /* don't bother trying the slow path */
652 }
653
654 for (i = 0; i < height; i++) {
655 _mesa_unpack_uint_24_8_depth_stencil_row(rb->Format, width,
656 map, (GLuint *)dst);
657 map += stride;
658 dst += dstStride;
659 }
660
661 ctx->Driver.UnmapRenderbuffer(ctx, rb);
662
663 return GL_TRUE;
664 }
665
666
667 /**
668 * For non-float-depth and stencil buffers being read as 24/8 depth/stencil,
669 * copy the integer data directly instead of converting depth to float and
670 * re-packing.
671 */
672 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)673 fast_read_depth_stencil_pixels_separate(struct gl_context *ctx,
674 GLint x, GLint y,
675 GLsizei width, GLsizei height,
676 uint32_t *dst, int dstStride)
677 {
678 struct gl_framebuffer *fb = ctx->ReadBuffer;
679 struct gl_renderbuffer *depthRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
680 struct gl_renderbuffer *stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
681 GLubyte *depthMap, *stencilMap, *stencilVals;
682 int depthStride, stencilStride, i, j;
683
684 if (_mesa_get_format_datatype(depthRb->Format) != GL_UNSIGNED_NORMALIZED)
685 return GL_FALSE;
686
687 ctx->Driver.MapRenderbuffer(ctx, depthRb, x, y, width, height,
688 GL_MAP_READ_BIT, &depthMap, &depthStride);
689 if (!depthMap) {
690 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
691 return GL_TRUE; /* don't bother trying the slow path */
692 }
693
694 ctx->Driver.MapRenderbuffer(ctx, stencilRb, x, y, width, height,
695 GL_MAP_READ_BIT, &stencilMap, &stencilStride);
696 if (!stencilMap) {
697 ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
698 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
699 return GL_TRUE; /* don't bother trying the slow path */
700 }
701
702 stencilVals = malloc(width * sizeof(GLubyte));
703
704 if (stencilVals) {
705 for (j = 0; j < height; j++) {
706 _mesa_unpack_uint_z_row(depthRb->Format, width, depthMap, dst);
707 _mesa_unpack_ubyte_stencil_row(stencilRb->Format, width,
708 stencilMap, stencilVals);
709
710 for (i = 0; i < width; i++) {
711 dst[i] = (dst[i] & 0xffffff00) | stencilVals[i];
712 }
713
714 depthMap += depthStride;
715 stencilMap += stencilStride;
716 dst += dstStride / 4;
717 }
718 }
719 else {
720 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
721 }
722
723 free(stencilVals);
724
725 ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
726 ctx->Driver.UnmapRenderbuffer(ctx, stencilRb);
727
728 return GL_TRUE;
729 }
730
731 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)732 slow_read_depth_stencil_pixels_separate(struct gl_context *ctx,
733 GLint x, GLint y,
734 GLsizei width, GLsizei height,
735 GLenum type,
736 const struct gl_pixelstore_attrib *packing,
737 GLubyte *dst, int dstStride)
738 {
739 struct gl_framebuffer *fb = ctx->ReadBuffer;
740 struct gl_renderbuffer *depthRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
741 struct gl_renderbuffer *stencilRb = fb->Attachment[BUFFER_STENCIL].Renderbuffer;
742 GLubyte *depthMap, *stencilMap;
743 int depthStride, stencilStride, j;
744 GLubyte *stencilVals;
745 GLfloat *depthVals;
746
747
748 /* The depth and stencil buffers might be separate, or a single buffer.
749 * If one buffer, only map it once.
750 */
751 ctx->Driver.MapRenderbuffer(ctx, depthRb, x, y, width, height,
752 GL_MAP_READ_BIT, &depthMap, &depthStride);
753 if (!depthMap) {
754 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
755 return;
756 }
757
758 if (stencilRb != depthRb) {
759 ctx->Driver.MapRenderbuffer(ctx, stencilRb, x, y, width, height,
760 GL_MAP_READ_BIT, &stencilMap,
761 &stencilStride);
762 if (!stencilMap) {
763 ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
764 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
765 return;
766 }
767 }
768 else {
769 stencilMap = depthMap;
770 stencilStride = depthStride;
771 }
772
773 stencilVals = malloc(width * sizeof(GLubyte));
774 depthVals = malloc(width * sizeof(GLfloat));
775
776 if (stencilVals && depthVals) {
777 for (j = 0; j < height; j++) {
778 _mesa_unpack_float_z_row(depthRb->Format, width, depthMap, depthVals);
779 _mesa_unpack_ubyte_stencil_row(stencilRb->Format, width,
780 stencilMap, stencilVals);
781
782 _mesa_pack_depth_stencil_span(ctx, width, type, (GLuint *)dst,
783 depthVals, stencilVals, packing);
784
785 depthMap += depthStride;
786 stencilMap += stencilStride;
787 dst += dstStride;
788 }
789 }
790 else {
791 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
792 }
793
794 free(stencilVals);
795 free(depthVals);
796
797 ctx->Driver.UnmapRenderbuffer(ctx, depthRb);
798 if (stencilRb != depthRb) {
799 ctx->Driver.UnmapRenderbuffer(ctx, stencilRb);
800 }
801 }
802
803
804 /**
805 * Read combined depth/stencil values.
806 * We'll have already done error checking to be sure the expected
807 * depth and stencil buffers really exist.
808 */
809 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)810 read_depth_stencil_pixels(struct gl_context *ctx,
811 GLint x, GLint y,
812 GLsizei width, GLsizei height,
813 GLenum type, GLvoid *pixels,
814 const struct gl_pixelstore_attrib *packing )
815 {
816 const GLboolean scaleOrBias
817 = ctx->Pixel.DepthScale != 1.0F || ctx->Pixel.DepthBias != 0.0F;
818 const GLboolean stencilTransfer = ctx->Pixel.IndexShift
819 || ctx->Pixel.IndexOffset || ctx->Pixel.MapStencilFlag;
820 GLubyte *dst;
821 int dstStride;
822
823 dst = (GLubyte *) _mesa_image_address2d(packing, pixels,
824 width, height,
825 GL_DEPTH_STENCIL_EXT,
826 type, 0, 0);
827 dstStride = _mesa_image_row_stride(packing, width,
828 GL_DEPTH_STENCIL_EXT, type);
829
830 /* Fast 24/8 reads. */
831 if (type == GL_UNSIGNED_INT_24_8 &&
832 !scaleOrBias && !stencilTransfer && !packing->SwapBytes) {
833 if (fast_read_depth_stencil_pixels(ctx, x, y, width, height,
834 dst, dstStride))
835 return;
836
837 if (fast_read_depth_stencil_pixels_separate(ctx, x, y, width, height,
838 (uint32_t *)dst, dstStride))
839 return;
840 }
841
842 slow_read_depth_stencil_pixels_separate(ctx, x, y, width, height,
843 type, packing,
844 dst, dstStride);
845 }
846
847
848
849 /**
850 * Software fallback routine for ctx->Driver.ReadPixels().
851 * By time we get here, all error checking will have been done.
852 */
853 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)854 _mesa_readpixels(struct gl_context *ctx,
855 GLint x, GLint y, GLsizei width, GLsizei height,
856 GLenum format, GLenum type,
857 const struct gl_pixelstore_attrib *packing,
858 GLvoid *pixels)
859 {
860 if (ctx->NewState)
861 _mesa_update_state(ctx);
862
863 pixels = _mesa_map_pbo_dest(ctx, packing, pixels);
864
865 if (pixels) {
866 /* Try memcpy first. */
867 if (readpixels_memcpy(ctx, x, y, width, height, format, type,
868 pixels, packing)) {
869 _mesa_unmap_pbo_dest(ctx, packing);
870 return;
871 }
872
873 /* Otherwise take the slow path. */
874 switch (format) {
875 case GL_STENCIL_INDEX:
876 read_stencil_pixels(ctx, x, y, width, height, type, pixels,
877 packing);
878 break;
879 case GL_DEPTH_COMPONENT:
880 read_depth_pixels(ctx, x, y, width, height, type, pixels,
881 packing);
882 break;
883 case GL_DEPTH_STENCIL_EXT:
884 read_depth_stencil_pixels(ctx, x, y, width, height, type, pixels,
885 packing);
886 break;
887 default:
888 /* all other formats should be color formats */
889 read_rgba_pixels(ctx, x, y, width, height, format, type, pixels,
890 packing);
891 }
892
893 _mesa_unmap_pbo_dest(ctx, packing);
894 }
895 }
896
897
898 static GLenum
read_pixels_es3_error_check(GLenum format,GLenum type,const struct gl_renderbuffer * rb)899 read_pixels_es3_error_check(GLenum format, GLenum type,
900 const struct gl_renderbuffer *rb)
901 {
902 const GLenum internalFormat = rb->InternalFormat;
903 const GLenum data_type = _mesa_get_format_datatype(rb->Format);
904 GLboolean is_unsigned_int = GL_FALSE;
905 GLboolean is_signed_int = GL_FALSE;
906 GLboolean is_float_depth = (internalFormat == GL_DEPTH_COMPONENT32F) ||
907 (internalFormat == GL_DEPTH32F_STENCIL8);
908
909 is_unsigned_int = _mesa_is_enum_format_unsigned_int(internalFormat);
910 if (!is_unsigned_int) {
911 is_signed_int = _mesa_is_enum_format_signed_int(internalFormat);
912 }
913
914 switch (format) {
915 case GL_RGBA:
916 if (type == GL_FLOAT && data_type == GL_FLOAT)
917 return GL_NO_ERROR; /* EXT_color_buffer_float */
918 if (type == GL_UNSIGNED_BYTE && data_type == GL_UNSIGNED_NORMALIZED)
919 return GL_NO_ERROR;
920 if (internalFormat == GL_RGB10_A2 &&
921 type == GL_UNSIGNED_INT_2_10_10_10_REV)
922 return GL_NO_ERROR;
923 if (internalFormat == GL_RGB10_A2UI && type == GL_UNSIGNED_BYTE)
924 return GL_NO_ERROR;
925 break;
926 case GL_BGRA:
927 /* GL_EXT_read_format_bgra */
928 if (type == GL_UNSIGNED_BYTE ||
929 type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
930 type == GL_UNSIGNED_SHORT_1_5_5_5_REV)
931 return GL_NO_ERROR;
932 break;
933 case GL_RGBA_INTEGER:
934 if ((is_signed_int && type == GL_INT) ||
935 (is_unsigned_int && type == GL_UNSIGNED_INT))
936 return GL_NO_ERROR;
937 break;
938 case GL_DEPTH_STENCIL:
939 switch (type) {
940 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
941 if (is_float_depth)
942 return GL_NO_ERROR;
943 break;
944 case GL_UNSIGNED_INT_24_8:
945 if (!is_float_depth)
946 return GL_NO_ERROR;
947 break;
948 default:
949 return GL_INVALID_ENUM;
950 }
951 break;
952 case GL_DEPTH_COMPONENT:
953 switch (type) {
954 case GL_FLOAT:
955 if (is_float_depth)
956 return GL_NO_ERROR;
957 break;
958 case GL_UNSIGNED_SHORT:
959 case GL_UNSIGNED_INT:
960 case GL_UNSIGNED_INT_24_8:
961 if (!is_float_depth)
962 return GL_NO_ERROR;
963 break;
964 default:
965 return GL_INVALID_ENUM;
966 }
967 break;
968 case GL_STENCIL_INDEX:
969 switch (type) {
970 case GL_UNSIGNED_BYTE:
971 return GL_NO_ERROR;
972 default:
973 return GL_INVALID_ENUM;
974 }
975 break;
976 }
977
978 return GL_INVALID_OPERATION;
979 }
980
981
982 void GLAPIENTRY
_mesa_ReadnPixelsARB(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,GLvoid * pixels)983 _mesa_ReadnPixelsARB( GLint x, GLint y, GLsizei width, GLsizei height,
984 GLenum format, GLenum type, GLsizei bufSize,
985 GLvoid *pixels )
986 {
987 GLenum err = GL_NO_ERROR;
988 struct gl_renderbuffer *rb;
989 struct gl_pixelstore_attrib clippedPacking;
990
991 GET_CURRENT_CONTEXT(ctx);
992
993 FLUSH_VERTICES(ctx, 0);
994 FLUSH_CURRENT(ctx, 0);
995
996 if (MESA_VERBOSE & VERBOSE_API)
997 _mesa_debug(ctx, "glReadPixels(%d, %d, %s, %s, %p)\n",
998 width, height,
999 _mesa_enum_to_string(format),
1000 _mesa_enum_to_string(type),
1001 pixels);
1002
1003 if (width < 0 || height < 0) {
1004 _mesa_error( ctx, GL_INVALID_VALUE,
1005 "glReadPixels(width=%d height=%d)", width, height );
1006 return;
1007 }
1008
1009 if (ctx->NewState)
1010 _mesa_update_state(ctx);
1011
1012 if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
1013 _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
1014 "glReadPixels(incomplete framebuffer)" );
1015 return;
1016 }
1017
1018 rb = _mesa_get_read_renderbuffer_for_format(ctx, format);
1019 if (rb == NULL) {
1020 _mesa_error(ctx, GL_INVALID_OPERATION,
1021 "glReadPixels(read buffer)");
1022 return;
1023 }
1024
1025 /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
1026 * combinations of format and type that can be used.
1027 *
1028 * Technically, only two combinations are actually allowed:
1029 * GL_RGBA/GL_UNSIGNED_BYTE, and some implementation-specific internal
1030 * preferred combination. This code doesn't know what that preferred
1031 * combination is, and Mesa can handle anything valid. Just work instead.
1032 */
1033 if (_mesa_is_gles(ctx)) {
1034 if (ctx->API == API_OPENGLES2 &&
1035 _mesa_is_color_format(format) &&
1036 _mesa_get_color_read_format(ctx) == format &&
1037 _mesa_get_color_read_type(ctx) == type) {
1038 err = GL_NO_ERROR;
1039 } else if (ctx->Version < 30) {
1040 err = _mesa_es_error_check_format_and_type(ctx, format, type, 2);
1041 if (err == GL_NO_ERROR) {
1042 if (type == GL_FLOAT || type == GL_HALF_FLOAT_OES) {
1043 err = GL_INVALID_OPERATION;
1044 }
1045 }
1046 } else {
1047 err = read_pixels_es3_error_check(format, type, rb);
1048 }
1049
1050 if (err != GL_NO_ERROR) {
1051 _mesa_error(ctx, err, "glReadPixels(invalid format %s and/or type %s)",
1052 _mesa_enum_to_string(format),
1053 _mesa_enum_to_string(type));
1054 return;
1055 }
1056 }
1057
1058 err = _mesa_error_check_format_and_type(ctx, format, type);
1059 if (err != GL_NO_ERROR) {
1060 _mesa_error(ctx, err, "glReadPixels(invalid format %s and/or type %s)",
1061 _mesa_enum_to_string(format),
1062 _mesa_enum_to_string(type));
1063 return;
1064 }
1065
1066 if (_mesa_is_user_fbo(ctx->ReadBuffer) &&
1067 ctx->ReadBuffer->Visual.samples > 0) {
1068 _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(multisample FBO)");
1069 return;
1070 }
1071
1072 if (!_mesa_source_buffer_exists(ctx, format)) {
1073 _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(no readbuffer)");
1074 return;
1075 }
1076
1077 /* Check that the destination format and source buffer are both
1078 * integer-valued or both non-integer-valued.
1079 */
1080 if (ctx->Extensions.EXT_texture_integer && _mesa_is_color_format(format)) {
1081 const struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
1082 const GLboolean srcInteger = _mesa_is_format_integer_color(rb->Format);
1083 const GLboolean dstInteger = _mesa_is_enum_format_integer(format);
1084 if (dstInteger != srcInteger) {
1085 _mesa_error(ctx, GL_INVALID_OPERATION,
1086 "glReadPixels(integer / non-integer format mismatch");
1087 return;
1088 }
1089 }
1090
1091 /* Do all needed clipping here, so that we can forget about it later */
1092 clippedPacking = ctx->Pack;
1093 if (!_mesa_clip_readpixels(ctx, &x, &y, &width, &height, &clippedPacking))
1094 return; /* nothing to do */
1095
1096 if (!_mesa_validate_pbo_access(2, &ctx->Pack, width, height, 1,
1097 format, type, bufSize, pixels)) {
1098 if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
1099 _mesa_error(ctx, GL_INVALID_OPERATION,
1100 "glReadPixels(out of bounds PBO access)");
1101 } else {
1102 _mesa_error(ctx, GL_INVALID_OPERATION,
1103 "glReadnPixelsARB(out of bounds access:"
1104 " bufSize (%d) is too small)", bufSize);
1105 }
1106 return;
1107 }
1108
1109 if (_mesa_is_bufferobj(ctx->Pack.BufferObj) &&
1110 _mesa_check_disallowed_mapping(ctx->Pack.BufferObj)) {
1111 /* buffer is mapped - that's an error */
1112 _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(PBO is mapped)");
1113 return;
1114 }
1115
1116 ctx->Driver.ReadPixels(ctx, x, y, width, height,
1117 format, type, &clippedPacking, pixels);
1118 }
1119
1120 void GLAPIENTRY
_mesa_ReadPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLvoid * pixels)1121 _mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,
1122 GLenum format, GLenum type, GLvoid *pixels )
1123 {
1124 _mesa_ReadnPixelsARB(x, y, width, height, format, type, INT_MAX, pixels);
1125 }
1126