1 /************************************************************************** 2 * 3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. 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 TUNGSTEN GRAPHICS 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 * @file 30 * Copy/blit pixel rect between surfaces 31 * 32 * @author Brian Paul 33 */ 34 35 36 #include "pipe/p_context.h" 37 #include "util/u_debug.h" 38 #include "pipe/p_defines.h" 39 #include "util/u_inlines.h" 40 #include "pipe/p_shader_tokens.h" 41 #include "pipe/p_state.h" 42 43 #include "util/u_blit.h" 44 #include "util/u_draw_quad.h" 45 #include "util/u_format.h" 46 #include "util/u_math.h" 47 #include "util/u_memory.h" 48 #include "util/u_sampler.h" 49 #include "util/u_simple_shaders.h" 50 51 #include "cso_cache/cso_context.h" 52 53 54 struct blit_state 55 { 56 struct pipe_context *pipe; 57 struct cso_context *cso; 58 59 struct pipe_blend_state blend_write_color, blend_keep_color; 60 struct pipe_depth_stencil_alpha_state dsa_keep_depthstencil; 61 struct pipe_depth_stencil_alpha_state dsa_write_depthstencil; 62 struct pipe_depth_stencil_alpha_state dsa_write_depth; 63 struct pipe_depth_stencil_alpha_state dsa_write_stencil; 64 struct pipe_rasterizer_state rasterizer; 65 struct pipe_sampler_state sampler; 66 struct pipe_viewport_state viewport; 67 struct pipe_vertex_element velem[2]; 68 enum pipe_texture_target internal_target; 69 70 void *vs; 71 void *fs[PIPE_MAX_TEXTURE_TYPES][TGSI_WRITEMASK_XYZW + 1]; 72 void *fs_depthstencil[PIPE_MAX_TEXTURE_TYPES]; 73 void *fs_depth[PIPE_MAX_TEXTURE_TYPES]; 74 void *fs_stencil[PIPE_MAX_TEXTURE_TYPES]; 75 76 struct pipe_resource *vbuf; /**< quad vertices */ 77 unsigned vbuf_slot; 78 79 float vertices[4][2][4]; /**< vertex/texcoords for quad */ 80 81 boolean has_stencil_export; 82 }; 83 84 85 /** 86 * Create state object for blit. 87 * Intended to be created once and re-used for many blit() calls. 88 */ 89 struct blit_state * 90 util_create_blit(struct pipe_context *pipe, struct cso_context *cso) 91 { 92 struct blit_state *ctx; 93 uint i; 94 95 ctx = CALLOC_STRUCT(blit_state); 96 if (!ctx) 97 return NULL; 98 99 ctx->pipe = pipe; 100 ctx->cso = cso; 101 102 /* disabled blending/masking */ 103 ctx->blend_write_color.rt[0].colormask = PIPE_MASK_RGBA; 104 105 /* depth stencil states */ 106 ctx->dsa_write_depth.depth.enabled = 1; 107 ctx->dsa_write_depth.depth.writemask = 1; 108 ctx->dsa_write_depth.depth.func = PIPE_FUNC_ALWAYS; 109 ctx->dsa_write_stencil.stencil[0].enabled = 1; 110 ctx->dsa_write_stencil.stencil[0].func = PIPE_FUNC_ALWAYS; 111 ctx->dsa_write_stencil.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE; 112 ctx->dsa_write_stencil.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE; 113 ctx->dsa_write_stencil.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE; 114 ctx->dsa_write_stencil.stencil[0].valuemask = 0xff; 115 ctx->dsa_write_stencil.stencil[0].writemask = 0xff; 116 ctx->dsa_write_depthstencil.depth = ctx->dsa_write_depth.depth; 117 ctx->dsa_write_depthstencil.stencil[0] = ctx->dsa_write_stencil.stencil[0]; 118 119 /* rasterizer */ 120 ctx->rasterizer.cull_face = PIPE_FACE_NONE; 121 ctx->rasterizer.gl_rasterization_rules = 1; 122 ctx->rasterizer.depth_clip = 1; 123 124 /* samplers */ 125 ctx->sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 126 ctx->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 127 ctx->sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 128 ctx->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; 129 ctx->sampler.min_img_filter = 0; /* set later */ 130 ctx->sampler.mag_img_filter = 0; /* set later */ 131 132 /* vertex elements state */ 133 for (i = 0; i < 2; i++) { 134 ctx->velem[i].src_offset = i * 4 * sizeof(float); 135 ctx->velem[i].instance_divisor = 0; 136 ctx->velem[i].vertex_buffer_index = 0; 137 ctx->velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 138 } 139 140 ctx->vbuf = NULL; 141 142 /* init vertex data that doesn't change */ 143 for (i = 0; i < 4; i++) { 144 ctx->vertices[i][0][3] = 1.0f; /* w */ 145 ctx->vertices[i][1][2] = 0.0f; /* r */ 146 ctx->vertices[i][1][3] = 1.0f; /* q */ 147 } 148 149 if(pipe->screen->get_param(pipe->screen, PIPE_CAP_NPOT_TEXTURES)) 150 ctx->internal_target = PIPE_TEXTURE_2D; 151 else 152 ctx->internal_target = PIPE_TEXTURE_RECT; 153 154 ctx->has_stencil_export = 155 pipe->screen->get_param(pipe->screen, PIPE_CAP_SHADER_STENCIL_EXPORT); 156 157 return ctx; 158 } 159 160 161 /** 162 * Destroy a blit context 163 */ 164 void 165 util_destroy_blit(struct blit_state *ctx) 166 { 167 struct pipe_context *pipe = ctx->pipe; 168 unsigned i, j; 169 170 if (ctx->vs) 171 pipe->delete_vs_state(pipe, ctx->vs); 172 173 for (i = 0; i < Elements(ctx->fs); i++) { 174 for (j = 0; j < Elements(ctx->fs[i]); j++) { 175 if (ctx->fs[i][j]) 176 pipe->delete_fs_state(pipe, ctx->fs[i][j]); 177 } 178 } 179 180 for (i = 0; i < PIPE_MAX_TEXTURE_TYPES; i++) { 181 if (ctx->fs_depthstencil[i]) { 182 pipe->delete_fs_state(pipe, ctx->fs_depthstencil[i]); 183 } 184 if (ctx->fs_depth[i]) { 185 pipe->delete_fs_state(pipe, ctx->fs_depth[i]); 186 } 187 if (ctx->fs_stencil[i]) { 188 pipe->delete_fs_state(pipe, ctx->fs_stencil[i]); 189 } 190 } 191 192 pipe_resource_reference(&ctx->vbuf, NULL); 193 194 FREE(ctx); 195 } 196 197 198 /** 199 * Helper function to set the fragment shaders. 200 */ 201 static INLINE void 202 set_fragment_shader(struct blit_state *ctx, uint writemask, 203 enum pipe_texture_target pipe_tex) 204 { 205 if (!ctx->fs[pipe_tex][writemask]) { 206 unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex, 0); 207 208 ctx->fs[pipe_tex][writemask] = 209 util_make_fragment_tex_shader_writemask(ctx->pipe, tgsi_tex, 210 TGSI_INTERPOLATE_LINEAR, 211 writemask); 212 } 213 214 cso_set_fragment_shader_handle(ctx->cso, ctx->fs[pipe_tex][writemask]); 215 } 216 217 218 /** 219 * Helper function to set the shader which writes depth and stencil. 220 */ 221 static INLINE void 222 set_depthstencil_fragment_shader(struct blit_state *ctx, 223 enum pipe_texture_target pipe_tex) 224 { 225 if (!ctx->fs_depthstencil[pipe_tex]) { 226 unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex, 0); 227 228 ctx->fs_depthstencil[pipe_tex] = 229 util_make_fragment_tex_shader_writedepthstencil(ctx->pipe, tgsi_tex, 230 TGSI_INTERPOLATE_LINEAR); 231 } 232 233 cso_set_fragment_shader_handle(ctx->cso, ctx->fs_depthstencil[pipe_tex]); 234 } 235 236 237 /** 238 * Helper function to set the shader which writes depth. 239 */ 240 static INLINE void 241 set_depth_fragment_shader(struct blit_state *ctx, 242 enum pipe_texture_target pipe_tex) 243 { 244 if (!ctx->fs_depth[pipe_tex]) { 245 unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex, 0); 246 247 ctx->fs_depth[pipe_tex] = 248 util_make_fragment_tex_shader_writedepth(ctx->pipe, tgsi_tex, 249 TGSI_INTERPOLATE_LINEAR); 250 } 251 252 cso_set_fragment_shader_handle(ctx->cso, ctx->fs_depth[pipe_tex]); 253 } 254 255 256 /** 257 * Helper function to set the shader which writes stencil. 258 */ 259 static INLINE void 260 set_stencil_fragment_shader(struct blit_state *ctx, 261 enum pipe_texture_target pipe_tex) 262 { 263 if (!ctx->fs_stencil[pipe_tex]) { 264 unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex, 0); 265 266 ctx->fs_stencil[pipe_tex] = 267 util_make_fragment_tex_shader_writestencil(ctx->pipe, tgsi_tex, 268 TGSI_INTERPOLATE_LINEAR); 269 } 270 271 cso_set_fragment_shader_handle(ctx->cso, ctx->fs_stencil[pipe_tex]); 272 } 273 274 275 /** 276 * Helper function to set the vertex shader. 277 */ 278 static INLINE void 279 set_vertex_shader(struct blit_state *ctx) 280 { 281 /* vertex shader - still required to provide the linkage between 282 * fragment shader input semantics and vertex_element/buffers. 283 */ 284 if (!ctx->vs) { 285 const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, 286 TGSI_SEMANTIC_GENERIC }; 287 const uint semantic_indexes[] = { 0, 0 }; 288 ctx->vs = util_make_vertex_passthrough_shader(ctx->pipe, 2, 289 semantic_names, 290 semantic_indexes); 291 } 292 293 cso_set_vertex_shader_handle(ctx->cso, ctx->vs); 294 } 295 296 297 /** 298 * Get offset of next free slot in vertex buffer for quad vertices. 299 */ 300 static unsigned 301 get_next_slot( struct blit_state *ctx ) 302 { 303 const unsigned max_slots = 4096 / sizeof ctx->vertices; 304 305 if (ctx->vbuf_slot >= max_slots) { 306 pipe_resource_reference(&ctx->vbuf, NULL); 307 ctx->vbuf_slot = 0; 308 } 309 310 if (!ctx->vbuf) { 311 ctx->vbuf = pipe_buffer_create(ctx->pipe->screen, 312 PIPE_BIND_VERTEX_BUFFER, 313 PIPE_USAGE_STREAM, 314 max_slots * sizeof ctx->vertices); 315 } 316 317 return ctx->vbuf_slot++ * sizeof ctx->vertices; 318 } 319 320 321 322 323 /** 324 * Setup vertex data for the textured quad we'll draw. 325 * Note: y=0=top 326 */ 327 static unsigned 328 setup_vertex_data_tex(struct blit_state *ctx, 329 float x0, float y0, float x1, float y1, 330 float s0, float t0, float s1, float t1, 331 float z) 332 { 333 unsigned offset; 334 335 ctx->vertices[0][0][0] = x0; 336 ctx->vertices[0][0][1] = y0; 337 ctx->vertices[0][0][2] = z; 338 ctx->vertices[0][1][0] = s0; /*s*/ 339 ctx->vertices[0][1][1] = t0; /*t*/ 340 341 ctx->vertices[1][0][0] = x1; 342 ctx->vertices[1][0][1] = y0; 343 ctx->vertices[1][0][2] = z; 344 ctx->vertices[1][1][0] = s1; /*s*/ 345 ctx->vertices[1][1][1] = t0; /*t*/ 346 347 ctx->vertices[2][0][0] = x1; 348 ctx->vertices[2][0][1] = y1; 349 ctx->vertices[2][0][2] = z; 350 ctx->vertices[2][1][0] = s1; 351 ctx->vertices[2][1][1] = t1; 352 353 ctx->vertices[3][0][0] = x0; 354 ctx->vertices[3][0][1] = y1; 355 ctx->vertices[3][0][2] = z; 356 ctx->vertices[3][1][0] = s0; 357 ctx->vertices[3][1][1] = t1; 358 359 offset = get_next_slot( ctx ); 360 361 if (ctx->vbuf) { 362 pipe_buffer_write_nooverlap(ctx->pipe, ctx->vbuf, 363 offset, sizeof(ctx->vertices), ctx->vertices); 364 } 365 366 return offset; 367 } 368 369 370 /** 371 * \return TRUE if two regions overlap, FALSE otherwise 372 */ 373 static boolean 374 regions_overlap(int srcX0, int srcY0, 375 int srcX1, int srcY1, 376 int dstX0, int dstY0, 377 int dstX1, int dstY1) 378 { 379 if (MAX2(srcX0, srcX1) < MIN2(dstX0, dstX1)) 380 return FALSE; /* src completely left of dst */ 381 382 if (MAX2(dstX0, dstX1) < MIN2(srcX0, srcX1)) 383 return FALSE; /* dst completely left of src */ 384 385 if (MAX2(srcY0, srcY1) < MIN2(dstY0, dstY1)) 386 return FALSE; /* src completely above dst */ 387 388 if (MAX2(dstY0, dstY1) < MIN2(srcY0, srcY1)) 389 return FALSE; /* dst completely above src */ 390 391 return TRUE; /* some overlap */ 392 } 393 394 395 /** 396 * Can we blit from src format to dest format with a simple copy? 397 */ 398 static boolean 399 formats_compatible(enum pipe_format src_format, 400 enum pipe_format dst_format) 401 { 402 if (src_format == dst_format) { 403 return TRUE; 404 } 405 else { 406 const struct util_format_description *src_desc = 407 util_format_description(src_format); 408 const struct util_format_description *dst_desc = 409 util_format_description(dst_format); 410 return util_is_format_compatible(src_desc, dst_desc); 411 } 412 } 413 414 415 /** 416 * Copy pixel block from src surface to dst surface. 417 * Overlapping regions are acceptable. 418 * Flipping and stretching are supported. 419 * \param filter one of PIPE_TEX_MIPFILTER_NEAREST/LINEAR 420 * \param writemask controls which channels in the dest surface are sourced 421 * from the src surface. Disabled channels are sourced 422 * from (0,0,0,1). 423 */ 424 void 425 util_blit_pixels(struct blit_state *ctx, 426 struct pipe_resource *src_tex, 427 unsigned src_level, 428 int srcX0, int srcY0, 429 int srcX1, int srcY1, 430 int srcZ0, 431 struct pipe_surface *dst, 432 int dstX0, int dstY0, 433 int dstX1, int dstY1, 434 float z, uint filter, 435 uint writemask, uint zs_writemask) 436 { 437 struct pipe_context *pipe = ctx->pipe; 438 struct pipe_screen *screen = pipe->screen; 439 enum pipe_format src_format, dst_format; 440 struct pipe_sampler_view *sampler_view = NULL; 441 struct pipe_sampler_view sv_templ; 442 struct pipe_surface *dst_surface; 443 struct pipe_framebuffer_state fb; 444 const int srcW = abs(srcX1 - srcX0); 445 const int srcH = abs(srcY1 - srcY0); 446 unsigned offset; 447 boolean overlap; 448 float s0, t0, s1, t1; 449 boolean normalized; 450 boolean is_stencil, is_depth, blit_depth, blit_stencil; 451 const struct util_format_description *src_desc = 452 util_format_description(src_tex->format); 453 454 assert(filter == PIPE_TEX_MIPFILTER_NEAREST || 455 filter == PIPE_TEX_MIPFILTER_LINEAR); 456 457 assert(src_level <= src_tex->last_level); 458 459 /* do the regions overlap? */ 460 overlap = src_tex == dst->texture && 461 dst->u.tex.level == src_level && 462 dst->u.tex.first_layer == srcZ0 && 463 regions_overlap(srcX0, srcY0, srcX1, srcY1, 464 dstX0, dstY0, dstX1, dstY1); 465 466 src_format = util_format_linear(src_tex->format); 467 dst_format = util_format_linear(dst->texture->format); 468 469 /* See whether we will blit depth or stencil. */ 470 is_depth = util_format_has_depth(src_desc); 471 is_stencil = util_format_has_stencil(src_desc); 472 473 blit_depth = is_depth && (zs_writemask & BLIT_WRITEMASK_Z); 474 blit_stencil = is_stencil && (zs_writemask & BLIT_WRITEMASK_STENCIL); 475 476 assert((writemask && !zs_writemask && !is_depth && !is_stencil) || 477 (!writemask && (blit_depth || blit_stencil))); 478 479 /* 480 * Check for simple case: no format conversion, no flipping, no stretching, 481 * no overlapping, same number of samples. 482 * Filter mode should not matter since there's no stretching. 483 */ 484 if (formats_compatible(src_format, dst_format) && 485 src_tex->nr_samples == dst->texture->nr_samples && 486 is_stencil == blit_stencil && 487 is_depth == blit_depth && 488 srcX0 < srcX1 && 489 dstX0 < dstX1 && 490 srcY0 < srcY1 && 491 dstY0 < dstY1 && 492 (dstX1 - dstX0) == (srcX1 - srcX0) && 493 (dstY1 - dstY0) == (srcY1 - srcY0) && 494 !overlap) { 495 struct pipe_box src_box; 496 src_box.x = srcX0; 497 src_box.y = srcY0; 498 src_box.z = srcZ0; 499 src_box.width = srcW; 500 src_box.height = srcH; 501 src_box.depth = 1; 502 pipe->resource_copy_region(pipe, 503 dst->texture, dst->u.tex.level, 504 dstX0, dstY0, dst->u.tex.first_layer,/* dest */ 505 src_tex, src_level, 506 &src_box); 507 return; 508 } 509 510 /* XXX Reading multisample textures is unimplemented. */ 511 assert(src_tex->nr_samples <= 1); 512 if (src_tex->nr_samples > 1) { 513 return; 514 } 515 516 /* It's a mistake to call this function with a stencil format and 517 * without shader stencil export. We don't do software fallbacks here. 518 * Ignore stencil and only copy depth. 519 */ 520 if (blit_stencil && !ctx->has_stencil_export) { 521 blit_stencil = FALSE; 522 523 if (!blit_depth) 524 return; 525 } 526 527 if (dst_format == dst->format) { 528 dst_surface = dst; 529 } else { 530 struct pipe_surface templ = *dst; 531 templ.format = dst_format; 532 dst_surface = pipe->create_surface(pipe, dst->texture, &templ); 533 } 534 535 /* Create a temporary texture when src and dest alias. 536 */ 537 if (src_tex == dst_surface->texture && 538 dst_surface->u.tex.level == src_level && 539 dst_surface->u.tex.first_layer == srcZ0) { 540 /* Make a temporary texture which contains a copy of the source pixels. 541 * Then we'll sample from the temporary texture. 542 */ 543 struct pipe_resource texTemp; 544 struct pipe_resource *tex; 545 struct pipe_sampler_view sv_templ; 546 struct pipe_box src_box; 547 const int srcLeft = MIN2(srcX0, srcX1); 548 const int srcTop = MIN2(srcY0, srcY1); 549 550 if (srcLeft != srcX0) { 551 /* left-right flip */ 552 int tmp = dstX0; 553 dstX0 = dstX1; 554 dstX1 = tmp; 555 } 556 557 if (srcTop != srcY0) { 558 /* up-down flip */ 559 int tmp = dstY0; 560 dstY0 = dstY1; 561 dstY1 = tmp; 562 } 563 564 /* create temp texture */ 565 memset(&texTemp, 0, sizeof(texTemp)); 566 texTemp.target = ctx->internal_target; 567 texTemp.format = src_format; 568 texTemp.last_level = 0; 569 texTemp.width0 = srcW; 570 texTemp.height0 = srcH; 571 texTemp.depth0 = 1; 572 texTemp.array_size = 1; 573 texTemp.bind = PIPE_BIND_SAMPLER_VIEW; 574 575 tex = screen->resource_create(screen, &texTemp); 576 if (!tex) 577 return; 578 579 src_box.x = srcLeft; 580 src_box.y = srcTop; 581 src_box.z = srcZ0; 582 src_box.width = srcW; 583 src_box.height = srcH; 584 src_box.depth = 1; 585 /* load temp texture */ 586 pipe->resource_copy_region(pipe, 587 tex, 0, 0, 0, 0, /* dest */ 588 src_tex, src_level, &src_box); 589 590 normalized = tex->target != PIPE_TEXTURE_RECT; 591 if(normalized) { 592 s0 = 0.0f; 593 s1 = 1.0f; 594 t0 = 0.0f; 595 t1 = 1.0f; 596 } 597 else { 598 s0 = 0; 599 s1 = srcW; 600 t0 = 0; 601 t1 = srcH; 602 } 603 604 u_sampler_view_default_template(&sv_templ, tex, tex->format); 605 if (!blit_depth && blit_stencil) { 606 /* set a stencil-only format, e.g. Z24S8 --> X24S8 */ 607 sv_templ.format = util_format_stencil_only(tex->format); 608 assert(sv_templ.format != PIPE_FORMAT_NONE); 609 } 610 sampler_view = pipe->create_sampler_view(pipe, tex, &sv_templ); 611 612 if (!sampler_view) { 613 pipe_resource_reference(&tex, NULL); 614 return; 615 } 616 pipe_resource_reference(&tex, NULL); 617 } 618 else { 619 /* Directly sample from the source resource/texture */ 620 u_sampler_view_default_template(&sv_templ, src_tex, src_format); 621 if (!blit_depth && blit_stencil) { 622 /* set a stencil-only format, e.g. Z24S8 --> X24S8 */ 623 sv_templ.format = util_format_stencil_only(src_format); 624 assert(sv_templ.format != PIPE_FORMAT_NONE); 625 } 626 sampler_view = pipe->create_sampler_view(pipe, src_tex, &sv_templ); 627 628 if (!sampler_view) { 629 return; 630 } 631 632 s0 = srcX0; 633 s1 = srcX1; 634 t0 = srcY0; 635 t1 = srcY1; 636 normalized = sampler_view->texture->target != PIPE_TEXTURE_RECT; 637 if(normalized) 638 { 639 s0 /= (float)(u_minify(sampler_view->texture->width0, src_level)); 640 s1 /= (float)(u_minify(sampler_view->texture->width0, src_level)); 641 t0 /= (float)(u_minify(sampler_view->texture->height0, src_level)); 642 t1 /= (float)(u_minify(sampler_view->texture->height0, src_level)); 643 } 644 } 645 646 assert(screen->is_format_supported(screen, sampler_view->format, 647 ctx->internal_target, sampler_view->texture->nr_samples, 648 PIPE_BIND_SAMPLER_VIEW)); 649 assert(screen->is_format_supported(screen, dst_format, ctx->internal_target, 650 dst_surface->texture->nr_samples, 651 is_depth || is_stencil ? PIPE_BIND_DEPTH_STENCIL : 652 PIPE_BIND_RENDER_TARGET)); 653 654 /* save state (restored below) */ 655 cso_save_blend(ctx->cso); 656 cso_save_depth_stencil_alpha(ctx->cso); 657 cso_save_rasterizer(ctx->cso); 658 cso_save_sample_mask(ctx->cso); 659 cso_save_samplers(ctx->cso, PIPE_SHADER_FRAGMENT); 660 cso_save_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT); 661 cso_save_stream_outputs(ctx->cso); 662 cso_save_viewport(ctx->cso); 663 cso_save_framebuffer(ctx->cso); 664 cso_save_fragment_shader(ctx->cso); 665 cso_save_vertex_shader(ctx->cso); 666 cso_save_geometry_shader(ctx->cso); 667 cso_save_vertex_elements(ctx->cso); 668 cso_save_vertex_buffers(ctx->cso); 669 670 /* set misc state we care about */ 671 if (writemask) 672 cso_set_blend(ctx->cso, &ctx->blend_write_color); 673 else 674 cso_set_blend(ctx->cso, &ctx->blend_keep_color); 675 676 cso_set_sample_mask(ctx->cso, ~0); 677 cso_set_rasterizer(ctx->cso, &ctx->rasterizer); 678 cso_set_vertex_elements(ctx->cso, 2, ctx->velem); 679 cso_set_stream_outputs(ctx->cso, 0, NULL, 0); 680 681 /* default sampler state */ 682 ctx->sampler.normalized_coords = normalized; 683 ctx->sampler.min_img_filter = filter; 684 ctx->sampler.mag_img_filter = filter; 685 ctx->sampler.min_lod = src_level; 686 ctx->sampler.max_lod = src_level; 687 688 /* Depth stencil state, fragment shader and sampler setup depending on what 689 * we blit. 690 */ 691 if (blit_depth && blit_stencil) { 692 cso_single_sampler(ctx->cso, PIPE_SHADER_FRAGMENT, 0, &ctx->sampler); 693 /* don't filter stencil */ 694 ctx->sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; 695 ctx->sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; 696 cso_single_sampler(ctx->cso, PIPE_SHADER_FRAGMENT, 1, &ctx->sampler); 697 698 cso_set_depth_stencil_alpha(ctx->cso, &ctx->dsa_write_depthstencil); 699 set_depthstencil_fragment_shader(ctx, sampler_view->texture->target); 700 } 701 else if (blit_depth) { 702 cso_single_sampler(ctx->cso, PIPE_SHADER_FRAGMENT, 0, &ctx->sampler); 703 cso_set_depth_stencil_alpha(ctx->cso, &ctx->dsa_write_depth); 704 set_depth_fragment_shader(ctx, sampler_view->texture->target); 705 } 706 else if (blit_stencil) { 707 /* don't filter stencil */ 708 ctx->sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; 709 ctx->sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; 710 cso_single_sampler(ctx->cso, PIPE_SHADER_FRAGMENT, 0, &ctx->sampler); 711 712 cso_set_depth_stencil_alpha(ctx->cso, &ctx->dsa_write_stencil); 713 set_stencil_fragment_shader(ctx, sampler_view->texture->target); 714 } 715 else { /* color */ 716 cso_single_sampler(ctx->cso, PIPE_SHADER_FRAGMENT, 0, &ctx->sampler); 717 cso_set_depth_stencil_alpha(ctx->cso, &ctx->dsa_keep_depthstencil); 718 set_fragment_shader(ctx, writemask, sampler_view->texture->target); 719 } 720 cso_single_sampler_done(ctx->cso, PIPE_SHADER_FRAGMENT); 721 722 /* textures */ 723 if (blit_depth && blit_stencil) { 724 /* Setup two samplers, one for depth and the other one for stencil. */ 725 struct pipe_sampler_view templ; 726 struct pipe_sampler_view *views[2]; 727 728 templ = *sampler_view; 729 templ.format = util_format_stencil_only(templ.format); 730 assert(templ.format != PIPE_FORMAT_NONE); 731 732 views[0] = sampler_view; 733 views[1] = pipe->create_sampler_view(pipe, views[0]->texture, &templ); 734 cso_set_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT, 2, views); 735 736 pipe_sampler_view_reference(&views[1], NULL); 737 } 738 else { 739 cso_set_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT, 1, &sampler_view); 740 } 741 742 /* viewport */ 743 ctx->viewport.scale[0] = 0.5f * dst_surface->width; 744 ctx->viewport.scale[1] = 0.5f * dst_surface->height; 745 ctx->viewport.scale[2] = 0.5f; 746 ctx->viewport.scale[3] = 1.0f; 747 ctx->viewport.translate[0] = 0.5f * dst_surface->width; 748 ctx->viewport.translate[1] = 0.5f * dst_surface->height; 749 ctx->viewport.translate[2] = 0.5f; 750 ctx->viewport.translate[3] = 0.0f; 751 cso_set_viewport(ctx->cso, &ctx->viewport); 752 753 set_vertex_shader(ctx); 754 cso_set_geometry_shader_handle(ctx->cso, NULL); 755 756 /* drawing dest */ 757 memset(&fb, 0, sizeof(fb)); 758 fb.width = dst_surface->width; 759 fb.height = dst_surface->height; 760 if (blit_depth || blit_stencil) { 761 fb.zsbuf = dst_surface; 762 } else { 763 fb.nr_cbufs = 1; 764 fb.cbufs[0] = dst_surface; 765 } 766 cso_set_framebuffer(ctx->cso, &fb); 767 768 /* draw quad */ 769 offset = setup_vertex_data_tex(ctx, 770 (float) dstX0 / dst_surface->width * 2.0f - 1.0f, 771 (float) dstY0 / dst_surface->height * 2.0f - 1.0f, 772 (float) dstX1 / dst_surface->width * 2.0f - 1.0f, 773 (float) dstY1 / dst_surface->height * 2.0f - 1.0f, 774 s0, t0, 775 s1, t1, 776 z); 777 778 if (ctx->vbuf) { 779 util_draw_vertex_buffer(ctx->pipe, ctx->cso, ctx->vbuf, offset, 780 PIPE_PRIM_TRIANGLE_FAN, 781 4, /* verts */ 782 2); /* attribs/vert */ 783 } 784 785 /* restore state we changed */ 786 cso_restore_blend(ctx->cso); 787 cso_restore_depth_stencil_alpha(ctx->cso); 788 cso_restore_rasterizer(ctx->cso); 789 cso_restore_sample_mask(ctx->cso); 790 cso_restore_samplers(ctx->cso, PIPE_SHADER_FRAGMENT); 791 cso_restore_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT); 792 cso_restore_viewport(ctx->cso); 793 cso_restore_framebuffer(ctx->cso); 794 cso_restore_fragment_shader(ctx->cso); 795 cso_restore_vertex_shader(ctx->cso); 796 cso_restore_geometry_shader(ctx->cso); 797 cso_restore_vertex_elements(ctx->cso); 798 cso_restore_vertex_buffers(ctx->cso); 799 cso_restore_stream_outputs(ctx->cso); 800 801 pipe_sampler_view_reference(&sampler_view, NULL); 802 if (dst_surface != dst) 803 pipe_surface_reference(&dst_surface, NULL); 804 } 805 806 807 /** 808 * Copy pixel block from src texture to dst surface. 809 * The sampler view's first_level field indicates the source 810 * mipmap level to use. 811 * XXX need some control over blitting Z and/or stencil. 812 */ 813 void 814 util_blit_pixels_tex(struct blit_state *ctx, 815 struct pipe_sampler_view *src_sampler_view, 816 int srcX0, int srcY0, 817 int srcX1, int srcY1, 818 struct pipe_surface *dst, 819 int dstX0, int dstY0, 820 int dstX1, int dstY1, 821 float z, uint filter) 822 { 823 boolean normalized = src_sampler_view->texture->target != PIPE_TEXTURE_RECT; 824 struct pipe_framebuffer_state fb; 825 float s0, t0, s1, t1; 826 unsigned offset; 827 struct pipe_resource *tex = src_sampler_view->texture; 828 829 assert(filter == PIPE_TEX_MIPFILTER_NEAREST || 830 filter == PIPE_TEX_MIPFILTER_LINEAR); 831 832 assert(tex); 833 assert(tex->width0 != 0); 834 assert(tex->height0 != 0); 835 836 s0 = srcX0; 837 s1 = srcX1; 838 t0 = srcY0; 839 t1 = srcY1; 840 841 if(normalized) 842 { 843 /* normalize according to the mipmap level's size */ 844 int level = src_sampler_view->u.tex.first_level; 845 float w = (float) u_minify(tex->width0, level); 846 float h = (float) u_minify(tex->height0, level); 847 s0 /= w; 848 s1 /= w; 849 t0 /= h; 850 t1 /= h; 851 } 852 853 assert(ctx->pipe->screen->is_format_supported(ctx->pipe->screen, dst->format, 854 PIPE_TEXTURE_2D, 855 dst->texture->nr_samples, 856 PIPE_BIND_RENDER_TARGET)); 857 858 /* save state (restored below) */ 859 cso_save_blend(ctx->cso); 860 cso_save_depth_stencil_alpha(ctx->cso); 861 cso_save_rasterizer(ctx->cso); 862 cso_save_sample_mask(ctx->cso); 863 cso_save_samplers(ctx->cso, PIPE_SHADER_FRAGMENT); 864 cso_save_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT); 865 cso_save_stream_outputs(ctx->cso); 866 cso_save_viewport(ctx->cso); 867 cso_save_framebuffer(ctx->cso); 868 cso_save_fragment_shader(ctx->cso); 869 cso_save_vertex_shader(ctx->cso); 870 cso_save_geometry_shader(ctx->cso); 871 cso_save_vertex_elements(ctx->cso); 872 cso_save_vertex_buffers(ctx->cso); 873 874 /* set misc state we care about */ 875 cso_set_blend(ctx->cso, &ctx->blend_write_color); 876 cso_set_depth_stencil_alpha(ctx->cso, &ctx->dsa_keep_depthstencil); 877 cso_set_sample_mask(ctx->cso, ~0); 878 cso_set_rasterizer(ctx->cso, &ctx->rasterizer); 879 cso_set_vertex_elements(ctx->cso, 2, ctx->velem); 880 cso_set_stream_outputs(ctx->cso, 0, NULL, 0); 881 882 /* sampler */ 883 ctx->sampler.normalized_coords = normalized; 884 ctx->sampler.min_img_filter = filter; 885 ctx->sampler.mag_img_filter = filter; 886 cso_single_sampler(ctx->cso, PIPE_SHADER_FRAGMENT, 0, &ctx->sampler); 887 cso_single_sampler_done(ctx->cso, PIPE_SHADER_FRAGMENT); 888 889 /* viewport */ 890 ctx->viewport.scale[0] = 0.5f * dst->width; 891 ctx->viewport.scale[1] = 0.5f * dst->height; 892 ctx->viewport.scale[2] = 0.5f; 893 ctx->viewport.scale[3] = 1.0f; 894 ctx->viewport.translate[0] = 0.5f * dst->width; 895 ctx->viewport.translate[1] = 0.5f * dst->height; 896 ctx->viewport.translate[2] = 0.5f; 897 ctx->viewport.translate[3] = 0.0f; 898 cso_set_viewport(ctx->cso, &ctx->viewport); 899 900 /* texture */ 901 cso_set_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT, 1, &src_sampler_view); 902 903 /* shaders */ 904 set_fragment_shader(ctx, TGSI_WRITEMASK_XYZW, 905 src_sampler_view->texture->target); 906 set_vertex_shader(ctx); 907 cso_set_geometry_shader_handle(ctx->cso, NULL); 908 909 /* drawing dest */ 910 memset(&fb, 0, sizeof(fb)); 911 fb.width = dst->width; 912 fb.height = dst->height; 913 fb.nr_cbufs = 1; 914 fb.cbufs[0] = dst; 915 cso_set_framebuffer(ctx->cso, &fb); 916 917 /* draw quad */ 918 offset = setup_vertex_data_tex(ctx, 919 (float) dstX0 / dst->width * 2.0f - 1.0f, 920 (float) dstY0 / dst->height * 2.0f - 1.0f, 921 (float) dstX1 / dst->width * 2.0f - 1.0f, 922 (float) dstY1 / dst->height * 2.0f - 1.0f, 923 s0, t0, s1, t1, 924 z); 925 926 util_draw_vertex_buffer(ctx->pipe, ctx->cso, 927 ctx->vbuf, offset, 928 PIPE_PRIM_TRIANGLE_FAN, 929 4, /* verts */ 930 2); /* attribs/vert */ 931 932 /* restore state we changed */ 933 cso_restore_blend(ctx->cso); 934 cso_restore_depth_stencil_alpha(ctx->cso); 935 cso_restore_rasterizer(ctx->cso); 936 cso_restore_sample_mask(ctx->cso); 937 cso_restore_samplers(ctx->cso, PIPE_SHADER_FRAGMENT); 938 cso_restore_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT); 939 cso_restore_viewport(ctx->cso); 940 cso_restore_framebuffer(ctx->cso); 941 cso_restore_fragment_shader(ctx->cso); 942 cso_restore_vertex_shader(ctx->cso); 943 cso_restore_geometry_shader(ctx->cso); 944 cso_restore_vertex_elements(ctx->cso); 945 cso_restore_vertex_buffers(ctx->cso); 946 cso_restore_stream_outputs(ctx->cso); 947 } 948