u_blitter.c revision 7ec681f3
1/************************************************************************** 2 * 3 * Copyright 2009 Marek Olšák <maraeo@gmail.com> 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sub license, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial portions 15 * of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 20 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 **************************************************************************/ 26 27/** 28 * @file 29 * Blitter utility to facilitate acceleration of the clear, clear_render_target, 30 * clear_depth_stencil, resource_copy_region, and blit functions. 31 * 32 * @author Marek Olšák 33 */ 34 35#include "pipe/p_context.h" 36#include "pipe/p_defines.h" 37#include "util/u_inlines.h" 38#include "pipe/p_shader_tokens.h" 39#include "pipe/p_state.h" 40 41#include "util/format/u_format.h" 42#include "util/u_memory.h" 43#include "util/u_math.h" 44#include "util/u_blitter.h" 45#include "util/u_draw_quad.h" 46#include "util/u_sampler.h" 47#include "util/u_simple_shaders.h" 48#include "util/u_surface.h" 49#include "util/u_texture.h" 50#include "util/u_upload_mgr.h" 51 52#define INVALID_PTR ((void*)~0) 53 54#define GET_CLEAR_BLEND_STATE_IDX(clear_buffers) \ 55 ((clear_buffers) / PIPE_CLEAR_COLOR0) 56 57#define NUM_RESOLVE_FRAG_SHADERS 5 /* MSAA 2x, 4x, 8x, 16x, 32x */ 58#define GET_MSAA_RESOLVE_FS_IDX(nr_samples) (util_logbase2(nr_samples)-1) 59 60struct blitter_context_priv 61{ 62 struct blitter_context base; 63 64 float vertices[4][2][4]; /**< {pos, color} or {pos, texcoord} */ 65 66 /* Templates for various state objects. */ 67 68 /* Constant state objects. */ 69 /* Vertex shaders. */ 70 void *vs; /**< Vertex shader which passes {pos, generic} to the output.*/ 71 void *vs_nogeneric; 72 void *vs_pos_only[4]; /**< Vertex shader which passes pos to the output 73 for clear_buffer/copy_buffer.*/ 74 void *vs_layered; /**< Vertex shader which sets LAYER = INSTANCEID. */ 75 76 /* Fragment shaders. */ 77 void *fs_empty; 78 void *fs_write_one_cbuf; 79 void *fs_write_all_cbufs; 80 81 /* FS which outputs a color from a texture where 82 * the 1st index indicates the texture type / destination type, 83 * the 2nd index is the PIPE_TEXTURE_* to be sampled, 84 * the 3rd index is 0 = use TEX, 1 = use TXF. 85 */ 86 void *fs_texfetch_col[5][PIPE_MAX_TEXTURE_TYPES][2]; 87 88 /* FS which outputs a depth from a texture, where 89 * the 1st index is the PIPE_TEXTURE_* to be sampled, 90 * the 2nd index is 0 = use TEX, 1 = use TXF. 91 */ 92 void *fs_texfetch_depth[PIPE_MAX_TEXTURE_TYPES][2]; 93 void *fs_texfetch_depthstencil[PIPE_MAX_TEXTURE_TYPES][2]; 94 void *fs_texfetch_stencil[PIPE_MAX_TEXTURE_TYPES][2]; 95 96 /* FS which outputs one sample from a multisample texture. */ 97 void *fs_texfetch_col_msaa[5][PIPE_MAX_TEXTURE_TYPES]; 98 void *fs_texfetch_depth_msaa[PIPE_MAX_TEXTURE_TYPES]; 99 void *fs_texfetch_depthstencil_msaa[PIPE_MAX_TEXTURE_TYPES]; 100 void *fs_texfetch_stencil_msaa[PIPE_MAX_TEXTURE_TYPES]; 101 102 /* FS which outputs an average of all samples. */ 103 void *fs_resolve[PIPE_MAX_TEXTURE_TYPES][NUM_RESOLVE_FRAG_SHADERS][2]; 104 105 /* FS which unpacks color to ZS or packs ZS to color, matching 106 * the ZS format. See util_blitter_get_color_format_for_zs(). 107 */ 108 void *fs_pack_color_zs[TGSI_TEXTURE_COUNT][10]; 109 110 /* FS which is meant for replicating indevidual stencil-buffer bits */ 111 void *fs_stencil_blit_fallback[2]; 112 113 /* Blend state. */ 114 void *blend[PIPE_MASK_RGBA+1][2]; /**< blend state with writemask */ 115 void *blend_clear[GET_CLEAR_BLEND_STATE_IDX(PIPE_CLEAR_COLOR)+1]; 116 117 /* Depth stencil alpha state. */ 118 void *dsa_write_depth_stencil; 119 void *dsa_write_depth_keep_stencil; 120 void *dsa_keep_depth_stencil; 121 void *dsa_keep_depth_write_stencil; 122 void *dsa_replicate_stencil_bit[8]; 123 124 /* Vertex elements states. */ 125 void *velem_state; 126 void *velem_state_readbuf[4]; /**< X, XY, XYZ, XYZW */ 127 128 /* Sampler state. */ 129 void *sampler_state; 130 void *sampler_state_linear; 131 void *sampler_state_rect; 132 void *sampler_state_rect_linear; 133 134 /* Rasterizer state. */ 135 void *rs_state[2][2]; /**< [scissor][msaa] */ 136 void *rs_discard_state; 137 138 /* Destination surface dimensions. */ 139 unsigned dst_width; 140 unsigned dst_height; 141 142 void *custom_vs; 143 144 bool has_geometry_shader; 145 bool has_tessellation; 146 bool has_layered; 147 bool has_stream_out; 148 bool has_stencil_export; 149 bool has_texture_multisample; 150 bool has_tex_lz; 151 bool has_txf; 152 bool cube_as_2darray; 153 bool cached_all_shaders; 154 155 /* The Draw module overrides these functions. 156 * Always create the blitter before Draw. */ 157 void (*bind_fs_state)(struct pipe_context *, void *); 158 void (*delete_fs_state)(struct pipe_context *, void *); 159}; 160 161struct blitter_context *util_blitter_create(struct pipe_context *pipe) 162{ 163 struct blitter_context_priv *ctx; 164 struct pipe_blend_state blend; 165 struct pipe_depth_stencil_alpha_state dsa; 166 struct pipe_rasterizer_state rs_state; 167 struct pipe_sampler_state sampler_state; 168 struct pipe_vertex_element velem[2]; 169 unsigned i, j; 170 171 ctx = CALLOC_STRUCT(blitter_context_priv); 172 if (!ctx) 173 return NULL; 174 175 ctx->base.pipe = pipe; 176 ctx->base.draw_rectangle = util_blitter_draw_rectangle; 177 178 ctx->bind_fs_state = pipe->bind_fs_state; 179 ctx->delete_fs_state = pipe->delete_fs_state; 180 181 /* init state objects for them to be considered invalid */ 182 ctx->base.saved_blend_state = INVALID_PTR; 183 ctx->base.saved_dsa_state = INVALID_PTR; 184 ctx->base.saved_rs_state = INVALID_PTR; 185 ctx->base.saved_fs = INVALID_PTR; 186 ctx->base.saved_vs = INVALID_PTR; 187 ctx->base.saved_gs = INVALID_PTR; 188 ctx->base.saved_velem_state = INVALID_PTR; 189 ctx->base.saved_fb_state.nr_cbufs = ~0; 190 ctx->base.saved_num_sampler_views = ~0; 191 ctx->base.saved_num_sampler_states = ~0; 192 ctx->base.saved_num_so_targets = ~0; 193 194 ctx->has_geometry_shader = 195 pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_GEOMETRY, 196 PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0; 197 198 ctx->has_tessellation = 199 pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_TESS_CTRL, 200 PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0; 201 202 ctx->has_stream_out = 203 pipe->screen->get_param(pipe->screen, 204 PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS) != 0; 205 206 ctx->has_stencil_export = 207 pipe->screen->get_param(pipe->screen, 208 PIPE_CAP_SHADER_STENCIL_EXPORT); 209 210 ctx->has_texture_multisample = 211 pipe->screen->get_param(pipe->screen, PIPE_CAP_TEXTURE_MULTISAMPLE); 212 213 ctx->has_tex_lz = pipe->screen->get_param(pipe->screen, 214 PIPE_CAP_TGSI_TEX_TXF_LZ); 215 ctx->has_txf = pipe->screen->get_param(pipe->screen, 216 PIPE_CAP_GLSL_FEATURE_LEVEL) > 130; 217 ctx->cube_as_2darray = pipe->screen->get_param(pipe->screen, 218 PIPE_CAP_SAMPLER_VIEW_TARGET); 219 220 /* blend state objects */ 221 memset(&blend, 0, sizeof(blend)); 222 223 for (i = 0; i <= PIPE_MASK_RGBA; i++) { 224 for (j = 0; j < 2; j++) { 225 memset(&blend.rt[0], 0, sizeof(blend.rt[0])); 226 blend.rt[0].colormask = i; 227 if (j) { 228 blend.rt[0].blend_enable = 1; 229 blend.rt[0].rgb_func = PIPE_BLEND_ADD; 230 blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA; 231 blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; 232 blend.rt[0].alpha_func = PIPE_BLEND_ADD; 233 blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA; 234 blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; 235 } 236 ctx->blend[i][j] = pipe->create_blend_state(pipe, &blend); 237 } 238 } 239 240 /* depth stencil alpha state objects */ 241 memset(&dsa, 0, sizeof(dsa)); 242 ctx->dsa_keep_depth_stencil = 243 pipe->create_depth_stencil_alpha_state(pipe, &dsa); 244 245 dsa.depth_enabled = 1; 246 dsa.depth_writemask = 1; 247 dsa.depth_func = PIPE_FUNC_ALWAYS; 248 ctx->dsa_write_depth_keep_stencil = 249 pipe->create_depth_stencil_alpha_state(pipe, &dsa); 250 251 dsa.stencil[0].enabled = 1; 252 dsa.stencil[0].func = PIPE_FUNC_ALWAYS; 253 dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE; 254 dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE; 255 dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE; 256 dsa.stencil[0].valuemask = 0xff; 257 dsa.stencil[0].writemask = 0xff; 258 ctx->dsa_write_depth_stencil = 259 pipe->create_depth_stencil_alpha_state(pipe, &dsa); 260 261 dsa.depth_enabled = 0; 262 dsa.depth_writemask = 0; 263 ctx->dsa_keep_depth_write_stencil = 264 pipe->create_depth_stencil_alpha_state(pipe, &dsa); 265 266 /* sampler state */ 267 memset(&sampler_state, 0, sizeof(sampler_state)); 268 sampler_state.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 269 sampler_state.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 270 sampler_state.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 271 sampler_state.normalized_coords = 1; 272 ctx->sampler_state = pipe->create_sampler_state(pipe, &sampler_state); 273 sampler_state.normalized_coords = 0; 274 ctx->sampler_state_rect = pipe->create_sampler_state(pipe, &sampler_state); 275 276 sampler_state.min_img_filter = PIPE_TEX_FILTER_LINEAR; 277 sampler_state.mag_img_filter = PIPE_TEX_FILTER_LINEAR; 278 sampler_state.normalized_coords = 1; 279 ctx->sampler_state_linear = pipe->create_sampler_state(pipe, &sampler_state); 280 sampler_state.normalized_coords = 0; 281 ctx->sampler_state_rect_linear = pipe->create_sampler_state(pipe, &sampler_state); 282 283 /* rasterizer state */ 284 memset(&rs_state, 0, sizeof(rs_state)); 285 rs_state.cull_face = PIPE_FACE_NONE; 286 rs_state.half_pixel_center = 1; 287 rs_state.bottom_edge_rule = 1; 288 rs_state.flatshade = 1; 289 rs_state.depth_clip_near = 1; 290 rs_state.depth_clip_far = 1; 291 292 unsigned scissor, msaa; 293 for (scissor = 0; scissor < 2; scissor++) { 294 for (msaa = 0; msaa < 2; msaa++) { 295 rs_state.scissor = scissor; 296 rs_state.multisample = msaa; 297 ctx->rs_state[scissor][msaa] = 298 pipe->create_rasterizer_state(pipe, &rs_state); 299 } 300 } 301 302 if (ctx->has_stream_out) { 303 rs_state.scissor = rs_state.multisample = 0; 304 rs_state.rasterizer_discard = 1; 305 ctx->rs_discard_state = pipe->create_rasterizer_state(pipe, &rs_state); 306 } 307 308 ctx->base.cb_slot = 0; /* 0 for now */ 309 ctx->base.vb_slot = 0; /* 0 for now */ 310 311 /* vertex elements states */ 312 memset(&velem[0], 0, sizeof(velem[0]) * 2); 313 for (i = 0; i < 2; i++) { 314 velem[i].src_offset = i * 4 * sizeof(float); 315 velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 316 velem[i].vertex_buffer_index = ctx->base.vb_slot; 317 } 318 ctx->velem_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]); 319 320 if (ctx->has_stream_out) { 321 static enum pipe_format formats[4] = { 322 PIPE_FORMAT_R32_UINT, 323 PIPE_FORMAT_R32G32_UINT, 324 PIPE_FORMAT_R32G32B32_UINT, 325 PIPE_FORMAT_R32G32B32A32_UINT 326 }; 327 328 for (i = 0; i < 4; i++) { 329 velem[0].src_format = formats[i]; 330 velem[0].vertex_buffer_index = ctx->base.vb_slot; 331 ctx->velem_state_readbuf[i] = 332 pipe->create_vertex_elements_state(pipe, 1, &velem[0]); 333 } 334 } 335 336 ctx->has_layered = 337 pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_INSTANCEID) && 338 pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_VS_LAYER_VIEWPORT); 339 340 /* set invariant vertex coordinates */ 341 for (i = 0; i < 4; i++) { 342 ctx->vertices[i][0][2] = 0; /*v.z*/ 343 ctx->vertices[i][0][3] = 1; /*v.w*/ 344 } 345 346 return &ctx->base; 347} 348 349void *util_blitter_get_noop_blend_state(struct blitter_context *blitter) 350{ 351 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 352 353 return ctx->blend[0][0]; 354} 355 356void *util_blitter_get_noop_dsa_state(struct blitter_context *blitter) 357{ 358 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 359 360 return ctx->dsa_keep_depth_stencil; 361} 362 363void *util_blitter_get_discard_rasterizer_state(struct blitter_context *blitter) 364{ 365 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 366 367 return ctx->rs_discard_state; 368} 369 370static void bind_vs_pos_only(struct blitter_context_priv *ctx, 371 unsigned num_so_channels) 372{ 373 struct pipe_context *pipe = ctx->base.pipe; 374 int index = num_so_channels ? num_so_channels - 1 : 0; 375 376 if (!ctx->vs_pos_only[index]) { 377 struct pipe_stream_output_info so; 378 static const enum tgsi_semantic semantic_names[] = 379 { TGSI_SEMANTIC_POSITION }; 380 const uint semantic_indices[] = { 0 }; 381 382 memset(&so, 0, sizeof(so)); 383 so.num_outputs = 1; 384 so.output[0].num_components = num_so_channels; 385 so.stride[0] = num_so_channels; 386 387 ctx->vs_pos_only[index] = 388 util_make_vertex_passthrough_shader_with_so(pipe, 1, semantic_names, 389 semantic_indices, false, 390 false, &so); 391 } 392 393 pipe->bind_vs_state(pipe, ctx->vs_pos_only[index]); 394} 395 396static void *get_vs_passthrough_pos_generic(struct blitter_context *blitter) 397{ 398 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 399 struct pipe_context *pipe = ctx->base.pipe; 400 401 if (!ctx->vs) { 402 static const enum tgsi_semantic semantic_names[] = 403 { TGSI_SEMANTIC_POSITION, TGSI_SEMANTIC_GENERIC }; 404 const uint semantic_indices[] = { 0, 0 }; 405 ctx->vs = 406 util_make_vertex_passthrough_shader(pipe, 2, semantic_names, 407 semantic_indices, false); 408 } 409 return ctx->vs; 410} 411 412static void *get_vs_passthrough_pos(struct blitter_context *blitter) 413{ 414 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 415 struct pipe_context *pipe = ctx->base.pipe; 416 417 if (!ctx->vs_nogeneric) { 418 static const enum tgsi_semantic semantic_names[] = 419 { TGSI_SEMANTIC_POSITION }; 420 const uint semantic_indices[] = { 0 }; 421 422 ctx->vs_nogeneric = 423 util_make_vertex_passthrough_shader(pipe, 1, 424 semantic_names, 425 semantic_indices, false); 426 } 427 return ctx->vs_nogeneric; 428} 429 430static void *get_vs_layered(struct blitter_context *blitter) 431{ 432 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 433 struct pipe_context *pipe = ctx->base.pipe; 434 435 if (!ctx->vs_layered) { 436 ctx->vs_layered = util_make_layered_clear_vertex_shader(pipe); 437 } 438 return ctx->vs_layered; 439} 440 441static void bind_fs_empty(struct blitter_context_priv *ctx) 442{ 443 struct pipe_context *pipe = ctx->base.pipe; 444 445 if (!ctx->fs_empty) { 446 assert(!ctx->cached_all_shaders); 447 ctx->fs_empty = util_make_empty_fragment_shader(pipe); 448 } 449 450 ctx->bind_fs_state(pipe, ctx->fs_empty); 451} 452 453static void bind_fs_write_one_cbuf(struct blitter_context_priv *ctx) 454{ 455 struct pipe_context *pipe = ctx->base.pipe; 456 457 if (!ctx->fs_write_one_cbuf) { 458 assert(!ctx->cached_all_shaders); 459 ctx->fs_write_one_cbuf = 460 util_make_fragment_passthrough_shader(pipe, TGSI_SEMANTIC_GENERIC, 461 TGSI_INTERPOLATE_CONSTANT, false); 462 } 463 464 ctx->bind_fs_state(pipe, ctx->fs_write_one_cbuf); 465} 466 467static void bind_fs_write_all_cbufs(struct blitter_context_priv *ctx) 468{ 469 struct pipe_context *pipe = ctx->base.pipe; 470 471 if (!ctx->fs_write_all_cbufs) { 472 assert(!ctx->cached_all_shaders); 473 ctx->fs_write_all_cbufs = 474 util_make_fragment_passthrough_shader(pipe, TGSI_SEMANTIC_GENERIC, 475 TGSI_INTERPOLATE_CONSTANT, true); 476 } 477 478 ctx->bind_fs_state(pipe, ctx->fs_write_all_cbufs); 479} 480 481void util_blitter_destroy(struct blitter_context *blitter) 482{ 483 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 484 struct pipe_context *pipe = blitter->pipe; 485 unsigned i, j, f; 486 487 for (i = 0; i <= PIPE_MASK_RGBA; i++) 488 for (j = 0; j < 2; j++) 489 pipe->delete_blend_state(pipe, ctx->blend[i][j]); 490 491 for (i = 0; i < ARRAY_SIZE(ctx->blend_clear); i++) { 492 if (ctx->blend_clear[i]) 493 pipe->delete_blend_state(pipe, ctx->blend_clear[i]); 494 } 495 pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 496 pipe->delete_depth_stencil_alpha_state(pipe, 497 ctx->dsa_write_depth_keep_stencil); 498 pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil); 499 pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil); 500 501 for (i = 0; i < ARRAY_SIZE(ctx->dsa_replicate_stencil_bit); i++) { 502 if (ctx->dsa_replicate_stencil_bit[i]) 503 pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_replicate_stencil_bit[i]); 504 } 505 506 unsigned scissor, msaa; 507 for (scissor = 0; scissor < 2; scissor++) { 508 for (msaa = 0; msaa < 2; msaa++) { 509 pipe->delete_rasterizer_state(pipe, ctx->rs_state[scissor][msaa]); 510 } 511 } 512 513 if (ctx->rs_discard_state) 514 pipe->delete_rasterizer_state(pipe, ctx->rs_discard_state); 515 if (ctx->vs) 516 pipe->delete_vs_state(pipe, ctx->vs); 517 if (ctx->vs_nogeneric) 518 pipe->delete_vs_state(pipe, ctx->vs_nogeneric); 519 for (i = 0; i < 4; i++) 520 if (ctx->vs_pos_only[i]) 521 pipe->delete_vs_state(pipe, ctx->vs_pos_only[i]); 522 if (ctx->vs_layered) 523 pipe->delete_vs_state(pipe, ctx->vs_layered); 524 pipe->delete_vertex_elements_state(pipe, ctx->velem_state); 525 for (i = 0; i < 4; i++) { 526 if (ctx->velem_state_readbuf[i]) { 527 pipe->delete_vertex_elements_state(pipe, ctx->velem_state_readbuf[i]); 528 } 529 } 530 531 for (i = 0; i < PIPE_MAX_TEXTURE_TYPES; i++) { 532 for (unsigned type = 0; type < ARRAY_SIZE(ctx->fs_texfetch_col); ++type) { 533 for (unsigned inst = 0; inst < 2; inst++) { 534 if (ctx->fs_texfetch_col[type][i][inst]) 535 ctx->delete_fs_state(pipe, ctx->fs_texfetch_col[type][i][inst]); 536 } 537 if (ctx->fs_texfetch_col_msaa[type][i]) 538 ctx->delete_fs_state(pipe, ctx->fs_texfetch_col_msaa[type][i]); 539 } 540 541 for (unsigned inst = 0; inst < 2; inst++) { 542 if (ctx->fs_texfetch_depth[i][inst]) 543 ctx->delete_fs_state(pipe, ctx->fs_texfetch_depth[i][inst]); 544 if (ctx->fs_texfetch_depthstencil[i][inst]) 545 ctx->delete_fs_state(pipe, ctx->fs_texfetch_depthstencil[i][inst]); 546 if (ctx->fs_texfetch_stencil[i][inst]) 547 ctx->delete_fs_state(pipe, ctx->fs_texfetch_stencil[i][inst]); 548 } 549 550 if (ctx->fs_texfetch_depth_msaa[i]) 551 ctx->delete_fs_state(pipe, ctx->fs_texfetch_depth_msaa[i]); 552 if (ctx->fs_texfetch_depthstencil_msaa[i]) 553 ctx->delete_fs_state(pipe, ctx->fs_texfetch_depthstencil_msaa[i]); 554 if (ctx->fs_texfetch_stencil_msaa[i]) 555 ctx->delete_fs_state(pipe, ctx->fs_texfetch_stencil_msaa[i]); 556 557 for (j = 0; j< ARRAY_SIZE(ctx->fs_resolve[i]); j++) 558 for (f = 0; f < 2; f++) 559 if (ctx->fs_resolve[i][j][f]) 560 ctx->delete_fs_state(pipe, ctx->fs_resolve[i][j][f]); 561 } 562 563 for (i = 0; i < ARRAY_SIZE(ctx->fs_pack_color_zs); i++) { 564 for (j = 0; j < ARRAY_SIZE(ctx->fs_pack_color_zs[0]); j++) { 565 if (ctx->fs_pack_color_zs[i][j]) 566 ctx->delete_fs_state(pipe, ctx->fs_pack_color_zs[i][j]); 567 } 568 } 569 570 if (ctx->fs_empty) 571 ctx->delete_fs_state(pipe, ctx->fs_empty); 572 if (ctx->fs_write_one_cbuf) 573 ctx->delete_fs_state(pipe, ctx->fs_write_one_cbuf); 574 if (ctx->fs_write_all_cbufs) 575 ctx->delete_fs_state(pipe, ctx->fs_write_all_cbufs); 576 577 for (i = 0; i < ARRAY_SIZE(ctx->fs_stencil_blit_fallback); ++i) 578 if (ctx->fs_stencil_blit_fallback[i]) 579 ctx->delete_fs_state(pipe, ctx->fs_stencil_blit_fallback[i]); 580 581 pipe->delete_sampler_state(pipe, ctx->sampler_state_rect_linear); 582 pipe->delete_sampler_state(pipe, ctx->sampler_state_rect); 583 pipe->delete_sampler_state(pipe, ctx->sampler_state_linear); 584 pipe->delete_sampler_state(pipe, ctx->sampler_state); 585 FREE(ctx); 586} 587 588void util_blitter_set_texture_multisample(struct blitter_context *blitter, 589 bool supported) 590{ 591 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 592 593 ctx->has_texture_multisample = supported; 594} 595 596void util_blitter_set_running_flag(struct blitter_context *blitter) 597{ 598 if (blitter->running) { 599 _debug_printf("u_blitter:%i: Caught recursion. This is a driver bug.\n", 600 __LINE__); 601 } 602 blitter->running = true; 603 604 blitter->pipe->set_active_query_state(blitter->pipe, false); 605} 606 607void util_blitter_unset_running_flag(struct blitter_context *blitter) 608{ 609 if (!blitter->running) { 610 _debug_printf("u_blitter:%i: Caught recursion. This is a driver bug.\n", 611 __LINE__); 612 } 613 blitter->running = false; 614 615 blitter->pipe->set_active_query_state(blitter->pipe, true); 616} 617 618static void blitter_check_saved_vertex_states(ASSERTED struct blitter_context_priv *ctx) 619{ 620 assert(ctx->base.saved_vs != INVALID_PTR); 621 assert(!ctx->has_geometry_shader || ctx->base.saved_gs != INVALID_PTR); 622 assert(!ctx->has_tessellation || ctx->base.saved_tcs != INVALID_PTR); 623 assert(!ctx->has_tessellation || ctx->base.saved_tes != INVALID_PTR); 624 assert(!ctx->has_stream_out || ctx->base.saved_num_so_targets != ~0u); 625 assert(ctx->base.saved_rs_state != INVALID_PTR); 626} 627 628void util_blitter_restore_vertex_states(struct blitter_context *blitter) 629{ 630 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 631 struct pipe_context *pipe = ctx->base.pipe; 632 unsigned i; 633 634 /* Vertex buffer. */ 635 if (ctx->base.saved_vertex_buffer.buffer.resource) { 636 pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, 0, true, 637 &ctx->base.saved_vertex_buffer); 638 ctx->base.saved_vertex_buffer.buffer.resource = NULL; 639 } 640 641 /* Vertex elements. */ 642 if (ctx->base.saved_velem_state != INVALID_PTR) { 643 pipe->bind_vertex_elements_state(pipe, ctx->base.saved_velem_state); 644 ctx->base.saved_velem_state = INVALID_PTR; 645 } 646 647 /* Vertex shader. */ 648 pipe->bind_vs_state(pipe, ctx->base.saved_vs); 649 ctx->base.saved_vs = INVALID_PTR; 650 651 /* Geometry shader. */ 652 if (ctx->has_geometry_shader) { 653 pipe->bind_gs_state(pipe, ctx->base.saved_gs); 654 ctx->base.saved_gs = INVALID_PTR; 655 } 656 657 if (ctx->has_tessellation) { 658 pipe->bind_tcs_state(pipe, ctx->base.saved_tcs); 659 pipe->bind_tes_state(pipe, ctx->base.saved_tes); 660 ctx->base.saved_tcs = INVALID_PTR; 661 ctx->base.saved_tes = INVALID_PTR; 662 } 663 664 /* Stream outputs. */ 665 if (ctx->has_stream_out) { 666 unsigned offsets[PIPE_MAX_SO_BUFFERS]; 667 for (i = 0; i < ctx->base.saved_num_so_targets; i++) 668 offsets[i] = (unsigned)-1; 669 pipe->set_stream_output_targets(pipe, 670 ctx->base.saved_num_so_targets, 671 ctx->base.saved_so_targets, offsets); 672 673 for (i = 0; i < ctx->base.saved_num_so_targets; i++) 674 pipe_so_target_reference(&ctx->base.saved_so_targets[i], NULL); 675 676 ctx->base.saved_num_so_targets = ~0; 677 } 678 679 /* Rasterizer. */ 680 pipe->bind_rasterizer_state(pipe, ctx->base.saved_rs_state); 681 ctx->base.saved_rs_state = INVALID_PTR; 682} 683 684static void blitter_check_saved_fragment_states(ASSERTED struct blitter_context_priv *ctx) 685{ 686 assert(ctx->base.saved_fs != INVALID_PTR); 687 assert(ctx->base.saved_dsa_state != INVALID_PTR); 688 assert(ctx->base.saved_blend_state != INVALID_PTR); 689} 690 691void util_blitter_restore_fragment_states(struct blitter_context *blitter) 692{ 693 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 694 struct pipe_context *pipe = ctx->base.pipe; 695 696 /* Fragment shader. */ 697 ctx->bind_fs_state(pipe, ctx->base.saved_fs); 698 ctx->base.saved_fs = INVALID_PTR; 699 700 /* Depth, stencil, alpha. */ 701 pipe->bind_depth_stencil_alpha_state(pipe, ctx->base.saved_dsa_state); 702 ctx->base.saved_dsa_state = INVALID_PTR; 703 704 /* Blend state. */ 705 pipe->bind_blend_state(pipe, ctx->base.saved_blend_state); 706 ctx->base.saved_blend_state = INVALID_PTR; 707 708 /* Sample mask. */ 709 if (ctx->base.is_sample_mask_saved) { 710 pipe->set_sample_mask(pipe, ctx->base.saved_sample_mask); 711 ctx->base.is_sample_mask_saved = false; 712 } 713 714 /* Miscellaneous states. */ 715 /* XXX check whether these are saved and whether they need to be restored 716 * (depending on the operation) */ 717 pipe->set_stencil_ref(pipe, ctx->base.saved_stencil_ref); 718 719 if (!blitter->skip_viewport_restore) 720 pipe->set_viewport_states(pipe, 0, 1, &ctx->base.saved_viewport); 721 722 if (blitter->saved_num_window_rectangles) { 723 pipe->set_window_rectangles(pipe, 724 blitter->saved_window_rectangles_include, 725 blitter->saved_num_window_rectangles, 726 blitter->saved_window_rectangles); 727 } 728} 729 730static void blitter_check_saved_fb_state(ASSERTED struct blitter_context_priv *ctx) 731{ 732 assert(ctx->base.saved_fb_state.nr_cbufs != (ubyte) ~0); 733} 734 735static void blitter_disable_render_cond(struct blitter_context_priv *ctx) 736{ 737 struct pipe_context *pipe = ctx->base.pipe; 738 739 if (ctx->base.saved_render_cond_query) { 740 pipe->render_condition(pipe, NULL, false, 0); 741 } 742} 743 744void util_blitter_restore_render_cond(struct blitter_context *blitter) 745{ 746 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 747 struct pipe_context *pipe = ctx->base.pipe; 748 749 if (ctx->base.saved_render_cond_query) { 750 pipe->render_condition(pipe, ctx->base.saved_render_cond_query, 751 ctx->base.saved_render_cond_cond, 752 ctx->base.saved_render_cond_mode); 753 ctx->base.saved_render_cond_query = NULL; 754 } 755} 756 757void util_blitter_restore_fb_state(struct blitter_context *blitter) 758{ 759 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 760 struct pipe_context *pipe = ctx->base.pipe; 761 762 pipe->set_framebuffer_state(pipe, &ctx->base.saved_fb_state); 763 util_unreference_framebuffer_state(&ctx->base.saved_fb_state); 764} 765 766static void blitter_check_saved_textures(ASSERTED struct blitter_context_priv *ctx) 767{ 768 assert(ctx->base.saved_num_sampler_states != ~0u); 769 assert(ctx->base.saved_num_sampler_views != ~0u); 770} 771 772void util_blitter_restore_textures(struct blitter_context *blitter) 773{ 774 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 775 struct pipe_context *pipe = ctx->base.pipe; 776 unsigned i; 777 778 /* Fragment sampler states. */ 779 pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0, 780 ctx->base.saved_num_sampler_states, 781 ctx->base.saved_sampler_states); 782 783 ctx->base.saved_num_sampler_states = ~0; 784 785 /* Fragment sampler views. */ 786 pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 787 ctx->base.saved_num_sampler_views, 0, true, 788 ctx->base.saved_sampler_views); 789 790 /* Just clear them to NULL because set_sampler_views(take_ownership = true). */ 791 for (i = 0; i < ctx->base.saved_num_sampler_views; i++) 792 ctx->base.saved_sampler_views[i] = NULL; 793 794 ctx->base.saved_num_sampler_views = ~0; 795} 796 797void util_blitter_restore_constant_buffer_state(struct blitter_context *blitter) 798{ 799 struct pipe_context *pipe = blitter->pipe; 800 801 pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, blitter->cb_slot, 802 true, &blitter->saved_fs_constant_buffer); 803 blitter->saved_fs_constant_buffer.buffer = NULL; 804} 805 806static void blitter_set_rectangle(struct blitter_context_priv *ctx, 807 int x1, int y1, int x2, int y2, 808 float depth) 809{ 810 /* set vertex positions */ 811 ctx->vertices[0][0][0] = (float)x1 / ctx->dst_width * 2.0f - 1.0f; /*v0.x*/ 812 ctx->vertices[0][0][1] = (float)y1 / ctx->dst_height * 2.0f - 1.0f; /*v0.y*/ 813 814 ctx->vertices[1][0][0] = (float)x2 / ctx->dst_width * 2.0f - 1.0f; /*v1.x*/ 815 ctx->vertices[1][0][1] = (float)y1 / ctx->dst_height * 2.0f - 1.0f; /*v1.y*/ 816 817 ctx->vertices[2][0][0] = (float)x2 / ctx->dst_width * 2.0f - 1.0f; /*v2.x*/ 818 ctx->vertices[2][0][1] = (float)y2 / ctx->dst_height * 2.0f - 1.0f; /*v2.y*/ 819 820 ctx->vertices[3][0][0] = (float)x1 / ctx->dst_width * 2.0f - 1.0f; /*v3.x*/ 821 ctx->vertices[3][0][1] = (float)y2 / ctx->dst_height * 2.0f - 1.0f; /*v3.y*/ 822 823 /* viewport */ 824 struct pipe_viewport_state viewport; 825 viewport.scale[0] = 0.5f * ctx->dst_width; 826 viewport.scale[1] = 0.5f * ctx->dst_height; 827 viewport.scale[2] = 0.0f; 828 viewport.translate[0] = 0.5f * ctx->dst_width; 829 viewport.translate[1] = 0.5f * ctx->dst_height; 830 viewport.translate[2] = depth; 831 viewport.swizzle_x = PIPE_VIEWPORT_SWIZZLE_POSITIVE_X; 832 viewport.swizzle_y = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Y; 833 viewport.swizzle_z = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Z; 834 viewport.swizzle_w = PIPE_VIEWPORT_SWIZZLE_POSITIVE_W; 835 ctx->base.pipe->set_viewport_states(ctx->base.pipe, 0, 1, &viewport); 836} 837 838static void blitter_set_clear_color(struct blitter_context_priv *ctx, 839 const float color[4]) 840{ 841 int i; 842 843 if (color) { 844 for (i = 0; i < 4; i++) 845 memcpy(&ctx->vertices[i][1][0], color, sizeof(uint32_t) * 4); 846 } else { 847 for (i = 0; i < 4; i++) 848 memset(&ctx->vertices[i][1][0], 0, sizeof(uint32_t) * 4); 849 } 850} 851 852static void get_texcoords(struct pipe_sampler_view *src, 853 unsigned src_width0, unsigned src_height0, 854 int x1, int y1, int x2, int y2, 855 float layer, unsigned sample, 856 bool uses_txf, union blitter_attrib *out) 857{ 858 unsigned level = src->u.tex.first_level; 859 bool normalized = !uses_txf && 860 src->target != PIPE_TEXTURE_RECT && 861 src->texture->nr_samples <= 1; 862 863 if (normalized) { 864 out->texcoord.x1 = x1 / (float)u_minify(src_width0, level); 865 out->texcoord.y1 = y1 / (float)u_minify(src_height0, level); 866 out->texcoord.x2 = x2 / (float)u_minify(src_width0, level); 867 out->texcoord.y2 = y2 / (float)u_minify(src_height0, level); 868 } else { 869 out->texcoord.x1 = x1; 870 out->texcoord.y1 = y1; 871 out->texcoord.x2 = x2; 872 out->texcoord.y2 = y2; 873 } 874 875 out->texcoord.z = 0; 876 out->texcoord.w = 0; 877 878 /* Set the layer. */ 879 switch (src->target) { 880 case PIPE_TEXTURE_3D: 881 { 882 float r = layer; 883 884 if (!uses_txf) 885 r /= u_minify(src->texture->depth0, src->u.tex.first_level); 886 887 out->texcoord.z = r; 888 } 889 break; 890 891 case PIPE_TEXTURE_1D_ARRAY: 892 out->texcoord.y1 = out->texcoord.y2 = layer; 893 break; 894 895 case PIPE_TEXTURE_2D_ARRAY: 896 out->texcoord.z = layer; 897 out->texcoord.w = sample; 898 break; 899 900 case PIPE_TEXTURE_CUBE_ARRAY: 901 out->texcoord.w = (unsigned)layer / 6; 902 break; 903 904 case PIPE_TEXTURE_2D: 905 out->texcoord.w = sample; 906 break; 907 908 default:; 909 } 910} 911 912static void blitter_set_dst_dimensions(struct blitter_context_priv *ctx, 913 unsigned width, unsigned height) 914{ 915 ctx->dst_width = width; 916 ctx->dst_height = height; 917} 918 919static void set_texcoords_in_vertices(const union blitter_attrib *attrib, 920 float *out, unsigned stride) 921{ 922 out[0] = attrib->texcoord.x1; 923 out[1] = attrib->texcoord.y1; 924 out += stride; 925 out[0] = attrib->texcoord.x2; 926 out[1] = attrib->texcoord.y1; 927 out += stride; 928 out[0] = attrib->texcoord.x2; 929 out[1] = attrib->texcoord.y2; 930 out += stride; 931 out[0] = attrib->texcoord.x1; 932 out[1] = attrib->texcoord.y2; 933} 934 935static void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx, 936 enum pipe_format src_format, 937 enum pipe_format dst_format, 938 enum pipe_texture_target target, 939 unsigned src_nr_samples, 940 unsigned dst_nr_samples, 941 unsigned filter, 942 bool use_txf) 943{ 944 struct pipe_context *pipe = ctx->base.pipe; 945 enum tgsi_texture_type tgsi_tex = 946 util_pipe_tex_to_tgsi_tex(target, src_nr_samples); 947 enum tgsi_return_type stype; 948 enum tgsi_return_type dtype; 949 unsigned type; 950 951 assert(target < PIPE_MAX_TEXTURE_TYPES); 952 953 if (util_format_is_pure_uint(src_format)) { 954 stype = TGSI_RETURN_TYPE_UINT; 955 if (util_format_is_pure_uint(dst_format)) { 956 dtype = TGSI_RETURN_TYPE_UINT; 957 type = 0; 958 } else { 959 assert(util_format_is_pure_sint(dst_format)); 960 dtype = TGSI_RETURN_TYPE_SINT; 961 type = 1; 962 } 963 } else if (util_format_is_pure_sint(src_format)) { 964 stype = TGSI_RETURN_TYPE_SINT; 965 if (util_format_is_pure_sint(dst_format)) { 966 dtype = TGSI_RETURN_TYPE_SINT; 967 type = 2; 968 } else { 969 assert(util_format_is_pure_uint(dst_format)); 970 dtype = TGSI_RETURN_TYPE_UINT; 971 type = 3; 972 } 973 } else { 974 assert(!util_format_is_pure_uint(dst_format) && 975 !util_format_is_pure_sint(dst_format)); 976 dtype = stype = TGSI_RETURN_TYPE_FLOAT; 977 type = 4; 978 } 979 980 if (src_nr_samples > 1) { 981 void **shader; 982 983 /* OpenGL requires that integer textures just copy 1 sample instead 984 * of averaging. 985 */ 986 if (dst_nr_samples <= 1 && 987 stype != TGSI_RETURN_TYPE_UINT && 988 stype != TGSI_RETURN_TYPE_SINT) { 989 /* The destination has one sample, so we'll do color resolve. */ 990 unsigned index = GET_MSAA_RESOLVE_FS_IDX(src_nr_samples); 991 992 assert(filter < 2); 993 994 shader = &ctx->fs_resolve[target][index][filter]; 995 996 if (!*shader) { 997 assert(!ctx->cached_all_shaders); 998 if (filter == PIPE_TEX_FILTER_LINEAR) { 999 *shader = util_make_fs_msaa_resolve_bilinear(pipe, tgsi_tex, 1000 src_nr_samples, 1001 stype); 1002 } 1003 else { 1004 *shader = util_make_fs_msaa_resolve(pipe, tgsi_tex, 1005 src_nr_samples, 1006 stype); 1007 } 1008 } 1009 } 1010 else { 1011 /* The destination has multiple samples, we'll do 1012 * an MSAA->MSAA copy. 1013 */ 1014 shader = &ctx->fs_texfetch_col_msaa[type][target]; 1015 1016 /* Create the fragment shader on-demand. */ 1017 if (!*shader) { 1018 assert(!ctx->cached_all_shaders); 1019 *shader = util_make_fs_blit_msaa_color(pipe, tgsi_tex, stype, dtype); 1020 } 1021 } 1022 1023 return *shader; 1024 } else { 1025 void **shader; 1026 1027 if (use_txf) 1028 shader = &ctx->fs_texfetch_col[type][target][1]; 1029 else 1030 shader = &ctx->fs_texfetch_col[type][target][0]; 1031 1032 /* Create the fragment shader on-demand. */ 1033 if (!*shader) { 1034 assert(!ctx->cached_all_shaders); 1035 *shader = util_make_fragment_tex_shader(pipe, tgsi_tex, 1036 TGSI_INTERPOLATE_LINEAR, 1037 stype, dtype, 1038 ctx->has_tex_lz, use_txf); 1039 } 1040 1041 return *shader; 1042 } 1043} 1044 1045static inline 1046void *blitter_get_fs_pack_color_zs(struct blitter_context_priv *ctx, 1047 enum pipe_texture_target target, 1048 unsigned nr_samples, 1049 enum pipe_format zs_format, 1050 bool dst_is_color) 1051{ 1052 struct pipe_context *pipe = ctx->base.pipe; 1053 enum tgsi_texture_type tgsi_tex = 1054 util_pipe_tex_to_tgsi_tex(target, nr_samples); 1055 int format_index = zs_format == PIPE_FORMAT_Z24_UNORM_S8_UINT ? 0 : 1056 zs_format == PIPE_FORMAT_S8_UINT_Z24_UNORM ? 1 : 1057 zs_format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT ? 2 : 1058 zs_format == PIPE_FORMAT_Z24X8_UNORM ? 3 : 1059 zs_format == PIPE_FORMAT_X8Z24_UNORM ? 4 : -1; 1060 1061 if (format_index == -1) { 1062 assert(0); 1063 return NULL; 1064 } 1065 1066 /* The first 5 shaders pack ZS to color, the last 5 shaders unpack color 1067 * to ZS. 1068 */ 1069 if (dst_is_color) 1070 format_index += 5; 1071 1072 void **shader = &ctx->fs_pack_color_zs[tgsi_tex][format_index]; 1073 1074 /* Create the fragment shader on-demand. */ 1075 if (!*shader) { 1076 assert(!ctx->cached_all_shaders); 1077 *shader = util_make_fs_pack_color_zs(pipe, tgsi_tex, zs_format, 1078 dst_is_color); 1079 } 1080 return *shader; 1081} 1082 1083static inline 1084void *blitter_get_fs_texfetch_depth(struct blitter_context_priv *ctx, 1085 enum pipe_texture_target target, 1086 unsigned nr_samples, 1087 bool use_txf) 1088{ 1089 struct pipe_context *pipe = ctx->base.pipe; 1090 1091 assert(target < PIPE_MAX_TEXTURE_TYPES); 1092 1093 if (nr_samples > 1) { 1094 void **shader = &ctx->fs_texfetch_depth_msaa[target]; 1095 1096 /* Create the fragment shader on-demand. */ 1097 if (!*shader) { 1098 enum tgsi_texture_type tgsi_tex; 1099 assert(!ctx->cached_all_shaders); 1100 tgsi_tex = util_pipe_tex_to_tgsi_tex(target, nr_samples); 1101 *shader = util_make_fs_blit_msaa_depth(pipe, tgsi_tex); 1102 } 1103 1104 return *shader; 1105 } else { 1106 void **shader; 1107 1108 if (use_txf) 1109 shader = &ctx->fs_texfetch_depth[target][1]; 1110 else 1111 shader = &ctx->fs_texfetch_depth[target][0]; 1112 1113 /* Create the fragment shader on-demand. */ 1114 if (!*shader) { 1115 enum tgsi_texture_type tgsi_tex; 1116 assert(!ctx->cached_all_shaders); 1117 tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0); 1118 *shader = util_make_fs_blit_zs(pipe, PIPE_MASK_Z, tgsi_tex, 1119 ctx->has_tex_lz, use_txf); 1120 } 1121 1122 return *shader; 1123 } 1124} 1125 1126static inline 1127void *blitter_get_fs_texfetch_depthstencil(struct blitter_context_priv *ctx, 1128 enum pipe_texture_target target, 1129 unsigned nr_samples, 1130 bool use_txf) 1131{ 1132 struct pipe_context *pipe = ctx->base.pipe; 1133 1134 assert(target < PIPE_MAX_TEXTURE_TYPES); 1135 1136 if (nr_samples > 1) { 1137 void **shader = &ctx->fs_texfetch_depthstencil_msaa[target]; 1138 1139 /* Create the fragment shader on-demand. */ 1140 if (!*shader) { 1141 enum tgsi_texture_type tgsi_tex; 1142 assert(!ctx->cached_all_shaders); 1143 tgsi_tex = util_pipe_tex_to_tgsi_tex(target, nr_samples); 1144 *shader = util_make_fs_blit_msaa_depthstencil(pipe, tgsi_tex); 1145 } 1146 1147 return *shader; 1148 } else { 1149 void **shader; 1150 1151 if (use_txf) 1152 shader = &ctx->fs_texfetch_depthstencil[target][1]; 1153 else 1154 shader = &ctx->fs_texfetch_depthstencil[target][0]; 1155 1156 /* Create the fragment shader on-demand. */ 1157 if (!*shader) { 1158 enum tgsi_texture_type tgsi_tex; 1159 assert(!ctx->cached_all_shaders); 1160 tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0); 1161 *shader = util_make_fs_blit_zs(pipe, PIPE_MASK_ZS, tgsi_tex, 1162 ctx->has_tex_lz, use_txf); 1163 } 1164 1165 return *shader; 1166 } 1167} 1168 1169static inline 1170void *blitter_get_fs_texfetch_stencil(struct blitter_context_priv *ctx, 1171 enum pipe_texture_target target, 1172 unsigned nr_samples, 1173 bool use_txf) 1174{ 1175 struct pipe_context *pipe = ctx->base.pipe; 1176 1177 assert(target < PIPE_MAX_TEXTURE_TYPES); 1178 1179 if (nr_samples > 1) { 1180 void **shader = &ctx->fs_texfetch_stencil_msaa[target]; 1181 1182 /* Create the fragment shader on-demand. */ 1183 if (!*shader) { 1184 enum tgsi_texture_type tgsi_tex; 1185 assert(!ctx->cached_all_shaders); 1186 tgsi_tex = util_pipe_tex_to_tgsi_tex(target, nr_samples); 1187 *shader = util_make_fs_blit_msaa_stencil(pipe, tgsi_tex); 1188 } 1189 1190 return *shader; 1191 } else { 1192 void **shader; 1193 1194 if (use_txf) 1195 shader = &ctx->fs_texfetch_stencil[target][1]; 1196 else 1197 shader = &ctx->fs_texfetch_stencil[target][0]; 1198 1199 /* Create the fragment shader on-demand. */ 1200 if (!*shader) { 1201 enum tgsi_texture_type tgsi_tex; 1202 assert(!ctx->cached_all_shaders); 1203 tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0); 1204 *shader = util_make_fs_blit_zs(pipe, PIPE_MASK_S, tgsi_tex, 1205 ctx->has_tex_lz, use_txf); 1206 } 1207 1208 return *shader; 1209 } 1210} 1211 1212 1213/** 1214 * Generate and save all fragment shaders that we will ever need for 1215 * blitting. Drivers which use the 'draw' fallbacks will typically use 1216 * this to make sure we generate/use shaders that don't go through the 1217 * draw module's wrapper functions. 1218 */ 1219void util_blitter_cache_all_shaders(struct blitter_context *blitter) 1220{ 1221 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 1222 struct pipe_context *pipe = blitter->pipe; 1223 struct pipe_screen *screen = pipe->screen; 1224 unsigned samples, j, f, target, max_samples, use_txf; 1225 bool has_arraytex, has_cubearraytex; 1226 1227 max_samples = ctx->has_texture_multisample ? 2 : 1; 1228 has_arraytex = screen->get_param(screen, 1229 PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS) != 0; 1230 has_cubearraytex = screen->get_param(screen, 1231 PIPE_CAP_CUBE_MAP_ARRAY) != 0; 1232 1233 /* It only matters if i <= 1 or > 1. */ 1234 for (samples = 1; samples <= max_samples; samples++) { 1235 for (target = PIPE_TEXTURE_1D; target < PIPE_MAX_TEXTURE_TYPES; target++) { 1236 for (use_txf = 0; use_txf <= ctx->has_txf; use_txf++) { 1237 if (!has_arraytex && 1238 (target == PIPE_TEXTURE_1D_ARRAY || 1239 target == PIPE_TEXTURE_2D_ARRAY)) { 1240 continue; 1241 } 1242 if (!has_cubearraytex && 1243 (target == PIPE_TEXTURE_CUBE_ARRAY)) 1244 continue; 1245 1246 if (samples > 1 && 1247 (target != PIPE_TEXTURE_2D && 1248 target != PIPE_TEXTURE_2D_ARRAY)) 1249 continue; 1250 1251 if (samples > 1 && use_txf) 1252 continue; /* TXF is the only option, use_txf has no effect */ 1253 1254 /* If samples == 1, the shaders read one texel. If samples >= 1, 1255 * they read one sample. 1256 */ 1257 blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_FLOAT, 1258 PIPE_FORMAT_R32_FLOAT, target, 1259 samples, samples, 0, use_txf); 1260 blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_UINT, 1261 PIPE_FORMAT_R32_UINT, target, 1262 samples, samples, 0, use_txf); 1263 blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_UINT, 1264 PIPE_FORMAT_R32_SINT, target, 1265 samples, samples, 0, use_txf); 1266 blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_SINT, 1267 PIPE_FORMAT_R32_SINT, target, 1268 samples, samples, 0, use_txf); 1269 blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_SINT, 1270 PIPE_FORMAT_R32_UINT, target, 1271 samples, samples, 0, use_txf); 1272 blitter_get_fs_texfetch_depth(ctx, target, samples, use_txf); 1273 if (ctx->has_stencil_export) { 1274 blitter_get_fs_texfetch_depthstencil(ctx, target, samples, use_txf); 1275 blitter_get_fs_texfetch_stencil(ctx, target, samples, use_txf); 1276 } 1277 1278 if (samples == 1) 1279 continue; 1280 1281 /* MSAA resolve shaders. */ 1282 for (j = 2; j < 32; j++) { 1283 if (!screen->is_format_supported(screen, PIPE_FORMAT_R32_FLOAT, 1284 target, j, j, 1285 PIPE_BIND_SAMPLER_VIEW)) { 1286 continue; 1287 } 1288 1289 for (f = 0; f < 2; f++) { 1290 if (f != PIPE_TEX_FILTER_NEAREST && use_txf) 1291 continue; 1292 1293 blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_FLOAT, 1294 PIPE_FORMAT_R32_FLOAT, target, 1295 j, 1, f, use_txf); 1296 blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_UINT, 1297 PIPE_FORMAT_R32_UINT, target, 1298 j, 1, f, use_txf); 1299 blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_SINT, 1300 PIPE_FORMAT_R32_SINT, target, 1301 j, 1, f, use_txf); 1302 } 1303 } 1304 } 1305 } 1306 } 1307 1308 ctx->fs_empty = util_make_empty_fragment_shader(pipe); 1309 1310 ctx->fs_write_one_cbuf = 1311 util_make_fragment_passthrough_shader(pipe, TGSI_SEMANTIC_GENERIC, 1312 TGSI_INTERPOLATE_CONSTANT, false); 1313 1314 ctx->fs_write_all_cbufs = 1315 util_make_fragment_passthrough_shader(pipe, TGSI_SEMANTIC_GENERIC, 1316 TGSI_INTERPOLATE_CONSTANT, true); 1317 1318 ctx->cached_all_shaders = true; 1319} 1320 1321static void blitter_set_common_draw_rect_state(struct blitter_context_priv *ctx, 1322 bool scissor, bool msaa) 1323{ 1324 struct pipe_context *pipe = ctx->base.pipe; 1325 1326 if (ctx->base.saved_num_window_rectangles) 1327 pipe->set_window_rectangles(pipe, false, 0, NULL); 1328 1329 pipe->bind_rasterizer_state(pipe, ctx->rs_state[scissor][msaa]); 1330 1331 if (ctx->has_geometry_shader) 1332 pipe->bind_gs_state(pipe, NULL); 1333 if (ctx->has_tessellation) { 1334 pipe->bind_tcs_state(pipe, NULL); 1335 pipe->bind_tes_state(pipe, NULL); 1336 } 1337 if (ctx->has_stream_out) 1338 pipe->set_stream_output_targets(pipe, 0, NULL, NULL); 1339} 1340 1341static void blitter_draw(struct blitter_context_priv *ctx, 1342 void *vertex_elements_cso, 1343 blitter_get_vs_func get_vs, 1344 int x1, int y1, int x2, int y2, float depth, 1345 unsigned num_instances) 1346{ 1347 struct pipe_context *pipe = ctx->base.pipe; 1348 struct pipe_vertex_buffer vb = {0}; 1349 1350 blitter_set_rectangle(ctx, x1, y1, x2, y2, depth); 1351 1352 vb.stride = 8 * sizeof(float); 1353 1354 u_upload_data(pipe->stream_uploader, 0, sizeof(ctx->vertices), 4, ctx->vertices, 1355 &vb.buffer_offset, &vb.buffer.resource); 1356 if (!vb.buffer.resource) 1357 return; 1358 u_upload_unmap(pipe->stream_uploader); 1359 1360 pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, 0, false, &vb); 1361 pipe->bind_vertex_elements_state(pipe, vertex_elements_cso); 1362 pipe->bind_vs_state(pipe, get_vs(&ctx->base)); 1363 1364 if (ctx->base.use_index_buffer) { 1365 /* Note that for V3D, 1366 * dEQP-GLES3.functional.fbo.blit.rect.nearest_consistency_* require 1367 * that the last vert of the two tris be the same. 1368 */ 1369 static uint8_t indices[6] = { 0, 1, 2, 0, 3, 2 }; 1370 util_draw_elements_instanced(pipe, indices, 1, 0, 1371 PIPE_PRIM_TRIANGLES, 0, 6, 1372 0, num_instances); 1373 } else { 1374 util_draw_arrays_instanced(pipe, PIPE_PRIM_TRIANGLE_FAN, 0, 4, 1375 0, num_instances); 1376 } 1377 pipe_resource_reference(&vb.buffer.resource, NULL); 1378} 1379 1380void util_blitter_draw_rectangle(struct blitter_context *blitter, 1381 void *vertex_elements_cso, 1382 blitter_get_vs_func get_vs, 1383 int x1, int y1, int x2, int y2, 1384 float depth, unsigned num_instances, 1385 enum blitter_attrib_type type, 1386 const union blitter_attrib *attrib) 1387{ 1388 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 1389 unsigned i; 1390 1391 switch (type) { 1392 case UTIL_BLITTER_ATTRIB_COLOR: 1393 blitter_set_clear_color(ctx, attrib->color); 1394 break; 1395 1396 case UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW: 1397 for (i = 0; i < 4; i++) { 1398 ctx->vertices[i][1][2] = attrib->texcoord.z; 1399 ctx->vertices[i][1][3] = attrib->texcoord.w; 1400 } 1401 FALLTHROUGH; 1402 case UTIL_BLITTER_ATTRIB_TEXCOORD_XY: 1403 set_texcoords_in_vertices(attrib, &ctx->vertices[0][1][0], 8); 1404 break; 1405 1406 default:; 1407 } 1408 1409 blitter_draw(ctx, vertex_elements_cso, get_vs, x1, y1, x2, y2, depth, 1410 num_instances); 1411} 1412 1413static void *get_clear_blend_state(struct blitter_context_priv *ctx, 1414 unsigned clear_buffers) 1415{ 1416 struct pipe_context *pipe = ctx->base.pipe; 1417 int index; 1418 1419 clear_buffers &= PIPE_CLEAR_COLOR; 1420 1421 /* Return an existing blend state. */ 1422 if (!clear_buffers) 1423 return ctx->blend[0][0]; 1424 1425 index = GET_CLEAR_BLEND_STATE_IDX(clear_buffers); 1426 1427 if (ctx->blend_clear[index]) 1428 return ctx->blend_clear[index]; 1429 1430 /* Create a new one. */ 1431 { 1432 struct pipe_blend_state blend = {0}; 1433 unsigned i; 1434 1435 blend.independent_blend_enable = 1; 1436 1437 for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { 1438 if (clear_buffers & (PIPE_CLEAR_COLOR0 << i)) { 1439 blend.rt[i].colormask = PIPE_MASK_RGBA; 1440 blend.max_rt = i; 1441 } 1442 } 1443 1444 ctx->blend_clear[index] = pipe->create_blend_state(pipe, &blend); 1445 } 1446 return ctx->blend_clear[index]; 1447} 1448 1449void util_blitter_common_clear_setup(struct blitter_context *blitter, 1450 unsigned width, unsigned height, 1451 unsigned clear_buffers, 1452 void *custom_blend, void *custom_dsa) 1453{ 1454 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 1455 struct pipe_context *pipe = ctx->base.pipe; 1456 1457 util_blitter_set_running_flag(blitter); 1458 blitter_check_saved_vertex_states(ctx); 1459 blitter_check_saved_fragment_states(ctx); 1460 blitter_disable_render_cond(ctx); 1461 1462 /* bind states */ 1463 if (custom_blend) { 1464 pipe->bind_blend_state(pipe, custom_blend); 1465 } else { 1466 pipe->bind_blend_state(pipe, get_clear_blend_state(ctx, clear_buffers)); 1467 } 1468 1469 if (custom_dsa) { 1470 pipe->bind_depth_stencil_alpha_state(pipe, custom_dsa); 1471 } else if ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) { 1472 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil); 1473 } else if (clear_buffers & PIPE_CLEAR_DEPTH) { 1474 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil); 1475 } else if (clear_buffers & PIPE_CLEAR_STENCIL) { 1476 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil); 1477 } else { 1478 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 1479 } 1480 1481 pipe->set_sample_mask(pipe, ~0); 1482 blitter_set_dst_dimensions(ctx, width, height); 1483} 1484 1485static void util_blitter_clear_custom(struct blitter_context *blitter, 1486 unsigned width, unsigned height, 1487 unsigned num_layers, 1488 unsigned clear_buffers, 1489 const union pipe_color_union *color, 1490 double depth, unsigned stencil, 1491 void *custom_blend, void *custom_dsa, 1492 bool msaa) 1493{ 1494 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 1495 struct pipe_context *pipe = ctx->base.pipe; 1496 struct pipe_stencil_ref sr = { { 0 } }; 1497 1498 assert(ctx->has_layered || num_layers <= 1); 1499 1500 util_blitter_common_clear_setup(blitter, width, height, clear_buffers, 1501 custom_blend, custom_dsa); 1502 1503 sr.ref_value[0] = stencil & 0xff; 1504 pipe->set_stencil_ref(pipe, sr); 1505 1506 union blitter_attrib attrib; 1507 memcpy(attrib.color, color->ui, sizeof(color->ui)); 1508 1509 bool pass_generic = (clear_buffers & PIPE_CLEAR_COLOR) != 0; 1510 enum blitter_attrib_type type = pass_generic ? UTIL_BLITTER_ATTRIB_COLOR : 1511 UTIL_BLITTER_ATTRIB_NONE; 1512 1513 if (pass_generic) 1514 bind_fs_write_all_cbufs(ctx); 1515 else 1516 bind_fs_empty(ctx); 1517 1518 if (num_layers > 1 && ctx->has_layered) { 1519 blitter_get_vs_func get_vs = get_vs_layered; 1520 1521 blitter_set_common_draw_rect_state(ctx, false, msaa); 1522 blitter->draw_rectangle(blitter, ctx->velem_state, get_vs, 1523 0, 0, width, height, 1524 (float) depth, num_layers, type, &attrib); 1525 } else { 1526 blitter_get_vs_func get_vs; 1527 1528 if (pass_generic) 1529 get_vs = get_vs_passthrough_pos_generic; 1530 else 1531 get_vs = get_vs_passthrough_pos; 1532 1533 blitter_set_common_draw_rect_state(ctx, false, msaa); 1534 blitter->draw_rectangle(blitter, ctx->velem_state, get_vs, 1535 0, 0, width, height, 1536 (float) depth, 1, type, &attrib); 1537 } 1538 1539 util_blitter_restore_vertex_states(blitter); 1540 util_blitter_restore_fragment_states(blitter); 1541 util_blitter_restore_render_cond(blitter); 1542 util_blitter_unset_running_flag(blitter); 1543} 1544 1545void util_blitter_clear(struct blitter_context *blitter, 1546 unsigned width, unsigned height, unsigned num_layers, 1547 unsigned clear_buffers, 1548 const union pipe_color_union *color, 1549 double depth, unsigned stencil, 1550 bool msaa) 1551{ 1552 util_blitter_clear_custom(blitter, width, height, num_layers, 1553 clear_buffers, color, depth, stencil, 1554 NULL, NULL, msaa); 1555} 1556 1557void util_blitter_custom_clear_depth(struct blitter_context *blitter, 1558 unsigned width, unsigned height, 1559 double depth, void *custom_dsa) 1560{ 1561 static const union pipe_color_union color; 1562 util_blitter_clear_custom(blitter, width, height, 0, 0, &color, depth, 0, 1563 NULL, custom_dsa, false); 1564} 1565 1566void util_blitter_default_dst_texture(struct pipe_surface *dst_templ, 1567 struct pipe_resource *dst, 1568 unsigned dstlevel, 1569 unsigned dstz) 1570{ 1571 memset(dst_templ, 0, sizeof(*dst_templ)); 1572 dst_templ->format = util_format_linear(dst->format); 1573 dst_templ->u.tex.level = dstlevel; 1574 dst_templ->u.tex.first_layer = dstz; 1575 dst_templ->u.tex.last_layer = dstz; 1576} 1577 1578static struct pipe_surface * 1579util_blitter_get_next_surface_layer(struct pipe_context *pipe, 1580 struct pipe_surface *surf) 1581{ 1582 struct pipe_surface dst_templ; 1583 1584 memset(&dst_templ, 0, sizeof(dst_templ)); 1585 dst_templ.format = surf->format; 1586 dst_templ.u.tex.level = surf->u.tex.level; 1587 dst_templ.u.tex.first_layer = surf->u.tex.first_layer + 1; 1588 dst_templ.u.tex.last_layer = surf->u.tex.last_layer + 1; 1589 1590 return pipe->create_surface(pipe, surf->texture, &dst_templ); 1591} 1592 1593void util_blitter_default_src_texture(struct blitter_context *blitter, 1594 struct pipe_sampler_view *src_templ, 1595 struct pipe_resource *src, 1596 unsigned srclevel) 1597{ 1598 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 1599 1600 memset(src_templ, 0, sizeof(*src_templ)); 1601 1602 if (ctx->cube_as_2darray && 1603 (src->target == PIPE_TEXTURE_CUBE || 1604 src->target == PIPE_TEXTURE_CUBE_ARRAY)) 1605 src_templ->target = PIPE_TEXTURE_2D_ARRAY; 1606 else 1607 src_templ->target = src->target; 1608 1609 src_templ->format = util_format_linear(src->format); 1610 src_templ->u.tex.first_level = srclevel; 1611 src_templ->u.tex.last_level = srclevel; 1612 src_templ->u.tex.first_layer = 0; 1613 src_templ->u.tex.last_layer = 1614 src->target == PIPE_TEXTURE_3D ? u_minify(src->depth0, srclevel) - 1 1615 : (unsigned)(src->array_size - 1); 1616 src_templ->swizzle_r = PIPE_SWIZZLE_X; 1617 src_templ->swizzle_g = PIPE_SWIZZLE_Y; 1618 src_templ->swizzle_b = PIPE_SWIZZLE_Z; 1619 src_templ->swizzle_a = PIPE_SWIZZLE_W; 1620} 1621 1622static bool is_blit_generic_supported(struct blitter_context *blitter, 1623 const struct pipe_resource *dst, 1624 enum pipe_format dst_format, 1625 const struct pipe_resource *src, 1626 enum pipe_format src_format, 1627 unsigned mask) 1628{ 1629 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 1630 struct pipe_screen *screen = ctx->base.pipe->screen; 1631 1632 if (dst) { 1633 unsigned bind; 1634 const struct util_format_description *desc = 1635 util_format_description(dst_format); 1636 bool dst_has_stencil = util_format_has_stencil(desc); 1637 1638 /* Stencil export must be supported for stencil copy. */ 1639 if ((mask & PIPE_MASK_S) && dst_has_stencil && 1640 !ctx->has_stencil_export) { 1641 return false; 1642 } 1643 1644 if (dst_has_stencil || util_format_has_depth(desc)) 1645 bind = PIPE_BIND_DEPTH_STENCIL; 1646 else 1647 bind = PIPE_BIND_RENDER_TARGET; 1648 1649 if (!screen->is_format_supported(screen, dst_format, dst->target, 1650 dst->nr_samples, dst->nr_storage_samples, 1651 bind)) { 1652 return false; 1653 } 1654 } 1655 1656 if (src) { 1657 if (src->nr_samples > 1 && !ctx->has_texture_multisample) { 1658 return false; 1659 } 1660 1661 if (!screen->is_format_supported(screen, src_format, src->target, 1662 src->nr_samples, src->nr_storage_samples, 1663 PIPE_BIND_SAMPLER_VIEW)) { 1664 return false; 1665 } 1666 1667 /* Check stencil sampler support for stencil copy. */ 1668 if (mask & PIPE_MASK_S) { 1669 if (util_format_has_stencil(util_format_description(src_format))) { 1670 enum pipe_format stencil_format = 1671 util_format_stencil_only(src_format); 1672 assert(stencil_format != PIPE_FORMAT_NONE); 1673 1674 if (stencil_format != src_format && 1675 !screen->is_format_supported(screen, stencil_format, 1676 src->target, src->nr_samples, 1677 src->nr_storage_samples, 1678 PIPE_BIND_SAMPLER_VIEW)) { 1679 return false; 1680 } 1681 } 1682 } 1683 } 1684 1685 return true; 1686} 1687 1688bool util_blitter_is_copy_supported(struct blitter_context *blitter, 1689 const struct pipe_resource *dst, 1690 const struct pipe_resource *src) 1691{ 1692 return is_blit_generic_supported(blitter, dst, dst->format, 1693 src, src->format, PIPE_MASK_RGBAZS); 1694} 1695 1696bool util_blitter_is_blit_supported(struct blitter_context *blitter, 1697 const struct pipe_blit_info *info) 1698{ 1699 return is_blit_generic_supported(blitter, 1700 info->dst.resource, info->dst.format, 1701 info->src.resource, info->src.format, 1702 info->mask); 1703} 1704 1705void util_blitter_copy_texture(struct blitter_context *blitter, 1706 struct pipe_resource *dst, 1707 unsigned dst_level, 1708 unsigned dstx, unsigned dsty, unsigned dstz, 1709 struct pipe_resource *src, 1710 unsigned src_level, 1711 const struct pipe_box *srcbox) 1712{ 1713 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 1714 struct pipe_context *pipe = ctx->base.pipe; 1715 struct pipe_surface *dst_view, dst_templ; 1716 struct pipe_sampler_view src_templ, *src_view; 1717 struct pipe_box dstbox; 1718 1719 assert(dst && src); 1720 assert(src->target < PIPE_MAX_TEXTURE_TYPES); 1721 1722 u_box_3d(dstx, dsty, dstz, abs(srcbox->width), abs(srcbox->height), 1723 abs(srcbox->depth), &dstbox); 1724 1725 /* Initialize the surface. */ 1726 util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz); 1727 dst_view = pipe->create_surface(pipe, dst, &dst_templ); 1728 1729 /* Initialize the sampler view. */ 1730 util_blitter_default_src_texture(blitter, &src_templ, src, src_level); 1731 src_view = pipe->create_sampler_view(pipe, src, &src_templ); 1732 1733 /* Copy. */ 1734 util_blitter_blit_generic(blitter, dst_view, &dstbox, 1735 src_view, srcbox, src->width0, src->height0, 1736 PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL, 1737 false, false); 1738 1739 pipe_surface_reference(&dst_view, NULL); 1740 pipe_sampler_view_reference(&src_view, NULL); 1741} 1742 1743static void 1744blitter_draw_tex(struct blitter_context_priv *ctx, 1745 int dst_x1, int dst_y1, int dst_x2, int dst_y2, 1746 struct pipe_sampler_view *src, 1747 unsigned src_width0, unsigned src_height0, 1748 int src_x1, int src_y1, int src_x2, int src_y2, 1749 float layer, unsigned sample, 1750 bool uses_txf, enum blitter_attrib_type type) 1751{ 1752 union blitter_attrib coord; 1753 blitter_get_vs_func get_vs = get_vs_passthrough_pos_generic; 1754 1755 get_texcoords(src, src_width0, src_height0, 1756 src_x1, src_y1, src_x2, src_y2, layer, sample, 1757 uses_txf, &coord); 1758 1759 if (src->target == PIPE_TEXTURE_CUBE || 1760 src->target == PIPE_TEXTURE_CUBE_ARRAY) { 1761 float face_coord[4][2]; 1762 1763 set_texcoords_in_vertices(&coord, &face_coord[0][0], 2); 1764 util_map_texcoords2d_onto_cubemap((unsigned)layer % 6, 1765 /* pointer, stride in floats */ 1766 &face_coord[0][0], 2, 1767 &ctx->vertices[0][1][0], 8, 1768 false); 1769 for (unsigned i = 0; i < 4; i++) 1770 ctx->vertices[i][1][3] = coord.texcoord.w; 1771 1772 /* Cubemaps don't use draw_rectangle. */ 1773 blitter_draw(ctx, ctx->velem_state, get_vs, 1774 dst_x1, dst_y1, dst_x2, dst_y2, 0, 1); 1775 } else { 1776 ctx->base.draw_rectangle(&ctx->base, ctx->velem_state, get_vs, 1777 dst_x1, dst_y1, dst_x2, dst_y2, 1778 0, 1, type, &coord); 1779 } 1780} 1781 1782static void do_blits(struct blitter_context_priv *ctx, 1783 struct pipe_surface *dst, 1784 const struct pipe_box *dstbox, 1785 struct pipe_sampler_view *src, 1786 unsigned src_width0, 1787 unsigned src_height0, 1788 const struct pipe_box *srcbox, 1789 bool is_zsbuf, 1790 bool uses_txf, bool sample0_only) 1791{ 1792 struct pipe_context *pipe = ctx->base.pipe; 1793 unsigned src_samples = src->texture->nr_samples; 1794 unsigned dst_samples = dst->texture->nr_samples; 1795 enum pipe_texture_target src_target = src->target; 1796 struct pipe_framebuffer_state fb_state = {0}; 1797 1798 /* Initialize framebuffer state. */ 1799 fb_state.width = dst->width; 1800 fb_state.height = dst->height; 1801 fb_state.nr_cbufs = is_zsbuf ? 0 : 1; 1802 1803 blitter_set_dst_dimensions(ctx, fb_state.width, fb_state.height); 1804 1805 if ((src_target == PIPE_TEXTURE_1D || 1806 src_target == PIPE_TEXTURE_2D || 1807 src_target == PIPE_TEXTURE_RECT) && 1808 src_samples <= 1) { 1809 /* Set framebuffer state. */ 1810 if (is_zsbuf) { 1811 fb_state.zsbuf = dst; 1812 } else { 1813 fb_state.cbufs[0] = dst; 1814 } 1815 pipe->set_framebuffer_state(pipe, &fb_state); 1816 1817 /* Draw. */ 1818 pipe->set_sample_mask(pipe, ~0); 1819 blitter_draw_tex(ctx, dstbox->x, dstbox->y, 1820 dstbox->x + dstbox->width, 1821 dstbox->y + dstbox->height, 1822 src, src_width0, src_height0, srcbox->x, srcbox->y, 1823 srcbox->x + srcbox->width, srcbox->y + srcbox->height, 1824 0, 0, uses_txf, UTIL_BLITTER_ATTRIB_TEXCOORD_XY); 1825 } else { 1826 /* Draw the quad with the generic codepath. */ 1827 int dst_z; 1828 for (dst_z = 0; dst_z < dstbox->depth; dst_z++) { 1829 struct pipe_surface *old; 1830 bool flipped = (srcbox->depth < 0); 1831 float depth_center_offset = 0.0; 1832 int src_depth = abs(srcbox->depth); 1833 float src_z_step = src_depth / (float)dstbox->depth; 1834 1835 /* Scale Z properly if the blit is scaled. 1836 * 1837 * When downscaling, we want the coordinates centered, so that 1838 * mipmapping works for 3D textures. For example, when generating 1839 * a 4x4x4 level, this wouldn't average the pixels: 1840 * 1841 * src Z: 0 1 2 3 4 5 6 7 1842 * dst Z: 0 1 2 3 1843 * 1844 * Because the pixels are not centered below the pixels of the higher 1845 * level. Therefore, we want this: 1846 * src Z: 0 1 2 3 4 5 6 7 1847 * dst Z: 0 1 2 3 1848 * 1849 * This calculation is taken from the radv driver. 1850 */ 1851 if (src_target == PIPE_TEXTURE_3D) 1852 depth_center_offset = 0.5 / dstbox->depth * src_depth; 1853 1854 if (flipped) { 1855 src_z_step *= - 1; 1856 depth_center_offset *= -1; 1857 } 1858 1859 float src_z = dst_z * src_z_step + depth_center_offset; 1860 1861 /* Set framebuffer state. */ 1862 if (is_zsbuf) { 1863 fb_state.zsbuf = dst; 1864 } else { 1865 fb_state.cbufs[0] = dst; 1866 } 1867 pipe->set_framebuffer_state(pipe, &fb_state); 1868 1869 /* See if we need to blit a multisample or singlesample buffer. */ 1870 if (sample0_only || (src_samples == dst_samples && dst_samples > 1)) { 1871 /* MSAA copy. */ 1872 unsigned i, max_sample = sample0_only ? 0 : dst_samples - 1; 1873 1874 for (i = 0; i <= max_sample; i++) { 1875 pipe->set_sample_mask(pipe, 1 << i); 1876 blitter_draw_tex(ctx, dstbox->x, dstbox->y, 1877 dstbox->x + dstbox->width, 1878 dstbox->y + dstbox->height, 1879 src, src_width0, src_height0, 1880 srcbox->x, srcbox->y, 1881 srcbox->x + srcbox->width, 1882 srcbox->y + srcbox->height, 1883 srcbox->z + src_z, i, uses_txf, 1884 UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW); 1885 } 1886 } else { 1887 /* Normal copy, MSAA upsampling, or MSAA resolve. */ 1888 pipe->set_sample_mask(pipe, ~0); 1889 blitter_draw_tex(ctx, dstbox->x, dstbox->y, 1890 dstbox->x + dstbox->width, 1891 dstbox->y + dstbox->height, 1892 src, src_width0, src_height0, 1893 srcbox->x, srcbox->y, 1894 srcbox->x + srcbox->width, 1895 srcbox->y + srcbox->height, 1896 srcbox->z + src_z, 0, uses_txf, 1897 UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW); 1898 } 1899 1900 /* Get the next surface or (if this is the last iteration) 1901 * just unreference the last one. */ 1902 old = dst; 1903 if (dst_z < dstbox->depth-1) { 1904 dst = util_blitter_get_next_surface_layer(ctx->base.pipe, dst); 1905 } 1906 if (dst_z) { 1907 pipe_surface_reference(&old, NULL); 1908 } 1909 } 1910 } 1911} 1912 1913void util_blitter_blit_generic(struct blitter_context *blitter, 1914 struct pipe_surface *dst, 1915 const struct pipe_box *dstbox, 1916 struct pipe_sampler_view *src, 1917 const struct pipe_box *srcbox, 1918 unsigned src_width0, unsigned src_height0, 1919 unsigned mask, unsigned filter, 1920 const struct pipe_scissor_state *scissor, 1921 bool alpha_blend, bool sample0_only) 1922{ 1923 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 1924 struct pipe_context *pipe = ctx->base.pipe; 1925 enum pipe_texture_target src_target = src->target; 1926 unsigned src_samples = src->texture->nr_samples; 1927 unsigned dst_samples = dst->texture->nr_samples; 1928 void *sampler_state; 1929 const struct util_format_description *src_desc = 1930 util_format_description(src->format); 1931 const struct util_format_description *dst_desc = 1932 util_format_description(dst->format); 1933 1934 bool src_has_color = src_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS; 1935 bool src_has_depth = util_format_has_depth(src_desc); 1936 bool src_has_stencil = util_format_has_stencil(src_desc); 1937 1938 bool dst_has_color = mask & PIPE_MASK_RGBA && 1939 dst_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS; 1940 bool dst_has_depth = mask & PIPE_MASK_Z && 1941 util_format_has_depth(dst_desc); 1942 bool dst_has_stencil = ctx->has_stencil_export && 1943 mask & PIPE_MASK_S && 1944 util_format_has_stencil(dst_desc); 1945 1946 /* Return if there is nothing to do. */ 1947 if (!dst_has_color && !dst_has_depth && !dst_has_stencil) { 1948 return; 1949 } 1950 1951 bool is_scaled = dstbox->width != abs(srcbox->width) || 1952 dstbox->height != abs(srcbox->height); 1953 1954 if (src_has_stencil || !is_scaled) 1955 filter = PIPE_TEX_FILTER_NEAREST; 1956 1957 bool use_txf = false; 1958 1959 /* Don't support scaled blits. The TXF shader uses F2I for rounding. */ 1960 if (ctx->has_txf && 1961 !is_scaled && 1962 filter == PIPE_TEX_FILTER_NEAREST && 1963 src->target != PIPE_TEXTURE_CUBE && 1964 src->target != PIPE_TEXTURE_CUBE_ARRAY) { 1965 int src_width = u_minify(src_width0, src->u.tex.first_level); 1966 int src_height = u_minify(src_height0, src->u.tex.first_level); 1967 int src_depth = src->u.tex.last_layer + 1; 1968 struct pipe_box box = *srcbox; 1969 1970 /* Eliminate negative width/height/depth. */ 1971 if (box.width < 0) { 1972 box.x += box.width; 1973 box.width *= -1; 1974 } 1975 if (box.height < 0) { 1976 box.y += box.height; 1977 box.height *= -1; 1978 } 1979 if (box.depth < 0) { 1980 box.z += box.depth; 1981 box.depth *= -1; 1982 } 1983 1984 /* See if srcbox is in bounds. TXF doesn't clamp the coordinates. */ 1985 use_txf = 1986 box.x >= 0 && box.x < src_width && 1987 box.y >= 0 && box.y < src_height && 1988 box.z >= 0 && box.z < src_depth && 1989 box.x + box.width > 0 && box.x + box.width <= src_width && 1990 box.y + box.height > 0 && box.y + box.height <= src_height && 1991 box.z + box.depth > 0 && box.z + box.depth <= src_depth; 1992 } 1993 1994 /* Check whether the states are properly saved. */ 1995 util_blitter_set_running_flag(blitter); 1996 blitter_check_saved_vertex_states(ctx); 1997 blitter_check_saved_fragment_states(ctx); 1998 blitter_check_saved_textures(ctx); 1999 blitter_check_saved_fb_state(ctx); 2000 blitter_disable_render_cond(ctx); 2001 2002 /* Blend, DSA, fragment shader. */ 2003 if (dst_has_depth && dst_has_stencil) { 2004 pipe->bind_blend_state(pipe, ctx->blend[0][0]); 2005 pipe->bind_depth_stencil_alpha_state(pipe, 2006 ctx->dsa_write_depth_stencil); 2007 if (src_has_color) { 2008 assert(use_txf); 2009 ctx->bind_fs_state(pipe, 2010 blitter_get_fs_pack_color_zs(ctx, src_target, 2011 src_samples, dst->format, false)); 2012 } else { 2013 ctx->bind_fs_state(pipe, 2014 blitter_get_fs_texfetch_depthstencil(ctx, src_target, 2015 src_samples, use_txf)); 2016 } 2017 } else if (dst_has_depth) { 2018 pipe->bind_blend_state(pipe, ctx->blend[0][0]); 2019 pipe->bind_depth_stencil_alpha_state(pipe, 2020 ctx->dsa_write_depth_keep_stencil); 2021 if (src_has_color && 2022 (src->format == PIPE_FORMAT_R32_UINT || 2023 src->format == PIPE_FORMAT_R32G32_UINT)) { 2024 assert(use_txf); 2025 ctx->bind_fs_state(pipe, 2026 blitter_get_fs_pack_color_zs(ctx, src_target, 2027 src_samples, dst->format, false)); 2028 } else { 2029 ctx->bind_fs_state(pipe, 2030 blitter_get_fs_texfetch_depth(ctx, src_target, 2031 src_samples, use_txf)); 2032 } 2033 } else if (dst_has_stencil) { 2034 pipe->bind_blend_state(pipe, ctx->blend[0][0]); 2035 pipe->bind_depth_stencil_alpha_state(pipe, 2036 ctx->dsa_keep_depth_write_stencil); 2037 2038 assert(src_has_stencil); /* unpacking from color is unsupported */ 2039 ctx->bind_fs_state(pipe, 2040 blitter_get_fs_texfetch_stencil(ctx, src_target, 2041 src_samples, use_txf)); 2042 } else { 2043 unsigned colormask = mask & PIPE_MASK_RGBA; 2044 2045 pipe->bind_blend_state(pipe, ctx->blend[colormask][alpha_blend]); 2046 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 2047 2048 if (src_has_depth && 2049 (dst->format == PIPE_FORMAT_R32_UINT || 2050 dst->format == PIPE_FORMAT_R32G32_UINT)) { 2051 assert(use_txf); 2052 ctx->bind_fs_state(pipe, 2053 blitter_get_fs_pack_color_zs(ctx, src_target, 2054 src_samples, src->format, true)); 2055 } else { 2056 ctx->bind_fs_state(pipe, 2057 blitter_get_fs_texfetch_col(ctx, src->format, dst->format, src_target, 2058 src_samples, dst_samples, filter, 2059 use_txf)); 2060 } 2061 } 2062 2063 /* Set the linear filter only for scaled color non-MSAA blits. */ 2064 if (filter == PIPE_TEX_FILTER_LINEAR) { 2065 if (src_target == PIPE_TEXTURE_RECT) { 2066 sampler_state = ctx->sampler_state_rect_linear; 2067 } else { 2068 sampler_state = ctx->sampler_state_linear; 2069 } 2070 } else { 2071 if (src_target == PIPE_TEXTURE_RECT) { 2072 sampler_state = ctx->sampler_state_rect; 2073 } else { 2074 sampler_state = ctx->sampler_state; 2075 } 2076 } 2077 2078 /* Set samplers. */ 2079 if (src_has_depth && src_has_stencil && 2080 (dst_has_color || (dst_has_depth && dst_has_stencil))) { 2081 /* Setup two samplers, one for depth and the other one for stencil. */ 2082 struct pipe_sampler_view templ; 2083 struct pipe_sampler_view *views[2]; 2084 void *samplers[2] = {sampler_state, sampler_state}; 2085 2086 templ = *src; 2087 templ.format = util_format_stencil_only(templ.format); 2088 assert(templ.format != PIPE_FORMAT_NONE); 2089 2090 views[0] = src; 2091 views[1] = pipe->create_sampler_view(pipe, src->texture, &templ); 2092 2093 pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 2, 0, false, views); 2094 pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0, 2, samplers); 2095 2096 pipe_sampler_view_reference(&views[1], NULL); 2097 } else if (src_has_stencil && dst_has_stencil) { 2098 /* Set a stencil-only sampler view for it not to sample depth instead. */ 2099 struct pipe_sampler_view templ; 2100 struct pipe_sampler_view *view; 2101 2102 templ = *src; 2103 templ.format = util_format_stencil_only(templ.format); 2104 assert(templ.format != PIPE_FORMAT_NONE); 2105 2106 view = pipe->create_sampler_view(pipe, src->texture, &templ); 2107 2108 pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, 0, false, &view); 2109 pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 2110 0, 1, &sampler_state); 2111 2112 pipe_sampler_view_reference(&view, NULL); 2113 } else { 2114 pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, 0, false, &src); 2115 pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 2116 0, 1, &sampler_state); 2117 } 2118 2119 if (scissor) { 2120 pipe->set_scissor_states(pipe, 0, 1, scissor); 2121 } 2122 2123 blitter_set_common_draw_rect_state(ctx, scissor != NULL, dst_samples > 1); 2124 2125 do_blits(ctx, dst, dstbox, src, src_width0, src_height0, 2126 srcbox, dst_has_depth || dst_has_stencil, use_txf, sample0_only); 2127 2128 util_blitter_restore_vertex_states(blitter); 2129 util_blitter_restore_fragment_states(blitter); 2130 util_blitter_restore_textures(blitter); 2131 util_blitter_restore_fb_state(blitter); 2132 if (scissor) { 2133 pipe->set_scissor_states(pipe, 0, 1, &ctx->base.saved_scissor); 2134 } 2135 util_blitter_restore_render_cond(blitter); 2136 util_blitter_unset_running_flag(blitter); 2137} 2138 2139void 2140util_blitter_blit(struct blitter_context *blitter, 2141 const struct pipe_blit_info *info) 2142{ 2143 struct pipe_resource *dst = info->dst.resource; 2144 struct pipe_resource *src = info->src.resource; 2145 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 2146 struct pipe_context *pipe = ctx->base.pipe; 2147 struct pipe_surface *dst_view, dst_templ; 2148 struct pipe_sampler_view src_templ, *src_view; 2149 2150 /* Initialize the surface. */ 2151 util_blitter_default_dst_texture(&dst_templ, dst, info->dst.level, 2152 info->dst.box.z); 2153 dst_templ.format = info->dst.format; 2154 dst_view = pipe->create_surface(pipe, dst, &dst_templ); 2155 2156 /* Initialize the sampler view. */ 2157 util_blitter_default_src_texture(blitter, &src_templ, src, info->src.level); 2158 src_templ.format = info->src.format; 2159 src_view = pipe->create_sampler_view(pipe, src, &src_templ); 2160 2161 /* Copy. */ 2162 util_blitter_blit_generic(blitter, dst_view, &info->dst.box, 2163 src_view, &info->src.box, src->width0, src->height0, 2164 info->mask, info->filter, 2165 info->scissor_enable ? &info->scissor : NULL, 2166 info->alpha_blend, info->sample0_only); 2167 2168 pipe_surface_reference(&dst_view, NULL); 2169 pipe_sampler_view_reference(&src_view, NULL); 2170} 2171 2172void util_blitter_generate_mipmap(struct blitter_context *blitter, 2173 struct pipe_resource *tex, 2174 enum pipe_format format, 2175 unsigned base_level, unsigned last_level, 2176 unsigned first_layer, unsigned last_layer) 2177{ 2178 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 2179 struct pipe_context *pipe = ctx->base.pipe; 2180 struct pipe_surface dst_templ, *dst_view; 2181 struct pipe_sampler_view src_templ, *src_view; 2182 bool is_depth; 2183 void *sampler_state; 2184 const struct util_format_description *desc = 2185 util_format_description(format); 2186 unsigned src_level; 2187 unsigned target = tex->target; 2188 2189 if (ctx->cube_as_2darray && 2190 (target == PIPE_TEXTURE_CUBE || target == PIPE_TEXTURE_CUBE_ARRAY)) 2191 target = PIPE_TEXTURE_2D_ARRAY; 2192 2193 assert(tex->nr_samples <= 1); 2194 /* Disallow stencil formats without depth. */ 2195 assert(!util_format_has_stencil(desc) || util_format_has_depth(desc)); 2196 2197 is_depth = desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS; 2198 2199 /* Check whether the states are properly saved. */ 2200 util_blitter_set_running_flag(blitter); 2201 blitter_check_saved_vertex_states(ctx); 2202 blitter_check_saved_fragment_states(ctx); 2203 blitter_check_saved_textures(ctx); 2204 blitter_check_saved_fb_state(ctx); 2205 blitter_disable_render_cond(ctx); 2206 2207 /* Set states. */ 2208 if (is_depth) { 2209 pipe->bind_blend_state(pipe, ctx->blend[0][0]); 2210 pipe->bind_depth_stencil_alpha_state(pipe, 2211 ctx->dsa_write_depth_keep_stencil); 2212 ctx->bind_fs_state(pipe, 2213 blitter_get_fs_texfetch_depth(ctx, target, 1, false)); 2214 } else { 2215 pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]); 2216 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 2217 ctx->bind_fs_state(pipe, 2218 blitter_get_fs_texfetch_col(ctx, tex->format, tex->format, target, 2219 1, 1, PIPE_TEX_FILTER_LINEAR, false)); 2220 } 2221 2222 if (target == PIPE_TEXTURE_RECT) { 2223 sampler_state = ctx->sampler_state_rect_linear; 2224 } else { 2225 sampler_state = ctx->sampler_state_linear; 2226 } 2227 pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 2228 0, 1, &sampler_state); 2229 2230 blitter_set_common_draw_rect_state(ctx, false, false); 2231 2232 for (src_level = base_level; src_level < last_level; src_level++) { 2233 struct pipe_box dstbox = {0}, srcbox = {0}; 2234 unsigned dst_level = src_level + 1; 2235 2236 dstbox.width = u_minify(tex->width0, dst_level); 2237 dstbox.height = u_minify(tex->height0, dst_level); 2238 2239 srcbox.width = u_minify(tex->width0, src_level); 2240 srcbox.height = u_minify(tex->height0, src_level); 2241 2242 if (target == PIPE_TEXTURE_3D) { 2243 dstbox.depth = util_num_layers(tex, dst_level); 2244 srcbox.depth = util_num_layers(tex, src_level); 2245 } else { 2246 dstbox.z = srcbox.z = first_layer; 2247 dstbox.depth = srcbox.depth = last_layer - first_layer + 1; 2248 } 2249 2250 /* Initialize the surface. */ 2251 util_blitter_default_dst_texture(&dst_templ, tex, dst_level, 2252 first_layer); 2253 dst_templ.format = format; 2254 dst_view = pipe->create_surface(pipe, tex, &dst_templ); 2255 2256 /* Initialize the sampler view. */ 2257 util_blitter_default_src_texture(blitter, &src_templ, tex, src_level); 2258 src_templ.format = format; 2259 src_view = pipe->create_sampler_view(pipe, tex, &src_templ); 2260 2261 pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, 0, false, &src_view); 2262 2263 do_blits(ctx, dst_view, &dstbox, src_view, tex->width0, tex->height0, 2264 &srcbox, is_depth, false, false); 2265 2266 pipe_surface_reference(&dst_view, NULL); 2267 pipe_sampler_view_reference(&src_view, NULL); 2268 } 2269 2270 util_blitter_restore_vertex_states(blitter); 2271 util_blitter_restore_fragment_states(blitter); 2272 util_blitter_restore_textures(blitter); 2273 util_blitter_restore_fb_state(blitter); 2274 util_blitter_restore_render_cond(blitter); 2275 util_blitter_unset_running_flag(blitter); 2276} 2277 2278/* Clear a region of a color surface to a constant value. */ 2279void util_blitter_clear_render_target(struct blitter_context *blitter, 2280 struct pipe_surface *dstsurf, 2281 const union pipe_color_union *color, 2282 unsigned dstx, unsigned dsty, 2283 unsigned width, unsigned height) 2284{ 2285 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 2286 struct pipe_context *pipe = ctx->base.pipe; 2287 struct pipe_framebuffer_state fb_state; 2288 bool msaa; 2289 unsigned num_layers; 2290 2291 assert(dstsurf->texture); 2292 if (!dstsurf->texture) 2293 return; 2294 2295 /* check the saved state */ 2296 util_blitter_set_running_flag(blitter); 2297 blitter_check_saved_vertex_states(ctx); 2298 blitter_check_saved_fragment_states(ctx); 2299 blitter_check_saved_fb_state(ctx); 2300 blitter_disable_render_cond(ctx); 2301 2302 /* bind states */ 2303 pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]); 2304 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 2305 bind_fs_write_one_cbuf(ctx); 2306 2307 /* set a framebuffer state */ 2308 fb_state.width = dstsurf->width; 2309 fb_state.height = dstsurf->height; 2310 fb_state.nr_cbufs = 1; 2311 fb_state.cbufs[0] = dstsurf; 2312 fb_state.zsbuf = 0; 2313 pipe->set_framebuffer_state(pipe, &fb_state); 2314 pipe->set_sample_mask(pipe, ~0); 2315 msaa = util_framebuffer_get_num_samples(&fb_state) > 1; 2316 2317 blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height); 2318 2319 union blitter_attrib attrib; 2320 memcpy(attrib.color, color->ui, sizeof(color->ui)); 2321 2322 num_layers = dstsurf->u.tex.last_layer - dstsurf->u.tex.first_layer + 1; 2323 if (num_layers > 1 && ctx->has_layered) { 2324 blitter_set_common_draw_rect_state(ctx, false, msaa); 2325 blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_layered, 2326 dstx, dsty, dstx+width, dsty+height, 0, 2327 num_layers, UTIL_BLITTER_ATTRIB_COLOR, &attrib); 2328 } else { 2329 blitter_set_common_draw_rect_state(ctx, false, msaa); 2330 blitter->draw_rectangle(blitter, ctx->velem_state, 2331 get_vs_passthrough_pos_generic, 2332 dstx, dsty, dstx+width, dsty+height, 0, 2333 1, UTIL_BLITTER_ATTRIB_COLOR, &attrib); 2334 } 2335 2336 util_blitter_restore_vertex_states(blitter); 2337 util_blitter_restore_fragment_states(blitter); 2338 util_blitter_restore_fb_state(blitter); 2339 util_blitter_restore_render_cond(blitter); 2340 util_blitter_unset_running_flag(blitter); 2341} 2342 2343/* Clear a region of a depth stencil surface. */ 2344void util_blitter_clear_depth_stencil(struct blitter_context *blitter, 2345 struct pipe_surface *dstsurf, 2346 unsigned clear_flags, 2347 double depth, 2348 unsigned stencil, 2349 unsigned dstx, unsigned dsty, 2350 unsigned width, unsigned height) 2351{ 2352 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 2353 struct pipe_context *pipe = ctx->base.pipe; 2354 struct pipe_framebuffer_state fb_state; 2355 struct pipe_stencil_ref sr = { { 0 } }; 2356 unsigned num_layers; 2357 2358 assert(dstsurf->texture); 2359 if (!dstsurf->texture) 2360 return; 2361 2362 /* check the saved state */ 2363 util_blitter_set_running_flag(blitter); 2364 blitter_check_saved_vertex_states(ctx); 2365 blitter_check_saved_fragment_states(ctx); 2366 blitter_check_saved_fb_state(ctx); 2367 blitter_disable_render_cond(ctx); 2368 2369 /* bind states */ 2370 pipe->bind_blend_state(pipe, ctx->blend[0][0]); 2371 if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) { 2372 sr.ref_value[0] = stencil & 0xff; 2373 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil); 2374 pipe->set_stencil_ref(pipe, sr); 2375 } 2376 else if (clear_flags & PIPE_CLEAR_DEPTH) { 2377 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil); 2378 } 2379 else if (clear_flags & PIPE_CLEAR_STENCIL) { 2380 sr.ref_value[0] = stencil & 0xff; 2381 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil); 2382 pipe->set_stencil_ref(pipe, sr); 2383 } 2384 else 2385 /* hmm that should be illegal probably, or make it a no-op somewhere */ 2386 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 2387 2388 bind_fs_empty(ctx); 2389 2390 /* set a framebuffer state */ 2391 fb_state.width = dstsurf->width; 2392 fb_state.height = dstsurf->height; 2393 fb_state.nr_cbufs = 0; 2394 fb_state.cbufs[0] = 0; 2395 fb_state.zsbuf = dstsurf; 2396 pipe->set_framebuffer_state(pipe, &fb_state); 2397 pipe->set_sample_mask(pipe, ~0); 2398 2399 blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height); 2400 2401 num_layers = dstsurf->u.tex.last_layer - dstsurf->u.tex.first_layer + 1; 2402 if (num_layers > 1 && ctx->has_layered) { 2403 blitter_set_common_draw_rect_state(ctx, false, false); 2404 blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_layered, 2405 dstx, dsty, dstx+width, dsty+height, depth, 2406 num_layers, UTIL_BLITTER_ATTRIB_NONE, NULL); 2407 } else { 2408 blitter_set_common_draw_rect_state(ctx, false, false); 2409 blitter->draw_rectangle(blitter, ctx->velem_state, 2410 get_vs_passthrough_pos, 2411 dstx, dsty, dstx+width, dsty+height, depth, 1, 2412 UTIL_BLITTER_ATTRIB_NONE, NULL); 2413 } 2414 2415 util_blitter_restore_vertex_states(blitter); 2416 util_blitter_restore_fragment_states(blitter); 2417 util_blitter_restore_fb_state(blitter); 2418 util_blitter_restore_render_cond(blitter); 2419 util_blitter_unset_running_flag(blitter); 2420} 2421 2422/* draw a rectangle across a region using a custom dsa stage - for r600g */ 2423void util_blitter_custom_depth_stencil(struct blitter_context *blitter, 2424 struct pipe_surface *zsurf, 2425 struct pipe_surface *cbsurf, 2426 unsigned sample_mask, 2427 void *dsa_stage, float depth) 2428{ 2429 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 2430 struct pipe_context *pipe = ctx->base.pipe; 2431 struct pipe_framebuffer_state fb_state; 2432 2433 assert(zsurf->texture); 2434 if (!zsurf->texture) 2435 return; 2436 2437 /* check the saved state */ 2438 util_blitter_set_running_flag(blitter); 2439 blitter_check_saved_vertex_states(ctx); 2440 blitter_check_saved_fragment_states(ctx); 2441 blitter_check_saved_fb_state(ctx); 2442 blitter_disable_render_cond(ctx); 2443 2444 /* bind states */ 2445 pipe->bind_blend_state(pipe, cbsurf ? ctx->blend[PIPE_MASK_RGBA][0] : 2446 ctx->blend[0][0]); 2447 pipe->bind_depth_stencil_alpha_state(pipe, dsa_stage); 2448 if (cbsurf) 2449 bind_fs_write_one_cbuf(ctx); 2450 else 2451 bind_fs_empty(ctx); 2452 2453 /* set a framebuffer state */ 2454 fb_state.width = zsurf->width; 2455 fb_state.height = zsurf->height; 2456 fb_state.nr_cbufs = 1; 2457 if (cbsurf) { 2458 fb_state.cbufs[0] = cbsurf; 2459 fb_state.nr_cbufs = 1; 2460 } else { 2461 fb_state.cbufs[0] = NULL; 2462 fb_state.nr_cbufs = 0; 2463 } 2464 fb_state.zsbuf = zsurf; 2465 pipe->set_framebuffer_state(pipe, &fb_state); 2466 pipe->set_sample_mask(pipe, sample_mask); 2467 2468 blitter_set_common_draw_rect_state(ctx, false, 2469 util_framebuffer_get_num_samples(&fb_state) > 1); 2470 blitter_set_dst_dimensions(ctx, zsurf->width, zsurf->height); 2471 blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_passthrough_pos, 2472 0, 0, zsurf->width, zsurf->height, depth, 2473 1, UTIL_BLITTER_ATTRIB_NONE, NULL); 2474 2475 util_blitter_restore_vertex_states(blitter); 2476 util_blitter_restore_fragment_states(blitter); 2477 util_blitter_restore_fb_state(blitter); 2478 util_blitter_restore_render_cond(blitter); 2479 util_blitter_unset_running_flag(blitter); 2480} 2481 2482void util_blitter_copy_buffer(struct blitter_context *blitter, 2483 struct pipe_resource *dst, 2484 unsigned dstx, 2485 struct pipe_resource *src, 2486 unsigned srcx, 2487 unsigned size) 2488{ 2489 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 2490 struct pipe_context *pipe = ctx->base.pipe; 2491 struct pipe_vertex_buffer vb; 2492 struct pipe_stream_output_target *so_target; 2493 unsigned offsets[PIPE_MAX_SO_BUFFERS] = {0}; 2494 2495 if (srcx >= src->width0 || 2496 dstx >= dst->width0) { 2497 return; 2498 } 2499 if (srcx + size > src->width0) { 2500 size = src->width0 - srcx; 2501 } 2502 if (dstx + size > dst->width0) { 2503 size = dst->width0 - dstx; 2504 } 2505 2506 /* Drivers not capable of Stream Out should not call this function 2507 * in the first place. */ 2508 assert(ctx->has_stream_out); 2509 2510 /* Some alignment is required. */ 2511 if (srcx % 4 != 0 || dstx % 4 != 0 || size % 4 != 0 || 2512 !ctx->has_stream_out) { 2513 struct pipe_box box; 2514 u_box_1d(srcx, size, &box); 2515 util_resource_copy_region(pipe, dst, 0, dstx, 0, 0, src, 0, &box); 2516 return; 2517 } 2518 2519 util_blitter_set_running_flag(blitter); 2520 blitter_check_saved_vertex_states(ctx); 2521 blitter_disable_render_cond(ctx); 2522 2523 vb.is_user_buffer = false; 2524 vb.buffer.resource = src; 2525 vb.buffer_offset = srcx; 2526 vb.stride = 4; 2527 2528 pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, 0, false, &vb); 2529 pipe->bind_vertex_elements_state(pipe, ctx->velem_state_readbuf[0]); 2530 bind_vs_pos_only(ctx, 1); 2531 if (ctx->has_geometry_shader) 2532 pipe->bind_gs_state(pipe, NULL); 2533 if (ctx->has_tessellation) { 2534 pipe->bind_tcs_state(pipe, NULL); 2535 pipe->bind_tes_state(pipe, NULL); 2536 } 2537 pipe->bind_rasterizer_state(pipe, ctx->rs_discard_state); 2538 2539 so_target = pipe->create_stream_output_target(pipe, dst, dstx, size); 2540 pipe->set_stream_output_targets(pipe, 1, &so_target, offsets); 2541 2542 util_draw_arrays(pipe, PIPE_PRIM_POINTS, 0, size / 4); 2543 2544 util_blitter_restore_vertex_states(blitter); 2545 util_blitter_restore_render_cond(blitter); 2546 util_blitter_unset_running_flag(blitter); 2547 pipe_so_target_reference(&so_target, NULL); 2548} 2549 2550void util_blitter_clear_buffer(struct blitter_context *blitter, 2551 struct pipe_resource *dst, 2552 unsigned offset, unsigned size, 2553 unsigned num_channels, 2554 const union pipe_color_union *clear_value) 2555{ 2556 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 2557 struct pipe_context *pipe = ctx->base.pipe; 2558 struct pipe_vertex_buffer vb = {0}; 2559 struct pipe_stream_output_target *so_target = NULL; 2560 unsigned offsets[PIPE_MAX_SO_BUFFERS] = {0}; 2561 2562 assert(num_channels >= 1); 2563 assert(num_channels <= 4); 2564 2565 /* IMPORTANT: DON'T DO ANY BOUNDS CHECKING HERE! 2566 * 2567 * R600 uses this to initialize texture resources, so width0 might not be 2568 * what you think it is. 2569 */ 2570 2571 /* Streamout is required. */ 2572 if (!ctx->has_stream_out) { 2573 assert(!"Streamout unsupported in util_blitter_clear_buffer()"); 2574 return; 2575 } 2576 2577 /* Some alignment is required. */ 2578 if (offset % 4 != 0 || size % 4 != 0) { 2579 assert(!"Bad alignment in util_blitter_clear_buffer()"); 2580 return; 2581 } 2582 2583 u_upload_data(pipe->stream_uploader, 0, num_channels*4, 4, clear_value, 2584 &vb.buffer_offset, &vb.buffer.resource); 2585 if (!vb.buffer.resource) 2586 goto out; 2587 2588 vb.stride = 0; 2589 2590 util_blitter_set_running_flag(blitter); 2591 blitter_check_saved_vertex_states(ctx); 2592 blitter_disable_render_cond(ctx); 2593 2594 pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, 0, false, &vb); 2595 pipe->bind_vertex_elements_state(pipe, 2596 ctx->velem_state_readbuf[num_channels-1]); 2597 bind_vs_pos_only(ctx, num_channels); 2598 if (ctx->has_geometry_shader) 2599 pipe->bind_gs_state(pipe, NULL); 2600 if (ctx->has_tessellation) { 2601 pipe->bind_tcs_state(pipe, NULL); 2602 pipe->bind_tes_state(pipe, NULL); 2603 } 2604 pipe->bind_rasterizer_state(pipe, ctx->rs_discard_state); 2605 2606 so_target = pipe->create_stream_output_target(pipe, dst, offset, size); 2607 pipe->set_stream_output_targets(pipe, 1, &so_target, offsets); 2608 2609 util_draw_arrays(pipe, PIPE_PRIM_POINTS, 0, size / 4); 2610 2611out: 2612 util_blitter_restore_vertex_states(blitter); 2613 util_blitter_restore_render_cond(blitter); 2614 util_blitter_unset_running_flag(blitter); 2615 pipe_so_target_reference(&so_target, NULL); 2616 pipe_resource_reference(&vb.buffer.resource, NULL); 2617} 2618 2619/* probably radeon specific */ 2620void util_blitter_custom_resolve_color(struct blitter_context *blitter, 2621 struct pipe_resource *dst, 2622 unsigned dst_level, 2623 unsigned dst_layer, 2624 struct pipe_resource *src, 2625 unsigned src_layer, 2626 unsigned sample_mask, 2627 void *custom_blend, 2628 enum pipe_format format) 2629{ 2630 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 2631 struct pipe_context *pipe = ctx->base.pipe; 2632 struct pipe_framebuffer_state fb_state; 2633 struct pipe_surface *srcsurf, *dstsurf, surf_tmpl; 2634 2635 util_blitter_set_running_flag(blitter); 2636 blitter_check_saved_vertex_states(ctx); 2637 blitter_check_saved_fragment_states(ctx); 2638 blitter_disable_render_cond(ctx); 2639 2640 /* bind states */ 2641 pipe->bind_blend_state(pipe, custom_blend); 2642 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 2643 bind_fs_write_one_cbuf(ctx); 2644 pipe->set_sample_mask(pipe, sample_mask); 2645 2646 memset(&surf_tmpl, 0, sizeof(surf_tmpl)); 2647 surf_tmpl.format = format; 2648 surf_tmpl.u.tex.level = dst_level; 2649 surf_tmpl.u.tex.first_layer = dst_layer; 2650 surf_tmpl.u.tex.last_layer = dst_layer; 2651 2652 dstsurf = pipe->create_surface(pipe, dst, &surf_tmpl); 2653 2654 surf_tmpl.u.tex.level = 0; 2655 surf_tmpl.u.tex.first_layer = src_layer; 2656 surf_tmpl.u.tex.last_layer = src_layer; 2657 2658 srcsurf = pipe->create_surface(pipe, src, &surf_tmpl); 2659 2660 /* set a framebuffer state */ 2661 fb_state.width = src->width0; 2662 fb_state.height = src->height0; 2663 fb_state.nr_cbufs = 2; 2664 fb_state.cbufs[0] = srcsurf; 2665 fb_state.cbufs[1] = dstsurf; 2666 fb_state.zsbuf = NULL; 2667 pipe->set_framebuffer_state(pipe, &fb_state); 2668 2669 blitter_set_common_draw_rect_state(ctx, false, 2670 util_framebuffer_get_num_samples(&fb_state) > 1); 2671 blitter_set_dst_dimensions(ctx, src->width0, src->height0); 2672 blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_passthrough_pos, 2673 0, 0, src->width0, src->height0, 2674 0, 1, UTIL_BLITTER_ATTRIB_NONE, NULL); 2675 util_blitter_restore_fb_state(blitter); 2676 util_blitter_restore_vertex_states(blitter); 2677 util_blitter_restore_fragment_states(blitter); 2678 util_blitter_restore_render_cond(blitter); 2679 util_blitter_unset_running_flag(blitter); 2680 2681 pipe_surface_reference(&srcsurf, NULL); 2682 pipe_surface_reference(&dstsurf, NULL); 2683} 2684 2685void util_blitter_custom_color(struct blitter_context *blitter, 2686 struct pipe_surface *dstsurf, 2687 void *custom_blend) 2688{ 2689 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 2690 struct pipe_context *pipe = ctx->base.pipe; 2691 struct pipe_framebuffer_state fb_state; 2692 2693 assert(dstsurf->texture); 2694 if (!dstsurf->texture) 2695 return; 2696 2697 /* check the saved state */ 2698 util_blitter_set_running_flag(blitter); 2699 blitter_check_saved_vertex_states(ctx); 2700 blitter_check_saved_fragment_states(ctx); 2701 blitter_check_saved_fb_state(ctx); 2702 blitter_disable_render_cond(ctx); 2703 2704 /* bind states */ 2705 pipe->bind_blend_state(pipe, custom_blend ? custom_blend 2706 : ctx->blend[PIPE_MASK_RGBA][0]); 2707 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 2708 bind_fs_write_one_cbuf(ctx); 2709 2710 /* set a framebuffer state */ 2711 fb_state.width = dstsurf->width; 2712 fb_state.height = dstsurf->height; 2713 fb_state.nr_cbufs = 1; 2714 fb_state.cbufs[0] = dstsurf; 2715 fb_state.zsbuf = 0; 2716 pipe->set_framebuffer_state(pipe, &fb_state); 2717 pipe->set_sample_mask(pipe, ~0); 2718 2719 blitter_set_common_draw_rect_state(ctx, false, 2720 util_framebuffer_get_num_samples(&fb_state) > 1); 2721 blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height); 2722 blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_passthrough_pos, 2723 0, 0, dstsurf->width, dstsurf->height, 2724 0, 1, UTIL_BLITTER_ATTRIB_NONE, NULL); 2725 2726 util_blitter_restore_vertex_states(blitter); 2727 util_blitter_restore_fragment_states(blitter); 2728 util_blitter_restore_fb_state(blitter); 2729 util_blitter_restore_render_cond(blitter); 2730 util_blitter_unset_running_flag(blitter); 2731} 2732 2733static void *get_custom_vs(struct blitter_context *blitter) 2734{ 2735 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 2736 2737 return ctx->custom_vs; 2738} 2739 2740/** 2741 * Performs a custom blit to the destination surface, using the VS and FS 2742 * provided. 2743 * 2744 * Used by vc4 for the 8-bit linear-to-tiled blit. 2745 */ 2746void util_blitter_custom_shader(struct blitter_context *blitter, 2747 struct pipe_surface *dstsurf, 2748 void *custom_vs, void *custom_fs) 2749{ 2750 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 2751 struct pipe_context *pipe = ctx->base.pipe; 2752 struct pipe_framebuffer_state fb_state = { 0 }; 2753 2754 ctx->custom_vs = custom_vs; 2755 2756 assert(dstsurf->texture); 2757 if (!dstsurf->texture) 2758 return; 2759 2760 /* check the saved state */ 2761 util_blitter_set_running_flag(blitter); 2762 blitter_check_saved_vertex_states(ctx); 2763 blitter_check_saved_fragment_states(ctx); 2764 blitter_check_saved_fb_state(ctx); 2765 blitter_disable_render_cond(ctx); 2766 2767 /* bind states */ 2768 pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]); 2769 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 2770 pipe->bind_fs_state(pipe, custom_fs); 2771 2772 /* set a framebuffer state */ 2773 fb_state.width = dstsurf->width; 2774 fb_state.height = dstsurf->height; 2775 fb_state.nr_cbufs = 1; 2776 fb_state.cbufs[0] = dstsurf; 2777 pipe->set_framebuffer_state(pipe, &fb_state); 2778 pipe->set_sample_mask(pipe, ~0); 2779 2780 blitter_set_common_draw_rect_state(ctx, false, 2781 util_framebuffer_get_num_samples(&fb_state) > 1); 2782 blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height); 2783 blitter->draw_rectangle(blitter, ctx->velem_state, get_custom_vs, 2784 0, 0, dstsurf->width, dstsurf->height, 2785 0, 1, UTIL_BLITTER_ATTRIB_NONE, NULL); 2786 2787 util_blitter_restore_vertex_states(blitter); 2788 util_blitter_restore_fragment_states(blitter); 2789 util_blitter_restore_fb_state(blitter); 2790 util_blitter_restore_render_cond(blitter); 2791 util_blitter_unset_running_flag(blitter); 2792} 2793 2794static void * 2795get_stencil_blit_fallback_fs(struct blitter_context_priv *ctx, bool msaa_src) 2796{ 2797 if (!ctx->fs_stencil_blit_fallback[msaa_src]) { 2798 ctx->fs_stencil_blit_fallback[msaa_src] = 2799 util_make_fs_stencil_blit(ctx->base.pipe, msaa_src); 2800 } 2801 2802 return ctx->fs_stencil_blit_fallback[msaa_src]; 2803} 2804 2805static void * 2806get_stencil_blit_fallback_dsa(struct blitter_context_priv *ctx, unsigned i) 2807{ 2808 assert(i < ARRAY_SIZE(ctx->dsa_replicate_stencil_bit)); 2809 if (!ctx->dsa_replicate_stencil_bit[i]) { 2810 struct pipe_depth_stencil_alpha_state dsa = { 0 }; 2811 dsa.depth_func = PIPE_FUNC_ALWAYS; 2812 dsa.stencil[0].enabled = 1; 2813 dsa.stencil[0].func = PIPE_FUNC_ALWAYS; 2814 dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE; 2815 dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE; 2816 dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE; 2817 dsa.stencil[0].valuemask = 0xff; 2818 dsa.stencil[0].writemask = 1u << i; 2819 2820 ctx->dsa_replicate_stencil_bit[i] = 2821 ctx->base.pipe->create_depth_stencil_alpha_state(ctx->base.pipe, &dsa); 2822 } 2823 return ctx->dsa_replicate_stencil_bit[i]; 2824} 2825 2826/** 2827 * Performs a series of draws to implement stencil blits texture without 2828 * requiring stencil writes, updating a single bit per pixel at the time. 2829 */ 2830void 2831util_blitter_stencil_fallback(struct blitter_context *blitter, 2832 struct pipe_resource *dst, 2833 unsigned dst_level, 2834 const struct pipe_box *dstbox, 2835 struct pipe_resource *src, 2836 unsigned src_level, 2837 const struct pipe_box *srcbox, 2838 const struct pipe_scissor_state *scissor) 2839{ 2840 struct blitter_context_priv *ctx = (struct blitter_context_priv *)blitter; 2841 struct pipe_context *pipe = ctx->base.pipe; 2842 2843 /* check the saved state */ 2844 util_blitter_set_running_flag(blitter); 2845 blitter_check_saved_vertex_states(ctx); 2846 blitter_check_saved_fragment_states(ctx); 2847 blitter_check_saved_fb_state(ctx); 2848 blitter_disable_render_cond(ctx); 2849 2850 /* Initialize the surface. */ 2851 struct pipe_surface *dst_view, dst_templ; 2852 util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstbox->z); 2853 dst_view = pipe->create_surface(pipe, dst, &dst_templ); 2854 2855 /* Initialize the sampler view. */ 2856 struct pipe_sampler_view src_templ, *src_view; 2857 util_blitter_default_src_texture(blitter, &src_templ, src, src_level); 2858 src_templ.format = util_format_stencil_only(src_templ.format); 2859 src_view = pipe->create_sampler_view(pipe, src, &src_templ); 2860 2861 /* bind states */ 2862 pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]); 2863 pipe->bind_fs_state(pipe, 2864 get_stencil_blit_fallback_fs(ctx, src->nr_samples > 1)); 2865 2866 /* set a framebuffer state */ 2867 struct pipe_framebuffer_state fb_state = { 0 }; 2868 fb_state.width = dstbox->width; 2869 fb_state.height = dstbox->height; 2870 fb_state.zsbuf = dst_view; 2871 pipe->set_framebuffer_state(pipe, &fb_state); 2872 pipe->set_sample_mask(pipe, ~0); 2873 2874 blitter_set_common_draw_rect_state(ctx, scissor != NULL, 2875 util_framebuffer_get_num_samples(&fb_state) > 1); 2876 blitter_set_dst_dimensions(ctx, dst_view->width, dst_view->height); 2877 2878 if (scissor) { 2879 pipe->clear_depth_stencil(pipe, dst_view, PIPE_CLEAR_STENCIL, 0.0, 0, 2880 MAX2(dstbox->x, scissor->minx), 2881 MAX2(dstbox->y, scissor->miny), 2882 MIN2(dstbox->x + dstbox->width, scissor->maxx) - dstbox->x, 2883 MIN2(dstbox->y + dstbox->height, scissor->maxy) - dstbox->y, 2884 true); 2885 pipe->set_scissor_states(pipe, 0, 1, scissor); 2886 } else { 2887 pipe->clear_depth_stencil(pipe, dst_view, PIPE_CLEAR_STENCIL, 0.0, 0, 2888 dstbox->x, dstbox->y, 2889 dstbox->width, dstbox->height, 2890 true); 2891 } 2892 2893 pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, 0, false, &src_view); 2894 pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0, 1, &ctx->sampler_state); 2895 2896 unsigned stencil_bits = 2897 util_format_get_component_bits(dst->format, 2898 UTIL_FORMAT_COLORSPACE_ZS, 1); 2899 2900 struct pipe_stencil_ref sr = { { (1u << stencil_bits) - 1 } }; 2901 pipe->set_stencil_ref(pipe, sr); 2902 2903 union blitter_attrib coord; 2904 get_texcoords(src_view, src->width0, src->height0, 2905 srcbox->x, srcbox->y, 2906 srcbox->x + srcbox->width, srcbox->y + srcbox->height, 2907 srcbox->z, 0, true, 2908 &coord); 2909 2910 for (int i = 0; i < stencil_bits; ++i) { 2911 uint32_t mask = 1 << i; 2912 struct pipe_constant_buffer cb = { 2913 .user_buffer = &mask, 2914 .buffer_size = sizeof(mask), 2915 }; 2916 pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, blitter->cb_slot, 2917 false, &cb); 2918 2919 pipe->bind_depth_stencil_alpha_state(pipe, 2920 get_stencil_blit_fallback_dsa(ctx, i)); 2921 2922 blitter->draw_rectangle(blitter, ctx->velem_state, 2923 get_vs_passthrough_pos_generic, 2924 dstbox->x, dstbox->y, 2925 dstbox->x + dstbox->width, 2926 dstbox->y + dstbox->height, 2927 0, 1, 2928 UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW, 2929 &coord); 2930 } 2931 2932 if (scissor) 2933 pipe->set_scissor_states(pipe, 0, 1, &ctx->base.saved_scissor); 2934 2935 util_blitter_restore_vertex_states(blitter); 2936 util_blitter_restore_fragment_states(blitter); 2937 util_blitter_restore_textures(blitter); 2938 util_blitter_restore_fb_state(blitter); 2939 util_blitter_restore_render_cond(blitter); 2940 util_blitter_restore_constant_buffer_state(blitter); 2941 util_blitter_unset_running_flag(blitter); 2942 2943 pipe_surface_reference(&dst_view, NULL); 2944 pipe_sampler_view_reference(&src_view, NULL); 2945} 2946