s_drawpix.c revision 848b8605
1/* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 1999-2007 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 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 */ 50static void 51fast_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 */ 97static void 98fast_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 */ 145static void 146fast_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 */ 191static GLboolean 192fast_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_B8G8R8X8_UNORM || 227 rb->Format == MESA_FORMAT_B8G8R8A8_UNORM)) { 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_B8G8R8X8_UNORM || 236 rb->Format == MESA_FORMAT_B8G8R8A8_UNORM)) { 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 ctx->Unpack.SwapBytes)) { 244 fast_draw_generic_pixels(ctx, rb, x, y, width, height, 245 format, type, &unpack, pixels); 246 return GL_TRUE; 247 } 248 249 /* can't handle this pixel format and/or data type */ 250 return GL_FALSE; 251} 252 253 254 255/* 256 * Draw stencil image. 257 */ 258static void 259draw_stencil_pixels( struct gl_context *ctx, GLint x, GLint y, 260 GLsizei width, GLsizei height, 261 GLenum type, 262 const struct gl_pixelstore_attrib *unpack, 263 const GLvoid *pixels ) 264{ 265 const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0; 266 const GLenum destType = GL_UNSIGNED_BYTE; 267 GLint row; 268 GLubyte *values; 269 270 values = malloc(width * sizeof(GLubyte)); 271 if (!values) { 272 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); 273 return; 274 } 275 276 for (row = 0; row < height; row++) { 277 const GLvoid *source = _mesa_image_address2d(unpack, pixels, 278 width, height, 279 GL_STENCIL_INDEX, type, 280 row, 0); 281 _mesa_unpack_stencil_span(ctx, width, destType, values, 282 type, source, unpack, 283 ctx->_ImageTransferState); 284 if (zoom) { 285 _swrast_write_zoomed_stencil_span(ctx, x, y, width, 286 x, y, values); 287 } 288 else { 289 _swrast_write_stencil_span(ctx, width, x, y, values); 290 } 291 292 y++; 293 } 294 295 free(values); 296} 297 298 299/* 300 * Draw depth image. 301 */ 302static void 303draw_depth_pixels( struct gl_context *ctx, GLint x, GLint y, 304 GLsizei width, GLsizei height, 305 GLenum type, 306 const struct gl_pixelstore_attrib *unpack, 307 const GLvoid *pixels ) 308{ 309 const GLboolean scaleOrBias 310 = ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0; 311 const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0; 312 SWspan span; 313 314 INIT_SPAN(span, GL_BITMAP); 315 span.arrayMask = SPAN_Z; 316 _swrast_span_default_attribs(ctx, &span); 317 318 if (type == GL_UNSIGNED_SHORT 319 && ctx->DrawBuffer->Visual.depthBits == 16 320 && !scaleOrBias 321 && !zoom 322 && width <= SWRAST_MAX_WIDTH 323 && !unpack->SwapBytes) { 324 /* Special case: directly write 16-bit depth values */ 325 GLint row; 326 for (row = 0; row < height; row++) { 327 const GLushort *zSrc = (const GLushort *) 328 _mesa_image_address2d(unpack, pixels, width, height, 329 GL_DEPTH_COMPONENT, type, row, 0); 330 GLint i; 331 for (i = 0; i < width; i++) 332 span.array->z[i] = zSrc[i]; 333 span.x = x; 334 span.y = y + row; 335 span.end = width; 336 _swrast_write_rgba_span(ctx, &span); 337 } 338 } 339 else if (type == GL_UNSIGNED_INT 340 && !scaleOrBias 341 && !zoom 342 && width <= SWRAST_MAX_WIDTH 343 && !unpack->SwapBytes) { 344 /* Special case: shift 32-bit values down to Visual.depthBits */ 345 const GLint shift = 32 - ctx->DrawBuffer->Visual.depthBits; 346 GLint row; 347 for (row = 0; row < height; row++) { 348 const GLuint *zSrc = (const GLuint *) 349 _mesa_image_address2d(unpack, pixels, width, height, 350 GL_DEPTH_COMPONENT, type, row, 0); 351 if (shift == 0) { 352 memcpy(span.array->z, zSrc, width * sizeof(GLuint)); 353 } 354 else { 355 GLint col; 356 for (col = 0; col < width; col++) 357 span.array->z[col] = zSrc[col] >> shift; 358 } 359 span.x = x; 360 span.y = y + row; 361 span.end = width; 362 _swrast_write_rgba_span(ctx, &span); 363 } 364 } 365 else { 366 /* General case */ 367 const GLuint depthMax = ctx->DrawBuffer->_DepthMax; 368 GLint skipPixels = 0; 369 370 /* in case width > SWRAST_MAX_WIDTH do the copy in chunks */ 371 while (skipPixels < width) { 372 const GLint spanWidth = MIN2(width - skipPixels, SWRAST_MAX_WIDTH); 373 GLint row; 374 ASSERT(span.end <= SWRAST_MAX_WIDTH); 375 for (row = 0; row < height; row++) { 376 const GLvoid *zSrc = _mesa_image_address2d(unpack, 377 pixels, width, height, 378 GL_DEPTH_COMPONENT, type, 379 row, skipPixels); 380 381 /* Set these for each row since the _swrast_write_* function may 382 * change them while clipping. 383 */ 384 span.x = x + skipPixels; 385 span.y = y + row; 386 span.end = spanWidth; 387 388 _mesa_unpack_depth_span(ctx, spanWidth, 389 GL_UNSIGNED_INT, span.array->z, depthMax, 390 type, zSrc, unpack); 391 if (zoom) { 392 _swrast_write_zoomed_depth_span(ctx, x, y, &span); 393 } 394 else { 395 _swrast_write_rgba_span(ctx, &span); 396 } 397 } 398 skipPixels += spanWidth; 399 } 400 } 401} 402 403 404 405/** 406 * Draw RGBA image. 407 */ 408static void 409draw_rgba_pixels( struct gl_context *ctx, GLint x, GLint y, 410 GLsizei width, GLsizei height, 411 GLenum format, GLenum type, 412 const struct gl_pixelstore_attrib *unpack, 413 const GLvoid *pixels ) 414{ 415 const GLint imgX = x, imgY = y; 416 const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; 417 GLfloat *convImage = NULL; 418 GLbitfield transferOps = ctx->_ImageTransferState; 419 SWspan span; 420 421 /* Try an optimized glDrawPixels first */ 422 if (fast_draw_rgba_pixels(ctx, x, y, width, height, format, type, 423 unpack, pixels)) { 424 return; 425 } 426 427 swrast_render_start(ctx); 428 429 INIT_SPAN(span, GL_BITMAP); 430 _swrast_span_default_attribs(ctx, &span); 431 span.arrayMask = SPAN_RGBA; 432 span.arrayAttribs = VARYING_BIT_COL0; /* we're fill in COL0 attrib values */ 433 434 if (ctx->DrawBuffer->_NumColorDrawBuffers > 0) { 435 GLenum datatype = _mesa_get_format_datatype( 436 ctx->DrawBuffer->_ColorDrawBuffers[0]->Format); 437 if (datatype != GL_FLOAT && 438 ctx->Color.ClampFragmentColor != GL_FALSE) { 439 /* need to clamp colors before applying fragment ops */ 440 transferOps |= IMAGE_CLAMP_BIT; 441 } 442 } 443 444 /* 445 * General solution 446 */ 447 { 448 const GLbitfield interpMask = span.interpMask; 449 const GLbitfield arrayMask = span.arrayMask; 450 const GLint srcStride 451 = _mesa_image_row_stride(unpack, width, format, type); 452 GLint skipPixels = 0; 453 /* use span array for temp color storage */ 454 GLfloat *rgba = (GLfloat *) span.array->attribs[VARYING_SLOT_COL0]; 455 456 /* if the span is wider than SWRAST_MAX_WIDTH we have to do it in chunks */ 457 while (skipPixels < width) { 458 const GLint spanWidth = MIN2(width - skipPixels, SWRAST_MAX_WIDTH); 459 const GLubyte *source 460 = (const GLubyte *) _mesa_image_address2d(unpack, pixels, 461 width, height, format, 462 type, 0, skipPixels); 463 GLint row; 464 465 for (row = 0; row < height; row++) { 466 /* get image row as float/RGBA */ 467 _mesa_unpack_color_span_float(ctx, spanWidth, GL_RGBA, rgba, 468 format, type, source, unpack, 469 transferOps); 470 /* Set these for each row since the _swrast_write_* functions 471 * may change them while clipping/rendering. 472 */ 473 span.array->ChanType = GL_FLOAT; 474 span.x = x + skipPixels; 475 span.y = y + row; 476 span.end = spanWidth; 477 span.arrayMask = arrayMask; 478 span.interpMask = interpMask; 479 if (zoom) { 480 _swrast_write_zoomed_rgba_span(ctx, imgX, imgY, &span, rgba); 481 } 482 else { 483 _swrast_write_rgba_span(ctx, &span); 484 } 485 486 source += srcStride; 487 } /* for row */ 488 489 skipPixels += spanWidth; 490 } /* while skipPixels < width */ 491 492 /* XXX this is ugly/temporary, to undo above change */ 493 span.array->ChanType = CHAN_TYPE; 494 } 495 496 free(convImage); 497 498 swrast_render_finish(ctx); 499} 500 501 502/** 503 * Draw depth+stencil values into a MESA_FORAMT_Z24_S8 or MESA_FORMAT_Z24_UNORM_S8_UINT 504 * renderbuffer. No masking, zooming, scaling, etc. 505 */ 506static void 507fast_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 */ 546static void 547draw_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_S8_UINT_Z24_UNORM || 576 depthRb->Format == MESA_FORMAT_Z24_UNORM_S8_UINT) && 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 GLuint *zValues; /* 32-bit Z values */ 591 GLint i; 592 593 zValues = malloc(width * sizeof(GLuint)); 594 if (!zValues) { 595 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); 596 return; 597 } 598 599 for (i = 0; i < height; i++) { 600 const GLuint *depthStencilSrc = (const GLuint *) 601 _mesa_image_address2d(&clippedUnpack, pixels, width, height, 602 GL_DEPTH_STENCIL_EXT, type, i, 0); 603 604 if (ctx->Depth.Mask) { 605 _mesa_unpack_depth_span(ctx, width, 606 GL_UNSIGNED_INT, /* dest type */ 607 zValues, /* dest addr */ 608 0xffffffff, /* depth max */ 609 type, /* src type */ 610 depthStencilSrc, /* src addr */ 611 &clippedUnpack); 612 if (zoom) { 613 _swrast_write_zoomed_z_span(ctx, imgX, imgY, width, x, 614 y + i, zValues); 615 } 616 else { 617 GLubyte *dst = _swrast_pixel_address(depthRb, x, y + i); 618 _mesa_pack_uint_z_row(depthRb->Format, width, zValues, dst); 619 } 620 } 621 622 if (stencilMask != 0x0) { 623 GLubyte *stencilValues = (GLubyte *) zValues; /* re-use buffer */ 624 /* get stencil values, with shift/offset/mapping */ 625 _mesa_unpack_stencil_span(ctx, width, stencilType, stencilValues, 626 type, depthStencilSrc, &clippedUnpack, 627 ctx->_ImageTransferState); 628 if (zoom) 629 _swrast_write_zoomed_stencil_span(ctx, imgX, imgY, width, 630 x, y + i, stencilValues); 631 else 632 _swrast_write_stencil_span(ctx, width, x, y + i, stencilValues); 633 } 634 } 635 636 free(zValues); 637 } 638} 639 640 641/** 642 * Execute software-based glDrawPixels. 643 * By time we get here, all error checking will have been done. 644 */ 645void 646_swrast_DrawPixels( struct gl_context *ctx, 647 GLint x, GLint y, 648 GLsizei width, GLsizei height, 649 GLenum format, GLenum type, 650 const struct gl_pixelstore_attrib *unpack, 651 const GLvoid *pixels ) 652{ 653 SWcontext *swrast = SWRAST_CONTEXT(ctx); 654 GLboolean save_vp_override = ctx->VertexProgram._Overriden; 655 656 if (!_mesa_check_conditional_render(ctx)) 657 return; /* don't draw */ 658 659 /* We are creating fragments directly, without going through vertex 660 * programs. 661 * 662 * This override flag tells the fragment processing code that its input 663 * comes from a non-standard source, and it may therefore not rely on 664 * optimizations that assume e.g. constant color if there is no color 665 * vertex array. 666 */ 667 _mesa_set_vp_override(ctx, GL_TRUE); 668 669 if (ctx->NewState) 670 _mesa_update_state(ctx); 671 672 if (swrast->NewState) 673 _swrast_validate_derived( ctx ); 674 675 pixels = _mesa_map_pbo_source(ctx, unpack, pixels); 676 if (!pixels) { 677 _mesa_set_vp_override(ctx, save_vp_override); 678 return; 679 } 680 681 /* 682 * By time we get here, all error checking should have been done. 683 */ 684 switch (format) { 685 case GL_STENCIL_INDEX: 686 swrast_render_start(ctx); 687 draw_stencil_pixels( ctx, x, y, width, height, type, unpack, pixels ); 688 swrast_render_finish(ctx); 689 break; 690 case GL_DEPTH_COMPONENT: 691 swrast_render_start(ctx); 692 draw_depth_pixels( ctx, x, y, width, height, type, unpack, pixels ); 693 swrast_render_finish(ctx); 694 break; 695 case GL_DEPTH_STENCIL_EXT: 696 swrast_render_start(ctx); 697 draw_depth_stencil_pixels(ctx, x, y, width, height, type, unpack, pixels); 698 swrast_render_finish(ctx); 699 break; 700 default: 701 /* all other formats should be color formats */ 702 draw_rgba_pixels(ctx, x, y, width, height, format, type, unpack, pixels); 703 } 704 705 _mesa_set_vp_override(ctx, save_vp_override); 706 707 _mesa_unmap_pbo_source(ctx, unpack); 708} 709