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