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