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/texformat.h" 45#include "main/teximage.h" 46#include "main/texstore.h" 47#include "main/glformats.h" 48#include "program/program.h" 49#include "program/prog_print.h" 50#include "program/prog_instruction.h" 51 52#include "st_atom.h" 53#include "st_atom_constbuf.h" 54#include "st_cb_bitmap.h" 55#include "st_cb_drawpixels.h" 56#include "st_cb_readpixels.h" 57#include "st_cb_fbo.h" 58#include "st_context.h" 59#include "st_debug.h" 60#include "st_draw.h" 61#include "st_format.h" 62#include "st_program.h" 63#include "st_sampler_view.h" 64#include "st_scissor.h" 65#include "st_texture.h" 66 67#include "pipe/p_context.h" 68#include "pipe/p_defines.h" 69#include "tgsi/tgsi_ureg.h" 70#include "util/u_format.h" 71#include "util/u_inlines.h" 72#include "util/u_math.h" 73#include "util/u_tile.h" 74#include "cso_cache/cso_context.h" 75 76 77/** 78 * We have a simple glDrawPixels cache to try to optimize the case where the 79 * same image is drawn over and over again. It basically works as follows: 80 * 81 * 1. After we construct a texture map with the image and draw it, we do 82 * not discard the texture. We keep it around, plus we note the 83 * glDrawPixels width, height, format, etc. parameters and keep a copy 84 * of the image in a malloc'd buffer. 85 * 86 * 2. On the next glDrawPixels we check if the parameters match the previous 87 * call. If those match, we check if the image matches the previous image 88 * via a memcmp() call. If everything matches, we re-use the previous 89 * texture, thereby avoiding the cost creating a new texture and copying 90 * the image to it. 91 * 92 * The effectiveness of this cache depends upon: 93 * 1. If the memcmp() finds a difference, it happens relatively quickly. 94 Hopefully, not just the last pixels differ! 95 * 2. If the memcmp() finds no difference, doing that check is faster than 96 * creating and loading a texture. 97 * 98 * Notes: 99 * 1. We don't support any pixel unpacking parameters. 100 * 2. We don't try to cache images in Pixel Buffer Objects. 101 * 3. Instead of saving the whole image, perhaps some sort of reliable 102 * checksum function could be used instead. 103 */ 104#define USE_DRAWPIXELS_CACHE 1 105 106 107 108/** 109 * Create fragment program that does a TEX() instruction to get a Z and/or 110 * stencil value value, then writes to FRAG_RESULT_DEPTH/FRAG_RESULT_STENCIL. 111 * Used for glDrawPixels(GL_DEPTH_COMPONENT / GL_STENCIL_INDEX). 112 * Pass fragment color through as-is. 113 * 114 * \return CSO of the fragment shader. 115 */ 116static void * 117get_drawpix_z_stencil_program(struct st_context *st, 118 GLboolean write_depth, 119 GLboolean write_stencil) 120{ 121 struct ureg_program *ureg; 122 struct ureg_src depth_sampler, stencil_sampler; 123 struct ureg_src texcoord, color; 124 struct ureg_dst out_color, out_depth, out_stencil; 125 const GLuint shaderIndex = write_depth * 2 + write_stencil; 126 void *cso; 127 128 assert(shaderIndex < ARRAY_SIZE(st->drawpix.zs_shaders)); 129 130 if (st->drawpix.zs_shaders[shaderIndex]) { 131 /* already have the proper shader */ 132 return st->drawpix.zs_shaders[shaderIndex]; 133 } 134 135 ureg = ureg_create(PIPE_SHADER_FRAGMENT); 136 if (ureg == NULL) 137 return NULL; 138 139 ureg_property(ureg, TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS, TRUE); 140 141 if (write_depth) { 142 color = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_COLOR, 0, 143 TGSI_INTERPOLATE_COLOR); 144 out_color = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0); 145 146 depth_sampler = ureg_DECL_sampler(ureg, 0); 147 ureg_DECL_sampler_view(ureg, 0, TGSI_TEXTURE_2D, 148 TGSI_RETURN_TYPE_FLOAT, 149 TGSI_RETURN_TYPE_FLOAT, 150 TGSI_RETURN_TYPE_FLOAT, 151 TGSI_RETURN_TYPE_FLOAT); 152 out_depth = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0); 153 } 154 155 if (write_stencil) { 156 stencil_sampler = ureg_DECL_sampler(ureg, 1); 157 ureg_DECL_sampler_view(ureg, 1, TGSI_TEXTURE_2D, 158 TGSI_RETURN_TYPE_UINT, 159 TGSI_RETURN_TYPE_UINT, 160 TGSI_RETURN_TYPE_UINT, 161 TGSI_RETURN_TYPE_UINT); 162 out_stencil = ureg_DECL_output(ureg, TGSI_SEMANTIC_STENCIL, 0); 163 } 164 165 texcoord = ureg_DECL_fs_input(ureg, 166 st->needs_texcoord_semantic ? 167 TGSI_SEMANTIC_TEXCOORD : 168 TGSI_SEMANTIC_GENERIC, 169 0, TGSI_INTERPOLATE_LINEAR); 170 171 if (write_depth) { 172 ureg_TEX(ureg, ureg_writemask(out_depth, TGSI_WRITEMASK_Z), 173 TGSI_TEXTURE_2D, texcoord, depth_sampler); 174 ureg_MOV(ureg, out_color, color); 175 } 176 177 if (write_stencil) 178 ureg_TEX(ureg, ureg_writemask(out_stencil, TGSI_WRITEMASK_Y), 179 TGSI_TEXTURE_2D, texcoord, stencil_sampler); 180 181 ureg_END(ureg); 182 cso = ureg_create_shader_and_destroy(ureg, st->pipe); 183 184 /* save the new shader */ 185 st->drawpix.zs_shaders[shaderIndex] = cso; 186 return cso; 187} 188 189 190/** 191 * Create a simple vertex shader that just passes through the 192 * vertex position and texcoord (and optionally, color). 193 */ 194static void * 195make_passthrough_vertex_shader(struct st_context *st, 196 GLboolean passColor) 197{ 198 const unsigned texcoord_semantic = st->needs_texcoord_semantic ? 199 TGSI_SEMANTIC_TEXCOORD : TGSI_SEMANTIC_GENERIC; 200 201 if (!st->drawpix.vert_shaders[passColor]) { 202 struct ureg_program *ureg = ureg_create( PIPE_SHADER_VERTEX ); 203 204 if (ureg == NULL) 205 return NULL; 206 207 /* MOV result.pos, vertex.pos; */ 208 ureg_MOV(ureg, 209 ureg_DECL_output( ureg, TGSI_SEMANTIC_POSITION, 0 ), 210 ureg_DECL_vs_input( ureg, 0 )); 211 212 if (passColor) { 213 /* MOV result.color0, vertex.attr[1]; */ 214 ureg_MOV(ureg, 215 ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, 0 ), 216 ureg_DECL_vs_input( ureg, 1 )); 217 } 218 219 /* MOV result.texcoord0, vertex.attr[2]; */ 220 ureg_MOV(ureg, 221 ureg_DECL_output( ureg, texcoord_semantic, 0 ), 222 ureg_DECL_vs_input( ureg, 2 )); 223 224 ureg_END( ureg ); 225 226 st->drawpix.vert_shaders[passColor] = 227 ureg_create_shader_and_destroy( ureg, st->pipe ); 228 } 229 230 return st->drawpix.vert_shaders[passColor]; 231} 232 233 234/** 235 * Return a texture internalFormat for drawing/copying an image 236 * of the given format and type. 237 */ 238static GLenum 239internal_format(struct gl_context *ctx, GLenum format, GLenum type) 240{ 241 switch (format) { 242 case GL_DEPTH_COMPONENT: 243 switch (type) { 244 case GL_UNSIGNED_SHORT: 245 return GL_DEPTH_COMPONENT16; 246 247 case GL_UNSIGNED_INT: 248 return GL_DEPTH_COMPONENT32; 249 250 case GL_FLOAT: 251 if (ctx->Extensions.ARB_depth_buffer_float) 252 return GL_DEPTH_COMPONENT32F; 253 else 254 return GL_DEPTH_COMPONENT; 255 256 default: 257 return GL_DEPTH_COMPONENT; 258 } 259 260 case GL_DEPTH_STENCIL: 261 switch (type) { 262 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: 263 return GL_DEPTH32F_STENCIL8; 264 265 case GL_UNSIGNED_INT_24_8: 266 default: 267 return GL_DEPTH24_STENCIL8; 268 } 269 270 case GL_STENCIL_INDEX: 271 return GL_STENCIL_INDEX; 272 273 default: 274 if (_mesa_is_enum_format_integer(format)) { 275 switch (type) { 276 case GL_BYTE: 277 return GL_RGBA8I; 278 case GL_UNSIGNED_BYTE: 279 return GL_RGBA8UI; 280 case GL_SHORT: 281 return GL_RGBA16I; 282 case GL_UNSIGNED_SHORT: 283 return GL_RGBA16UI; 284 case GL_INT: 285 return GL_RGBA32I; 286 case GL_UNSIGNED_INT: 287 return GL_RGBA32UI; 288 default: 289 assert(0 && "Unexpected type in internal_format()"); 290 return GL_RGBA_INTEGER; 291 } 292 } 293 else { 294 switch (type) { 295 case GL_UNSIGNED_BYTE: 296 case GL_UNSIGNED_INT_8_8_8_8: 297 case GL_UNSIGNED_INT_8_8_8_8_REV: 298 default: 299 return GL_RGBA8; 300 301 case GL_UNSIGNED_BYTE_3_3_2: 302 case GL_UNSIGNED_BYTE_2_3_3_REV: 303 return GL_R3_G3_B2; 304 305 case GL_UNSIGNED_SHORT_4_4_4_4: 306 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 307 return GL_RGBA4; 308 309 case GL_UNSIGNED_SHORT_5_6_5: 310 case GL_UNSIGNED_SHORT_5_6_5_REV: 311 return GL_RGB565; 312 313 case GL_UNSIGNED_SHORT_5_5_5_1: 314 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 315 return GL_RGB5_A1; 316 317 case GL_UNSIGNED_INT_10_10_10_2: 318 case GL_UNSIGNED_INT_2_10_10_10_REV: 319 return GL_RGB10_A2; 320 321 case GL_UNSIGNED_SHORT: 322 case GL_UNSIGNED_INT: 323 return GL_RGBA16; 324 325 case GL_BYTE: 326 return 327 ctx->Extensions.EXT_texture_snorm ? GL_RGBA8_SNORM : GL_RGBA8; 328 329 case GL_SHORT: 330 case GL_INT: 331 return 332 ctx->Extensions.EXT_texture_snorm ? GL_RGBA16_SNORM : GL_RGBA16; 333 334 case GL_HALF_FLOAT_ARB: 335 return 336 ctx->Extensions.ARB_texture_float ? GL_RGBA16F : 337 ctx->Extensions.EXT_texture_snorm ? GL_RGBA16_SNORM : GL_RGBA16; 338 339 case GL_FLOAT: 340 case GL_DOUBLE: 341 return 342 ctx->Extensions.ARB_texture_float ? GL_RGBA32F : 343 ctx->Extensions.EXT_texture_snorm ? GL_RGBA16_SNORM : GL_RGBA16; 344 345 case GL_UNSIGNED_INT_5_9_9_9_REV: 346 assert(ctx->Extensions.EXT_texture_shared_exponent); 347 return GL_RGB9_E5; 348 349 case GL_UNSIGNED_INT_10F_11F_11F_REV: 350 assert(ctx->Extensions.EXT_packed_float); 351 return GL_R11F_G11F_B10F; 352 } 353 } 354 } 355} 356 357 358/** 359 * Create a temporary texture to hold an image of the given size. 360 * If width, height are not POT and the driver only handles POT textures, 361 * allocate the next larger size of texture that is POT. 362 */ 363static struct pipe_resource * 364alloc_texture(struct st_context *st, GLsizei width, GLsizei height, 365 enum pipe_format texFormat, unsigned bind) 366{ 367 struct pipe_resource *pt; 368 369 pt = st_texture_create(st, st->internal_target, texFormat, 0, 370 width, height, 1, 1, 0, bind); 371 372 return pt; 373} 374 375 376/** 377 * Make texture containing an image for glDrawPixels image. 378 * If 'pixels' is NULL, leave the texture image data undefined. 379 */ 380static struct pipe_resource * 381make_texture(struct st_context *st, 382 GLsizei width, GLsizei height, GLenum format, GLenum type, 383 const struct gl_pixelstore_attrib *unpack, 384 const void *pixels) 385{ 386 struct gl_context *ctx = st->ctx; 387 struct pipe_context *pipe = st->pipe; 388 mesa_format mformat; 389 struct pipe_resource *pt = NULL; 390 enum pipe_format pipeFormat; 391 GLenum baseInternalFormat; 392 393#if USE_DRAWPIXELS_CACHE 394 const GLint bpp = _mesa_bytes_per_pixel(format, type); 395 396 /* Check if the glDrawPixels() parameters and state matches the cache */ 397 if (width == st->drawpix_cache.width && 398 height == st->drawpix_cache.height && 399 format == st->drawpix_cache.format && 400 type == st->drawpix_cache.type && 401 pixels == st->drawpix_cache.user_pointer && 402 !_mesa_is_bufferobj(unpack->BufferObj) && 403 (unpack->RowLength == 0 || unpack->RowLength == width) && 404 unpack->SkipPixels == 0 && 405 unpack->SkipRows == 0 && 406 unpack->SwapBytes == GL_FALSE && 407 st->drawpix_cache.image) { 408 assert(st->drawpix_cache.texture); 409 410 /* check if the pixel data is the same */ 411 if (memcmp(pixels, st->drawpix_cache.image, width * height * bpp) == 0) { 412 /* OK, re-use the cached texture */ 413 pipe_resource_reference(&pt, st->drawpix_cache.texture); 414 /* refcount of returned texture should be at least two here. One 415 * reference for the cache to hold on to, one for the caller (which 416 * it will release), and possibly more held by the driver. 417 */ 418 assert(pt->reference.count >= 2); 419 return pt; 420 } 421 } 422 423 /* discard the cached image and texture (if there is one) */ 424 st->drawpix_cache.width = 0; 425 st->drawpix_cache.height = 0; 426 st->drawpix_cache.user_pointer = NULL; 427 if (st->drawpix_cache.image) { 428 free(st->drawpix_cache.image); 429 st->drawpix_cache.image = NULL; 430 } 431 pipe_resource_reference(&st->drawpix_cache.texture, NULL); 432#endif 433 434 /* Choose a pixel format for the temp texture which will hold the 435 * image to draw. 436 */ 437 pipeFormat = st_choose_matching_format(st, PIPE_BIND_SAMPLER_VIEW, 438 format, type, unpack->SwapBytes); 439 440 if (pipeFormat == PIPE_FORMAT_NONE) { 441 /* Use the generic approach. */ 442 GLenum intFormat = internal_format(ctx, format, type); 443 444 pipeFormat = st_choose_format(st, intFormat, format, type, 445 st->internal_target, 0, 446 PIPE_BIND_SAMPLER_VIEW, FALSE); 447 assert(pipeFormat != PIPE_FORMAT_NONE); 448 } 449 450 mformat = st_pipe_format_to_mesa_format(pipeFormat); 451 baseInternalFormat = _mesa_get_format_base_format(mformat); 452 453 pixels = _mesa_map_pbo_source(ctx, unpack, pixels); 454 if (!pixels) 455 return NULL; 456 457 /* alloc temporary texture */ 458 pt = alloc_texture(st, width, height, pipeFormat, PIPE_BIND_SAMPLER_VIEW); 459 if (!pt) { 460 _mesa_unmap_pbo_source(ctx, unpack); 461 return NULL; 462 } 463 464 { 465 struct pipe_transfer *transfer; 466 GLboolean success; 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 success = GL_TRUE; 500 } 501 else { 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 513 /* unmap */ 514 pipe_transfer_unmap(pipe, transfer); 515 516 assert(success); 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 553static void 554draw_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 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 */ 759static void 760draw_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 */ 939static struct st_fp_variant * 940get_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 */ 971static void 972clamp_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 */ 994static unsigned 995search_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 */ 1015static void 1016setup_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 */ 1056static void 1057st_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 st_flush_bitmap_cache(st); 1076 st_invalidate_readpix_cache(st); 1077 1078 st_validate_state(st, ST_PIPELINE_RENDER); 1079 1080 /* Limit the size of the glDrawPixels to the max texture size. 1081 * Strictly speaking, that's not correct but since we don't handle 1082 * larger images yet, this is better than crashing. 1083 */ 1084 clippedUnpack = *unpack; 1085 unpack = &clippedUnpack; 1086 clamp_size(st->pipe, &width, &height, &clippedUnpack); 1087 1088 if (format == GL_DEPTH_STENCIL) 1089 write_stencil = write_depth = GL_TRUE; 1090 else if (format == GL_STENCIL_INDEX) 1091 write_stencil = GL_TRUE; 1092 else if (format == GL_DEPTH_COMPONENT) 1093 write_depth = GL_TRUE; 1094 1095 if (write_stencil && 1096 !pipe->screen->get_param(pipe->screen, PIPE_CAP_SHADER_STENCIL_EXPORT)) { 1097 /* software fallback */ 1098 draw_stencil_pixels(ctx, x, y, width, height, format, type, 1099 unpack, pixels); 1100 return; 1101 } 1102 1103 /* 1104 * Get vertex/fragment shaders 1105 */ 1106 if (write_depth || write_stencil) { 1107 driver_fp = get_drawpix_z_stencil_program(st, write_depth, 1108 write_stencil); 1109 driver_vp = make_passthrough_vertex_shader(st, GL_TRUE); 1110 } 1111 else { 1112 fpv = get_color_fp_variant(st); 1113 1114 driver_fp = fpv->driver_shader; 1115 driver_vp = make_passthrough_vertex_shader(st, GL_FALSE); 1116 1117 if (ctx->Pixel.MapColorFlag) { 1118 pipe_sampler_view_reference(&sv[1], 1119 st->pixel_xfer.pixelmap_sampler_view); 1120 num_sampler_view++; 1121 } 1122 1123 /* compiling a new fragment shader variant added new state constants 1124 * into the constant buffer, we need to update them 1125 */ 1126 st_upload_constants(st, st->fp->Base.Parameters, MESA_SHADER_FRAGMENT); 1127 } 1128 1129 /* Put glDrawPixels image into a texture */ 1130 pt = make_texture(st, width, height, format, type, unpack, pixels); 1131 if (!pt) { 1132 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); 1133 return; 1134 } 1135 1136 /* create sampler view for the image */ 1137 sv[0] = st_create_texture_sampler_view(st->pipe, pt); 1138 if (!sv[0]) { 1139 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); 1140 pipe_resource_reference(&pt, NULL); 1141 return; 1142 } 1143 1144 /* Set up the sampler view's swizzle */ 1145 setup_sampler_swizzle(sv[0], format, type); 1146 1147 /* Create a second sampler view to read stencil. The stencil is 1148 * written using the shader stencil export functionality. 1149 */ 1150 if (write_stencil) { 1151 enum pipe_format stencil_format = 1152 util_format_stencil_only(pt->format); 1153 /* we should not be doing pixel map/transfer (see above) */ 1154 assert(num_sampler_view == 1); 1155 sv[1] = st_create_texture_sampler_view_format(st->pipe, pt, 1156 stencil_format); 1157 if (!sv[1]) { 1158 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); 1159 pipe_resource_reference(&pt, NULL); 1160 pipe_sampler_view_reference(&sv[0], NULL); 1161 return; 1162 } 1163 num_sampler_view++; 1164 } 1165 1166 draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2], 1167 width, height, 1168 ctx->Pixel.ZoomX, ctx->Pixel.ZoomY, 1169 sv, 1170 num_sampler_view, 1171 driver_vp, 1172 driver_fp, fpv, 1173 ctx->Current.RasterColor, 1174 GL_FALSE, write_depth, write_stencil); 1175 pipe_sampler_view_reference(&sv[0], NULL); 1176 if (num_sampler_view > 1) 1177 pipe_sampler_view_reference(&sv[1], NULL); 1178 1179 /* free the texture (but may persist in the cache) */ 1180 pipe_resource_reference(&pt, NULL); 1181} 1182 1183 1184 1185/** 1186 * Software fallback for glCopyPixels(GL_STENCIL). 1187 */ 1188static void 1189copy_stencil_pixels(struct gl_context *ctx, GLint srcx, GLint srcy, 1190 GLsizei width, GLsizei height, 1191 GLint dstx, GLint dsty) 1192{ 1193 struct st_renderbuffer *rbDraw; 1194 struct pipe_context *pipe = st_context(ctx)->pipe; 1195 enum pipe_transfer_usage usage; 1196 struct pipe_transfer *ptDraw; 1197 ubyte *drawMap; 1198 ubyte *buffer; 1199 int i; 1200 1201 buffer = malloc(width * height * sizeof(ubyte)); 1202 if (!buffer) { 1203 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels(stencil)"); 1204 return; 1205 } 1206 1207 /* Get the dest renderbuffer */ 1208 rbDraw = st_renderbuffer(ctx->DrawBuffer-> 1209 Attachment[BUFFER_STENCIL].Renderbuffer); 1210 1211 /* this will do stencil pixel transfer ops */ 1212 _mesa_readpixels(ctx, srcx, srcy, width, height, 1213 GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, 1214 &ctx->DefaultPacking, buffer); 1215 1216 if (0) { 1217 /* debug code: dump stencil values */ 1218 GLint row, col; 1219 for (row = 0; row < height; row++) { 1220 printf("%3d: ", row); 1221 for (col = 0; col < width; col++) { 1222 printf("%02x ", buffer[col + row * width]); 1223 } 1224 printf("\n"); 1225 } 1226 } 1227 1228 if (_mesa_is_format_packed_depth_stencil(rbDraw->Base.Format)) 1229 usage = PIPE_TRANSFER_READ_WRITE; 1230 else 1231 usage = PIPE_TRANSFER_WRITE; 1232 1233 if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { 1234 dsty = rbDraw->Base.Height - dsty - height; 1235 } 1236 1237 assert(util_format_get_blockwidth(rbDraw->texture->format) == 1); 1238 assert(util_format_get_blockheight(rbDraw->texture->format) == 1); 1239 1240 /* map the stencil buffer */ 1241 drawMap = pipe_transfer_map(pipe, 1242 rbDraw->texture, 1243 rbDraw->surface->u.tex.level, 1244 rbDraw->surface->u.tex.first_layer, 1245 usage, dstx, dsty, 1246 width, height, &ptDraw); 1247 1248 /* draw */ 1249 /* XXX PixelZoom not handled yet */ 1250 for (i = 0; i < height; i++) { 1251 ubyte *dst; 1252 const ubyte *src; 1253 int y; 1254 1255 y = i; 1256 1257 if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { 1258 y = height - y - 1; 1259 } 1260 1261 dst = drawMap + y * ptDraw->stride; 1262 src = buffer + i * width; 1263 1264 _mesa_pack_ubyte_stencil_row(rbDraw->Base.Format, width, src, dst); 1265 } 1266 1267 free(buffer); 1268 1269 /* unmap the stencil buffer */ 1270 pipe_transfer_unmap(pipe, ptDraw); 1271} 1272 1273 1274/** 1275 * Return renderbuffer to use for reading color pixels for glCopyPixels 1276 */ 1277static struct st_renderbuffer * 1278st_get_color_read_renderbuffer(struct gl_context *ctx) 1279{ 1280 struct gl_framebuffer *fb = ctx->ReadBuffer; 1281 struct st_renderbuffer *strb = 1282 st_renderbuffer(fb->_ColorReadBuffer); 1283 1284 return strb; 1285} 1286 1287 1288/** 1289 * Try to do a glCopyPixels for simple cases with a blit by calling 1290 * pipe->blit(). 1291 * 1292 * We can do this when we're copying color pixels (depth/stencil 1293 * eventually) with no pixel zoom, no pixel transfer ops, no 1294 * per-fragment ops, and the src/dest regions don't overlap. 1295 */ 1296static GLboolean 1297blit_copy_pixels(struct gl_context *ctx, GLint srcx, GLint srcy, 1298 GLsizei width, GLsizei height, 1299 GLint dstx, GLint dsty, GLenum type) 1300{ 1301 struct st_context *st = st_context(ctx); 1302 struct pipe_context *pipe = st->pipe; 1303 struct pipe_screen *screen = pipe->screen; 1304 struct gl_pixelstore_attrib pack, unpack; 1305 GLint readX, readY, readW, readH, drawX, drawY, drawW, drawH; 1306 1307 if (type == GL_COLOR && 1308 ctx->Pixel.ZoomX == 1.0 && 1309 ctx->Pixel.ZoomY == 1.0 && 1310 ctx->_ImageTransferState == 0x0 && 1311 !ctx->Color.BlendEnabled && 1312 !ctx->Color.AlphaEnabled && 1313 (!ctx->Color.ColorLogicOpEnabled || ctx->Color.LogicOp == GL_COPY) && 1314 !ctx->Depth.Test && 1315 !ctx->Fog.Enabled && 1316 !ctx->Stencil.Enabled && 1317 !ctx->FragmentProgram.Enabled && 1318 !ctx->VertexProgram.Enabled && 1319 !ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT] && 1320 !ctx->ATIFragmentShader._Enabled && 1321 ctx->DrawBuffer->_NumColorDrawBuffers == 1 && 1322 !ctx->Query.CondRenderQuery && 1323 !ctx->Query.CurrentOcclusionObject) { 1324 struct st_renderbuffer *rbRead, *rbDraw; 1325 1326 /* 1327 * Clip the read region against the src buffer bounds. 1328 * We'll still allocate a temporary buffer/texture for the original 1329 * src region size but we'll only read the region which is on-screen. 1330 * This may mean that we draw garbage pixels into the dest region, but 1331 * that's expected. 1332 */ 1333 readX = srcx; 1334 readY = srcy; 1335 readW = width; 1336 readH = height; 1337 pack = ctx->DefaultPacking; 1338 if (!_mesa_clip_readpixels(ctx, &readX, &readY, &readW, &readH, &pack)) 1339 return GL_TRUE; /* all done */ 1340 1341 /* clip against dest buffer bounds and scissor box */ 1342 drawX = dstx + pack.SkipPixels; 1343 drawY = dsty + pack.SkipRows; 1344 unpack = pack; 1345 if (!_mesa_clip_drawpixels(ctx, &drawX, &drawY, &readW, &readH, &unpack)) 1346 return GL_TRUE; /* all done */ 1347 1348 readX = readX - pack.SkipPixels + unpack.SkipPixels; 1349 readY = readY - pack.SkipRows + unpack.SkipRows; 1350 1351 drawW = readW; 1352 drawH = readH; 1353 1354 rbRead = st_get_color_read_renderbuffer(ctx); 1355 rbDraw = st_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]); 1356 1357 /* Flip src/dst position depending on the orientation of buffers. */ 1358 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 1359 readY = rbRead->Base.Height - readY; 1360 readH = -readH; 1361 } 1362 1363 if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) { 1364 /* We can't flip the destination for pipe->blit, so we only adjust 1365 * its position and flip the source. 1366 */ 1367 drawY = rbDraw->Base.Height - drawY - drawH; 1368 readY += readH; 1369 readH = -readH; 1370 } 1371 1372 if (rbRead != rbDraw || 1373 !_mesa_regions_overlap(readX, readY, readX + readW, readY + readH, 1374 drawX, drawY, drawX + drawW, drawY + drawH)) { 1375 struct pipe_blit_info blit; 1376 1377 memset(&blit, 0, sizeof(blit)); 1378 blit.src.resource = rbRead->texture; 1379 blit.src.level = rbRead->surface->u.tex.level; 1380 blit.src.format = rbRead->texture->format; 1381 blit.src.box.x = readX; 1382 blit.src.box.y = readY; 1383 blit.src.box.z = rbRead->surface->u.tex.first_layer; 1384 blit.src.box.width = readW; 1385 blit.src.box.height = readH; 1386 blit.src.box.depth = 1; 1387 blit.dst.resource = rbDraw->texture; 1388 blit.dst.level = rbDraw->surface->u.tex.level; 1389 blit.dst.format = rbDraw->texture->format; 1390 blit.dst.box.x = drawX; 1391 blit.dst.box.y = drawY; 1392 blit.dst.box.z = rbDraw->surface->u.tex.first_layer; 1393 blit.dst.box.width = drawW; 1394 blit.dst.box.height = drawH; 1395 blit.dst.box.depth = 1; 1396 blit.mask = PIPE_MASK_RGBA; 1397 blit.filter = PIPE_TEX_FILTER_NEAREST; 1398 1399 if (ctx->DrawBuffer != ctx->WinSysDrawBuffer) 1400 st_window_rectangles_to_blit(ctx, &blit); 1401 1402 if (screen->is_format_supported(screen, blit.src.format, 1403 blit.src.resource->target, 1404 blit.src.resource->nr_samples, 1405 PIPE_BIND_SAMPLER_VIEW) && 1406 screen->is_format_supported(screen, blit.dst.format, 1407 blit.dst.resource->target, 1408 blit.dst.resource->nr_samples, 1409 PIPE_BIND_RENDER_TARGET)) { 1410 pipe->blit(pipe, &blit); 1411 return GL_TRUE; 1412 } 1413 } 1414 } 1415 1416 return GL_FALSE; 1417} 1418 1419 1420static void 1421st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy, 1422 GLsizei width, GLsizei height, 1423 GLint dstx, GLint dsty, GLenum type) 1424{ 1425 struct st_context *st = st_context(ctx); 1426 struct pipe_context *pipe = st->pipe; 1427 struct pipe_screen *screen = pipe->screen; 1428 struct st_renderbuffer *rbRead; 1429 void *driver_vp, *driver_fp; 1430 struct pipe_resource *pt; 1431 struct pipe_sampler_view *sv[2] = { NULL }; 1432 struct st_fp_variant *fpv = NULL; 1433 int num_sampler_view = 1; 1434 enum pipe_format srcFormat; 1435 unsigned srcBind; 1436 GLboolean invertTex = GL_FALSE; 1437 GLint readX, readY, readW, readH; 1438 struct gl_pixelstore_attrib pack = ctx->DefaultPacking; 1439 1440 st_flush_bitmap_cache(st); 1441 st_invalidate_readpix_cache(st); 1442 1443 st_validate_state(st, ST_PIPELINE_RENDER); 1444 1445 if (type == GL_DEPTH_STENCIL) { 1446 /* XXX make this more efficient */ 1447 st_CopyPixels(ctx, srcx, srcy, width, height, dstx, dsty, GL_STENCIL); 1448 st_CopyPixels(ctx, srcx, srcy, width, height, dstx, dsty, GL_DEPTH); 1449 return; 1450 } 1451 1452 if (type == GL_STENCIL) { 1453 /* can't use texturing to do stencil */ 1454 copy_stencil_pixels(ctx, srcx, srcy, width, height, dstx, dsty); 1455 return; 1456 } 1457 1458 if (blit_copy_pixels(ctx, srcx, srcy, width, height, dstx, dsty, type)) 1459 return; 1460 1461 /* 1462 * The subsequent code implements glCopyPixels by copying the source 1463 * pixels into a temporary texture that's then applied to a textured quad. 1464 * When we draw the textured quad, all the usual per-fragment operations 1465 * are handled. 1466 */ 1467 1468 1469 /* 1470 * Get vertex/fragment shaders 1471 */ 1472 if (type == GL_COLOR) { 1473 fpv = get_color_fp_variant(st); 1474 1475 rbRead = st_get_color_read_renderbuffer(ctx); 1476 1477 driver_fp = fpv->driver_shader; 1478 driver_vp = make_passthrough_vertex_shader(st, GL_FALSE); 1479 1480 if (ctx->Pixel.MapColorFlag) { 1481 pipe_sampler_view_reference(&sv[1], 1482 st->pixel_xfer.pixelmap_sampler_view); 1483 num_sampler_view++; 1484 } 1485 1486 /* compiling a new fragment shader variant added new state constants 1487 * into the constant buffer, we need to update them 1488 */ 1489 st_upload_constants(st, st->fp->Base.Parameters, MESA_SHADER_FRAGMENT); 1490 } 1491 else { 1492 assert(type == GL_DEPTH); 1493 rbRead = st_renderbuffer(ctx->ReadBuffer-> 1494 Attachment[BUFFER_DEPTH].Renderbuffer); 1495 1496 driver_fp = get_drawpix_z_stencil_program(st, GL_TRUE, GL_FALSE); 1497 driver_vp = make_passthrough_vertex_shader(st, GL_TRUE); 1498 } 1499 1500 /* Choose the format for the temporary texture. */ 1501 srcFormat = rbRead->texture->format; 1502 srcBind = PIPE_BIND_SAMPLER_VIEW | 1503 (type == GL_COLOR ? PIPE_BIND_RENDER_TARGET : PIPE_BIND_DEPTH_STENCIL); 1504 1505 if (!screen->is_format_supported(screen, srcFormat, st->internal_target, 0, 1506 srcBind)) { 1507 /* srcFormat is non-renderable. Find a compatible renderable format. */ 1508 if (type == GL_DEPTH) { 1509 srcFormat = st_choose_format(st, GL_DEPTH_COMPONENT, GL_NONE, 1510 GL_NONE, st->internal_target, 0, 1511 srcBind, FALSE); 1512 } 1513 else { 1514 assert(type == GL_COLOR); 1515 1516 if (util_format_is_float(srcFormat)) { 1517 srcFormat = st_choose_format(st, GL_RGBA32F, GL_NONE, 1518 GL_NONE, st->internal_target, 0, 1519 srcBind, FALSE); 1520 } 1521 else if (util_format_is_pure_sint(srcFormat)) { 1522 srcFormat = st_choose_format(st, GL_RGBA32I, GL_NONE, 1523 GL_NONE, st->internal_target, 0, 1524 srcBind, FALSE); 1525 } 1526 else if (util_format_is_pure_uint(srcFormat)) { 1527 srcFormat = st_choose_format(st, GL_RGBA32UI, GL_NONE, 1528 GL_NONE, st->internal_target, 0, 1529 srcBind, FALSE); 1530 } 1531 else if (util_format_is_snorm(srcFormat)) { 1532 srcFormat = st_choose_format(st, GL_RGBA16_SNORM, GL_NONE, 1533 GL_NONE, st->internal_target, 0, 1534 srcBind, FALSE); 1535 } 1536 else { 1537 srcFormat = st_choose_format(st, GL_RGBA, GL_NONE, 1538 GL_NONE, st->internal_target, 0, 1539 srcBind, FALSE); 1540 } 1541 } 1542 1543 if (srcFormat == PIPE_FORMAT_NONE) { 1544 assert(0 && "cannot choose a format for src of CopyPixels"); 1545 return; 1546 } 1547 } 1548 1549 /* Invert src region if needed */ 1550 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) { 1551 srcy = ctx->ReadBuffer->Height - srcy - height; 1552 invertTex = !invertTex; 1553 } 1554 1555 /* Clip the read region against the src buffer bounds. 1556 * We'll still allocate a temporary buffer/texture for the original 1557 * src region size but we'll only read the region which is on-screen. 1558 * This may mean that we draw garbage pixels into the dest region, but 1559 * that's expected. 1560 */ 1561 readX = srcx; 1562 readY = srcy; 1563 readW = width; 1564 readH = height; 1565 if (!_mesa_clip_readpixels(ctx, &readX, &readY, &readW, &readH, &pack)) { 1566 /* The source region is completely out of bounds. Do nothing. 1567 * The GL spec says "Results of copies from outside the window, 1568 * or from regions of the window that are not exposed, are 1569 * hardware dependent and undefined." 1570 */ 1571 return; 1572 } 1573 1574 readW = MAX2(0, readW); 1575 readH = MAX2(0, readH); 1576 1577 /* Allocate the temporary texture. */ 1578 pt = alloc_texture(st, width, height, srcFormat, srcBind); 1579 if (!pt) 1580 return; 1581 1582 sv[0] = st_create_texture_sampler_view(st->pipe, pt); 1583 if (!sv[0]) { 1584 pipe_resource_reference(&pt, NULL); 1585 return; 1586 } 1587 1588 /* Copy the src region to the temporary texture. */ 1589 { 1590 struct pipe_blit_info blit; 1591 1592 memset(&blit, 0, sizeof(blit)); 1593 blit.src.resource = rbRead->texture; 1594 blit.src.level = rbRead->surface->u.tex.level; 1595 blit.src.format = rbRead->texture->format; 1596 blit.src.box.x = readX; 1597 blit.src.box.y = readY; 1598 blit.src.box.z = rbRead->surface->u.tex.first_layer; 1599 blit.src.box.width = readW; 1600 blit.src.box.height = readH; 1601 blit.src.box.depth = 1; 1602 blit.dst.resource = pt; 1603 blit.dst.level = 0; 1604 blit.dst.format = pt->format; 1605 blit.dst.box.x = pack.SkipPixels; 1606 blit.dst.box.y = pack.SkipRows; 1607 blit.dst.box.z = 0; 1608 blit.dst.box.width = readW; 1609 blit.dst.box.height = readH; 1610 blit.dst.box.depth = 1; 1611 blit.mask = util_format_get_mask(pt->format) & ~PIPE_MASK_S; 1612 blit.filter = PIPE_TEX_FILTER_NEAREST; 1613 1614 pipe->blit(pipe, &blit); 1615 } 1616 1617 /* OK, the texture 'pt' contains the src image/pixels. Now draw a 1618 * textured quad with that texture. 1619 */ 1620 draw_textured_quad(ctx, dstx, dsty, ctx->Current.RasterPos[2], 1621 width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY, 1622 sv, 1623 num_sampler_view, 1624 driver_vp, 1625 driver_fp, fpv, 1626 ctx->Current.Attrib[VERT_ATTRIB_COLOR0], 1627 invertTex, GL_FALSE, GL_FALSE); 1628 1629 pipe_resource_reference(&pt, NULL); 1630 pipe_sampler_view_reference(&sv[0], NULL); 1631} 1632 1633 1634 1635void st_init_drawpixels_functions(struct dd_function_table *functions) 1636{ 1637 functions->DrawPixels = st_DrawPixels; 1638 functions->CopyPixels = st_CopyPixels; 1639} 1640 1641 1642void 1643st_destroy_drawpix(struct st_context *st) 1644{ 1645 GLuint i; 1646 1647 for (i = 0; i < ARRAY_SIZE(st->drawpix.zs_shaders); i++) { 1648 if (st->drawpix.zs_shaders[i]) 1649 cso_delete_fragment_shader(st->cso_context, 1650 st->drawpix.zs_shaders[i]); 1651 } 1652 1653 if (st->drawpix.vert_shaders[0]) 1654 cso_delete_vertex_shader(st->cso_context, st->drawpix.vert_shaders[0]); 1655 if (st->drawpix.vert_shaders[1]) 1656 cso_delete_vertex_shader(st->cso_context, st->drawpix.vert_shaders[1]); 1657} 1658