1 /************************************************************************** 2 * 3 * Copyright 2007 VMware, Inc. 4 * 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 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28 /* 29 * Authors: 30 * Brian Paul 31 */ 32 33 #include "main/imports.h" 34 #include "main/image.h" 35 #include "main/bufferobj.h" 36 #include "main/blit.h" 37 #include "main/format_pack.h" 38 #include "main/framebuffer.h" 39 #include "main/macros.h" 40 #include "main/mtypes.h" 41 #include "main/pack.h" 42 #include "main/pbo.h" 43 #include "main/readpix.h" 44 #include "main/state.h" 45 #include "main/texformat.h" 46 #include "main/teximage.h" 47 #include "main/texstore.h" 48 #include "main/glformats.h" 49 #include "program/program.h" 50 #include "program/prog_print.h" 51 #include "program/prog_instruction.h" 52 53 #include "st_atom.h" 54 #include "st_atom_constbuf.h" 55 #include "st_cb_bitmap.h" 56 #include "st_cb_drawpixels.h" 57 #include "st_cb_readpixels.h" 58 #include "st_cb_fbo.h" 59 #include "st_context.h" 60 #include "st_debug.h" 61 #include "st_draw.h" 62 #include "st_format.h" 63 #include "st_program.h" 64 #include "st_sampler_view.h" 65 #include "st_scissor.h" 66 #include "st_texture.h" 67 68 #include "pipe/p_context.h" 69 #include "pipe/p_defines.h" 70 #include "tgsi/tgsi_ureg.h" 71 #include "util/u_format.h" 72 #include "util/u_inlines.h" 73 #include "util/u_math.h" 74 #include "util/u_tile.h" 75 #include "cso_cache/cso_context.h" 76 77 78 /** 79 * We have a simple glDrawPixels cache to try to optimize the case where the 80 * same image is drawn over and over again. It basically works as follows: 81 * 82 * 1. After we construct a texture map with the image and draw it, we do 83 * not discard the texture. We keep it around, plus we note the 84 * glDrawPixels width, height, format, etc. parameters and keep a copy 85 * of the image in a malloc'd buffer. 86 * 87 * 2. On the next glDrawPixels we check if the parameters match the previous 88 * call. If those match, we check if the image matches the previous image 89 * via a memcmp() call. If everything matches, we re-use the previous 90 * texture, thereby avoiding the cost creating a new texture and copying 91 * the image to it. 92 * 93 * The effectiveness of this cache depends upon: 94 * 1. If the memcmp() finds a difference, it happens relatively quickly. 95 Hopefully, not just the last pixels differ! 96 * 2. If the memcmp() finds no difference, doing that check is faster than 97 * creating and loading a texture. 98 * 99 * Notes: 100 * 1. We don't support any pixel unpacking parameters. 101 * 2. We don't try to cache images in Pixel Buffer Objects. 102 * 3. Instead of saving the whole image, perhaps some sort of reliable 103 * checksum function could be used instead. 104 */ 105 #define USE_DRAWPIXELS_CACHE 1 106 107 108 109 /** 110 * Create fragment program that does a TEX() instruction to get a Z and/or 111 * stencil value value, then writes to FRAG_RESULT_DEPTH/FRAG_RESULT_STENCIL. 112 * Used for glDrawPixels(GL_DEPTH_COMPONENT / GL_STENCIL_INDEX). 113 * Pass fragment color through as-is. 114 * 115 * \return CSO of the fragment shader. 116 */ 117 static void * 118 get_drawpix_z_stencil_program(struct st_context *st, 119 GLboolean write_depth, 120 GLboolean write_stencil) 121 { 122 struct ureg_program *ureg; 123 struct ureg_src depth_sampler, stencil_sampler; 124 struct ureg_src texcoord, color; 125 struct ureg_dst out_color, out_depth, out_stencil; 126 const GLuint shaderIndex = write_depth * 2 + write_stencil; 127 void *cso; 128 129 assert(shaderIndex < ARRAY_SIZE(st->drawpix.zs_shaders)); 130 131 if (st->drawpix.zs_shaders[shaderIndex]) { 132 /* already have the proper shader */ 133 return st->drawpix.zs_shaders[shaderIndex]; 134 } 135 136 ureg = ureg_create(PIPE_SHADER_FRAGMENT); 137 if (ureg == NULL) 138 return NULL; 139 140 ureg_property(ureg, TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS, TRUE); 141 142 if (write_depth) { 143 color = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_COLOR, 0, 144 TGSI_INTERPOLATE_COLOR); 145 out_color = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0); 146 147 depth_sampler = ureg_DECL_sampler(ureg, 0); 148 ureg_DECL_sampler_view(ureg, 0, TGSI_TEXTURE_2D, 149 TGSI_RETURN_TYPE_FLOAT, 150 TGSI_RETURN_TYPE_FLOAT, 151 TGSI_RETURN_TYPE_FLOAT, 152 TGSI_RETURN_TYPE_FLOAT); 153 out_depth = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0); 154 } 155 156 if (write_stencil) { 157 stencil_sampler = ureg_DECL_sampler(ureg, 1); 158 ureg_DECL_sampler_view(ureg, 1, TGSI_TEXTURE_2D, 159 TGSI_RETURN_TYPE_UINT, 160 TGSI_RETURN_TYPE_UINT, 161 TGSI_RETURN_TYPE_UINT, 162 TGSI_RETURN_TYPE_UINT); 163 out_stencil = ureg_DECL_output(ureg, TGSI_SEMANTIC_STENCIL, 0); 164 } 165 166 texcoord = ureg_DECL_fs_input(ureg, 167 st->needs_texcoord_semantic ? 168 TGSI_SEMANTIC_TEXCOORD : 169 TGSI_SEMANTIC_GENERIC, 170 0, TGSI_INTERPOLATE_LINEAR); 171 172 if (write_depth) { 173 ureg_TEX(ureg, ureg_writemask(out_depth, TGSI_WRITEMASK_Z), 174 TGSI_TEXTURE_2D, texcoord, depth_sampler); 175 ureg_MOV(ureg, out_color, color); 176 } 177 178 if (write_stencil) 179 ureg_TEX(ureg, ureg_writemask(out_stencil, TGSI_WRITEMASK_Y), 180 TGSI_TEXTURE_2D, texcoord, stencil_sampler); 181 182 ureg_END(ureg); 183 cso = ureg_create_shader_and_destroy(ureg, st->pipe); 184 185 /* save the new shader */ 186 st->drawpix.zs_shaders[shaderIndex] = cso; 187 return cso; 188 } 189 190 191 /** 192 * Create a simple vertex shader that just passes through the 193 * vertex position and texcoord (and optionally, color). 194 */ 195 static void * 196 make_passthrough_vertex_shader(struct st_context *st, 197 GLboolean passColor) 198 { 199 const unsigned texcoord_semantic = st->needs_texcoord_semantic ? 200 TGSI_SEMANTIC_TEXCOORD : TGSI_SEMANTIC_GENERIC; 201 202 if (!st->drawpix.vert_shaders[passColor]) { 203 struct ureg_program *ureg = ureg_create( PIPE_SHADER_VERTEX ); 204 205 if (ureg == NULL) 206 return NULL; 207 208 /* MOV result.pos, vertex.pos; */ 209 ureg_MOV(ureg, 210 ureg_DECL_output( ureg, TGSI_SEMANTIC_POSITION, 0 ), 211 ureg_DECL_vs_input( ureg, 0 )); 212 213 if (passColor) { 214 /* MOV result.color0, vertex.attr[1]; */ 215 ureg_MOV(ureg, 216 ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, 0 ), 217 ureg_DECL_vs_input( ureg, 1 )); 218 } 219 220 /* MOV result.texcoord0, vertex.attr[2]; */ 221 ureg_MOV(ureg, 222 ureg_DECL_output( ureg, texcoord_semantic, 0 ), 223 ureg_DECL_vs_input( ureg, 2 )); 224 225 ureg_END( ureg ); 226 227 st->drawpix.vert_shaders[passColor] = 228 ureg_create_shader_and_destroy( ureg, st->pipe ); 229 } 230 231 return st->drawpix.vert_shaders[passColor]; 232 } 233 234 235 /** 236 * Return a texture internalFormat for drawing/copying an image 237 * of the given format and type. 238 */ 239 static GLenum 240 internal_format(struct gl_context *ctx, GLenum format, GLenum type) 241 { 242 switch (format) { 243 case GL_DEPTH_COMPONENT: 244 switch (type) { 245 case GL_UNSIGNED_SHORT: 246 return GL_DEPTH_COMPONENT16; 247 248 case GL_UNSIGNED_INT: 249 return GL_DEPTH_COMPONENT32; 250 251 case GL_FLOAT: 252 if (ctx->Extensions.ARB_depth_buffer_float) 253 return GL_DEPTH_COMPONENT32F; 254 else 255 return GL_DEPTH_COMPONENT; 256 257 default: 258 return GL_DEPTH_COMPONENT; 259 } 260 261 case GL_DEPTH_STENCIL: 262 switch (type) { 263 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: 264 return GL_DEPTH32F_STENCIL8; 265 266 case GL_UNSIGNED_INT_24_8: 267 default: 268 return GL_DEPTH24_STENCIL8; 269 } 270 271 case GL_STENCIL_INDEX: 272 return GL_STENCIL_INDEX; 273 274 default: 275 if (_mesa_is_enum_format_integer(format)) { 276 switch (type) { 277 case GL_BYTE: 278 return GL_RGBA8I; 279 case GL_UNSIGNED_BYTE: 280 return GL_RGBA8UI; 281 case GL_SHORT: 282 return GL_RGBA16I; 283 case GL_UNSIGNED_SHORT: 284 return GL_RGBA16UI; 285 case GL_INT: 286 return GL_RGBA32I; 287 case GL_UNSIGNED_INT: 288 return GL_RGBA32UI; 289 default: 290 assert(0 && "Unexpected type in internal_format()"); 291 return GL_RGBA_INTEGER; 292 } 293 } 294 else { 295 switch (type) { 296 case GL_UNSIGNED_BYTE: 297 case GL_UNSIGNED_INT_8_8_8_8: 298 case GL_UNSIGNED_INT_8_8_8_8_REV: 299 default: 300 return GL_RGBA8; 301 302 case GL_UNSIGNED_BYTE_3_3_2: 303 case GL_UNSIGNED_BYTE_2_3_3_REV: 304 return GL_R3_G3_B2; 305 306 case GL_UNSIGNED_SHORT_4_4_4_4: 307 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 308 return GL_RGBA4; 309 310 case GL_UNSIGNED_SHORT_5_6_5: 311 case GL_UNSIGNED_SHORT_5_6_5_REV: 312 return GL_RGB565; 313 314 case GL_UNSIGNED_SHORT_5_5_5_1: 315 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 316 return GL_RGB5_A1; 317 318 case GL_UNSIGNED_INT_10_10_10_2: 319 case GL_UNSIGNED_INT_2_10_10_10_REV: 320 return GL_RGB10_A2; 321 322 case GL_UNSIGNED_SHORT: 323 case GL_UNSIGNED_INT: 324 return GL_RGBA16; 325 326 case GL_BYTE: 327 return 328 ctx->Extensions.EXT_texture_snorm ? GL_RGBA8_SNORM : GL_RGBA8; 329 330 case GL_SHORT: 331 case GL_INT: 332 return 333 ctx->Extensions.EXT_texture_snorm ? GL_RGBA16_SNORM : GL_RGBA16; 334 335 case GL_HALF_FLOAT_ARB: 336 return 337 ctx->Extensions.ARB_texture_float ? GL_RGBA16F : 338 ctx->Extensions.EXT_texture_snorm ? GL_RGBA16_SNORM : GL_RGBA16; 339 340 case GL_FLOAT: 341 case GL_DOUBLE: 342 return 343 ctx->Extensions.ARB_texture_float ? GL_RGBA32F : 344 ctx->Extensions.EXT_texture_snorm ? GL_RGBA16_SNORM : GL_RGBA16; 345 346 case GL_UNSIGNED_INT_5_9_9_9_REV: 347 assert(ctx->Extensions.EXT_texture_shared_exponent); 348 return GL_RGB9_E5; 349 350 case GL_UNSIGNED_INT_10F_11F_11F_REV: 351 assert(ctx->Extensions.EXT_packed_float); 352 return GL_R11F_G11F_B10F; 353 } 354 } 355 } 356 } 357 358 359 /** 360 * Create a temporary texture to hold an image of the given size. 361 * If width, height are not POT and the driver only handles POT textures, 362 * allocate the next larger size of texture that is POT. 363 */ 364 static struct pipe_resource * 365 alloc_texture(struct st_context *st, GLsizei width, GLsizei height, 366 enum pipe_format texFormat, unsigned bind) 367 { 368 struct pipe_resource *pt; 369 370 pt = st_texture_create(st, st->internal_target, texFormat, 0, 371 width, height, 1, 1, 0, bind); 372 373 return pt; 374 } 375 376 377 /** 378 * Make texture containing an image for glDrawPixels image. 379 * If 'pixels' is NULL, leave the texture image data undefined. 380 */ 381 static struct pipe_resource * 382 make_texture(struct st_context *st, 383 GLsizei width, GLsizei height, GLenum format, GLenum type, 384 const struct gl_pixelstore_attrib *unpack, 385 const void *pixels) 386 { 387 struct gl_context *ctx = st->ctx; 388 struct pipe_context *pipe = st->pipe; 389 mesa_format mformat; 390 struct pipe_resource *pt = NULL; 391 enum pipe_format pipeFormat; 392 GLenum baseInternalFormat; 393 394 #if USE_DRAWPIXELS_CACHE 395 const GLint bpp = _mesa_bytes_per_pixel(format, type); 396 397 /* Check if the glDrawPixels() parameters and state matches the cache */ 398 if (width == st->drawpix_cache.width && 399 height == st->drawpix_cache.height && 400 format == st->drawpix_cache.format && 401 type == st->drawpix_cache.type && 402 pixels == st->drawpix_cache.user_pointer && 403 !_mesa_is_bufferobj(unpack->BufferObj) && 404 (unpack->RowLength == 0 || unpack->RowLength == width) && 405 unpack->SkipPixels == 0 && 406 unpack->SkipRows == 0 && 407 unpack->SwapBytes == GL_FALSE && 408 st->drawpix_cache.image) { 409 assert(st->drawpix_cache.texture); 410 411 /* check if the pixel data is the same */ 412 if (memcmp(pixels, st->drawpix_cache.image, width * height * bpp) == 0) { 413 /* OK, re-use the cached texture */ 414 pipe_resource_reference(&pt, st->drawpix_cache.texture); 415 /* refcount of returned texture should be at least two here. One 416 * reference for the cache to hold on to, one for the caller (which 417 * it will release), and possibly more held by the driver. 418 */ 419 assert(pt->reference.count >= 2); 420 return pt; 421 } 422 } 423 424 /* discard the cached image and texture (if there is one) */ 425 st->drawpix_cache.width = 0; 426 st->drawpix_cache.height = 0; 427 st->drawpix_cache.user_pointer = NULL; 428 if (st->drawpix_cache.image) { 429 free(st->drawpix_cache.image); 430 st->drawpix_cache.image = NULL; 431 } 432 pipe_resource_reference(&st->drawpix_cache.texture, NULL); 433 #endif 434 435 /* Choose a pixel format for the temp texture which will hold the 436 * image to draw. 437 */ 438 pipeFormat = st_choose_matching_format(st, PIPE_BIND_SAMPLER_VIEW, 439 format, type, unpack->SwapBytes); 440 441 if (pipeFormat == PIPE_FORMAT_NONE) { 442 /* Use the generic approach. */ 443 GLenum intFormat = internal_format(ctx, format, type); 444 445 pipeFormat = st_choose_format(st, intFormat, format, type, 446 st->internal_target, 0, 447 PIPE_BIND_SAMPLER_VIEW, FALSE); 448 assert(pipeFormat != PIPE_FORMAT_NONE); 449 } 450 451 mformat = st_pipe_format_to_mesa_format(pipeFormat); 452 baseInternalFormat = _mesa_get_format_base_format(mformat); 453 454 pixels = _mesa_map_pbo_source(ctx, unpack, pixels); 455 if (!pixels) 456 return NULL; 457 458 /* alloc temporary texture */ 459 pt = alloc_texture(st, width, height, pipeFormat, PIPE_BIND_SAMPLER_VIEW); 460 if (!pt) { 461 _mesa_unmap_pbo_source(ctx, unpack); 462 return NULL; 463 } 464 465 { 466 struct pipe_transfer *transfer; 467 GLubyte *dest; 468 const GLbitfield imageTransferStateSave = ctx->_ImageTransferState; 469 470 /* we'll do pixel transfer in a fragment shader */ 471 ctx->_ImageTransferState = 0x0; 472 473 /* map texture transfer */ 474 dest = pipe_transfer_map(pipe, pt, 0, 0, 475 PIPE_TRANSFER_WRITE, 0, 0, 476 width, height, &transfer); 477 478 479 /* Put image into texture transfer. 480 * Note that the image is actually going to be upside down in 481 * the texture. We deal with that with texcoords. 482 */ 483 if ((format == GL_RGBA || format == GL_BGRA) 484 && type == GL_UNSIGNED_BYTE) { 485 /* Use a memcpy-based texstore to avoid software pixel swizzling. 486 * We'll do the necessary swizzling with the pipe_sampler_view to 487 * give much better performance. 488 * XXX in the future, expand this to accomodate more format and 489 * type combinations. 490 */ 491 _mesa_memcpy_texture(ctx, 2, 492 mformat, /* mesa_format */ 493 transfer->stride, /* dstRowStride, bytes */ 494 &dest, /* destSlices */ 495 width, height, 1, /* size */ 496 format, type, /* src format/type */ 497 pixels, /* data source */ 498 unpack); 499 } 500 else { 501 bool MAYBE_UNUSED success; 502 success = _mesa_texstore(ctx, 2, /* dims */ 503 baseInternalFormat, /* baseInternalFormat */ 504 mformat, /* mesa_format */ 505 transfer->stride, /* dstRowStride, bytes */ 506 &dest, /* destSlices */ 507 width, height, 1, /* size */ 508 format, type, /* src format/type */ 509 pixels, /* data source */ 510 unpack); 511 512 assert(success); 513 } 514 515 /* unmap */ 516 pipe_transfer_unmap(pipe, transfer); 517 518 /* restore */ 519 ctx->_ImageTransferState = imageTransferStateSave; 520 } 521 522 _mesa_unmap_pbo_source(ctx, unpack); 523 524 #if USE_DRAWPIXELS_CACHE 525 /* Save the glDrawPixels parameter and image in the cache */ 526 if ((unpack->RowLength == 0 || unpack->RowLength == width) && 527 unpack->SkipPixels == 0 && 528 unpack->SkipRows == 0) { 529 st->drawpix_cache.width = width; 530 st->drawpix_cache.height = height; 531 st->drawpix_cache.format = format; 532 st->drawpix_cache.type = type; 533 st->drawpix_cache.user_pointer = pixels; 534 assert(!st->drawpix_cache.image); 535 st->drawpix_cache.image = malloc(width * height * bpp); 536 if (st->drawpix_cache.image) { 537 memcpy(st->drawpix_cache.image, pixels, width * height * bpp); 538 pipe_resource_reference(&st->drawpix_cache.texture, pt); 539 } 540 else { 541 /* out of memory, free/disable cached texture */ 542 st->drawpix_cache.width = 0; 543 st->drawpix_cache.height = 0; 544 pipe_resource_reference(&st->drawpix_cache.texture, NULL); 545 } 546 } 547 #endif 548 549 return pt; 550 } 551 552 553 static void 554 draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z, 555 GLsizei width, GLsizei height, 556 GLfloat zoomX, GLfloat zoomY, 557 struct pipe_sampler_view **sv, 558 int num_sampler_view, 559 void *driver_vp, 560 void *driver_fp, 561 struct st_fp_variant *fpv, 562 const GLfloat *color, 563 GLboolean invertTex, 564 GLboolean write_depth, GLboolean write_stencil) 565 { 566 struct st_context *st = st_context(ctx); 567 struct pipe_context *pipe = st->pipe; 568 struct cso_context *cso = st->cso_context; 569 const unsigned fb_width = _mesa_geometric_width(ctx->DrawBuffer); 570 const unsigned fb_height = _mesa_geometric_height(ctx->DrawBuffer); 571 GLfloat x0, y0, x1, y1; 572 GLsizei MAYBE_UNUSED maxSize; 573 boolean normalized = sv[0]->texture->target == PIPE_TEXTURE_2D; 574 unsigned cso_state_mask; 575 576 assert(sv[0]->texture->target == st->internal_target); 577 578 /* limit checks */ 579 /* XXX if DrawPixels image is larger than max texture size, break 580 * it up into chunks. 581 */ 582 maxSize = 1 << (pipe->screen->get_param(pipe->screen, 583 PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1); 584 assert(width <= maxSize); 585 assert(height <= maxSize); 586 587 cso_state_mask = (CSO_BIT_RASTERIZER | 588 CSO_BIT_VIEWPORT | 589 CSO_BIT_FRAGMENT_SAMPLERS | 590 CSO_BIT_FRAGMENT_SAMPLER_VIEWS | 591 CSO_BIT_STREAM_OUTPUTS | 592 CSO_BIT_VERTEX_ELEMENTS | 593 CSO_BIT_AUX_VERTEX_BUFFER_SLOT | 594 CSO_BITS_ALL_SHADERS); 595 if (write_stencil) { 596 cso_state_mask |= (CSO_BIT_DEPTH_STENCIL_ALPHA | 597 CSO_BIT_BLEND); 598 } 599 cso_save_state(cso, cso_state_mask); 600 601 /* rasterizer state: just scissor */ 602 { 603 struct pipe_rasterizer_state rasterizer; 604 memset(&rasterizer, 0, sizeof(rasterizer)); 605 rasterizer.clamp_fragment_color = !st->clamp_frag_color_in_shader && 606 ctx->Color._ClampFragmentColor; 607 rasterizer.half_pixel_center = 1; 608 rasterizer.bottom_edge_rule = 1; 609 rasterizer.depth_clip = !ctx->Transform.DepthClamp; 610 rasterizer.scissor = ctx->Scissor.EnableFlags; 611 cso_set_rasterizer(cso, &rasterizer); 612 } 613 614 if (write_stencil) { 615 /* Stencil writing bypasses the normal fragment pipeline to 616 * disable color writing and set stencil test to always pass. 617 */ 618 struct pipe_depth_stencil_alpha_state dsa; 619 struct pipe_blend_state blend; 620 621 /* depth/stencil */ 622 memset(&dsa, 0, sizeof(dsa)); 623 dsa.stencil[0].enabled = 1; 624 dsa.stencil[0].func = PIPE_FUNC_ALWAYS; 625 dsa.stencil[0].writemask = ctx->Stencil.WriteMask[0] & 0xff; 626 dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE; 627 if (write_depth) { 628 /* writing depth+stencil: depth test always passes */ 629 dsa.depth.enabled = 1; 630 dsa.depth.writemask = ctx->Depth.Mask; 631 dsa.depth.func = PIPE_FUNC_ALWAYS; 632 } 633 cso_set_depth_stencil_alpha(cso, &dsa); 634 635 /* blend (colormask) */ 636 memset(&blend, 0, sizeof(blend)); 637 cso_set_blend(cso, &blend); 638 } 639 640 /* fragment shader state: TEX lookup program */ 641 cso_set_fragment_shader_handle(cso, driver_fp); 642 643 /* vertex shader state: position + texcoord pass-through */ 644 cso_set_vertex_shader_handle(cso, driver_vp); 645 646 /* disable other shaders */ 647 cso_set_tessctrl_shader_handle(cso, NULL); 648 cso_set_tesseval_shader_handle(cso, NULL); 649 cso_set_geometry_shader_handle(cso, NULL); 650 651 /* user samplers, plus the drawpix samplers */ 652 { 653 struct pipe_sampler_state sampler; 654 655 memset(&sampler, 0, sizeof(sampler)); 656 sampler.wrap_s = PIPE_TEX_WRAP_CLAMP; 657 sampler.wrap_t = PIPE_TEX_WRAP_CLAMP; 658 sampler.wrap_r = PIPE_TEX_WRAP_CLAMP; 659 sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; 660 sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; 661 sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; 662 sampler.normalized_coords = normalized; 663 664 if (fpv) { 665 /* drawing a color image */ 666 const struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS]; 667 uint num = MAX3(fpv->drawpix_sampler + 1, 668 fpv->pixelmap_sampler + 1, 669 st->state.num_samplers[PIPE_SHADER_FRAGMENT]); 670 uint i; 671 672 for (i = 0; i < st->state.num_samplers[PIPE_SHADER_FRAGMENT]; i++) 673 samplers[i] = &st->state.samplers[PIPE_SHADER_FRAGMENT][i]; 674 675 samplers[fpv->drawpix_sampler] = &sampler; 676 if (sv[1]) 677 samplers[fpv->pixelmap_sampler] = &sampler; 678 679 cso_set_samplers(cso, PIPE_SHADER_FRAGMENT, num, samplers); 680 } else { 681 /* drawing a depth/stencil image */ 682 const struct pipe_sampler_state *samplers[2] = {&sampler, &sampler}; 683 684 cso_set_samplers(cso, PIPE_SHADER_FRAGMENT, num_sampler_view, samplers); 685 } 686 } 687 688 /* user textures, plus the drawpix textures */ 689 if (fpv) { 690 /* drawing a color image */ 691 struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS]; 692 uint num = MAX3(fpv->drawpix_sampler + 1, 693 fpv->pixelmap_sampler + 1, 694 st->state.num_sampler_views[PIPE_SHADER_FRAGMENT]); 695 696 memcpy(sampler_views, st->state.sampler_views[PIPE_SHADER_FRAGMENT], 697 sizeof(sampler_views)); 698 699 sampler_views[fpv->drawpix_sampler] = sv[0]; 700 if (sv[1]) 701 sampler_views[fpv->pixelmap_sampler] = sv[1]; 702 cso_set_sampler_views(cso, PIPE_SHADER_FRAGMENT, num, sampler_views); 703 } else { 704 /* drawing a depth/stencil image */ 705 cso_set_sampler_views(cso, PIPE_SHADER_FRAGMENT, num_sampler_view, sv); 706 } 707 708 /* viewport state: viewport matching window dims */ 709 cso_set_viewport_dims(cso, fb_width, fb_height, TRUE); 710 711 cso_set_vertex_elements(cso, 3, st->util_velems); 712 cso_set_stream_outputs(cso, 0, NULL, NULL); 713 714 /* Compute Gallium window coords (y=0=top) with pixel zoom. 715 * Recall that these coords are transformed by the current 716 * vertex shader and viewport transformation. 717 */ 718 if (st_fb_orientation(ctx->DrawBuffer) == Y_0_BOTTOM) { 719 y = fb_height - (int) (y + height * ctx->Pixel.ZoomY); 720 invertTex = !invertTex; 721 } 722 723 x0 = (GLfloat) x; 724 x1 = x + width * ctx->Pixel.ZoomX; 725 y0 = (GLfloat) y; 726 y1 = y + height * ctx->Pixel.ZoomY; 727 728 /* convert Z from [0,1] to [-1,-1] to match viewport Z scale/bias */ 729 z = z * 2.0f - 1.0f; 730 731 { 732 const float clip_x0 = x0 / (float) fb_width * 2.0f - 1.0f; 733 const float clip_y0 = y0 / (float) fb_height * 2.0f - 1.0f; 734 const float clip_x1 = x1 / (float) fb_width * 2.0f - 1.0f; 735 const float clip_y1 = y1 / (float) fb_height * 2.0f - 1.0f; 736 const float maxXcoord = normalized ? 737 ((float) width / sv[0]->texture->width0) : (float) width; 738 const float maxYcoord = normalized 739 ? ((float) height / sv[0]->texture->height0) : (float) height; 740 const float sLeft = 0.0f, sRight = maxXcoord; 741 const float tTop = invertTex ? maxYcoord : 0.0f; 742 const float tBot = invertTex ? 0.0f : maxYcoord; 743 744 if (!st_draw_quad(st, clip_x0, clip_y0, clip_x1, clip_y1, z, 745 sLeft, tBot, sRight, tTop, color, 0)) { 746 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); 747 } 748 } 749 750 /* restore state */ 751 cso_restore_state(cso); 752 } 753 754 755 /** 756 * Software fallback to do glDrawPixels(GL_STENCIL_INDEX) when we 757 * can't use a fragment shader to write stencil values. 758 */ 759 static void 760 draw_stencil_pixels(struct gl_context *ctx, GLint x, GLint y, 761 GLsizei width, GLsizei height, GLenum format, GLenum type, 762 const struct gl_pixelstore_attrib *unpack, 763 const void *pixels) 764 { 765 struct st_context *st = st_context(ctx); 766 struct pipe_context *pipe = st->pipe; 767 struct st_renderbuffer *strb; 768 enum pipe_transfer_usage usage; 769 struct pipe_transfer *pt; 770 const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0; 771 ubyte *stmap; 772 struct gl_pixelstore_attrib clippedUnpack = *unpack; 773 GLubyte *sValues; 774 GLuint *zValues; 775 776 if (!zoom) { 777 if (!_mesa_clip_drawpixels(ctx, &x, &y, &width, &height, 778 &clippedUnpack)) { 779 /* totally clipped */ 780 return; 781 } 782 } 783 784 strb = st_renderbuffer(ctx->DrawBuffer-> 785 Attachment[BUFFER_STENCIL].Renderbuffer); 786 787 if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { 788 y = ctx->DrawBuffer->Height - y - height; 789 } 790 791 if (format == GL_STENCIL_INDEX && 792 _mesa_is_format_packed_depth_stencil(strb->Base.Format)) { 793 /* writing stencil to a combined depth+stencil buffer */ 794 usage = PIPE_TRANSFER_READ_WRITE; 795 } 796 else { 797 usage = PIPE_TRANSFER_WRITE; 798 } 799 800 stmap = pipe_transfer_map(pipe, strb->texture, 801 strb->surface->u.tex.level, 802 strb->surface->u.tex.first_layer, 803 usage, x, y, 804 width, height, &pt); 805 806 pixels = _mesa_map_pbo_source(ctx, &clippedUnpack, pixels); 807 assert(pixels); 808 809 sValues = malloc(width * sizeof(GLubyte)); 810 zValues = malloc(width * sizeof(GLuint)); 811 812 if (sValues && zValues) { 813 GLint row; 814 for (row = 0; row < height; row++) { 815 GLfloat *zValuesFloat = (GLfloat*)zValues; 816 GLenum destType = GL_UNSIGNED_BYTE; 817 const void *source = _mesa_image_address2d(&clippedUnpack, pixels, 818 width, height, 819 format, type, 820 row, 0); 821 _mesa_unpack_stencil_span(ctx, width, destType, sValues, 822 type, source, &clippedUnpack, 823 ctx->_ImageTransferState); 824 825 if (format == GL_DEPTH_STENCIL) { 826 GLenum ztype = 827 pt->resource->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT ? 828 GL_FLOAT : GL_UNSIGNED_INT; 829 830 _mesa_unpack_depth_span(ctx, width, ztype, zValues, 831 (1 << 24) - 1, type, source, 832 &clippedUnpack); 833 } 834 835 if (zoom) { 836 _mesa_problem(ctx, "Gallium glDrawPixels(GL_STENCIL) with " 837 "zoom not complete"); 838 } 839 840 { 841 GLint spanY; 842 843 if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { 844 spanY = height - row - 1; 845 } 846 else { 847 spanY = row; 848 } 849 850 /* now pack the stencil (and Z) values in the dest format */ 851 switch (pt->resource->format) { 852 case PIPE_FORMAT_S8_UINT: 853 { 854 ubyte *dest = stmap + spanY * pt->stride; 855 assert(usage == PIPE_TRANSFER_WRITE); 856 memcpy(dest, sValues, width); 857 } 858 break; 859 case PIPE_FORMAT_Z24_UNORM_S8_UINT: 860 if (format == GL_DEPTH_STENCIL) { 861 uint *dest = (uint *) (stmap + spanY * pt->stride); 862 GLint k; 863 assert(usage == PIPE_TRANSFER_WRITE); 864 for (k = 0; k < width; k++) { 865 dest[k] = zValues[k] | (sValues[k] << 24); 866 } 867 } 868 else { 869 uint *dest = (uint *) (stmap + spanY * pt->stride); 870 GLint k; 871 assert(usage == PIPE_TRANSFER_READ_WRITE); 872 for (k = 0; k < width; k++) { 873 dest[k] = (dest[k] & 0xffffff) | (sValues[k] << 24); 874 } 875 } 876 break; 877 case PIPE_FORMAT_S8_UINT_Z24_UNORM: 878 if (format == GL_DEPTH_STENCIL) { 879 uint *dest = (uint *) (stmap + spanY * pt->stride); 880 GLint k; 881 assert(usage == PIPE_TRANSFER_WRITE); 882 for (k = 0; k < width; k++) { 883 dest[k] = (zValues[k] << 8) | (sValues[k] & 0xff); 884 } 885 } 886 else { 887 uint *dest = (uint *) (stmap + spanY * pt->stride); 888 GLint k; 889 assert(usage == PIPE_TRANSFER_READ_WRITE); 890 for (k = 0; k < width; k++) { 891 dest[k] = (dest[k] & 0xffffff00) | (sValues[k] & 0xff); 892 } 893 } 894 break; 895 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: 896 if (format == GL_DEPTH_STENCIL) { 897 uint *dest = (uint *) (stmap + spanY * pt->stride); 898 GLfloat *destf = (GLfloat*)dest; 899 GLint k; 900 assert(usage == PIPE_TRANSFER_WRITE); 901 for (k = 0; k < width; k++) { 902 destf[k*2] = zValuesFloat[k]; 903 dest[k*2+1] = sValues[k] & 0xff; 904 } 905 } 906 else { 907 uint *dest = (uint *) (stmap + spanY * pt->stride); 908 GLint k; 909 assert(usage == PIPE_TRANSFER_READ_WRITE); 910 for (k = 0; k < width; k++) { 911 dest[k*2+1] = sValues[k] & 0xff; 912 } 913 } 914 break; 915 default: 916 assert(0); 917 } 918 } 919 } 920 } 921 else { 922 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels()"); 923 } 924 925 free(sValues); 926 free(zValues); 927 928 _mesa_unmap_pbo_source(ctx, &clippedUnpack); 929 930 /* unmap the stencil buffer */ 931 pipe_transfer_unmap(pipe, pt); 932 } 933 934 935 /** 936 * Get fragment program variant for a glDrawPixels or glCopyPixels 937 * command for RGBA data. 938 */ 939 static struct st_fp_variant * 940 get_color_fp_variant(struct st_context *st) 941 { 942 struct gl_context *ctx = st->ctx; 943 struct st_fp_variant_key key; 944 struct st_fp_variant *fpv; 945 946 memset(&key, 0, sizeof(key)); 947 948 key.st = st->has_shareable_shaders ? NULL : st; 949 key.drawpixels = 1; 950 key.scaleAndBias = (ctx->Pixel.RedBias != 0.0 || 951 ctx->Pixel.RedScale != 1.0 || 952 ctx->Pixel.GreenBias != 0.0 || 953 ctx->Pixel.GreenScale != 1.0 || 954 ctx->Pixel.BlueBias != 0.0 || 955 ctx->Pixel.BlueScale != 1.0 || 956 ctx->Pixel.AlphaBias != 0.0 || 957 ctx->Pixel.AlphaScale != 1.0); 958 key.pixelMaps = ctx->Pixel.MapColorFlag; 959 key.clamp_color = st->clamp_frag_color_in_shader && 960 ctx->Color._ClampFragmentColor; 961 962 fpv = st_get_fp_variant(st, st->fp, &key); 963 964 return fpv; 965 } 966 967 968 /** 969 * Clamp glDrawPixels width and height to the maximum texture size. 970 */ 971 static void 972 clamp_size(struct pipe_context *pipe, GLsizei *width, GLsizei *height, 973 struct gl_pixelstore_attrib *unpack) 974 { 975 const int maxSize = 976 1 << (pipe->screen->get_param(pipe->screen, 977 PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1); 978 979 if (*width > maxSize) { 980 if (unpack->RowLength == 0) 981 unpack->RowLength = *width; 982 *width = maxSize; 983 } 984 if (*height > maxSize) { 985 *height = maxSize; 986 } 987 } 988 989 990 /** 991 * Search the array of 4 swizzle components for the named component and return 992 * its position. 993 */ 994 static unsigned 995 search_swizzle(const unsigned char swizzle[4], unsigned component) 996 { 997 unsigned i; 998 for (i = 0; i < 4; i++) { 999 if (swizzle[i] == component) 1000 return i; 1001 } 1002 assert(!"search_swizzle() failed"); 1003 return 0; 1004 } 1005 1006 1007 /** 1008 * Set the sampler view's swizzle terms. This is used to handle RGBA 1009 * swizzling when the incoming image format isn't an exact match for 1010 * the actual texture format. For example, if we have glDrawPixels( 1011 * GL_RGBA, GL_UNSIGNED_BYTE) and we chose the texture format 1012 * PIPE_FORMAT_B8G8R8A8 then we can do use the sampler view swizzle to 1013 * avoid swizzling all the pixels in software in the texstore code. 1014 */ 1015 static void 1016 setup_sampler_swizzle(struct pipe_sampler_view *sv, GLenum format, GLenum type) 1017 { 1018 if ((format == GL_RGBA || format == GL_BGRA) && type == GL_UNSIGNED_BYTE) { 1019 const struct util_format_description *desc = 1020 util_format_description(sv->texture->format); 1021 unsigned c0, c1, c2, c3; 1022 1023 /* Every gallium driver supports at least one 32-bit packed RGBA format. 1024 * We must have chosen one for (GL_RGBA, GL_UNSIGNED_BYTE). 1025 */ 1026 assert(desc->block.bits == 32); 1027 1028 /* invert the format's swizzle to setup the sampler's swizzle */ 1029 if (format == GL_RGBA) { 1030 c0 = PIPE_SWIZZLE_X; 1031 c1 = PIPE_SWIZZLE_Y; 1032 c2 = PIPE_SWIZZLE_Z; 1033 c3 = PIPE_SWIZZLE_W; 1034 } 1035 else { 1036 assert(format == GL_BGRA); 1037 c0 = PIPE_SWIZZLE_Z; 1038 c1 = PIPE_SWIZZLE_Y; 1039 c2 = PIPE_SWIZZLE_X; 1040 c3 = PIPE_SWIZZLE_W; 1041 } 1042 sv->swizzle_r = search_swizzle(desc->swizzle, c0); 1043 sv->swizzle_g = search_swizzle(desc->swizzle, c1); 1044 sv->swizzle_b = search_swizzle(desc->swizzle, c2); 1045 sv->swizzle_a = search_swizzle(desc->swizzle, c3); 1046 } 1047 else { 1048 /* use the default sampler swizzle */ 1049 } 1050 } 1051 1052 1053 /** 1054 * Called via ctx->Driver.DrawPixels() 1055 */ 1056 static void 1057 st_DrawPixels(struct gl_context *ctx, GLint x, GLint y, 1058 GLsizei width, GLsizei height, 1059 GLenum format, GLenum type, 1060 const struct gl_pixelstore_attrib *unpack, const void *pixels) 1061 { 1062 void *driver_vp, *driver_fp; 1063 struct st_context *st = st_context(ctx); 1064 struct pipe_context *pipe = st->pipe; 1065 GLboolean write_stencil = GL_FALSE, write_depth = GL_FALSE; 1066 struct pipe_sampler_view *sv[2] = { NULL }; 1067 int num_sampler_view = 1; 1068 struct gl_pixelstore_attrib clippedUnpack; 1069 struct st_fp_variant *fpv = NULL; 1070 struct pipe_resource *pt; 1071 1072 /* Mesa state should be up to date by now */ 1073 assert(ctx->NewState == 0x0); 1074 1075 _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer); 1076 1077 st_flush_bitmap_cache(st); 1078 st_invalidate_readpix_cache(st); 1079 1080 st_validate_state(st, ST_PIPELINE_RENDER); 1081 1082 /* Limit the size of the glDrawPixels to the max texture size. 1083 * Strictly speaking, that's not correct but since we don't handle 1084 * larger images yet, this is better than crashing. 1085 */ 1086 clippedUnpack = *unpack; 1087 unpack = &clippedUnpack; 1088 clamp_size(st->pipe, &width, &height, &clippedUnpack); 1089 1090 if (format == GL_DEPTH_STENCIL) 1091 write_stencil = write_depth = GL_TRUE; 1092 else if (format == GL_STENCIL_INDEX) 1093 write_stencil = GL_TRUE; 1094 else if (format == GL_DEPTH_COMPONENT) 1095 write_depth = GL_TRUE; 1096 1097 if (write_stencil && 1098 !pipe->screen->get_param(pipe->screen, PIPE_CAP_SHADER_STENCIL_EXPORT)) { 1099 /* software fallback */ 1100 draw_stencil_pixels(ctx, x, y, width, height, format, type, 1101 unpack, pixels); 1102 return; 1103 } 1104 1105 /* 1106 * Get vertex/fragment shaders 1107 */ 1108 if (write_depth || write_stencil) { 1109 driver_fp = get_drawpix_z_stencil_program(st, write_depth, 1110 write_stencil); 1111 driver_vp = make_passthrough_vertex_shader(st, GL_TRUE); 1112 } 1113 else { 1114 fpv = get_color_fp_variant(st); 1115 1116 driver_fp = fpv->driver_shader; 1117 driver_vp = make_passthrough_vertex_shader(st, GL_FALSE); 1118 1119 if (ctx->Pixel.MapColorFlag) { 1120 pipe_sampler_view_reference(&sv[1], 1121 st->pixel_xfer.pixelmap_sampler_view); 1122 num_sampler_view++; 1123 } 1124 1125 /* compiling a new fragment shader variant added new state constants 1126 * into the constant buffer, we need to update them 1127 */ 1128 st_upload_constants(st, &st->fp->Base); 1129 } 1130 1131 /* Put glDrawPixels image into a texture */ 1132 pt = make_texture(st, width, height, format, type, unpack, pixels); 1133 if (!pt) { 1134 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); 1135 return; 1136 } 1137 1138 /* create sampler view for the image */ 1139 sv[0] = st_create_texture_sampler_view(st->pipe, pt); 1140 if (!sv[0]) { 1141 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); 1142 pipe_resource_reference(&pt, NULL); 1143 return; 1144 } 1145 1146 /* Set up the sampler view's swizzle */ 1147 setup_sampler_swizzle(sv[0], format, type); 1148 1149 /* Create a second sampler view to read stencil. The stencil is 1150 * written using the shader stencil export functionality. 1151 */ 1152 if (write_stencil) { 1153 enum pipe_format stencil_format = 1154 util_format_stencil_only(pt->format); 1155 /* we should not be doing pixel map/transfer (see above) */ 1156 assert(num_sampler_view == 1); 1157 sv[1] = st_create_texture_sampler_view_format(st->pipe, pt, 1158 stencil_format); 1159 if (!sv[1]) { 1160 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); 1161 pipe_resource_reference(&pt, NULL); 1162 pipe_sampler_view_reference(&sv[0], NULL); 1163 return; 1164 } 1165 num_sampler_view++; 1166 } 1167 1168 draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2], 1169 width, height, 1170 ctx->Pixel.ZoomX, ctx->Pixel.ZoomY, 1171 sv, 1172 num_sampler_view, 1173 driver_vp, 1174 driver_fp, fpv, 1175 ctx->Current.RasterColor, 1176 GL_FALSE, write_depth, write_stencil); 1177 pipe_sampler_view_reference(&sv[0], NULL); 1178 if (num_sampler_view > 1) 1179 pipe_sampler_view_reference(&sv[1], NULL); 1180 1181 /* free the texture (but may persist in the cache) */ 1182 pipe_resource_reference(&pt, NULL); 1183 } 1184 1185 1186 1187 /** 1188 * Software fallback for glCopyPixels(GL_STENCIL). 1189 */ 1190 static void 1191 copy_stencil_pixels(struct gl_context *ctx, GLint srcx, GLint srcy, 1192 GLsizei width, GLsizei height, 1193 GLint dstx, GLint dsty) 1194 { 1195 struct st_renderbuffer *rbDraw; 1196 struct pipe_context *pipe = st_context(ctx)->pipe; 1197 enum pipe_transfer_usage usage; 1198 struct pipe_transfer *ptDraw; 1199 ubyte *drawMap; 1200 ubyte *buffer; 1201 int i; 1202 1203 buffer = malloc(width * height * sizeof(ubyte)); 1204 if (!buffer) { 1205 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels(stencil)"); 1206 return; 1207 } 1208 1209 /* Get the dest renderbuffer */ 1210 rbDraw = st_renderbuffer(ctx->DrawBuffer-> 1211 Attachment[BUFFER_STENCIL].Renderbuffer); 1212 1213 /* this will do stencil pixel transfer ops */ 1214 _mesa_readpixels(ctx, srcx, srcy, width, height, 1215 GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, 1216 &ctx->DefaultPacking, buffer); 1217 1218 if (0) { 1219 /* debug code: dump stencil values */ 1220 GLint row, col; 1221 for (row = 0; row < height; row++) { 1222 printf("%3d: ", row); 1223 for (col = 0; col < width; col++) { 1224 printf("%02x ", buffer[col + row * width]); 1225 } 1226 printf("\n"); 1227 } 1228 } 1229 1230 if (_mesa_is_format_packed_depth_stencil(rbDraw->Base.Format)) 1231 usage = PIPE_TRANSFER_READ_WRITE; 1232 else 1233 usage = PIPE_TRANSFER_WRITE; 1234 1235 if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { 1236 dsty = rbDraw->Base.Height - dsty - height; 1237 } 1238 1239 assert(util_format_get_blockwidth(rbDraw->texture->format) == 1); 1240 assert(util_format_get_blockheight(rbDraw->texture->format) == 1); 1241 1242 /* map the stencil buffer */ 1243 drawMap = pipe_transfer_map(pipe, 1244 rbDraw->texture, 1245 rbDraw->surface->u.tex.level, 1246 rbDraw->surface->u.tex.first_layer, 1247 usage, dstx, dsty, 1248 width, height, &ptDraw); 1249 1250 /* draw */ 1251 /* XXX PixelZoom not handled yet */ 1252 for (i = 0; i < height; i++) { 1253 ubyte *dst; 1254 const ubyte *src; 1255 int y; 1256 1257 y = i; 1258 1259 if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { 1260 y = height - y - 1; 1261 } 1262 1263 dst = drawMap + y * ptDraw->stride; 1264 src = buffer + i * width; 1265 1266 _mesa_pack_ubyte_stencil_row(rbDraw->Base.Format, width, src, dst); 1267 } 1268 1269 free(buffer); 1270 1271 /* unmap the stencil buffer */ 1272 pipe_transfer_unmap(pipe, ptDraw); 1273 } 1274 1275 1276 /** 1277 * Return renderbuffer to use for reading color pixels for glCopyPixels 1278 */ 1279 static struct st_renderbuffer * 1280 st_get_color_read_renderbuffer(struct gl_context *ctx) 1281 { 1282 struct gl_framebuffer *fb = ctx->ReadBuffer; 1283 struct st_renderbuffer *strb = 1284 st_renderbuffer(fb->_ColorReadBuffer); 1285 1286 return strb; 1287 } 1288 1289 1290 /** 1291 * Try to do a glCopyPixels for simple cases with a blit by calling 1292 * pipe->blit(). 1293 * 1294 * We can do this when we're copying color pixels (depth/stencil 1295 * eventually) with no pixel zoom, no pixel transfer ops, no 1296 * per-fragment ops, and the src/dest regions don't overlap. 1297 */ 1298 static GLboolean 1299 blit_copy_pixels(struct gl_context *ctx, GLint srcx, GLint srcy, 1300 GLsizei width, GLsizei height, 1301 GLint dstx, GLint dsty, GLenum type) 1302 { 1303 struct st_context *st = st_context(ctx); 1304 struct pipe_context *pipe = st->pipe; 1305 struct pipe_screen *screen = pipe->screen; 1306 struct gl_pixelstore_attrib pack, unpack; 1307 GLint readX, readY, readW, readH, drawX, drawY, drawW, drawH; 1308 1309 if (type == GL_COLOR && 1310 ctx->Pixel.ZoomX == 1.0 && 1311 ctx->Pixel.ZoomY == 1.0 && 1312 ctx->_ImageTransferState == 0x0 && 1313 !ctx->Color.BlendEnabled && 1314 !ctx->Color.AlphaEnabled && 1315 (!ctx->Color.ColorLogicOpEnabled || ctx->Color.LogicOp == GL_COPY) && 1316 !ctx->Depth.Test && 1317 !ctx->Fog.Enabled && 1318 !ctx->Stencil.Enabled && 1319 !ctx->FragmentProgram.Enabled && 1320 !ctx->VertexProgram.Enabled && 1321 !ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT] && 1322 !_mesa_ati_fragment_shader_enabled(ctx) && 1323 ctx->DrawBuffer->_NumColorDrawBuffers == 1 && 1324 !ctx->Query.CondRenderQuery && 1325 !ctx->Query.CurrentOcclusionObject) { 1326 struct st_renderbuffer *rbRead, *rbDraw; 1327 1328 /* 1329 * Clip the read region against the src buffer bounds. 1330 * We'll still allocate a temporary buffer/texture for the original 1331 * src region size but we'll only read the region which is on-screen. 1332 * This may mean that we draw garbage pixels into the dest region, but 1333 * that's expected. 1334 */ 1335 readX = srcx; 1336 readY = srcy; 1337 readW = width; 1338 readH = height; 1339 pack = ctx->DefaultPacking; 1340 if (!_mesa_clip_readpixels(ctx, &readX, &readY, &readW, &readH, &pack)) 1341 return GL_TRUE; /* all done */ 1342 1343 /* clip against dest buffer bounds and scissor box */ 1344 drawX = dstx + pack.SkipPixels; 1345 drawY = dsty + pack.SkipRows; 1346 unpack = pack; 1347 if (!_mesa_clip_drawpixels(ctx, &drawX, &drawY, &readW, &readH, &unpack)) 1348 return GL_TRUE; /* all done */ 1349 1350 readX = readX - pack.SkipPixels + unpack.SkipPixels; 1351 readY = readY - pack.SkipRows + unpack.SkipRows; 1352 1353 drawW = readW; 1354 drawH = readH; 1355 1356 rbRead = st_get_color_read_renderbuffer(ctx); 1357 rbDraw = st_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]); 1358 1359 /* Flip src/dst position depending on the orientation of buffers. */ 1360 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 1361 readY = rbRead->Base.Height - readY; 1362 readH = -readH; 1363 } 1364 1365 if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { 1366 /* We can't flip the destination for pipe->blit, so we only adjust 1367 * its position and flip the source. 1368 */ 1369 drawY = rbDraw->Base.Height - drawY - drawH; 1370 readY += readH; 1371 readH = -readH; 1372 } 1373 1374 if (rbRead != rbDraw || 1375 !_mesa_regions_overlap(readX, readY, readX + readW, readY + readH, 1376 drawX, drawY, drawX + drawW, drawY + drawH)) { 1377 struct pipe_blit_info blit; 1378 1379 memset(&blit, 0, sizeof(blit)); 1380 blit.src.resource = rbRead->texture; 1381 blit.src.level = rbRead->surface->u.tex.level; 1382 blit.src.format = rbRead->texture->format; 1383 blit.src.box.x = readX; 1384 blit.src.box.y = readY; 1385 blit.src.box.z = rbRead->surface->u.tex.first_layer; 1386 blit.src.box.width = readW; 1387 blit.src.box.height = readH; 1388 blit.src.box.depth = 1; 1389 blit.dst.resource = rbDraw->texture; 1390 blit.dst.level = rbDraw->surface->u.tex.level; 1391 blit.dst.format = rbDraw->texture->format; 1392 blit.dst.box.x = drawX; 1393 blit.dst.box.y = drawY; 1394 blit.dst.box.z = rbDraw->surface->u.tex.first_layer; 1395 blit.dst.box.width = drawW; 1396 blit.dst.box.height = drawH; 1397 blit.dst.box.depth = 1; 1398 blit.mask = PIPE_MASK_RGBA; 1399 blit.filter = PIPE_TEX_FILTER_NEAREST; 1400 1401 if (ctx->DrawBuffer != ctx->WinSysDrawBuffer) 1402 st_window_rectangles_to_blit(ctx, &blit); 1403 1404 if (screen->is_format_supported(screen, blit.src.format, 1405 blit.src.resource->target, 1406 blit.src.resource->nr_samples, 1407 PIPE_BIND_SAMPLER_VIEW) && 1408 screen->is_format_supported(screen, blit.dst.format, 1409 blit.dst.resource->target, 1410 blit.dst.resource->nr_samples, 1411 PIPE_BIND_RENDER_TARGET)) { 1412 pipe->blit(pipe, &blit); 1413 return GL_TRUE; 1414 } 1415 } 1416 } 1417 1418 return GL_FALSE; 1419 } 1420 1421 1422 static void 1423 st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy, 1424 GLsizei width, GLsizei height, 1425 GLint dstx, GLint dsty, GLenum type) 1426 { 1427 struct st_context *st = st_context(ctx); 1428 struct pipe_context *pipe = st->pipe; 1429 struct pipe_screen *screen = pipe->screen; 1430 struct st_renderbuffer *rbRead; 1431 void *driver_vp, *driver_fp; 1432 struct pipe_resource *pt; 1433 struct pipe_sampler_view *sv[2] = { NULL }; 1434 struct st_fp_variant *fpv = NULL; 1435 int num_sampler_view = 1; 1436 enum pipe_format srcFormat; 1437 unsigned srcBind; 1438 GLboolean invertTex = GL_FALSE; 1439 GLint readX, readY, readW, readH; 1440 struct gl_pixelstore_attrib pack = ctx->DefaultPacking; 1441 1442 _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer); 1443 1444 st_flush_bitmap_cache(st); 1445 st_invalidate_readpix_cache(st); 1446 1447 st_validate_state(st, ST_PIPELINE_RENDER); 1448 1449 if (type == GL_DEPTH_STENCIL) { 1450 /* XXX make this more efficient */ 1451 st_CopyPixels(ctx, srcx, srcy, width, height, dstx, dsty, GL_STENCIL); 1452 st_CopyPixels(ctx, srcx, srcy, width, height, dstx, dsty, GL_DEPTH); 1453 return; 1454 } 1455 1456 if (type == GL_STENCIL) { 1457 /* can't use texturing to do stencil */ 1458 copy_stencil_pixels(ctx, srcx, srcy, width, height, dstx, dsty); 1459 return; 1460 } 1461 1462 if (blit_copy_pixels(ctx, srcx, srcy, width, height, dstx, dsty, type)) 1463 return; 1464 1465 /* 1466 * The subsequent code implements glCopyPixels by copying the source 1467 * pixels into a temporary texture that's then applied to a textured quad. 1468 * When we draw the textured quad, all the usual per-fragment operations 1469 * are handled. 1470 */ 1471 1472 1473 /* 1474 * Get vertex/fragment shaders 1475 */ 1476 if (type == GL_COLOR) { 1477 fpv = get_color_fp_variant(st); 1478 1479 rbRead = st_get_color_read_renderbuffer(ctx); 1480 1481 driver_fp = fpv->driver_shader; 1482 driver_vp = make_passthrough_vertex_shader(st, GL_FALSE); 1483 1484 if (ctx->Pixel.MapColorFlag) { 1485 pipe_sampler_view_reference(&sv[1], 1486 st->pixel_xfer.pixelmap_sampler_view); 1487 num_sampler_view++; 1488 } 1489 1490 /* compiling a new fragment shader variant added new state constants 1491 * into the constant buffer, we need to update them 1492 */ 1493 st_upload_constants(st, &st->fp->Base); 1494 } 1495 else { 1496 assert(type == GL_DEPTH); 1497 rbRead = st_renderbuffer(ctx->ReadBuffer-> 1498 Attachment[BUFFER_DEPTH].Renderbuffer); 1499 1500 driver_fp = get_drawpix_z_stencil_program(st, GL_TRUE, GL_FALSE); 1501 driver_vp = make_passthrough_vertex_shader(st, GL_TRUE); 1502 } 1503 1504 /* Choose the format for the temporary texture. */ 1505 srcFormat = rbRead->texture->format; 1506 srcBind = PIPE_BIND_SAMPLER_VIEW | 1507 (type == GL_COLOR ? PIPE_BIND_RENDER_TARGET : PIPE_BIND_DEPTH_STENCIL); 1508 1509 if (!screen->is_format_supported(screen, srcFormat, st->internal_target, 0, 1510 srcBind)) { 1511 /* srcFormat is non-renderable. Find a compatible renderable format. */ 1512 if (type == GL_DEPTH) { 1513 srcFormat = st_choose_format(st, GL_DEPTH_COMPONENT, GL_NONE, 1514 GL_NONE, st->internal_target, 0, 1515 srcBind, FALSE); 1516 } 1517 else { 1518 assert(type == GL_COLOR); 1519 1520 if (util_format_is_float(srcFormat)) { 1521 srcFormat = st_choose_format(st, GL_RGBA32F, GL_NONE, 1522 GL_NONE, st->internal_target, 0, 1523 srcBind, FALSE); 1524 } 1525 else if (util_format_is_pure_sint(srcFormat)) { 1526 srcFormat = st_choose_format(st, GL_RGBA32I, GL_NONE, 1527 GL_NONE, st->internal_target, 0, 1528 srcBind, FALSE); 1529 } 1530 else if (util_format_is_pure_uint(srcFormat)) { 1531 srcFormat = st_choose_format(st, GL_RGBA32UI, GL_NONE, 1532 GL_NONE, st->internal_target, 0, 1533 srcBind, FALSE); 1534 } 1535 else if (util_format_is_snorm(srcFormat)) { 1536 srcFormat = st_choose_format(st, GL_RGBA16_SNORM, GL_NONE, 1537 GL_NONE, st->internal_target, 0, 1538 srcBind, FALSE); 1539 } 1540 else { 1541 srcFormat = st_choose_format(st, GL_RGBA, GL_NONE, 1542 GL_NONE, st->internal_target, 0, 1543 srcBind, FALSE); 1544 } 1545 } 1546 1547 if (srcFormat == PIPE_FORMAT_NONE) { 1548 assert(0 && "cannot choose a format for src of CopyPixels"); 1549 return; 1550 } 1551 } 1552 1553 /* Invert src region if needed */ 1554 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 1555 srcy = ctx->ReadBuffer->Height - srcy - height; 1556 invertTex = !invertTex; 1557 } 1558 1559 /* Clip the read region against the src buffer bounds. 1560 * We'll still allocate a temporary buffer/texture for the original 1561 * src region size but we'll only read the region which is on-screen. 1562 * This may mean that we draw garbage pixels into the dest region, but 1563 * that's expected. 1564 */ 1565 readX = srcx; 1566 readY = srcy; 1567 readW = width; 1568 readH = height; 1569 if (!_mesa_clip_readpixels(ctx, &readX, &readY, &readW, &readH, &pack)) { 1570 /* The source region is completely out of bounds. Do nothing. 1571 * The GL spec says "Results of copies from outside the window, 1572 * or from regions of the window that are not exposed, are 1573 * hardware dependent and undefined." 1574 */ 1575 return; 1576 } 1577 1578 readW = MAX2(0, readW); 1579 readH = MAX2(0, readH); 1580 1581 /* Allocate the temporary texture. */ 1582 pt = alloc_texture(st, width, height, srcFormat, srcBind); 1583 if (!pt) 1584 return; 1585 1586 sv[0] = st_create_texture_sampler_view(st->pipe, pt); 1587 if (!sv[0]) { 1588 pipe_resource_reference(&pt, NULL); 1589 return; 1590 } 1591 1592 /* Copy the src region to the temporary texture. */ 1593 { 1594 struct pipe_blit_info blit; 1595 1596 memset(&blit, 0, sizeof(blit)); 1597 blit.src.resource = rbRead->texture; 1598 blit.src.level = rbRead->surface->u.tex.level; 1599 blit.src.format = rbRead->texture->format; 1600 blit.src.box.x = readX; 1601 blit.src.box.y = readY; 1602 blit.src.box.z = rbRead->surface->u.tex.first_layer; 1603 blit.src.box.width = readW; 1604 blit.src.box.height = readH; 1605 blit.src.box.depth = 1; 1606 blit.dst.resource = pt; 1607 blit.dst.level = 0; 1608 blit.dst.format = pt->format; 1609 blit.dst.box.x = pack.SkipPixels; 1610 blit.dst.box.y = pack.SkipRows; 1611 blit.dst.box.z = 0; 1612 blit.dst.box.width = readW; 1613 blit.dst.box.height = readH; 1614 blit.dst.box.depth = 1; 1615 blit.mask = util_format_get_mask(pt->format) & ~PIPE_MASK_S; 1616 blit.filter = PIPE_TEX_FILTER_NEAREST; 1617 1618 pipe->blit(pipe, &blit); 1619 } 1620 1621 /* OK, the texture 'pt' contains the src image/pixels. Now draw a 1622 * textured quad with that texture. 1623 */ 1624 draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2], 1625 width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY, 1626 sv, 1627 num_sampler_view, 1628 driver_vp, 1629 driver_fp, fpv, 1630 ctx->Current.Attrib[VERT_ATTRIB_COLOR0], 1631 invertTex, GL_FALSE, GL_FALSE); 1632 1633 pipe_resource_reference(&pt, NULL); 1634 pipe_sampler_view_reference(&sv[0], NULL); 1635 } 1636 1637 1638 1639 void st_init_drawpixels_functions(struct dd_function_table *functions) 1640 { 1641 functions->DrawPixels = st_DrawPixels; 1642 functions->CopyPixels = st_CopyPixels; 1643 } 1644 1645 1646 void 1647 st_destroy_drawpix(struct st_context *st) 1648 { 1649 GLuint i; 1650 1651 for (i = 0; i < ARRAY_SIZE(st->drawpix.zs_shaders); i++) { 1652 if (st->drawpix.zs_shaders[i]) 1653 cso_delete_fragment_shader(st->cso_context, 1654 st->drawpix.zs_shaders[i]); 1655 } 1656 1657 if (st->drawpix.vert_shaders[0]) 1658 cso_delete_vertex_shader(st->cso_context, st->drawpix.vert_shaders[0]); 1659 if (st->drawpix.vert_shaders[1]) 1660 cso_delete_vertex_shader(st->cso_context, st->drawpix.vert_shaders[1]); 1661 } 1662