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