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