swrast: use swrast_renderbuffer instead of gl_renderbuffer
[mesa.git] / src / mesa / swrast / s_drawpix.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.1
4 *
5 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
6 *
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:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
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.
23 */
24
25
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/image.h"
33 #include "main/imports.h"
34 #include "main/macros.h"
35 #include "main/pack.h"
36 #include "main/pbo.h"
37 #include "main/pixeltransfer.h"
38 #include "main/state.h"
39
40 #include "s_context.h"
41 #include "s_span.h"
42 #include "s_stencil.h"
43 #include "s_zoom.h"
44
45
46 /**
47 * Handle a common case of drawing GL_RGB/GL_UNSIGNED_BYTE into a
48 * MESA_FORMAT_XRGB888 or MESA_FORMAT_ARGB888 renderbuffer.
49 */
50 static void
51 fast_draw_rgb_ubyte_pixels(struct gl_context *ctx,
52 struct gl_renderbuffer *rb,
53 GLint x, GLint y,
54 GLsizei width, GLsizei height,
55 const struct gl_pixelstore_attrib *unpack,
56 const GLvoid *pixels)
57 {
58 const GLubyte *src = (const GLubyte *)
59 _mesa_image_address2d(unpack, pixels, width,
60 height, GL_RGB, GL_UNSIGNED_BYTE, 0, 0);
61 const GLint srcRowStride = _mesa_image_row_stride(unpack, width,
62 GL_RGB, GL_UNSIGNED_BYTE);
63 GLint i, j;
64 GLubyte *dst;
65 GLint dstRowStride;
66
67 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height,
68 GL_MAP_WRITE_BIT, &dst, &dstRowStride);
69
70 if (!dst) {
71 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
72 return;
73 }
74
75 if (ctx->Pixel.ZoomY == -1.0f) {
76 dst = dst + (height - 1) * dstRowStride;
77 dstRowStride = -dstRowStride;
78 }
79
80 for (i = 0; i < height; i++) {
81 GLuint *dst4 = (GLuint *) dst;
82 for (j = 0; j < width; j++) {
83 dst4[j] = PACK_COLOR_8888(0xff, src[j*3+0], src[j*3+1], src[j*3+2]);
84 }
85 dst += dstRowStride;
86 src += srcRowStride;
87 }
88
89 ctx->Driver.UnmapRenderbuffer(ctx, rb);
90 }
91
92
93 /**
94 * Handle a common case of drawing GL_RGBA/GL_UNSIGNED_BYTE into a
95 * MESA_FORMAT_ARGB888 or MESA_FORMAT_xRGB888 renderbuffer.
96 */
97 static void
98 fast_draw_rgba_ubyte_pixels(struct gl_context *ctx,
99 struct gl_renderbuffer *rb,
100 GLint x, GLint y,
101 GLsizei width, GLsizei height,
102 const struct gl_pixelstore_attrib *unpack,
103 const GLvoid *pixels)
104 {
105 const GLubyte *src = (const GLubyte *)
106 _mesa_image_address2d(unpack, pixels, width,
107 height, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0);
108 const GLint srcRowStride =
109 _mesa_image_row_stride(unpack, width, GL_RGBA, GL_UNSIGNED_BYTE);
110 GLint i, j;
111 GLubyte *dst;
112 GLint dstRowStride;
113
114 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height,
115 GL_MAP_WRITE_BIT, &dst, &dstRowStride);
116
117 if (!dst) {
118 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
119 return;
120 }
121
122 if (ctx->Pixel.ZoomY == -1.0f) {
123 dst = dst + (height - 1) * dstRowStride;
124 dstRowStride = -dstRowStride;
125 }
126
127 for (i = 0; i < height; i++) {
128 GLuint *dst4 = (GLuint *) dst;
129 for (j = 0; j < width; j++) {
130 dst4[j] = PACK_COLOR_8888(src[j*4+3], src[j*4+0],
131 src[j*4+1], src[j*4+2]);
132 }
133 dst += dstRowStride;
134 src += srcRowStride;
135 }
136
137 ctx->Driver.UnmapRenderbuffer(ctx, rb);
138 }
139
140
141 /**
142 * Handle a common case of drawing a format/type combination that
143 * exactly matches the renderbuffer format.
144 */
145 static void
146 fast_draw_generic_pixels(struct gl_context *ctx,
147 struct gl_renderbuffer *rb,
148 GLint x, GLint y,
149 GLsizei width, GLsizei height,
150 GLenum format, GLenum type,
151 const struct gl_pixelstore_attrib *unpack,
152 const GLvoid *pixels)
153 {
154 const GLubyte *src = (const GLubyte *)
155 _mesa_image_address2d(unpack, pixels, width,
156 height, format, type, 0, 0);
157 const GLint srcRowStride =
158 _mesa_image_row_stride(unpack, width, format, type);
159 const GLint rowLength = width * _mesa_get_format_bytes(rb->Format);
160 GLint i;
161 GLubyte *dst;
162 GLint dstRowStride;
163
164 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height,
165 GL_MAP_WRITE_BIT, &dst, &dstRowStride);
166
167 if (!dst) {
168 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
169 return;
170 }
171
172 if (ctx->Pixel.ZoomY == -1.0f) {
173 dst = dst + (height - 1) * dstRowStride;
174 dstRowStride = -dstRowStride;
175 }
176
177 for (i = 0; i < height; i++) {
178 memcpy(dst, src, rowLength);
179 dst += dstRowStride;
180 src += srcRowStride;
181 }
182
183 ctx->Driver.UnmapRenderbuffer(ctx, rb);
184 }
185
186
187 /**
188 * Try to do a fast and simple RGB(a) glDrawPixels.
189 * Return: GL_TRUE if success, GL_FALSE if slow path must be used instead
190 */
191 static GLboolean
192 fast_draw_rgba_pixels(struct gl_context *ctx, GLint x, GLint y,
193 GLsizei width, GLsizei height,
194 GLenum format, GLenum type,
195 const struct gl_pixelstore_attrib *userUnpack,
196 const GLvoid *pixels)
197 {
198 struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
199 SWcontext *swrast = SWRAST_CONTEXT(ctx);
200 struct gl_pixelstore_attrib unpack;
201
202 if (!rb)
203 return GL_TRUE; /* no-op */
204
205 if (ctx->DrawBuffer->_NumColorDrawBuffers > 1 ||
206 (swrast->_RasterMask & ~CLIP_BIT) ||
207 ctx->Texture._EnabledCoordUnits ||
208 userUnpack->SwapBytes ||
209 ctx->Pixel.ZoomX != 1.0f ||
210 fabsf(ctx->Pixel.ZoomY) != 1.0f ||
211 ctx->_ImageTransferState) {
212 /* can't handle any of those conditions */
213 return GL_FALSE;
214 }
215
216 unpack = *userUnpack;
217
218 /* clipping */
219 if (!_mesa_clip_drawpixels(ctx, &x, &y, &width, &height, &unpack)) {
220 /* image was completely clipped: no-op, all done */
221 return GL_TRUE;
222 }
223
224 if (format == GL_RGB &&
225 type == GL_UNSIGNED_BYTE &&
226 (rb->Format == MESA_FORMAT_XRGB8888 ||
227 rb->Format == MESA_FORMAT_ARGB8888)) {
228 fast_draw_rgb_ubyte_pixels(ctx, rb, x, y, width, height,
229 &unpack, pixels);
230 return GL_TRUE;
231 }
232
233 if (format == GL_RGBA &&
234 type == GL_UNSIGNED_BYTE &&
235 (rb->Format == MESA_FORMAT_XRGB8888 ||
236 rb->Format == MESA_FORMAT_ARGB8888)) {
237 fast_draw_rgba_ubyte_pixels(ctx, rb, x, y, width, height,
238 &unpack, pixels);
239 return GL_TRUE;
240 }
241
242 if (_mesa_format_matches_format_and_type(rb->Format, format, type)) {
243 fast_draw_generic_pixels(ctx, rb, x, y, width, height,
244 format, type, &unpack, pixels);
245 return GL_TRUE;
246 }
247
248 /* can't handle this pixel format and/or data type */
249 return GL_FALSE;
250 }
251
252
253
254 /*
255 * Draw stencil image.
256 */
257 static void
258 draw_stencil_pixels( struct gl_context *ctx, GLint x, GLint y,
259 GLsizei width, GLsizei height,
260 GLenum type,
261 const struct gl_pixelstore_attrib *unpack,
262 const GLvoid *pixels )
263 {
264 const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
265 const GLenum destType = GL_UNSIGNED_BYTE;
266 GLint skipPixels;
267
268 /* if width > MAX_WIDTH, have to process image in chunks */
269 skipPixels = 0;
270 while (skipPixels < width) {
271 const GLint spanX = x + skipPixels;
272 const GLint spanWidth = MIN2(width - skipPixels, MAX_WIDTH);
273 GLint row;
274 for (row = 0; row < height; row++) {
275 const GLint spanY = y + row;
276 GLubyte values[MAX_WIDTH];
277 const GLvoid *source = _mesa_image_address2d(unpack, pixels,
278 width, height,
279 GL_STENCIL_INDEX, type,
280 row, skipPixels);
281 _mesa_unpack_stencil_span(ctx, spanWidth, destType, values,
282 type, source, unpack,
283 ctx->_ImageTransferState);
284 if (zoom) {
285 _swrast_write_zoomed_stencil_span(ctx, x, y, spanWidth,
286 spanX, spanY, values);
287 }
288 else {
289 _swrast_write_stencil_span(ctx, spanWidth, spanX, spanY, values);
290 }
291 }
292 skipPixels += spanWidth;
293 }
294 }
295
296
297 /*
298 * Draw depth image.
299 */
300 static void
301 draw_depth_pixels( struct gl_context *ctx, GLint x, GLint y,
302 GLsizei width, GLsizei height,
303 GLenum type,
304 const struct gl_pixelstore_attrib *unpack,
305 const GLvoid *pixels )
306 {
307 const GLboolean scaleOrBias
308 = ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0;
309 const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
310 SWspan span;
311
312 INIT_SPAN(span, GL_BITMAP);
313 span.arrayMask = SPAN_Z;
314 _swrast_span_default_attribs(ctx, &span);
315
316 if (type == GL_UNSIGNED_SHORT
317 && ctx->DrawBuffer->Visual.depthBits == 16
318 && !scaleOrBias
319 && !zoom
320 && width <= MAX_WIDTH
321 && !unpack->SwapBytes) {
322 /* Special case: directly write 16-bit depth values */
323 GLint row;
324 for (row = 0; row < height; row++) {
325 const GLushort *zSrc = (const GLushort *)
326 _mesa_image_address2d(unpack, pixels, width, height,
327 GL_DEPTH_COMPONENT, type, row, 0);
328 GLint i;
329 for (i = 0; i < width; i++)
330 span.array->z[i] = zSrc[i];
331 span.x = x;
332 span.y = y + row;
333 span.end = width;
334 _swrast_write_rgba_span(ctx, &span);
335 }
336 }
337 else if (type == GL_UNSIGNED_INT
338 && !scaleOrBias
339 && !zoom
340 && width <= MAX_WIDTH
341 && !unpack->SwapBytes) {
342 /* Special case: shift 32-bit values down to Visual.depthBits */
343 const GLint shift = 32 - ctx->DrawBuffer->Visual.depthBits;
344 GLint row;
345 for (row = 0; row < height; row++) {
346 const GLuint *zSrc = (const GLuint *)
347 _mesa_image_address2d(unpack, pixels, width, height,
348 GL_DEPTH_COMPONENT, type, row, 0);
349 if (shift == 0) {
350 memcpy(span.array->z, zSrc, width * sizeof(GLuint));
351 }
352 else {
353 GLint col;
354 for (col = 0; col < width; col++)
355 span.array->z[col] = zSrc[col] >> shift;
356 }
357 span.x = x;
358 span.y = y + row;
359 span.end = width;
360 _swrast_write_rgba_span(ctx, &span);
361 }
362 }
363 else {
364 /* General case */
365 const GLuint depthMax = ctx->DrawBuffer->_DepthMax;
366 GLint skipPixels = 0;
367
368 /* in case width > MAX_WIDTH do the copy in chunks */
369 while (skipPixels < width) {
370 const GLint spanWidth = MIN2(width - skipPixels, MAX_WIDTH);
371 GLint row;
372 ASSERT(span.end <= MAX_WIDTH);
373 for (row = 0; row < height; row++) {
374 const GLvoid *zSrc = _mesa_image_address2d(unpack,
375 pixels, width, height,
376 GL_DEPTH_COMPONENT, type,
377 row, skipPixels);
378
379 /* Set these for each row since the _swrast_write_* function may
380 * change them while clipping.
381 */
382 span.x = x + skipPixels;
383 span.y = y + row;
384 span.end = spanWidth;
385
386 _mesa_unpack_depth_span(ctx, spanWidth,
387 GL_UNSIGNED_INT, span.array->z, depthMax,
388 type, zSrc, unpack);
389 if (zoom) {
390 _swrast_write_zoomed_depth_span(ctx, x, y, &span);
391 }
392 else {
393 _swrast_write_rgba_span(ctx, &span);
394 }
395 }
396 skipPixels += spanWidth;
397 }
398 }
399 }
400
401
402
403 /**
404 * Draw RGBA image.
405 */
406 static void
407 draw_rgba_pixels( struct gl_context *ctx, GLint x, GLint y,
408 GLsizei width, GLsizei height,
409 GLenum format, GLenum type,
410 const struct gl_pixelstore_attrib *unpack,
411 const GLvoid *pixels )
412 {
413 const GLint imgX = x, imgY = y;
414 const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
415 GLfloat *convImage = NULL;
416 GLbitfield transferOps = ctx->_ImageTransferState;
417 SWspan span;
418
419 /* Try an optimized glDrawPixels first */
420 if (fast_draw_rgba_pixels(ctx, x, y, width, height, format, type,
421 unpack, pixels)) {
422 return;
423 }
424
425 swrast_render_start(ctx);
426
427 INIT_SPAN(span, GL_BITMAP);
428 _swrast_span_default_attribs(ctx, &span);
429 span.arrayMask = SPAN_RGBA;
430 span.arrayAttribs = FRAG_BIT_COL0; /* we're fill in COL0 attrib values */
431
432 if (ctx->DrawBuffer->_NumColorDrawBuffers > 0) {
433 GLenum datatype = _mesa_get_format_datatype(
434 ctx->DrawBuffer->_ColorDrawBuffers[0]->Format);
435 if (datatype != GL_FLOAT &&
436 ctx->Color.ClampFragmentColor != GL_FALSE) {
437 /* need to clamp colors before applying fragment ops */
438 transferOps |= IMAGE_CLAMP_BIT;
439 }
440 }
441
442 /*
443 * General solution
444 */
445 {
446 const GLbitfield interpMask = span.interpMask;
447 const GLbitfield arrayMask = span.arrayMask;
448 const GLint srcStride
449 = _mesa_image_row_stride(unpack, width, format, type);
450 GLint skipPixels = 0;
451 /* use span array for temp color storage */
452 GLfloat *rgba = (GLfloat *) span.array->attribs[FRAG_ATTRIB_COL0];
453
454 /* if the span is wider than MAX_WIDTH we have to do it in chunks */
455 while (skipPixels < width) {
456 const GLint spanWidth = MIN2(width - skipPixels, MAX_WIDTH);
457 const GLubyte *source
458 = (const GLubyte *) _mesa_image_address2d(unpack, pixels,
459 width, height, format,
460 type, 0, skipPixels);
461 GLint row;
462
463 for (row = 0; row < height; row++) {
464 /* get image row as float/RGBA */
465 _mesa_unpack_color_span_float(ctx, spanWidth, GL_RGBA, rgba,
466 format, type, source, unpack,
467 transferOps);
468 /* Set these for each row since the _swrast_write_* functions
469 * may change them while clipping/rendering.
470 */
471 span.array->ChanType = GL_FLOAT;
472 span.x = x + skipPixels;
473 span.y = y + row;
474 span.end = spanWidth;
475 span.arrayMask = arrayMask;
476 span.interpMask = interpMask;
477 if (zoom) {
478 _swrast_write_zoomed_rgba_span(ctx, imgX, imgY, &span, rgba);
479 }
480 else {
481 _swrast_write_rgba_span(ctx, &span);
482 }
483
484 source += srcStride;
485 } /* for row */
486
487 skipPixels += spanWidth;
488 } /* while skipPixels < width */
489
490 /* XXX this is ugly/temporary, to undo above change */
491 span.array->ChanType = CHAN_TYPE;
492 }
493
494 if (convImage) {
495 free(convImage);
496 }
497
498 swrast_render_finish(ctx);
499 }
500
501
502 /**
503 * Draw depth+stencil values into a MESA_FORAMT_Z24_S8 or MESA_FORMAT_S8_Z24
504 * renderbuffer. No masking, zooming, scaling, etc.
505 */
506 static void
507 fast_draw_depth_stencil(struct gl_context *ctx, GLint x, GLint y,
508 GLsizei width, GLsizei height,
509 const struct gl_pixelstore_attrib *unpack,
510 const GLvoid *pixels)
511 {
512 const GLenum format = GL_DEPTH_STENCIL_EXT;
513 const GLenum type = GL_UNSIGNED_INT_24_8;
514 struct gl_renderbuffer *rb =
515 ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
516 struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
517 GLubyte *src, *dst;
518 GLint srcRowStride, dstRowStride;
519 GLint i;
520
521 src = _mesa_image_address2d(unpack, pixels, width, height,
522 format, type, 0, 0);
523 srcRowStride = _mesa_image_row_stride(unpack, width, format, type);
524
525 dst = _swrast_pixel_address(rb, x, y);
526 dstRowStride = srb->RowStride;
527
528 for (i = 0; i < height; i++) {
529 _mesa_pack_uint_24_8_depth_stencil_row(rb->Format, width,
530 (const GLuint *) src, dst);
531 dst += dstRowStride;
532 src += srcRowStride;
533 }
534 }
535
536
537
538 /**
539 * This is a bit different from drawing GL_DEPTH_COMPONENT pixels.
540 * The only per-pixel operations that apply are depth scale/bias,
541 * stencil offset/shift, GL_DEPTH_WRITEMASK and GL_STENCIL_WRITEMASK,
542 * and pixel zoom.
543 * Also, only the depth buffer and stencil buffers are touched, not the
544 * color buffer(s).
545 */
546 static void
547 draw_depth_stencil_pixels(struct gl_context *ctx, GLint x, GLint y,
548 GLsizei width, GLsizei height, GLenum type,
549 const struct gl_pixelstore_attrib *unpack,
550 const GLvoid *pixels)
551 {
552 const GLint imgX = x, imgY = y;
553 const GLboolean scaleOrBias
554 = ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0;
555 const GLuint stencilMask = ctx->Stencil.WriteMask[0];
556 const GLenum stencilType = GL_UNSIGNED_BYTE;
557 const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
558 struct gl_renderbuffer *depthRb, *stencilRb;
559 struct gl_pixelstore_attrib clippedUnpack = *unpack;
560
561 if (!zoom) {
562 if (!_mesa_clip_drawpixels(ctx, &x, &y, &width, &height,
563 &clippedUnpack)) {
564 /* totally clipped */
565 return;
566 }
567 }
568
569 depthRb = ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
570 stencilRb = ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
571 ASSERT(depthRb);
572 ASSERT(stencilRb);
573
574 if (depthRb == stencilRb &&
575 (depthRb->Format == MESA_FORMAT_Z24_S8 ||
576 depthRb->Format == MESA_FORMAT_S8_Z24) &&
577 type == GL_UNSIGNED_INT_24_8 &&
578 !scaleOrBias &&
579 !zoom &&
580 ctx->Depth.Mask &&
581 (stencilMask & 0xff) == 0xff) {
582 fast_draw_depth_stencil(ctx, x, y, width, height,
583 &clippedUnpack, pixels);
584 }
585 else {
586 /* sub-optimal cases:
587 * Separate depth/stencil buffers, or pixel transfer ops required.
588 */
589 /* XXX need to handle very wide images (skippixels) */
590 GLint i;
591
592 for (i = 0; i < height; i++) {
593 const GLuint *depthStencilSrc = (const GLuint *)
594 _mesa_image_address2d(&clippedUnpack, pixels, width, height,
595 GL_DEPTH_STENCIL_EXT, type, i, 0);
596
597 if (ctx->Depth.Mask) {
598 GLuint zValues[MAX_WIDTH]; /* 32-bit Z values */
599 _mesa_unpack_depth_span(ctx, width,
600 GL_UNSIGNED_INT, /* dest type */
601 zValues, /* dest addr */
602 0xffffffff, /* depth max */
603 type, /* src type */
604 depthStencilSrc, /* src addr */
605 &clippedUnpack);
606 if (zoom) {
607 _swrast_write_zoomed_z_span(ctx, imgX, imgY, width, x,
608 y + i, zValues);
609 }
610 else {
611 GLubyte *dst = _swrast_pixel_address(depthRb, x, y + i);
612 _mesa_pack_uint_z_row(depthRb->Format, width, zValues, dst);
613 }
614 }
615
616 if (stencilMask != 0x0) {
617 GLubyte stencilValues[MAX_WIDTH];
618 /* get stencil values, with shift/offset/mapping */
619 _mesa_unpack_stencil_span(ctx, width, stencilType, stencilValues,
620 type, depthStencilSrc, &clippedUnpack,
621 ctx->_ImageTransferState);
622 if (zoom)
623 _swrast_write_zoomed_stencil_span(ctx, imgX, imgY, width,
624 x, y + i, stencilValues);
625 else
626 _swrast_write_stencil_span(ctx, width, x, y + i, stencilValues);
627 }
628 }
629 }
630 }
631
632
633 /**
634 * Execute software-based glDrawPixels.
635 * By time we get here, all error checking will have been done.
636 */
637 void
638 _swrast_DrawPixels( struct gl_context *ctx,
639 GLint x, GLint y,
640 GLsizei width, GLsizei height,
641 GLenum format, GLenum type,
642 const struct gl_pixelstore_attrib *unpack,
643 const GLvoid *pixels )
644 {
645 SWcontext *swrast = SWRAST_CONTEXT(ctx);
646 GLboolean save_vp_override = ctx->VertexProgram._Overriden;
647
648 if (!_mesa_check_conditional_render(ctx))
649 return; /* don't draw */
650
651 /* We are creating fragments directly, without going through vertex
652 * programs.
653 *
654 * This override flag tells the fragment processing code that its input
655 * comes from a non-standard source, and it may therefore not rely on
656 * optimizations that assume e.g. constant color if there is no color
657 * vertex array.
658 */
659 _mesa_set_vp_override(ctx, GL_TRUE);
660
661 if (ctx->NewState)
662 _mesa_update_state(ctx);
663
664 if (swrast->NewState)
665 _swrast_validate_derived( ctx );
666
667 pixels = _mesa_map_pbo_source(ctx, unpack, pixels);
668 if (!pixels) {
669 _mesa_set_vp_override(ctx, save_vp_override);
670 return;
671 }
672
673 /*
674 * By time we get here, all error checking should have been done.
675 */
676 switch (format) {
677 case GL_STENCIL_INDEX:
678 swrast_render_start(ctx);
679 draw_stencil_pixels( ctx, x, y, width, height, type, unpack, pixels );
680 swrast_render_finish(ctx);
681 break;
682 case GL_DEPTH_COMPONENT:
683 swrast_render_start(ctx);
684 draw_depth_pixels( ctx, x, y, width, height, type, unpack, pixels );
685 swrast_render_finish(ctx);
686 break;
687 case GL_DEPTH_STENCIL_EXT:
688 swrast_render_start(ctx);
689 draw_depth_stencil_pixels(ctx, x, y, width, height, type, unpack, pixels);
690 swrast_render_finish(ctx);
691 break;
692 default:
693 /* all other formats should be color formats */
694 draw_rgba_pixels(ctx, x, y, width, height, format, type, unpack, pixels);
695 }
696
697 _mesa_set_vp_override(ctx, save_vp_override);
698
699 _mesa_unmap_pbo_source(ctx, unpack);
700 }