2 * Mesa 3-D graphics library
4 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
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:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
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.
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/format_pack.h"
32 #include "main/format_utils.h"
33 #include "main/glformats.h"
34 #include "main/image.h"
35 #include "main/imports.h"
36 #include "main/macros.h"
37 #include "main/pack.h"
39 #include "main/pixeltransfer.h"
40 #include "main/state.h"
42 #include "s_context.h"
44 #include "s_stencil.h"
49 * Handle a common case of drawing GL_RGB/GL_UNSIGNED_BYTE into a
50 * MESA_FORMAT_XRGB888 or MESA_FORMAT_ARGB888 renderbuffer.
53 fast_draw_rgb_ubyte_pixels(struct gl_context
*ctx
,
54 struct gl_renderbuffer
*rb
,
56 GLsizei width
, GLsizei height
,
57 const struct gl_pixelstore_attrib
*unpack
,
61 const GLubyte
*src
= (const GLubyte
*)
62 _mesa_image_address2d(unpack
, pixels
, width
,
63 height
, GL_RGB
, GL_UNSIGNED_BYTE
, 0, 0);
64 const GLint srcRowStride
= _mesa_image_row_stride(unpack
, width
,
65 GL_RGB
, GL_UNSIGNED_BYTE
);
70 ctx
->Driver
.MapRenderbuffer(ctx
, rb
, x
, y
, width
, height
,
71 GL_MAP_WRITE_BIT
, &dst
, &dstRowStride
,
75 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDrawPixels");
79 if (ctx
->Pixel
.ZoomY
== -1.0f
) {
80 dst
= dst
+ (height
- 1) * dstRowStride
;
81 dstRowStride
= -dstRowStride
;
84 for (i
= 0; i
< height
; i
++) {
85 GLuint
*dst4
= (GLuint
*) dst
;
86 for (j
= 0; j
< width
; j
++) {
87 dst4
[j
] = PACK_COLOR_8888(0xff, src
[j
*3+0], src
[j
*3+1], src
[j
*3+2]);
93 ctx
->Driver
.UnmapRenderbuffer(ctx
, rb
);
98 * Handle a common case of drawing GL_RGBA/GL_UNSIGNED_BYTE into a
99 * MESA_FORMAT_ARGB888 or MESA_FORMAT_xRGB888 renderbuffer.
102 fast_draw_rgba_ubyte_pixels(struct gl_context
*ctx
,
103 struct gl_renderbuffer
*rb
,
105 GLsizei width
, GLsizei height
,
106 const struct gl_pixelstore_attrib
*unpack
,
107 const GLvoid
*pixels
,
110 const GLubyte
*src
= (const GLubyte
*)
111 _mesa_image_address2d(unpack
, pixels
, width
,
112 height
, GL_RGBA
, GL_UNSIGNED_BYTE
, 0, 0);
113 const GLint srcRowStride
=
114 _mesa_image_row_stride(unpack
, width
, GL_RGBA
, GL_UNSIGNED_BYTE
);
119 ctx
->Driver
.MapRenderbuffer(ctx
, rb
, x
, y
, width
, height
,
120 GL_MAP_WRITE_BIT
, &dst
, &dstRowStride
,
124 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDrawPixels");
128 if (ctx
->Pixel
.ZoomY
== -1.0f
) {
129 dst
= dst
+ (height
- 1) * dstRowStride
;
130 dstRowStride
= -dstRowStride
;
133 for (i
= 0; i
< height
; i
++) {
134 GLuint
*dst4
= (GLuint
*) dst
;
135 for (j
= 0; j
< width
; j
++) {
136 dst4
[j
] = PACK_COLOR_8888(src
[j
*4+3], src
[j
*4+0],
137 src
[j
*4+1], src
[j
*4+2]);
143 ctx
->Driver
.UnmapRenderbuffer(ctx
, rb
);
148 * Handle a common case of drawing a format/type combination that
149 * exactly matches the renderbuffer format.
152 fast_draw_generic_pixels(struct gl_context
*ctx
,
153 struct gl_renderbuffer
*rb
,
155 GLsizei width
, GLsizei height
,
156 GLenum format
, GLenum type
,
157 const struct gl_pixelstore_attrib
*unpack
,
158 const GLvoid
*pixels
,
161 const GLubyte
*src
= (const GLubyte
*)
162 _mesa_image_address2d(unpack
, pixels
, width
,
163 height
, format
, type
, 0, 0);
164 const GLint srcRowStride
=
165 _mesa_image_row_stride(unpack
, width
, format
, type
);
166 const GLint rowLength
= width
* _mesa_get_format_bytes(rb
->Format
);
171 ctx
->Driver
.MapRenderbuffer(ctx
, rb
, x
, y
, width
, height
,
172 GL_MAP_WRITE_BIT
, &dst
, &dstRowStride
,
176 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDrawPixels");
180 if (ctx
->Pixel
.ZoomY
== -1.0f
) {
181 dst
= dst
+ (height
- 1) * dstRowStride
;
182 dstRowStride
= -dstRowStride
;
185 for (i
= 0; i
< height
; i
++) {
186 memcpy(dst
, src
, rowLength
);
191 ctx
->Driver
.UnmapRenderbuffer(ctx
, rb
);
196 * Try to do a fast and simple RGB(a) glDrawPixels.
197 * Return: GL_TRUE if success, GL_FALSE if slow path must be used instead
200 fast_draw_rgba_pixels(struct gl_context
*ctx
, GLint x
, GLint y
,
201 GLsizei width
, GLsizei height
,
202 GLenum format
, GLenum type
,
203 const struct gl_pixelstore_attrib
*userUnpack
,
204 const GLvoid
*pixels
)
206 struct gl_framebuffer
*fb
= ctx
->DrawBuffer
;
207 struct gl_renderbuffer
*rb
= ctx
->DrawBuffer
->_ColorDrawBuffers
[0];
208 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
209 struct gl_pixelstore_attrib unpack
;
212 return GL_TRUE
; /* no-op */
214 if (ctx
->DrawBuffer
->_NumColorDrawBuffers
> 1 ||
215 (swrast
->_RasterMask
& ~CLIP_BIT
) ||
216 ctx
->Texture
._EnabledCoordUnits
||
217 userUnpack
->SwapBytes
||
218 ctx
->Pixel
.ZoomX
!= 1.0f
||
219 fabsf(ctx
->Pixel
.ZoomY
) != 1.0f
||
220 ctx
->_ImageTransferState
) {
221 /* can't handle any of those conditions */
225 unpack
= *userUnpack
;
228 if (!_mesa_clip_drawpixels(ctx
, &x
, &y
, &width
, &height
, &unpack
)) {
229 /* image was completely clipped: no-op, all done */
233 if (format
== GL_RGB
&&
234 type
== GL_UNSIGNED_BYTE
&&
235 (rb
->Format
== MESA_FORMAT_B8G8R8X8_UNORM
||
236 rb
->Format
== MESA_FORMAT_B8G8R8A8_UNORM
)) {
237 fast_draw_rgb_ubyte_pixels(ctx
, rb
, x
, y
, width
, height
,
238 &unpack
, pixels
, fb
->FlipY
);
242 if (format
== GL_RGBA
&&
243 type
== GL_UNSIGNED_BYTE
&&
244 (rb
->Format
== MESA_FORMAT_B8G8R8X8_UNORM
||
245 rb
->Format
== MESA_FORMAT_B8G8R8A8_UNORM
)) {
246 fast_draw_rgba_ubyte_pixels(ctx
, rb
, x
, y
, width
, height
,
247 &unpack
, pixels
, fb
->FlipY
);
251 if (_mesa_format_matches_format_and_type(rb
->Format
, format
, type
,
252 ctx
->Unpack
.SwapBytes
, NULL
)) {
253 fast_draw_generic_pixels(ctx
, rb
, x
, y
, width
, height
,
254 format
, type
, &unpack
, pixels
,
259 /* can't handle this pixel format and/or data type */
266 * Draw stencil image.
269 draw_stencil_pixels( struct gl_context
*ctx
, GLint x
, GLint y
,
270 GLsizei width
, GLsizei height
,
272 const struct gl_pixelstore_attrib
*unpack
,
273 const GLvoid
*pixels
)
275 const GLboolean zoom
= ctx
->Pixel
.ZoomX
!= 1.0F
|| ctx
->Pixel
.ZoomY
!= 1.0F
;
276 const GLenum destType
= GL_UNSIGNED_BYTE
;
280 values
= malloc(width
* sizeof(GLubyte
));
282 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDrawPixels");
286 for (row
= 0; row
< height
; row
++) {
287 const GLvoid
*source
= _mesa_image_address2d(unpack
, pixels
,
289 GL_STENCIL_INDEX
, type
,
291 _mesa_unpack_stencil_span(ctx
, width
, destType
, values
,
292 type
, source
, unpack
,
293 ctx
->_ImageTransferState
);
295 _swrast_write_zoomed_stencil_span(ctx
, x
, y
, width
,
299 _swrast_write_stencil_span(ctx
, width
, x
, y
, values
);
313 draw_depth_pixels( struct gl_context
*ctx
, GLint x
, GLint y
,
314 GLsizei width
, GLsizei height
,
316 const struct gl_pixelstore_attrib
*unpack
,
317 const GLvoid
*pixels
)
319 const GLboolean scaleOrBias
320 = ctx
->Pixel
.DepthScale
!= 1.0f
|| ctx
->Pixel
.DepthBias
!= 0.0f
;
321 const GLboolean zoom
= ctx
->Pixel
.ZoomX
!= 1.0f
|| ctx
->Pixel
.ZoomY
!= 1.0f
;
324 INIT_SPAN(span
, GL_BITMAP
);
325 span
.arrayMask
= SPAN_Z
;
326 _swrast_span_default_attribs(ctx
, &span
);
328 if (type
== GL_UNSIGNED_SHORT
329 && ctx
->DrawBuffer
->Visual
.depthBits
== 16
332 && width
<= SWRAST_MAX_WIDTH
333 && !unpack
->SwapBytes
) {
334 /* Special case: directly write 16-bit depth values */
336 for (row
= 0; row
< height
; row
++) {
337 const GLushort
*zSrc
= (const GLushort
*)
338 _mesa_image_address2d(unpack
, pixels
, width
, height
,
339 GL_DEPTH_COMPONENT
, type
, row
, 0);
341 for (i
= 0; i
< width
; i
++)
342 span
.array
->z
[i
] = zSrc
[i
];
346 _swrast_write_rgba_span(ctx
, &span
);
349 else if (type
== GL_UNSIGNED_INT
352 && width
<= SWRAST_MAX_WIDTH
353 && !unpack
->SwapBytes
) {
354 /* Special case: shift 32-bit values down to Visual.depthBits */
355 const GLint shift
= 32 - ctx
->DrawBuffer
->Visual
.depthBits
;
357 for (row
= 0; row
< height
; row
++) {
358 const GLuint
*zSrc
= (const GLuint
*)
359 _mesa_image_address2d(unpack
, pixels
, width
, height
,
360 GL_DEPTH_COMPONENT
, type
, row
, 0);
362 memcpy(span
.array
->z
, zSrc
, width
* sizeof(GLuint
));
366 for (col
= 0; col
< width
; col
++)
367 span
.array
->z
[col
] = zSrc
[col
] >> shift
;
372 _swrast_write_rgba_span(ctx
, &span
);
377 const GLuint depthMax
= ctx
->DrawBuffer
->_DepthMax
;
378 GLint skipPixels
= 0;
380 /* in case width > SWRAST_MAX_WIDTH do the copy in chunks */
381 while (skipPixels
< width
) {
382 const GLint spanWidth
= MIN2(width
- skipPixels
, SWRAST_MAX_WIDTH
);
384 assert(span
.end
<= SWRAST_MAX_WIDTH
);
385 for (row
= 0; row
< height
; row
++) {
386 const GLvoid
*zSrc
= _mesa_image_address2d(unpack
,
387 pixels
, width
, height
,
388 GL_DEPTH_COMPONENT
, type
,
391 /* Set these for each row since the _swrast_write_* function may
392 * change them while clipping.
394 span
.x
= x
+ skipPixels
;
396 span
.end
= spanWidth
;
398 _mesa_unpack_depth_span(ctx
, spanWidth
,
399 GL_UNSIGNED_INT
, span
.array
->z
, depthMax
,
402 _swrast_write_zoomed_depth_span(ctx
, x
, y
, &span
);
405 _swrast_write_rgba_span(ctx
, &span
);
408 skipPixels
+= spanWidth
;
419 draw_rgba_pixels( struct gl_context
*ctx
, GLint x
, GLint y
,
420 GLsizei width
, GLsizei height
,
421 GLenum format
, GLenum type
,
422 const struct gl_pixelstore_attrib
*unpack
,
423 const GLvoid
*pixels
)
425 const GLint imgX
= x
, imgY
= y
;
426 const GLboolean zoom
= ctx
->Pixel
.ZoomX
!= 1.0F
|| ctx
->Pixel
.ZoomY
!= 1.0F
;
427 GLbitfield transferOps
= ctx
->_ImageTransferState
;
430 /* Try an optimized glDrawPixels first */
431 if (fast_draw_rgba_pixels(ctx
, x
, y
, width
, height
, format
, type
,
436 swrast_render_start(ctx
);
438 INIT_SPAN(span
, GL_BITMAP
);
439 _swrast_span_default_attribs(ctx
, &span
);
440 span
.arrayMask
= SPAN_RGBA
;
441 span
.arrayAttribs
= VARYING_BIT_COL0
; /* we're fill in COL0 attrib values */
443 if (ctx
->DrawBuffer
->_NumColorDrawBuffers
> 0) {
444 GLenum datatype
= _mesa_get_format_datatype(
445 ctx
->DrawBuffer
->_ColorDrawBuffers
[0]->Format
);
446 if (datatype
!= GL_FLOAT
&&
447 ctx
->Color
.ClampFragmentColor
!= GL_FALSE
) {
448 /* need to clamp colors before applying fragment ops */
449 transferOps
|= IMAGE_CLAMP_BIT
;
457 const GLbitfield interpMask
= span
.interpMask
;
458 const GLbitfield arrayMask
= span
.arrayMask
;
459 GLint skipPixels
= 0;
460 /* use span array for temp color storage */
461 GLfloat
*rgba
= (GLfloat
*) span
.array
->attribs
[VARYING_SLOT_COL0
];
462 void *tempImage
= NULL
;
464 /* We have to deal with GL_COLOR_INDEX manually because
465 * _mesa_format_convert does not handle this format. So what we do here is
466 * convert it to RGBA ubyte first and then convert from that to dst as
469 if (format
== GL_COLOR_INDEX
) {
470 /* This will handle byte swapping and transferops if needed */
472 _mesa_unpack_color_index_to_rgba_ubyte(ctx
, 2,
473 pixels
, format
, type
,
478 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDrawPixels");
485 type
= GL_UNSIGNED_BYTE
;
486 } else if (unpack
->SwapBytes
) {
487 /* We have to handle byte-swapping scenarios before calling
488 * _mesa_format_convert
490 GLint swapSize
= _mesa_sizeof_packed_type(type
);
491 if (swapSize
== 2 || swapSize
== 4) {
492 int imageStride
= _mesa_image_image_stride(unpack
, width
, height
, format
, type
);
494 tempImage
= malloc(imageStride
);
496 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDrawPixels");
500 _mesa_swap_bytes_2d_image(format
, type
, unpack
,
501 width
, height
, tempImage
, pixels
);
507 const GLint srcStride
508 = _mesa_image_row_stride(unpack
, width
, format
, type
);
510 /* if the span is wider than SWRAST_MAX_WIDTH we have to do it in chunks */
511 while (skipPixels
< width
) {
512 const GLint spanWidth
= MIN2(width
- skipPixels
, SWRAST_MAX_WIDTH
);
513 const GLubyte
*source
514 = (const GLubyte
*) _mesa_image_address2d(unpack
, pixels
,
515 width
, height
, format
,
516 type
, 0, skipPixels
);
519 /* get image row as float/RGBA */
520 uint32_t srcMesaFormat
= _mesa_format_from_format_and_type(format
, type
);
521 for (row
= 0; row
< height
; row
++) {
522 int dstRowStride
= 4 * width
* sizeof(float);
523 _mesa_format_convert(rgba
, RGBA32_FLOAT
, dstRowStride
,
524 (void*)source
, srcMesaFormat
, srcStride
,
527 _mesa_apply_rgba_transfer_ops(ctx
, transferOps
, spanWidth
, (GLfloat (*)[4])rgba
);
528 /* Set these for each row since the _swrast_write_* functions
529 * may change them while clipping/rendering.
531 span
.array
->ChanType
= GL_FLOAT
;
532 span
.x
= x
+ skipPixels
;
534 span
.end
= spanWidth
;
535 span
.arrayMask
= arrayMask
;
536 span
.interpMask
= interpMask
;
538 _swrast_write_zoomed_rgba_span(ctx
, imgX
, imgY
, &span
, rgba
);
541 _swrast_write_rgba_span(ctx
, &span
);
547 skipPixels
+= spanWidth
;
548 } /* while skipPixels < width */
550 /* XXX this is ugly/temporary, to undo above change */
551 span
.array
->ChanType
= CHAN_TYPE
;
556 swrast_render_finish(ctx
);
561 * Draw depth+stencil values into a MESA_FORAMT_Z24_S8 or MESA_FORMAT_Z24_UNORM_S8_UINT
562 * renderbuffer. No masking, zooming, scaling, etc.
565 fast_draw_depth_stencil(struct gl_context
*ctx
, GLint x
, GLint y
,
566 GLsizei width
, GLsizei height
,
567 const struct gl_pixelstore_attrib
*unpack
,
568 const GLvoid
*pixels
)
570 const GLenum format
= GL_DEPTH_STENCIL_EXT
;
571 const GLenum type
= GL_UNSIGNED_INT_24_8
;
572 struct gl_renderbuffer
*rb
=
573 ctx
->DrawBuffer
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
574 struct swrast_renderbuffer
*srb
= swrast_renderbuffer(rb
);
576 GLint srcRowStride
, dstRowStride
;
579 src
= _mesa_image_address2d(unpack
, pixels
, width
, height
,
581 srcRowStride
= _mesa_image_row_stride(unpack
, width
, format
, type
);
583 dst
= _swrast_pixel_address(rb
, x
, y
);
584 dstRowStride
= srb
->RowStride
;
586 for (i
= 0; i
< height
; i
++) {
587 _mesa_pack_uint_24_8_depth_stencil_row(rb
->Format
, width
,
588 (const GLuint
*) src
, dst
);
597 * This is a bit different from drawing GL_DEPTH_COMPONENT pixels.
598 * The only per-pixel operations that apply are depth scale/bias,
599 * stencil offset/shift, GL_DEPTH_WRITEMASK and GL_STENCIL_WRITEMASK,
601 * Also, only the depth buffer and stencil buffers are touched, not the
605 draw_depth_stencil_pixels(struct gl_context
*ctx
, GLint x
, GLint y
,
606 GLsizei width
, GLsizei height
, GLenum type
,
607 const struct gl_pixelstore_attrib
*unpack
,
608 const GLvoid
*pixels
)
610 const GLint imgX
= x
, imgY
= y
;
611 const GLboolean scaleOrBias
612 = ctx
->Pixel
.DepthScale
!= 1.0F
|| ctx
->Pixel
.DepthBias
!= 0.0F
;
613 const GLuint stencilMask
= ctx
->Stencil
.WriteMask
[0];
614 const GLenum stencilType
= GL_UNSIGNED_BYTE
;
615 const GLboolean zoom
= ctx
->Pixel
.ZoomX
!= 1.0F
|| ctx
->Pixel
.ZoomY
!= 1.0F
;
616 struct gl_renderbuffer
*depthRb
, *stencilRb
;
617 struct gl_pixelstore_attrib clippedUnpack
= *unpack
;
620 if (!_mesa_clip_drawpixels(ctx
, &x
, &y
, &width
, &height
,
622 /* totally clipped */
627 depthRb
= ctx
->ReadBuffer
->Attachment
[BUFFER_DEPTH
].Renderbuffer
;
628 stencilRb
= ctx
->ReadBuffer
->Attachment
[BUFFER_STENCIL
].Renderbuffer
;
632 if (depthRb
== stencilRb
&&
633 (depthRb
->Format
== MESA_FORMAT_S8_UINT_Z24_UNORM
||
634 depthRb
->Format
== MESA_FORMAT_Z24_UNORM_S8_UINT
) &&
635 type
== GL_UNSIGNED_INT_24_8
&&
639 (stencilMask
& 0xff) == 0xff) {
640 fast_draw_depth_stencil(ctx
, x
, y
, width
, height
,
641 &clippedUnpack
, pixels
);
644 /* sub-optimal cases:
645 * Separate depth/stencil buffers, or pixel transfer ops required.
647 /* XXX need to handle very wide images (skippixels) */
648 GLuint
*zValues
; /* 32-bit Z values */
651 zValues
= malloc(width
* sizeof(GLuint
));
653 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDrawPixels");
657 for (i
= 0; i
< height
; i
++) {
658 const GLuint
*depthStencilSrc
= (const GLuint
*)
659 _mesa_image_address2d(&clippedUnpack
, pixels
, width
, height
,
660 GL_DEPTH_STENCIL_EXT
, type
, i
, 0);
662 if (ctx
->Depth
.Mask
) {
663 _mesa_unpack_depth_span(ctx
, width
,
664 GL_UNSIGNED_INT
, /* dest type */
665 zValues
, /* dest addr */
666 0xffffffff, /* depth max */
668 depthStencilSrc
, /* src addr */
671 _swrast_write_zoomed_z_span(ctx
, imgX
, imgY
, width
, x
,
675 GLubyte
*dst
= _swrast_pixel_address(depthRb
, x
, y
+ i
);
676 _mesa_pack_uint_z_row(depthRb
->Format
, width
, zValues
, dst
);
680 if (stencilMask
!= 0x0) {
681 GLubyte
*stencilValues
= (GLubyte
*) zValues
; /* re-use buffer */
682 /* get stencil values, with shift/offset/mapping */
683 _mesa_unpack_stencil_span(ctx
, width
, stencilType
, stencilValues
,
684 type
, depthStencilSrc
, &clippedUnpack
,
685 ctx
->_ImageTransferState
);
687 _swrast_write_zoomed_stencil_span(ctx
, imgX
, imgY
, width
,
688 x
, y
+ i
, stencilValues
);
690 _swrast_write_stencil_span(ctx
, width
, x
, y
+ i
, stencilValues
);
700 * Execute software-based glDrawPixels.
701 * By time we get here, all error checking will have been done.
704 _swrast_DrawPixels( struct gl_context
*ctx
,
706 GLsizei width
, GLsizei height
,
707 GLenum format
, GLenum type
,
708 const struct gl_pixelstore_attrib
*unpack
,
709 const GLvoid
*pixels
)
711 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
712 GLboolean save_vp_override
= ctx
->VertexProgram
._Overriden
;
714 if (!_mesa_check_conditional_render(ctx
))
715 return; /* don't draw */
717 /* We are creating fragments directly, without going through vertex
720 * This override flag tells the fragment processing code that its input
721 * comes from a non-standard source, and it may therefore not rely on
722 * optimizations that assume e.g. constant color if there is no color
725 _mesa_set_vp_override(ctx
, GL_TRUE
);
728 _mesa_update_state(ctx
);
730 if (swrast
->NewState
)
731 _swrast_validate_derived( ctx
);
733 pixels
= _mesa_map_pbo_source(ctx
, unpack
, pixels
);
735 _mesa_set_vp_override(ctx
, save_vp_override
);
740 * By time we get here, all error checking should have been done.
743 case GL_STENCIL_INDEX
:
744 swrast_render_start(ctx
);
745 draw_stencil_pixels( ctx
, x
, y
, width
, height
, type
, unpack
, pixels
);
746 swrast_render_finish(ctx
);
748 case GL_DEPTH_COMPONENT
:
749 swrast_render_start(ctx
);
750 draw_depth_pixels( ctx
, x
, y
, width
, height
, type
, unpack
, pixels
);
751 swrast_render_finish(ctx
);
753 case GL_DEPTH_STENCIL_EXT
:
754 swrast_render_start(ctx
);
755 draw_depth_stencil_pixels(ctx
, x
, y
, width
, height
, type
, unpack
, pixels
);
756 swrast_render_finish(ctx
);
759 /* all other formats should be color formats */
760 draw_rgba_pixels(ctx
, x
, y
, width
, height
, format
, type
, unpack
, pixels
);
763 _mesa_set_vp_override(ctx
, save_vp_override
);
765 _mesa_unmap_pbo_source(ctx
, unpack
);