2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 #include "main/glheader.h"
27 #include "main/bufferobj.h"
28 #include "main/colormac.h"
29 #include "main/condrender.h"
30 #include "main/context.h"
31 #include "main/image.h"
32 #include "main/imports.h"
33 #include "main/macros.h"
34 #include "main/pack.h"
36 #include "main/pixeltransfer.h"
37 #include "main/state.h"
39 #include "s_context.h"
41 #include "s_stencil.h"
46 * Handle a common case of drawing GL_RGB/GL_UNSIGNED_BYTE into a
47 * MESA_FORMAT_XRGB888 or MESA_FORMAT_ARGB888 renderbuffer.
50 fast_draw_rgb_ubyte_pixels(struct gl_context
*ctx
,
51 struct gl_renderbuffer
*rb
,
53 GLsizei width
, GLsizei height
,
54 const struct gl_pixelstore_attrib
*unpack
,
57 const GLubyte
*src
= (const GLubyte
*)
58 _mesa_image_address2d(unpack
, pixels
, width
,
59 height
, GL_RGB
, GL_UNSIGNED_BYTE
, 0, 0);
60 const GLint srcRowStride
= _mesa_image_row_stride(unpack
, width
,
61 GL_RGB
, GL_UNSIGNED_BYTE
);
66 ctx
->Driver
.MapRenderbuffer(ctx
, rb
, x
, y
, width
, height
,
67 GL_MAP_WRITE_BIT
, &dst
, &dstRowStride
);
70 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDrawPixels");
74 if (ctx
->Pixel
.ZoomY
== -1.0f
) {
75 dst
= dst
+ (height
- 1) * dstRowStride
;
76 dstRowStride
= -dstRowStride
;
79 for (i
= 0; i
< height
; i
++) {
80 GLuint
*dst4
= (GLuint
*) dst
;
81 for (j
= 0; j
< width
; j
++) {
82 dst4
[j
] = PACK_COLOR_8888(0xff, src
[j
*3+0], src
[j
*3+1], src
[j
*3+2]);
88 ctx
->Driver
.UnmapRenderbuffer(ctx
, rb
);
93 * Handle a common case of drawing GL_RGBA/GL_UNSIGNED_BYTE into a
94 * MESA_FORMAT_ARGB888 or MESA_FORMAT_xRGB888 renderbuffer.
97 fast_draw_rgba_ubyte_pixels(struct gl_context
*ctx
,
98 struct gl_renderbuffer
*rb
,
100 GLsizei width
, GLsizei height
,
101 const struct gl_pixelstore_attrib
*unpack
,
102 const GLvoid
*pixels
)
104 const GLubyte
*src
= (const GLubyte
*)
105 _mesa_image_address2d(unpack
, pixels
, width
,
106 height
, GL_RGBA
, GL_UNSIGNED_BYTE
, 0, 0);
107 const GLint srcRowStride
=
108 _mesa_image_row_stride(unpack
, width
, GL_RGBA
, GL_UNSIGNED_BYTE
);
113 ctx
->Driver
.MapRenderbuffer(ctx
, rb
, x
, y
, width
, height
,
114 GL_MAP_WRITE_BIT
, &dst
, &dstRowStride
);
117 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDrawPixels");
121 if (ctx
->Pixel
.ZoomY
== -1.0f
) {
122 dst
= dst
+ (height
- 1) * dstRowStride
;
123 dstRowStride
= -dstRowStride
;
126 for (i
= 0; i
< height
; i
++) {
127 GLuint
*dst4
= (GLuint
*) dst
;
128 for (j
= 0; j
< width
; j
++) {
129 dst4
[j
] = PACK_COLOR_8888(src
[j
*4+3], src
[j
*4+0],
130 src
[j
*4+1], src
[j
*4+2]);
136 ctx
->Driver
.UnmapRenderbuffer(ctx
, rb
);
141 * Handle a common case of drawing a format/type combination that
142 * exactly matches the renderbuffer format.
145 fast_draw_generic_pixels(struct gl_context
*ctx
,
146 struct gl_renderbuffer
*rb
,
148 GLsizei width
, GLsizei height
,
149 GLenum format
, GLenum type
,
150 const struct gl_pixelstore_attrib
*unpack
,
151 const GLvoid
*pixels
)
153 const GLubyte
*src
= (const GLubyte
*)
154 _mesa_image_address2d(unpack
, pixels
, width
,
155 height
, format
, type
, 0, 0);
156 const GLint srcRowStride
=
157 _mesa_image_row_stride(unpack
, width
, format
, type
);
158 const GLint rowLength
= width
* _mesa_get_format_bytes(rb
->Format
);
163 ctx
->Driver
.MapRenderbuffer(ctx
, rb
, x
, y
, width
, height
,
164 GL_MAP_WRITE_BIT
, &dst
, &dstRowStride
);
167 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDrawPixels");
171 if (ctx
->Pixel
.ZoomY
== -1.0f
) {
172 dst
= dst
+ (height
- 1) * dstRowStride
;
173 dstRowStride
= -dstRowStride
;
176 for (i
= 0; i
< height
; i
++) {
177 memcpy(dst
, src
, rowLength
);
182 ctx
->Driver
.UnmapRenderbuffer(ctx
, rb
);
187 * Try to do a fast and simple RGB(a) glDrawPixels.
188 * Return: GL_TRUE if success, GL_FALSE if slow path must be used instead
191 fast_draw_rgba_pixels(struct gl_context
*ctx
, GLint x
, GLint y
,
192 GLsizei width
, GLsizei height
,
193 GLenum format
, GLenum type
,
194 const struct gl_pixelstore_attrib
*userUnpack
,
195 const GLvoid
*pixels
)
197 struct gl_renderbuffer
*rb
= ctx
->DrawBuffer
->_ColorDrawBuffers
[0];
198 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
199 struct gl_pixelstore_attrib unpack
;
202 return GL_TRUE
; /* no-op */
204 if (ctx
->DrawBuffer
->_NumColorDrawBuffers
> 1 ||
205 (swrast
->_RasterMask
& ~CLIP_BIT
) ||
206 ctx
->Texture
._EnabledCoordUnits
||
207 userUnpack
->SwapBytes
||
208 ctx
->Pixel
.ZoomX
!= 1.0f
||
209 fabsf(ctx
->Pixel
.ZoomY
) != 1.0f
||
210 ctx
->_ImageTransferState
) {
211 /* can't handle any of those conditions */
215 unpack
= *userUnpack
;
218 if (!_mesa_clip_drawpixels(ctx
, &x
, &y
, &width
, &height
, &unpack
)) {
219 /* image was completely clipped: no-op, all done */
223 if (format
== GL_RGB
&&
224 type
== GL_UNSIGNED_BYTE
&&
225 (rb
->Format
== MESA_FORMAT_XRGB8888
||
226 rb
->Format
== MESA_FORMAT_ARGB8888
)) {
227 fast_draw_rgb_ubyte_pixels(ctx
, rb
, x
, y
, width
, height
,
232 if (format
== GL_RGBA
&&
233 type
== GL_UNSIGNED_BYTE
&&
234 (rb
->Format
== MESA_FORMAT_XRGB8888
||
235 rb
->Format
== MESA_FORMAT_ARGB8888
)) {
236 fast_draw_rgba_ubyte_pixels(ctx
, rb
, x
, y
, width
, height
,
241 if (_mesa_format_matches_format_and_type(rb
->Format
, format
, type
)) {
242 fast_draw_generic_pixels(ctx
, rb
, x
, y
, width
, height
,
243 format
, type
, &unpack
, pixels
);
247 /* can't handle this pixel format and/or data type */
254 * Draw stencil image.
257 draw_stencil_pixels( struct gl_context
*ctx
, GLint x
, GLint y
,
258 GLsizei width
, GLsizei height
,
260 const struct gl_pixelstore_attrib
*unpack
,
261 const GLvoid
*pixels
)
263 const GLboolean zoom
= ctx
->Pixel
.ZoomX
!= 1.0 || ctx
->Pixel
.ZoomY
!= 1.0;
264 const GLenum destType
= GL_UNSIGNED_BYTE
;
267 /* if width > MAX_WIDTH, have to process image in chunks */
269 while (skipPixels
< width
) {
270 const GLint spanX
= x
+ skipPixels
;
271 const GLint spanWidth
= MIN2(width
- skipPixels
, MAX_WIDTH
);
273 for (row
= 0; row
< height
; row
++) {
274 const GLint spanY
= y
+ row
;
275 GLubyte values
[MAX_WIDTH
];
276 const GLvoid
*source
= _mesa_image_address2d(unpack
, pixels
,
278 GL_STENCIL_INDEX
, type
,
280 _mesa_unpack_stencil_span(ctx
, spanWidth
, destType
, values
,
281 type
, source
, unpack
,
282 ctx
->_ImageTransferState
);
284 _swrast_write_zoomed_stencil_span(ctx
, x
, y
, spanWidth
,
285 spanX
, spanY
, values
);
288 _swrast_write_stencil_span(ctx
, spanWidth
, spanX
, spanY
, values
);
291 skipPixels
+= spanWidth
;
300 draw_depth_pixels( struct gl_context
*ctx
, GLint x
, GLint y
,
301 GLsizei width
, GLsizei height
,
303 const struct gl_pixelstore_attrib
*unpack
,
304 const GLvoid
*pixels
)
306 const GLboolean scaleOrBias
307 = ctx
->Pixel
.DepthScale
!= 1.0 || ctx
->Pixel
.DepthBias
!= 0.0;
308 const GLboolean zoom
= ctx
->Pixel
.ZoomX
!= 1.0 || ctx
->Pixel
.ZoomY
!= 1.0;
311 INIT_SPAN(span
, GL_BITMAP
);
312 span
.arrayMask
= SPAN_Z
;
313 _swrast_span_default_attribs(ctx
, &span
);
315 if (type
== GL_UNSIGNED_SHORT
316 && ctx
->DrawBuffer
->Visual
.depthBits
== 16
319 && width
<= MAX_WIDTH
320 && !unpack
->SwapBytes
) {
321 /* Special case: directly write 16-bit depth values */
323 for (row
= 0; row
< height
; row
++) {
324 const GLushort
*zSrc
= (const GLushort
*)
325 _mesa_image_address2d(unpack
, pixels
, width
, height
,
326 GL_DEPTH_COMPONENT
, type
, row
, 0);
328 for (i
= 0; i
< width
; i
++)
329 span
.array
->z
[i
] = zSrc
[i
];
333 _swrast_write_rgba_span(ctx
, &span
);
336 else if (type
== GL_UNSIGNED_INT
339 && width
<= MAX_WIDTH
340 && !unpack
->SwapBytes
) {
341 /* Special case: shift 32-bit values down to Visual.depthBits */
342 const GLint shift
= 32 - ctx
->DrawBuffer
->Visual
.depthBits
;
344 for (row
= 0; row
< height
; row
++) {
345 const GLuint
*zSrc
= (const GLuint
*)
346 _mesa_image_address2d(unpack
, pixels
, width
, height
,
347 GL_DEPTH_COMPONENT
, type
, row
, 0);
349 memcpy(span
.array
->z
, zSrc
, width
* sizeof(GLuint
));
353 for (col
= 0; col
< width
; col
++)
354 span
.array
->z
[col
] = zSrc
[col
] >> shift
;
359 _swrast_write_rgba_span(ctx
, &span
);
364 const GLuint depthMax
= ctx
->DrawBuffer
->_DepthMax
;
365 GLint skipPixels
= 0;
367 /* in case width > MAX_WIDTH do the copy in chunks */
368 while (skipPixels
< width
) {
369 const GLint spanWidth
= MIN2(width
- skipPixels
, MAX_WIDTH
);
371 ASSERT(span
.end
<= MAX_WIDTH
);
372 for (row
= 0; row
< height
; row
++) {
373 const GLvoid
*zSrc
= _mesa_image_address2d(unpack
,
374 pixels
, width
, height
,
375 GL_DEPTH_COMPONENT
, type
,
378 /* Set these for each row since the _swrast_write_* function may
379 * change them while clipping.
381 span
.x
= x
+ skipPixels
;
383 span
.end
= spanWidth
;
385 _mesa_unpack_depth_span(ctx
, spanWidth
,
386 GL_UNSIGNED_INT
, span
.array
->z
, depthMax
,
389 _swrast_write_zoomed_depth_span(ctx
, x
, y
, &span
);
392 _swrast_write_rgba_span(ctx
, &span
);
395 skipPixels
+= spanWidth
;
406 draw_rgba_pixels( struct gl_context
*ctx
, GLint x
, GLint y
,
407 GLsizei width
, GLsizei height
,
408 GLenum format
, GLenum type
,
409 const struct gl_pixelstore_attrib
*unpack
,
410 const GLvoid
*pixels
)
412 const GLint imgX
= x
, imgY
= y
;
413 const GLboolean zoom
= ctx
->Pixel
.ZoomX
!=1.0 || ctx
->Pixel
.ZoomY
!=1.0;
414 GLfloat
*convImage
= NULL
;
415 GLbitfield transferOps
= ctx
->_ImageTransferState
;
418 /* Try an optimized glDrawPixels first */
419 if (fast_draw_rgba_pixels(ctx
, x
, y
, width
, height
, format
, type
,
424 swrast_render_start(ctx
);
426 INIT_SPAN(span
, GL_BITMAP
);
427 _swrast_span_default_attribs(ctx
, &span
);
428 span
.arrayMask
= SPAN_RGBA
;
429 span
.arrayAttribs
= FRAG_BIT_COL0
; /* we're fill in COL0 attrib values */
431 if (ctx
->DrawBuffer
->_NumColorDrawBuffers
> 0 &&
432 ctx
->DrawBuffer
->_ColorDrawBuffers
[0]->DataType
!= GL_FLOAT
&&
433 ctx
->Color
.ClampFragmentColor
!= GL_FALSE
) {
434 /* need to clamp colors before applying fragment ops */
435 transferOps
|= IMAGE_CLAMP_BIT
;
442 const GLbitfield interpMask
= span
.interpMask
;
443 const GLbitfield arrayMask
= span
.arrayMask
;
444 const GLint srcStride
445 = _mesa_image_row_stride(unpack
, width
, format
, type
);
446 GLint skipPixels
= 0;
447 /* use span array for temp color storage */
448 GLfloat
*rgba
= (GLfloat
*) span
.array
->attribs
[FRAG_ATTRIB_COL0
];
450 /* if the span is wider than MAX_WIDTH we have to do it in chunks */
451 while (skipPixels
< width
) {
452 const GLint spanWidth
= MIN2(width
- skipPixels
, MAX_WIDTH
);
453 const GLubyte
*source
454 = (const GLubyte
*) _mesa_image_address2d(unpack
, pixels
,
455 width
, height
, format
,
456 type
, 0, skipPixels
);
459 for (row
= 0; row
< height
; row
++) {
460 /* get image row as float/RGBA */
461 _mesa_unpack_color_span_float(ctx
, spanWidth
, GL_RGBA
, rgba
,
462 format
, type
, source
, unpack
,
464 /* Set these for each row since the _swrast_write_* functions
465 * may change them while clipping/rendering.
467 span
.array
->ChanType
= GL_FLOAT
;
468 span
.x
= x
+ skipPixels
;
470 span
.end
= spanWidth
;
471 span
.arrayMask
= arrayMask
;
472 span
.interpMask
= interpMask
;
474 _swrast_write_zoomed_rgba_span(ctx
, imgX
, imgY
, &span
, rgba
);
477 _swrast_write_rgba_span(ctx
, &span
);
483 skipPixels
+= spanWidth
;
484 } /* while skipPixels < width */
486 /* XXX this is ugly/temporary, to undo above change */
487 span
.array
->ChanType
= CHAN_TYPE
;
494 swrast_render_finish(ctx
);
499 * Draw depth+stencil values into a MESA_FORAMT_Z24_S8 or MESA_FORMAT_S8_Z24
500 * renderbuffer. No masking, zooming, scaling, etc.
503 fast_draw_depth_stencil(struct gl_context
*ctx
, GLint x
, GLint y
,
504 GLsizei width
, GLsizei height
,
505 const struct gl_pixelstore_attrib
*unpack
,
506 const GLvoid
*pixels
)
508 const GLenum format
= GL_DEPTH_STENCIL_EXT
;
509 const GLenum type
= GL_UNSIGNED_INT_24_8
;
510 struct gl_renderbuffer
*rb
=
511 ctx
->DrawBuffer
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
513 GLint srcRowStride
, dstRowStride
;
516 src
= _mesa_image_address2d(unpack
, pixels
, width
, height
,
518 srcRowStride
= _mesa_image_row_stride(unpack
, width
, format
, type
);
520 dst
= _swrast_pixel_address(rb
, x
, y
);
521 dstRowStride
= rb
->RowStride
* 4;
523 for (i
= 0; i
< height
; i
++) {
524 _mesa_pack_uint_24_8_depth_stencil_row(rb
->Format
, width
,
525 (const GLuint
*) src
, dst
);
534 * This is a bit different from drawing GL_DEPTH_COMPONENT pixels.
535 * The only per-pixel operations that apply are depth scale/bias,
536 * stencil offset/shift, GL_DEPTH_WRITEMASK and GL_STENCIL_WRITEMASK,
538 * Also, only the depth buffer and stencil buffers are touched, not the
542 draw_depth_stencil_pixels(struct gl_context
*ctx
, GLint x
, GLint y
,
543 GLsizei width
, GLsizei height
, GLenum type
,
544 const struct gl_pixelstore_attrib
*unpack
,
545 const GLvoid
*pixels
)
547 const GLint imgX
= x
, imgY
= y
;
548 const GLboolean scaleOrBias
549 = ctx
->Pixel
.DepthScale
!= 1.0 || ctx
->Pixel
.DepthBias
!= 0.0;
550 const GLuint depthMax
= ctx
->DrawBuffer
->_DepthMax
;
551 const GLuint stencilMask
= ctx
->Stencil
.WriteMask
[0];
552 const GLenum stencilType
= GL_UNSIGNED_BYTE
;
553 const GLboolean zoom
= ctx
->Pixel
.ZoomX
!= 1.0 || ctx
->Pixel
.ZoomY
!= 1.0;
554 struct gl_renderbuffer
*depthRb
, *stencilRb
;
555 struct gl_pixelstore_attrib clippedUnpack
= *unpack
;
558 if (!_mesa_clip_drawpixels(ctx
, &x
, &y
, &width
, &height
,
560 /* totally clipped */
565 depthRb
= ctx
->ReadBuffer
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
566 stencilRb
= ctx
->ReadBuffer
->Attachment
[BUFFER_STENCIL
].Renderbuffer
;
570 if (depthRb
== stencilRb
&&
571 (depthRb
->Format
== MESA_FORMAT_Z24_S8
||
572 depthRb
->Format
== MESA_FORMAT_S8_Z24
) &&
573 type
== GL_UNSIGNED_INT_24_8
&&
577 (stencilMask
& 0xff) == 0xff) {
578 fast_draw_depth_stencil(ctx
, x
, y
, width
, height
,
579 &clippedUnpack
, pixels
);
582 /* sub-optimal cases:
583 * Separate depth/stencil buffers, or pixel transfer ops required.
585 /* XXX need to handle very wide images (skippixels) */
588 depthRb
= ctx
->DrawBuffer
->_DepthBuffer
;
590 for (i
= 0; i
< height
; i
++) {
591 const GLuint
*depthStencilSrc
= (const GLuint
*)
592 _mesa_image_address2d(&clippedUnpack
, pixels
, width
, height
,
593 GL_DEPTH_STENCIL_EXT
, type
, i
, 0);
595 if (ctx
->Depth
.Mask
) {
596 if (!scaleOrBias
&& ctx
->DrawBuffer
->Visual
.depthBits
== 24 &&
597 type
== GL_UNSIGNED_INT_24_8
) {
598 /* fast path 24-bit zbuffer */
599 GLuint zValues
[MAX_WIDTH
];
601 ASSERT(depthRb
->DataType
== GL_UNSIGNED_INT
);
602 for (j
= 0; j
< width
; j
++) {
603 zValues
[j
] = depthStencilSrc
[j
] >> 8;
606 _swrast_write_zoomed_z_span(ctx
, imgX
, imgY
, width
,
609 depthRb
->PutRow(ctx
, depthRb
, width
, x
, y
+ i
, zValues
,NULL
);
611 else if (!scaleOrBias
&& ctx
->DrawBuffer
->Visual
.depthBits
== 16 &&
612 type
== GL_UNSIGNED_INT_24_8
) {
613 /* fast path 16-bit zbuffer */
614 GLushort zValues
[MAX_WIDTH
];
616 ASSERT(depthRb
->DataType
== GL_UNSIGNED_SHORT
);
617 for (j
= 0; j
< width
; j
++) {
618 zValues
[j
] = depthStencilSrc
[j
] >> 16;
621 _swrast_write_zoomed_z_span(ctx
, imgX
, imgY
, width
,
624 depthRb
->PutRow(ctx
, depthRb
, width
, x
, y
+ i
, zValues
,NULL
);
628 GLuint zValues
[MAX_WIDTH
]; /* 16 or 32-bit Z value storage */
629 _mesa_unpack_depth_span(ctx
, width
,
630 depthRb
->DataType
, zValues
, depthMax
,
631 type
, depthStencilSrc
, &clippedUnpack
);
633 _swrast_write_zoomed_z_span(ctx
, imgX
, imgY
, width
, x
,
637 depthRb
->PutRow(ctx
, depthRb
, width
, x
, y
+ i
, zValues
,NULL
);
642 if (stencilMask
!= 0x0) {
643 GLubyte stencilValues
[MAX_WIDTH
];
644 /* get stencil values, with shift/offset/mapping */
645 _mesa_unpack_stencil_span(ctx
, width
, stencilType
, stencilValues
,
646 type
, depthStencilSrc
, &clippedUnpack
,
647 ctx
->_ImageTransferState
);
649 _swrast_write_zoomed_stencil_span(ctx
, imgX
, imgY
, width
,
650 x
, y
+ i
, stencilValues
);
652 _swrast_write_stencil_span(ctx
, width
, x
, y
+ i
, stencilValues
);
660 * Execute software-based glDrawPixels.
661 * By time we get here, all error checking will have been done.
664 _swrast_DrawPixels( struct gl_context
*ctx
,
666 GLsizei width
, GLsizei height
,
667 GLenum format
, GLenum type
,
668 const struct gl_pixelstore_attrib
*unpack
,
669 const GLvoid
*pixels
)
671 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
672 GLboolean save_vp_override
= ctx
->VertexProgram
._Overriden
;
674 if (!_mesa_check_conditional_render(ctx
))
675 return; /* don't draw */
677 /* We are creating fragments directly, without going through vertex
680 * This override flag tells the fragment processing code that its input
681 * comes from a non-standard source, and it may therefore not rely on
682 * optimizations that assume e.g. constant color if there is no color
685 _mesa_set_vp_override(ctx
, GL_TRUE
);
688 _mesa_update_state(ctx
);
690 if (swrast
->NewState
)
691 _swrast_validate_derived( ctx
);
693 pixels
= _mesa_map_pbo_source(ctx
, unpack
, pixels
);
695 _mesa_set_vp_override(ctx
, save_vp_override
);
700 * By time we get here, all error checking should have been done.
703 case GL_STENCIL_INDEX
:
704 swrast_render_start(ctx
);
705 draw_stencil_pixels( ctx
, x
, y
, width
, height
, type
, unpack
, pixels
);
706 swrast_render_finish(ctx
);
708 case GL_DEPTH_COMPONENT
:
709 swrast_render_start(ctx
);
710 draw_depth_pixels( ctx
, x
, y
, width
, height
, type
, unpack
, pixels
);
711 swrast_render_finish(ctx
);
713 case GL_DEPTH_STENCIL_EXT
:
714 swrast_render_start(ctx
);
715 draw_depth_stencil_pixels(ctx
, x
, y
, width
, height
, type
, unpack
, pixels
);
716 swrast_render_finish(ctx
);
719 /* all other formats should be color formats */
720 draw_rgba_pixels(ctx
, x
, y
, width
, height
, format
, type
, unpack
, pixels
);
723 _mesa_set_vp_override(ctx
, save_vp_override
);
725 _mesa_unmap_pbo_source(ctx
, unpack
);