s_drawpix.c revision 743c664c8c13a7d20beb17290316cd178681482e
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/image.h" 32#include "main/imports.h" 33#include "main/macros.h" 34#include "main/pack.h" 35#include "main/pbo.h" 36#include "main/pixeltransfer.h" 37#include "main/state.h" 38 39#include "s_context.h" 40#include "s_span.h" 41#include "s_stencil.h" 42#include "s_zoom.h" 43 44 45/** 46 * Handle a common case of drawing GL_RGB/GL_UNSIGNED_BYTE into a 47 * MESA_FORMAT_XRGB888 or MESA_FORMAT_ARGB888 renderbuffer. 48 */ 49static void 50fast_draw_rgb_ubyte_pixels(struct gl_context *ctx, 51 struct gl_renderbuffer *rb, 52 GLint x, GLint y, 53 GLsizei width, GLsizei height, 54 const struct gl_pixelstore_attrib *unpack, 55 const GLvoid *pixels) 56{ 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); 62 GLint i, j; 63 GLubyte *dst; 64 GLint dstRowStride; 65 66 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, 67 GL_MAP_WRITE_BIT, &dst, &dstRowStride); 68 69 if (!dst) { 70 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); 71 return; 72 } 73 74 if (ctx->Pixel.ZoomY == -1.0f) { 75 dst = dst + (height - 1) * dstRowStride; 76 dstRowStride = -dstRowStride; 77 } 78 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]); 83 } 84 dst += dstRowStride; 85 src += srcRowStride; 86 } 87 88 ctx->Driver.UnmapRenderbuffer(ctx, rb); 89} 90 91 92/** 93 * Handle a common case of drawing GL_RGBA/GL_UNSIGNED_BYTE into a 94 * MESA_FORMAT_ARGB888 or MESA_FORMAT_xRGB888 renderbuffer. 95 */ 96static void 97fast_draw_rgba_ubyte_pixels(struct gl_context *ctx, 98 struct gl_renderbuffer *rb, 99 GLint x, GLint y, 100 GLsizei width, GLsizei height, 101 const struct gl_pixelstore_attrib *unpack, 102 const GLvoid *pixels) 103{ 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); 109 GLint i, j; 110 GLubyte *dst; 111 GLint dstRowStride; 112 113 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, 114 GL_MAP_WRITE_BIT, &dst, &dstRowStride); 115 116 if (!dst) { 117 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); 118 return; 119 } 120 121 if (ctx->Pixel.ZoomY == -1.0f) { 122 dst = dst + (height - 1) * dstRowStride; 123 dstRowStride = -dstRowStride; 124 } 125 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]); 131 } 132 dst += dstRowStride; 133 src += srcRowStride; 134 } 135 136 ctx->Driver.UnmapRenderbuffer(ctx, rb); 137} 138 139 140/** 141 * Handle a common case of drawing a format/type combination that 142 * exactly matches the renderbuffer format. 143 */ 144static void 145fast_draw_generic_pixels(struct gl_context *ctx, 146 struct gl_renderbuffer *rb, 147 GLint x, GLint y, 148 GLsizei width, GLsizei height, 149 GLenum format, GLenum type, 150 const struct gl_pixelstore_attrib *unpack, 151 const GLvoid *pixels) 152{ 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); 159 GLint i; 160 GLubyte *dst; 161 GLint dstRowStride; 162 163 ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, 164 GL_MAP_WRITE_BIT, &dst, &dstRowStride); 165 166 if (!dst) { 167 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); 168 return; 169 } 170 171 if (ctx->Pixel.ZoomY == -1.0f) { 172 dst = dst + (height - 1) * dstRowStride; 173 dstRowStride = -dstRowStride; 174 } 175 176 for (i = 0; i < height; i++) { 177 memcpy(dst, src, rowLength); 178 dst += dstRowStride; 179 src += srcRowStride; 180 } 181 182 ctx->Driver.UnmapRenderbuffer(ctx, rb); 183} 184 185 186/** 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 189 */ 190static GLboolean 191fast_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) 196{ 197 struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; 198 SWcontext *swrast = SWRAST_CONTEXT(ctx); 199 struct gl_pixelstore_attrib unpack; 200 201 if (!rb) 202 return GL_TRUE; /* no-op */ 203 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 */ 212 return GL_FALSE; 213 } 214 215 unpack = *userUnpack; 216 217 /* clipping */ 218 if (!_mesa_clip_drawpixels(ctx, &x, &y, &width, &height, &unpack)) { 219 /* image was completely clipped: no-op, all done */ 220 return GL_TRUE; 221 } 222 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, 228 &unpack, pixels); 229 return GL_TRUE; 230 } 231 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, 237 &unpack, pixels); 238 return GL_TRUE; 239 } 240 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); 244 return GL_TRUE; 245 } 246 247 /* can't handle this pixel format and/or data type */ 248 return GL_FALSE; 249} 250 251 252 253/* 254 * Draw stencil image. 255 */ 256static void 257draw_stencil_pixels( struct gl_context *ctx, GLint x, GLint y, 258 GLsizei width, GLsizei height, 259 GLenum type, 260 const struct gl_pixelstore_attrib *unpack, 261 const GLvoid *pixels ) 262{ 263 const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0; 264 const GLenum destType = GL_UNSIGNED_BYTE; 265 GLint skipPixels; 266 267 /* if width > MAX_WIDTH, have to process image in chunks */ 268 skipPixels = 0; 269 while (skipPixels < width) { 270 const GLint spanX = x + skipPixels; 271 const GLint spanWidth = MIN2(width - skipPixels, MAX_WIDTH); 272 GLint row; 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, 277 width, height, 278 GL_STENCIL_INDEX, type, 279 row, skipPixels); 280 _mesa_unpack_stencil_span(ctx, spanWidth, destType, values, 281 type, source, unpack, 282 ctx->_ImageTransferState); 283 if (zoom) { 284 _swrast_write_zoomed_stencil_span(ctx, x, y, spanWidth, 285 spanX, spanY, values); 286 } 287 else { 288 _swrast_write_stencil_span(ctx, spanWidth, spanX, spanY, values); 289 } 290 } 291 skipPixels += spanWidth; 292 } 293} 294 295 296/* 297 * Draw depth image. 298 */ 299static void 300draw_depth_pixels( struct gl_context *ctx, GLint x, GLint y, 301 GLsizei width, GLsizei height, 302 GLenum type, 303 const struct gl_pixelstore_attrib *unpack, 304 const GLvoid *pixels ) 305{ 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; 309 SWspan span; 310 311 INIT_SPAN(span, GL_BITMAP); 312 span.arrayMask = SPAN_Z; 313 _swrast_span_default_attribs(ctx, &span); 314 315 if (type == GL_UNSIGNED_SHORT 316 && ctx->DrawBuffer->Visual.depthBits == 16 317 && !scaleOrBias 318 && !zoom 319 && width <= MAX_WIDTH 320 && !unpack->SwapBytes) { 321 /* Special case: directly write 16-bit depth values */ 322 GLint row; 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); 327 GLint i; 328 for (i = 0; i < width; i++) 329 span.array->z[i] = zSrc[i]; 330 span.x = x; 331 span.y = y + row; 332 span.end = width; 333 _swrast_write_rgba_span(ctx, &span); 334 } 335 } 336 else if (type == GL_UNSIGNED_INT 337 && !scaleOrBias 338 && !zoom 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; 343 GLint row; 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); 348 if (shift == 0) { 349 memcpy(span.array->z, zSrc, width * sizeof(GLuint)); 350 } 351 else { 352 GLint col; 353 for (col = 0; col < width; col++) 354 span.array->z[col] = zSrc[col] >> shift; 355 } 356 span.x = x; 357 span.y = y + row; 358 span.end = width; 359 _swrast_write_rgba_span(ctx, &span); 360 } 361 } 362 else { 363 /* General case */ 364 const GLuint depthMax = ctx->DrawBuffer->_DepthMax; 365 GLint skipPixels = 0; 366 367 /* in case width > MAX_WIDTH do the copy in chunks */ 368 while (skipPixels < width) { 369 const GLint spanWidth = MIN2(width - skipPixels, MAX_WIDTH); 370 GLint row; 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, 376 row, skipPixels); 377 378 /* Set these for each row since the _swrast_write_* function may 379 * change them while clipping. 380 */ 381 span.x = x + skipPixels; 382 span.y = y + row; 383 span.end = spanWidth; 384 385 _mesa_unpack_depth_span(ctx, spanWidth, 386 GL_UNSIGNED_INT, span.array->z, depthMax, 387 type, zSrc, unpack); 388 if (zoom) { 389 _swrast_write_zoomed_depth_span(ctx, x, y, &span); 390 } 391 else { 392 _swrast_write_rgba_span(ctx, &span); 393 } 394 } 395 skipPixels += spanWidth; 396 } 397 } 398} 399 400 401 402/** 403 * Draw RGBA image. 404 */ 405static void 406draw_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 ) 411{ 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; 416 SWspan span; 417 418 /* Try an optimized glDrawPixels first */ 419 if (fast_draw_rgba_pixels(ctx, x, y, width, height, format, type, 420 unpack, pixels)) { 421 return; 422 } 423 424 swrast_render_start(ctx); 425 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 */ 430 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; 436 } 437 438 /* 439 * General solution 440 */ 441 { 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]; 449 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); 457 GLint row; 458 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, 463 transferOps); 464 /* Set these for each row since the _swrast_write_* functions 465 * may change them while clipping/rendering. 466 */ 467 span.array->ChanType = GL_FLOAT; 468 span.x = x + skipPixels; 469 span.y = y + row; 470 span.end = spanWidth; 471 span.arrayMask = arrayMask; 472 span.interpMask = interpMask; 473 if (zoom) { 474 _swrast_write_zoomed_rgba_span(ctx, imgX, imgY, &span, rgba); 475 } 476 else { 477 _swrast_write_rgba_span(ctx, &span); 478 } 479 480 source += srcStride; 481 } /* for row */ 482 483 skipPixels += spanWidth; 484 } /* while skipPixels < width */ 485 486 /* XXX this is ugly/temporary, to undo above change */ 487 span.array->ChanType = CHAN_TYPE; 488 } 489 490 if (convImage) { 491 free(convImage); 492 } 493 494 swrast_render_finish(ctx); 495} 496 497 498/** 499 * Draw depth+stencil values into a MESA_FORAMT_Z24_S8 or MESA_FORMAT_S8_Z24 500 * renderbuffer. No masking, zooming, scaling, etc. 501 */ 502static void 503fast_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) 507{ 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; 512 GLubyte *src, *dst; 513 GLint srcRowStride, dstRowStride; 514 GLint i; 515 516 src = _mesa_image_address2d(unpack, pixels, width, height, 517 format, type, 0, 0); 518 srcRowStride = _mesa_image_row_stride(unpack, width, format, type); 519 520 dst = _swrast_pixel_address(rb, x, y); 521 dstRowStride = rb->RowStride * 4; 522 523 for (i = 0; i < height; i++) { 524 _mesa_pack_uint_24_8_depth_stencil_row(rb->Format, width, 525 (const GLuint *) src, dst); 526 dst += dstRowStride; 527 src += srcRowStride; 528 } 529} 530 531 532 533/** 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, 537 * and pixel zoom. 538 * Also, only the depth buffer and stencil buffers are touched, not the 539 * color buffer(s). 540 */ 541static void 542draw_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) 546{ 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; 556 557 if (!zoom) { 558 if (!_mesa_clip_drawpixels(ctx, &x, &y, &width, &height, 559 &clippedUnpack)) { 560 /* totally clipped */ 561 return; 562 } 563 } 564 565 depthRb = ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; 566 stencilRb = ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; 567 ASSERT(depthRb); 568 ASSERT(stencilRb); 569 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 && 574 !scaleOrBias && 575 !zoom && 576 ctx->Depth.Mask && 577 (stencilMask & 0xff) == 0xff) { 578 fast_draw_depth_stencil(ctx, x, y, width, height, 579 &clippedUnpack, pixels); 580 } 581 else { 582 /* sub-optimal cases: 583 * Separate depth/stencil buffers, or pixel transfer ops required. 584 */ 585 /* XXX need to handle very wide images (skippixels) */ 586 GLint i; 587 588 depthRb = ctx->DrawBuffer->_DepthBuffer; 589 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); 594 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]; 600 GLint j; 601 ASSERT(depthRb->DataType == GL_UNSIGNED_INT); 602 for (j = 0; j < width; j++) { 603 zValues[j] = depthStencilSrc[j] >> 8; 604 } 605 if (zoom) 606 _swrast_write_zoomed_z_span(ctx, imgX, imgY, width, 607 x, y + i, zValues); 608 else 609 depthRb->PutRow(ctx, depthRb, width, x, y + i, zValues,NULL); 610 } 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]; 615 GLint j; 616 ASSERT(depthRb->DataType == GL_UNSIGNED_SHORT); 617 for (j = 0; j < width; j++) { 618 zValues[j] = depthStencilSrc[j] >> 16; 619 } 620 if (zoom) 621 _swrast_write_zoomed_z_span(ctx, imgX, imgY, width, 622 x, y + i, zValues); 623 else 624 depthRb->PutRow(ctx, depthRb, width, x, y + i, zValues,NULL); 625 } 626 else { 627 /* general case */ 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); 632 if (zoom) { 633 _swrast_write_zoomed_z_span(ctx, imgX, imgY, width, x, 634 y + i, zValues); 635 } 636 else { 637 depthRb->PutRow(ctx, depthRb, width, x, y + i, zValues,NULL); 638 } 639 } 640 } 641 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); 648 if (zoom) 649 _swrast_write_zoomed_stencil_span(ctx, imgX, imgY, width, 650 x, y + i, stencilValues); 651 else 652 _swrast_write_stencil_span(ctx, width, x, y + i, stencilValues); 653 } 654 } 655 } 656} 657 658 659/** 660 * Execute software-based glDrawPixels. 661 * By time we get here, all error checking will have been done. 662 */ 663void 664_swrast_DrawPixels( struct gl_context *ctx, 665 GLint x, GLint y, 666 GLsizei width, GLsizei height, 667 GLenum format, GLenum type, 668 const struct gl_pixelstore_attrib *unpack, 669 const GLvoid *pixels ) 670{ 671 SWcontext *swrast = SWRAST_CONTEXT(ctx); 672 GLboolean save_vp_override = ctx->VertexProgram._Overriden; 673 674 if (!_mesa_check_conditional_render(ctx)) 675 return; /* don't draw */ 676 677 /* We are creating fragments directly, without going through vertex 678 * programs. 679 * 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 683 * vertex array. 684 */ 685 _mesa_set_vp_override(ctx, GL_TRUE); 686 687 if (ctx->NewState) 688 _mesa_update_state(ctx); 689 690 if (swrast->NewState) 691 _swrast_validate_derived( ctx ); 692 693 pixels = _mesa_map_pbo_source(ctx, unpack, pixels); 694 if (!pixels) { 695 _mesa_set_vp_override(ctx, save_vp_override); 696 return; 697 } 698 699 /* 700 * By time we get here, all error checking should have been done. 701 */ 702 switch (format) { 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); 707 break; 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); 712 break; 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); 717 break; 718 default: 719 /* all other formats should be color formats */ 720 draw_rgba_pixels(ctx, x, y, width, height, format, type, unpack, pixels); 721 } 722 723 _mesa_set_vp_override(ctx, save_vp_override); 724 725 _mesa_unmap_pbo_source(ctx, unpack); 726} 727