u_blit.c revision 5ba15d8d38d98cb7b625fa55e7d818ef9c6629ce
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 54struct 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 */ 89struct blit_state * 90util_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 */ 164void 165util_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 */ 201static INLINE void 202set_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); 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 */ 221static INLINE void 222set_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); 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 */ 240static INLINE void 241set_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); 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 */ 259static INLINE void 260set_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); 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 */ 278static INLINE void 279set_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 */ 300static unsigned 301get_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 */ 327static unsigned 328setup_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 */ 373static boolean 374regions_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 */ 398static boolean 399formats_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 */ 424void 425util_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->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. 482 * Filter mode should not matter since there's no stretching. 483 */ 484 if (formats_compatible(src_format, dst_format) && 485 is_stencil == blit_stencil && 486 is_depth == blit_depth && 487 srcX0 < srcX1 && 488 dstX0 < dstX1 && 489 srcY0 < srcY1 && 490 dstY0 < dstY1 && 491 (dstX1 - dstX0) == (srcX1 - srcX0) && 492 (dstY1 - dstY0) == (srcY1 - srcY0) && 493 !overlap) { 494 struct pipe_box src_box; 495 src_box.x = srcX0; 496 src_box.y = srcY0; 497 src_box.z = srcZ0; 498 src_box.width = srcW; 499 src_box.height = srcH; 500 src_box.depth = 1; 501 pipe->resource_copy_region(pipe, 502 dst->texture, dst->u.tex.level, 503 dstX0, dstY0, dst->u.tex.first_layer,/* dest */ 504 src_tex, src_level, 505 &src_box); 506 return; 507 } 508 509 /* It's a mistake to call this function with a stencil format and 510 * without shader stencil export. We don't do software fallbacks here. 511 * Ignore stencil and only copy depth. 512 */ 513 if (blit_stencil && !ctx->has_stencil_export) { 514 blit_stencil = FALSE; 515 516 if (!blit_depth) 517 return; 518 } 519 520 if (dst_format == dst->format) { 521 dst_surface = dst; 522 } else { 523 struct pipe_surface templ = *dst; 524 templ.format = dst_format; 525 dst_surface = pipe->create_surface(pipe, dst->texture, &templ); 526 } 527 528 /* Create a temporary texture when src and dest alias. 529 */ 530 if (src_tex == dst_surface->texture && 531 dst_surface->u.tex.level == src_level && 532 dst_surface->u.tex.first_layer == srcZ0) { 533 /* Make a temporary texture which contains a copy of the source pixels. 534 * Then we'll sample from the temporary texture. 535 */ 536 struct pipe_resource texTemp; 537 struct pipe_resource *tex; 538 struct pipe_sampler_view sv_templ; 539 struct pipe_box src_box; 540 const int srcLeft = MIN2(srcX0, srcX1); 541 const int srcTop = MIN2(srcY0, srcY1); 542 543 if (srcLeft != srcX0) { 544 /* left-right flip */ 545 int tmp = dstX0; 546 dstX0 = dstX1; 547 dstX1 = tmp; 548 } 549 550 if (srcTop != srcY0) { 551 /* up-down flip */ 552 int tmp = dstY0; 553 dstY0 = dstY1; 554 dstY1 = tmp; 555 } 556 557 /* create temp texture */ 558 memset(&texTemp, 0, sizeof(texTemp)); 559 texTemp.target = ctx->internal_target; 560 texTemp.format = src_format; 561 texTemp.last_level = 0; 562 texTemp.width0 = srcW; 563 texTemp.height0 = srcH; 564 texTemp.depth0 = 1; 565 texTemp.array_size = 1; 566 texTemp.bind = PIPE_BIND_SAMPLER_VIEW; 567 568 tex = screen->resource_create(screen, &texTemp); 569 if (!tex) 570 return; 571 572 src_box.x = srcLeft; 573 src_box.y = srcTop; 574 src_box.z = srcZ0; 575 src_box.width = srcW; 576 src_box.height = srcH; 577 src_box.depth = 1; 578 /* load temp texture */ 579 pipe->resource_copy_region(pipe, 580 tex, 0, 0, 0, 0, /* dest */ 581 src_tex, src_level, &src_box); 582 583 normalized = tex->target != PIPE_TEXTURE_RECT; 584 if(normalized) { 585 s0 = 0.0f; 586 s1 = 1.0f; 587 t0 = 0.0f; 588 t1 = 1.0f; 589 } 590 else { 591 s0 = 0; 592 s1 = srcW; 593 t0 = 0; 594 t1 = srcH; 595 } 596 597 u_sampler_view_default_template(&sv_templ, tex, tex->format); 598 if (!blit_depth && blit_stencil) { 599 /* set a stencil-only format, e.g. Z24S8 --> X24S8 */ 600 sv_templ.format = util_format_stencil_only(tex->format); 601 assert(sv_templ.format != PIPE_FORMAT_NONE); 602 } 603 sampler_view = pipe->create_sampler_view(pipe, tex, &sv_templ); 604 605 if (!sampler_view) { 606 pipe_resource_reference(&tex, NULL); 607 return; 608 } 609 pipe_resource_reference(&tex, NULL); 610 } 611 else { 612 /* Directly sample from the source resource/texture */ 613 u_sampler_view_default_template(&sv_templ, src_tex, src_format); 614 if (!blit_depth && blit_stencil) { 615 /* set a stencil-only format, e.g. Z24S8 --> X24S8 */ 616 sv_templ.format = util_format_stencil_only(src_format); 617 assert(sv_templ.format != PIPE_FORMAT_NONE); 618 } 619 sampler_view = pipe->create_sampler_view(pipe, src_tex, &sv_templ); 620 621 if (!sampler_view) { 622 return; 623 } 624 625 s0 = srcX0; 626 s1 = srcX1; 627 t0 = srcY0; 628 t1 = srcY1; 629 normalized = sampler_view->texture->target != PIPE_TEXTURE_RECT; 630 if(normalized) 631 { 632 s0 /= (float)(u_minify(sampler_view->texture->width0, src_level)); 633 s1 /= (float)(u_minify(sampler_view->texture->width0, src_level)); 634 t0 /= (float)(u_minify(sampler_view->texture->height0, src_level)); 635 t1 /= (float)(u_minify(sampler_view->texture->height0, src_level)); 636 } 637 } 638 639 assert(screen->is_format_supported(screen, sampler_view->format, 640 ctx->internal_target, sampler_view->texture->nr_samples, 641 PIPE_BIND_SAMPLER_VIEW)); 642 assert(screen->is_format_supported(screen, dst_format, ctx->internal_target, 643 dst_surface->texture->nr_samples, 644 is_depth || is_stencil ? PIPE_BIND_DEPTH_STENCIL : 645 PIPE_BIND_RENDER_TARGET)); 646 647 /* save state (restored below) */ 648 cso_save_blend(ctx->cso); 649 cso_save_depth_stencil_alpha(ctx->cso); 650 cso_save_rasterizer(ctx->cso); 651 cso_save_samplers(ctx->cso); 652 cso_save_fragment_sampler_views(ctx->cso); 653 cso_save_stream_outputs(ctx->cso); 654 cso_save_viewport(ctx->cso); 655 cso_save_framebuffer(ctx->cso); 656 cso_save_fragment_shader(ctx->cso); 657 cso_save_vertex_shader(ctx->cso); 658 cso_save_geometry_shader(ctx->cso); 659 cso_save_vertex_elements(ctx->cso); 660 cso_save_vertex_buffers(ctx->cso); 661 662 /* set misc state we care about */ 663 if (writemask) 664 cso_set_blend(ctx->cso, &ctx->blend_write_color); 665 else 666 cso_set_blend(ctx->cso, &ctx->blend_keep_color); 667 668 cso_set_rasterizer(ctx->cso, &ctx->rasterizer); 669 cso_set_vertex_elements(ctx->cso, 2, ctx->velem); 670 cso_set_stream_outputs(ctx->cso, 0, NULL, 0); 671 672 /* default sampler state */ 673 ctx->sampler.normalized_coords = normalized; 674 ctx->sampler.min_img_filter = filter; 675 ctx->sampler.mag_img_filter = filter; 676 ctx->sampler.min_lod = src_level; 677 ctx->sampler.max_lod = src_level; 678 679 /* Depth stencil state, fragment shader and sampler setup depending on what 680 * we blit. 681 */ 682 if (blit_depth && blit_stencil) { 683 cso_single_sampler(ctx->cso, 0, &ctx->sampler); 684 /* don't filter stencil */ 685 ctx->sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; 686 ctx->sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; 687 cso_single_sampler(ctx->cso, 1, &ctx->sampler); 688 689 cso_set_depth_stencil_alpha(ctx->cso, &ctx->dsa_write_depthstencil); 690 set_depthstencil_fragment_shader(ctx, sampler_view->texture->target); 691 } 692 else if (blit_depth) { 693 cso_single_sampler(ctx->cso, 0, &ctx->sampler); 694 cso_set_depth_stencil_alpha(ctx->cso, &ctx->dsa_write_depth); 695 set_depth_fragment_shader(ctx, sampler_view->texture->target); 696 } 697 else if (blit_stencil) { 698 /* don't filter stencil */ 699 ctx->sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; 700 ctx->sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; 701 cso_single_sampler(ctx->cso, 0, &ctx->sampler); 702 703 cso_set_depth_stencil_alpha(ctx->cso, &ctx->dsa_write_stencil); 704 set_stencil_fragment_shader(ctx, sampler_view->texture->target); 705 } 706 else { /* color */ 707 cso_single_sampler(ctx->cso, 0, &ctx->sampler); 708 cso_set_depth_stencil_alpha(ctx->cso, &ctx->dsa_keep_depthstencil); 709 set_fragment_shader(ctx, writemask, sampler_view->texture->target); 710 } 711 cso_single_sampler_done(ctx->cso); 712 713 /* textures */ 714 if (blit_depth && blit_stencil) { 715 /* Setup two samplers, one for depth and the other one for stencil. */ 716 struct pipe_sampler_view templ; 717 struct pipe_sampler_view *views[2]; 718 719 templ = *sampler_view; 720 templ.format = util_format_stencil_only(templ.format); 721 assert(templ.format != PIPE_FORMAT_NONE); 722 723 views[0] = sampler_view; 724 views[1] = pipe->create_sampler_view(pipe, views[0]->texture, &templ); 725 cso_set_fragment_sampler_views(ctx->cso, 2, views); 726 727 pipe_sampler_view_reference(&views[1], NULL); 728 } 729 else { 730 cso_set_fragment_sampler_views(ctx->cso, 1, &sampler_view); 731 } 732 733 /* viewport */ 734 ctx->viewport.scale[0] = 0.5f * dst_surface->width; 735 ctx->viewport.scale[1] = 0.5f * dst_surface->height; 736 ctx->viewport.scale[2] = 0.5f; 737 ctx->viewport.scale[3] = 1.0f; 738 ctx->viewport.translate[0] = 0.5f * dst_surface->width; 739 ctx->viewport.translate[1] = 0.5f * dst_surface->height; 740 ctx->viewport.translate[2] = 0.5f; 741 ctx->viewport.translate[3] = 0.0f; 742 cso_set_viewport(ctx->cso, &ctx->viewport); 743 744 set_vertex_shader(ctx); 745 cso_set_geometry_shader_handle(ctx->cso, NULL); 746 747 /* drawing dest */ 748 memset(&fb, 0, sizeof(fb)); 749 fb.width = dst_surface->width; 750 fb.height = dst_surface->height; 751 if (blit_depth || blit_stencil) { 752 fb.zsbuf = dst_surface; 753 } else { 754 fb.nr_cbufs = 1; 755 fb.cbufs[0] = dst_surface; 756 } 757 cso_set_framebuffer(ctx->cso, &fb); 758 759 /* draw quad */ 760 offset = setup_vertex_data_tex(ctx, 761 (float) dstX0 / dst_surface->width * 2.0f - 1.0f, 762 (float) dstY0 / dst_surface->height * 2.0f - 1.0f, 763 (float) dstX1 / dst_surface->width * 2.0f - 1.0f, 764 (float) dstY1 / dst_surface->height * 2.0f - 1.0f, 765 s0, t0, 766 s1, t1, 767 z); 768 769 if (ctx->vbuf) { 770 util_draw_vertex_buffer(ctx->pipe, ctx->cso, ctx->vbuf, offset, 771 PIPE_PRIM_TRIANGLE_FAN, 772 4, /* verts */ 773 2); /* attribs/vert */ 774 } 775 776 /* restore state we changed */ 777 cso_restore_blend(ctx->cso); 778 cso_restore_depth_stencil_alpha(ctx->cso); 779 cso_restore_rasterizer(ctx->cso); 780 cso_restore_samplers(ctx->cso); 781 cso_restore_fragment_sampler_views(ctx->cso); 782 cso_restore_viewport(ctx->cso); 783 cso_restore_framebuffer(ctx->cso); 784 cso_restore_fragment_shader(ctx->cso); 785 cso_restore_vertex_shader(ctx->cso); 786 cso_restore_geometry_shader(ctx->cso); 787 cso_restore_vertex_elements(ctx->cso); 788 cso_restore_vertex_buffers(ctx->cso); 789 cso_restore_stream_outputs(ctx->cso); 790 791 pipe_sampler_view_reference(&sampler_view, NULL); 792 if (dst_surface != dst) 793 pipe_surface_reference(&dst_surface, NULL); 794} 795 796 797/** 798 * Copy pixel block from src texture to dst surface. 799 * The sampler view's first_level field indicates the source 800 * mipmap level to use. 801 * XXX need some control over blitting Z and/or stencil. 802 */ 803void 804util_blit_pixels_tex(struct blit_state *ctx, 805 struct pipe_sampler_view *src_sampler_view, 806 int srcX0, int srcY0, 807 int srcX1, int srcY1, 808 struct pipe_surface *dst, 809 int dstX0, int dstY0, 810 int dstX1, int dstY1, 811 float z, uint filter) 812{ 813 boolean normalized = src_sampler_view->texture->target != PIPE_TEXTURE_RECT; 814 struct pipe_framebuffer_state fb; 815 float s0, t0, s1, t1; 816 unsigned offset; 817 struct pipe_resource *tex = src_sampler_view->texture; 818 819 assert(filter == PIPE_TEX_MIPFILTER_NEAREST || 820 filter == PIPE_TEX_MIPFILTER_LINEAR); 821 822 assert(tex); 823 assert(tex->width0 != 0); 824 assert(tex->height0 != 0); 825 826 s0 = srcX0; 827 s1 = srcX1; 828 t0 = srcY0; 829 t1 = srcY1; 830 831 if(normalized) 832 { 833 /* normalize according to the mipmap level's size */ 834 int level = src_sampler_view->u.tex.first_level; 835 float w = (float) u_minify(tex->width0, level); 836 float h = (float) u_minify(tex->height0, level); 837 s0 /= w; 838 s1 /= w; 839 t0 /= h; 840 t1 /= h; 841 } 842 843 assert(ctx->pipe->screen->is_format_supported(ctx->pipe->screen, dst->format, 844 PIPE_TEXTURE_2D, 845 dst->texture->nr_samples, 846 PIPE_BIND_RENDER_TARGET)); 847 848 /* save state (restored below) */ 849 cso_save_blend(ctx->cso); 850 cso_save_depth_stencil_alpha(ctx->cso); 851 cso_save_rasterizer(ctx->cso); 852 cso_save_samplers(ctx->cso); 853 cso_save_fragment_sampler_views(ctx->cso); 854 cso_save_stream_outputs(ctx->cso); 855 cso_save_viewport(ctx->cso); 856 cso_save_framebuffer(ctx->cso); 857 cso_save_fragment_shader(ctx->cso); 858 cso_save_vertex_shader(ctx->cso); 859 cso_save_geometry_shader(ctx->cso); 860 cso_save_vertex_elements(ctx->cso); 861 cso_save_vertex_buffers(ctx->cso); 862 863 /* set misc state we care about */ 864 cso_set_blend(ctx->cso, &ctx->blend_write_color); 865 cso_set_depth_stencil_alpha(ctx->cso, &ctx->dsa_keep_depthstencil); 866 cso_set_rasterizer(ctx->cso, &ctx->rasterizer); 867 cso_set_vertex_elements(ctx->cso, 2, ctx->velem); 868 cso_set_stream_outputs(ctx->cso, 0, NULL, 0); 869 870 /* sampler */ 871 ctx->sampler.normalized_coords = normalized; 872 ctx->sampler.min_img_filter = filter; 873 ctx->sampler.mag_img_filter = filter; 874 cso_single_sampler(ctx->cso, 0, &ctx->sampler); 875 cso_single_sampler_done(ctx->cso); 876 877 /* viewport */ 878 ctx->viewport.scale[0] = 0.5f * dst->width; 879 ctx->viewport.scale[1] = 0.5f * dst->height; 880 ctx->viewport.scale[2] = 0.5f; 881 ctx->viewport.scale[3] = 1.0f; 882 ctx->viewport.translate[0] = 0.5f * dst->width; 883 ctx->viewport.translate[1] = 0.5f * dst->height; 884 ctx->viewport.translate[2] = 0.5f; 885 ctx->viewport.translate[3] = 0.0f; 886 cso_set_viewport(ctx->cso, &ctx->viewport); 887 888 /* texture */ 889 cso_set_fragment_sampler_views(ctx->cso, 1, &src_sampler_view); 890 891 /* shaders */ 892 set_fragment_shader(ctx, TGSI_WRITEMASK_XYZW, 893 src_sampler_view->texture->target); 894 set_vertex_shader(ctx); 895 cso_set_geometry_shader_handle(ctx->cso, NULL); 896 897 /* drawing dest */ 898 memset(&fb, 0, sizeof(fb)); 899 fb.width = dst->width; 900 fb.height = dst->height; 901 fb.nr_cbufs = 1; 902 fb.cbufs[0] = dst; 903 cso_set_framebuffer(ctx->cso, &fb); 904 905 /* draw quad */ 906 offset = setup_vertex_data_tex(ctx, 907 (float) dstX0 / dst->width * 2.0f - 1.0f, 908 (float) dstY0 / dst->height * 2.0f - 1.0f, 909 (float) dstX1 / dst->width * 2.0f - 1.0f, 910 (float) dstY1 / dst->height * 2.0f - 1.0f, 911 s0, t0, s1, t1, 912 z); 913 914 util_draw_vertex_buffer(ctx->pipe, ctx->cso, 915 ctx->vbuf, offset, 916 PIPE_PRIM_TRIANGLE_FAN, 917 4, /* verts */ 918 2); /* attribs/vert */ 919 920 /* restore state we changed */ 921 cso_restore_blend(ctx->cso); 922 cso_restore_depth_stencil_alpha(ctx->cso); 923 cso_restore_rasterizer(ctx->cso); 924 cso_restore_samplers(ctx->cso); 925 cso_restore_fragment_sampler_views(ctx->cso); 926 cso_restore_viewport(ctx->cso); 927 cso_restore_framebuffer(ctx->cso); 928 cso_restore_fragment_shader(ctx->cso); 929 cso_restore_vertex_shader(ctx->cso); 930 cso_restore_geometry_shader(ctx->cso); 931 cso_restore_vertex_elements(ctx->cso); 932 cso_restore_vertex_buffers(ctx->cso); 933 cso_restore_stream_outputs(ctx->cso); 934} 935