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 TUNGSTEN GRAPHICS 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, and resource_copy_region 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 54struct blitter_context_priv 55{ 56 struct blitter_context base; 57 58 struct u_upload_mgr *upload; 59 60 float vertices[4][2][4]; /**< {pos, color} or {pos, texcoord} */ 61 62 /* Templates for various state objects. */ 63 64 /* Constant state objects. */ 65 /* Vertex shaders. */ 66 void *vs; /**< Vertex shader which passes {pos, generic} to the output.*/ 67 void *vs_pos_only; /**< Vertex shader which passes pos to the output.*/ 68 69 /* Fragment shaders. */ 70 /* The shader at index i outputs color to color buffers 0,1,...,i-1. */ 71 void *fs_col[PIPE_MAX_COLOR_BUFS+1]; 72 void *fs_col_int[PIPE_MAX_COLOR_BUFS+1]; 73 74 /* FS which outputs a color from a texture, 75 where the index is PIPE_TEXTURE_* to be sampled. */ 76 void *fs_texfetch_col[PIPE_MAX_TEXTURE_TYPES]; 77 78 /* FS which outputs a depth from a texture, 79 where the index is PIPE_TEXTURE_* to be sampled. */ 80 void *fs_texfetch_depth[PIPE_MAX_TEXTURE_TYPES]; 81 void *fs_texfetch_depthstencil[PIPE_MAX_TEXTURE_TYPES]; 82 void *fs_texfetch_stencil[PIPE_MAX_TEXTURE_TYPES]; 83 84 /* FS which outputs one sample from a multisample texture. */ 85 void *fs_texfetch_col_msaa[PIPE_MAX_TEXTURE_TYPES]; 86 void *fs_texfetch_depth_msaa[PIPE_MAX_TEXTURE_TYPES]; 87 void *fs_texfetch_depthstencil_msaa[PIPE_MAX_TEXTURE_TYPES]; 88 void *fs_texfetch_stencil_msaa[PIPE_MAX_TEXTURE_TYPES]; 89 90 /* Blend state. */ 91 void *blend_write_color; /**< blend state with writemask of RGBA */ 92 void *blend_keep_color; /**< blend state with writemask of 0 */ 93 94 /* Depth stencil alpha state. */ 95 void *dsa_write_depth_stencil; 96 void *dsa_write_depth_keep_stencil; 97 void *dsa_keep_depth_stencil; 98 void *dsa_keep_depth_write_stencil; 99 100 /* Vertex elements states. */ 101 void *velem_state; 102 void *velem_uint_state; 103 void *velem_sint_state; 104 void *velem_state_readbuf; 105 106 /* Sampler state. */ 107 void *sampler_state; 108 109 /* Rasterizer state. */ 110 void *rs_state; 111 void *rs_discard_state; 112 113 /* Viewport state. */ 114 struct pipe_viewport_state viewport; 115 116 /* Destination surface dimensions. */ 117 unsigned dst_width; 118 unsigned dst_height; 119 120 boolean has_geometry_shader; 121 boolean vertex_has_integers; 122 boolean has_stream_out; 123 boolean has_stencil_export; 124}; 125 126 127struct blitter_context *util_blitter_create(struct pipe_context *pipe) 128{ 129 struct blitter_context_priv *ctx; 130 struct pipe_blend_state blend; 131 struct pipe_depth_stencil_alpha_state dsa; 132 struct pipe_rasterizer_state rs_state; 133 struct pipe_sampler_state sampler_state; 134 struct pipe_vertex_element velem[2]; 135 unsigned i; 136 137 ctx = CALLOC_STRUCT(blitter_context_priv); 138 if (!ctx) 139 return NULL; 140 141 ctx->base.pipe = pipe; 142 ctx->base.draw_rectangle = util_blitter_draw_rectangle; 143 144 /* init state objects for them to be considered invalid */ 145 ctx->base.saved_blend_state = INVALID_PTR; 146 ctx->base.saved_dsa_state = INVALID_PTR; 147 ctx->base.saved_rs_state = INVALID_PTR; 148 ctx->base.saved_fs = INVALID_PTR; 149 ctx->base.saved_vs = INVALID_PTR; 150 ctx->base.saved_gs = INVALID_PTR; 151 ctx->base.saved_velem_state = INVALID_PTR; 152 ctx->base.saved_fb_state.nr_cbufs = ~0; 153 ctx->base.saved_num_sampler_views = ~0; 154 ctx->base.saved_num_sampler_states = ~0; 155 ctx->base.saved_num_vertex_buffers = ~0; 156 ctx->base.saved_num_so_targets = ~0; 157 158 ctx->has_geometry_shader = 159 pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_GEOMETRY, 160 PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0; 161 ctx->vertex_has_integers = 162 pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_VERTEX, 163 PIPE_SHADER_CAP_INTEGERS); 164 ctx->has_stream_out = 165 pipe->screen->get_param(pipe->screen, 166 PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS) != 0; 167 168 ctx->has_stencil_export = 169 pipe->screen->get_param(pipe->screen, 170 PIPE_CAP_SHADER_STENCIL_EXPORT); 171 172 /* blend state objects */ 173 memset(&blend, 0, sizeof(blend)); 174 ctx->blend_keep_color = pipe->create_blend_state(pipe, &blend); 175 176 blend.rt[0].colormask = PIPE_MASK_RGBA; 177 ctx->blend_write_color = pipe->create_blend_state(pipe, &blend); 178 179 /* depth stencil alpha state objects */ 180 memset(&dsa, 0, sizeof(dsa)); 181 ctx->dsa_keep_depth_stencil = 182 pipe->create_depth_stencil_alpha_state(pipe, &dsa); 183 184 dsa.depth.enabled = 1; 185 dsa.depth.writemask = 1; 186 dsa.depth.func = PIPE_FUNC_ALWAYS; 187 ctx->dsa_write_depth_keep_stencil = 188 pipe->create_depth_stencil_alpha_state(pipe, &dsa); 189 190 dsa.stencil[0].enabled = 1; 191 dsa.stencil[0].func = PIPE_FUNC_ALWAYS; 192 dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE; 193 dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE; 194 dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE; 195 dsa.stencil[0].valuemask = 0xff; 196 dsa.stencil[0].writemask = 0xff; 197 ctx->dsa_write_depth_stencil = 198 pipe->create_depth_stencil_alpha_state(pipe, &dsa); 199 200 dsa.depth.enabled = 0; 201 dsa.depth.writemask = 0; 202 ctx->dsa_keep_depth_write_stencil = 203 pipe->create_depth_stencil_alpha_state(pipe, &dsa); 204 205 /* sampler state */ 206 memset(&sampler_state, 0, sizeof(sampler_state)); 207 sampler_state.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 208 sampler_state.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 209 sampler_state.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 210 sampler_state.normalized_coords = 1; 211 ctx->sampler_state = pipe->create_sampler_state(pipe, &sampler_state); 212 213 /* rasterizer state */ 214 memset(&rs_state, 0, sizeof(rs_state)); 215 rs_state.cull_face = PIPE_FACE_NONE; 216 rs_state.gl_rasterization_rules = 1; 217 rs_state.flatshade = 1; 218 rs_state.depth_clip = 1; 219 ctx->rs_state = pipe->create_rasterizer_state(pipe, &rs_state); 220 221 if (ctx->has_stream_out) { 222 rs_state.rasterizer_discard = 1; 223 ctx->rs_discard_state = pipe->create_rasterizer_state(pipe, &rs_state); 224 } 225 226 /* vertex elements states */ 227 memset(&velem[0], 0, sizeof(velem[0]) * 2); 228 for (i = 0; i < 2; i++) { 229 velem[i].src_offset = i * 4 * sizeof(float); 230 velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 231 } 232 ctx->velem_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]); 233 234 if (ctx->vertex_has_integers) { 235 memset(&velem[0], 0, sizeof(velem[0]) * 2); 236 velem[0].src_offset = 0; 237 velem[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 238 velem[1].src_offset = 4 * sizeof(float); 239 velem[1].src_format = PIPE_FORMAT_R32G32B32A32_SINT; 240 ctx->velem_sint_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]); 241 242 memset(&velem[0], 0, sizeof(velem[0]) * 2); 243 velem[0].src_offset = 0; 244 velem[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 245 velem[1].src_offset = 4 * sizeof(float); 246 velem[1].src_format = PIPE_FORMAT_R32G32B32A32_UINT; 247 ctx->velem_uint_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]); 248 } 249 250 if (ctx->has_stream_out) { 251 velem[0].src_format = PIPE_FORMAT_R32_UINT; 252 ctx->velem_state_readbuf = pipe->create_vertex_elements_state(pipe, 1, &velem[0]); 253 } 254 255 /* fragment shaders are created on-demand */ 256 257 /* vertex shaders */ 258 { 259 const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, 260 TGSI_SEMANTIC_GENERIC }; 261 const uint semantic_indices[] = { 0, 0 }; 262 ctx->vs = 263 util_make_vertex_passthrough_shader(pipe, 2, semantic_names, 264 semantic_indices); 265 } 266 if (ctx->has_stream_out) { 267 struct pipe_stream_output_info so; 268 const uint semantic_names[] = { TGSI_SEMANTIC_POSITION }; 269 const uint semantic_indices[] = { 0 }; 270 271 memset(&so, 0, sizeof(so)); 272 so.num_outputs = 1; 273 so.output[0].num_components = 1; 274 so.stride[0] = 1; 275 276 ctx->vs_pos_only = 277 util_make_vertex_passthrough_shader_with_so(pipe, 1, semantic_names, 278 semantic_indices, &so); 279 } 280 281 /* set invariant vertex coordinates */ 282 for (i = 0; i < 4; i++) 283 ctx->vertices[i][0][3] = 1; /*v.w*/ 284 285 ctx->upload = u_upload_create(pipe, 65536, 4, PIPE_BIND_VERTEX_BUFFER); 286 287 return &ctx->base; 288} 289 290void util_blitter_destroy(struct blitter_context *blitter) 291{ 292 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 293 struct pipe_context *pipe = blitter->pipe; 294 int i; 295 296 pipe->delete_blend_state(pipe, ctx->blend_write_color); 297 pipe->delete_blend_state(pipe, ctx->blend_keep_color); 298 pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 299 pipe->delete_depth_stencil_alpha_state(pipe, 300 ctx->dsa_write_depth_keep_stencil); 301 pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil); 302 pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil); 303 304 pipe->delete_rasterizer_state(pipe, ctx->rs_state); 305 if (ctx->rs_discard_state) 306 pipe->delete_rasterizer_state(pipe, ctx->rs_discard_state); 307 pipe->delete_vs_state(pipe, ctx->vs); 308 if (ctx->vs_pos_only) 309 pipe->delete_vs_state(pipe, ctx->vs_pos_only); 310 pipe->delete_vertex_elements_state(pipe, ctx->velem_state); 311 if (ctx->vertex_has_integers) { 312 pipe->delete_vertex_elements_state(pipe, ctx->velem_sint_state); 313 pipe->delete_vertex_elements_state(pipe, ctx->velem_uint_state); 314 } 315 if (ctx->velem_state_readbuf) 316 pipe->delete_vertex_elements_state(pipe, ctx->velem_state_readbuf); 317 318 for (i = 0; i < PIPE_MAX_TEXTURE_TYPES; i++) { 319 if (ctx->fs_texfetch_col[i]) 320 pipe->delete_fs_state(pipe, ctx->fs_texfetch_col[i]); 321 if (ctx->fs_texfetch_depth[i]) 322 pipe->delete_fs_state(pipe, ctx->fs_texfetch_depth[i]); 323 if (ctx->fs_texfetch_depthstencil[i]) 324 pipe->delete_fs_state(pipe, ctx->fs_texfetch_depthstencil[i]); 325 if (ctx->fs_texfetch_stencil[i]) 326 pipe->delete_fs_state(pipe, ctx->fs_texfetch_stencil[i]); 327 } 328 329 for (i = 0; i <= PIPE_MAX_COLOR_BUFS; i++) { 330 if (ctx->fs_col[i]) 331 pipe->delete_fs_state(pipe, ctx->fs_col[i]); 332 if (ctx->fs_col_int[i]) 333 pipe->delete_fs_state(pipe, ctx->fs_col_int[i]); 334 } 335 336 pipe->delete_sampler_state(pipe, ctx->sampler_state); 337 u_upload_destroy(ctx->upload); 338 FREE(ctx); 339} 340 341static void blitter_set_running_flag(struct blitter_context_priv *ctx) 342{ 343 if (ctx->base.running) { 344 _debug_printf("u_blitter:%i: Caught recursion. This is a driver bug.\n", 345 __LINE__); 346 } 347 ctx->base.running = TRUE; 348} 349 350static void blitter_unset_running_flag(struct blitter_context_priv *ctx) 351{ 352 if (!ctx->base.running) { 353 _debug_printf("u_blitter:%i: Caught recursion. This is a driver bug.\n", 354 __LINE__); 355 } 356 ctx->base.running = FALSE; 357} 358 359static void blitter_check_saved_vertex_states(struct blitter_context_priv *ctx) 360{ 361 assert(ctx->base.saved_num_vertex_buffers != ~0); 362 assert(ctx->base.saved_velem_state != INVALID_PTR); 363 assert(ctx->base.saved_vs != INVALID_PTR); 364 assert(!ctx->has_geometry_shader || ctx->base.saved_gs != INVALID_PTR); 365 assert(!ctx->has_stream_out || ctx->base.saved_num_so_targets != ~0); 366 assert(ctx->base.saved_rs_state != INVALID_PTR); 367} 368 369static void blitter_restore_vertex_states(struct blitter_context_priv *ctx) 370{ 371 struct pipe_context *pipe = ctx->base.pipe; 372 unsigned i; 373 374 /* Vertex buffers. */ 375 pipe->set_vertex_buffers(pipe, 376 ctx->base.saved_num_vertex_buffers, 377 ctx->base.saved_vertex_buffers); 378 379 for (i = 0; i < ctx->base.saved_num_vertex_buffers; i++) { 380 if (ctx->base.saved_vertex_buffers[i].buffer) { 381 pipe_resource_reference(&ctx->base.saved_vertex_buffers[i].buffer, 382 NULL); 383 } 384 } 385 ctx->base.saved_num_vertex_buffers = ~0; 386 387 /* Vertex elements. */ 388 pipe->bind_vertex_elements_state(pipe, ctx->base.saved_velem_state); 389 ctx->base.saved_velem_state = INVALID_PTR; 390 391 /* Vertex shader. */ 392 pipe->bind_vs_state(pipe, ctx->base.saved_vs); 393 ctx->base.saved_vs = INVALID_PTR; 394 395 /* Geometry shader. */ 396 if (ctx->has_geometry_shader) { 397 pipe->bind_gs_state(pipe, ctx->base.saved_gs); 398 ctx->base.saved_gs = INVALID_PTR; 399 } 400 401 /* Stream outputs. */ 402 if (ctx->has_stream_out) { 403 pipe->set_stream_output_targets(pipe, 404 ctx->base.saved_num_so_targets, 405 ctx->base.saved_so_targets, ~0); 406 407 for (i = 0; i < ctx->base.saved_num_so_targets; i++) 408 pipe_so_target_reference(&ctx->base.saved_so_targets[i], NULL); 409 410 ctx->base.saved_num_so_targets = ~0; 411 } 412 413 /* Rasterizer. */ 414 pipe->bind_rasterizer_state(pipe, ctx->base.saved_rs_state); 415 ctx->base.saved_rs_state = INVALID_PTR; 416} 417 418static void blitter_check_saved_fragment_states(struct blitter_context_priv *ctx) 419{ 420 assert(ctx->base.saved_fs != INVALID_PTR); 421 assert(ctx->base.saved_dsa_state != INVALID_PTR); 422 assert(ctx->base.saved_blend_state != INVALID_PTR); 423} 424 425static void blitter_restore_fragment_states(struct blitter_context_priv *ctx) 426{ 427 struct pipe_context *pipe = ctx->base.pipe; 428 429 /* Fragment shader. */ 430 pipe->bind_fs_state(pipe, ctx->base.saved_fs); 431 ctx->base.saved_fs = INVALID_PTR; 432 433 /* Depth, stencil, alpha. */ 434 pipe->bind_depth_stencil_alpha_state(pipe, ctx->base.saved_dsa_state); 435 ctx->base.saved_dsa_state = INVALID_PTR; 436 437 /* Blend state. */ 438 pipe->bind_blend_state(pipe, ctx->base.saved_blend_state); 439 ctx->base.saved_blend_state = INVALID_PTR; 440 441 /* Sample mask. */ 442 if (ctx->base.is_sample_mask_saved) { 443 pipe->set_sample_mask(pipe, ctx->base.saved_sample_mask); 444 ctx->base.is_sample_mask_saved = FALSE; 445 } 446 447 /* Miscellaneous states. */ 448 /* XXX check whether these are saved and whether they need to be restored 449 * (depending on the operation) */ 450 pipe->set_stencil_ref(pipe, &ctx->base.saved_stencil_ref); 451 pipe->set_viewport_state(pipe, &ctx->base.saved_viewport); 452} 453 454static void blitter_check_saved_fb_state(struct blitter_context_priv *ctx) 455{ 456 assert(ctx->base.saved_fb_state.nr_cbufs != ~0); 457} 458 459static void blitter_restore_fb_state(struct blitter_context_priv *ctx) 460{ 461 struct pipe_context *pipe = ctx->base.pipe; 462 463 pipe->set_framebuffer_state(pipe, &ctx->base.saved_fb_state); 464 util_unreference_framebuffer_state(&ctx->base.saved_fb_state); 465} 466 467static void blitter_check_saved_textures(struct blitter_context_priv *ctx) 468{ 469 assert(ctx->base.saved_num_sampler_states != ~0); 470 assert(ctx->base.saved_num_sampler_views != ~0); 471} 472 473static void blitter_restore_textures(struct blitter_context_priv *ctx) 474{ 475 struct pipe_context *pipe = ctx->base.pipe; 476 unsigned i; 477 478 /* Fragment sampler states. */ 479 pipe->bind_fragment_sampler_states(pipe, 480 ctx->base.saved_num_sampler_states, 481 ctx->base.saved_sampler_states); 482 ctx->base.saved_num_sampler_states = ~0; 483 484 /* Fragment sampler views. */ 485 pipe->set_fragment_sampler_views(pipe, 486 ctx->base.saved_num_sampler_views, 487 ctx->base.saved_sampler_views); 488 489 for (i = 0; i < ctx->base.saved_num_sampler_views; i++) 490 pipe_sampler_view_reference(&ctx->base.saved_sampler_views[i], NULL); 491 492 ctx->base.saved_num_sampler_views = ~0; 493} 494 495static void blitter_set_rectangle(struct blitter_context_priv *ctx, 496 unsigned x1, unsigned y1, 497 unsigned x2, unsigned y2, 498 float depth) 499{ 500 int i; 501 502 /* set vertex positions */ 503 ctx->vertices[0][0][0] = (float)x1 / ctx->dst_width * 2.0f - 1.0f; /*v0.x*/ 504 ctx->vertices[0][0][1] = (float)y1 / ctx->dst_height * 2.0f - 1.0f; /*v0.y*/ 505 506 ctx->vertices[1][0][0] = (float)x2 / ctx->dst_width * 2.0f - 1.0f; /*v1.x*/ 507 ctx->vertices[1][0][1] = (float)y1 / ctx->dst_height * 2.0f - 1.0f; /*v1.y*/ 508 509 ctx->vertices[2][0][0] = (float)x2 / ctx->dst_width * 2.0f - 1.0f; /*v2.x*/ 510 ctx->vertices[2][0][1] = (float)y2 / ctx->dst_height * 2.0f - 1.0f; /*v2.y*/ 511 512 ctx->vertices[3][0][0] = (float)x1 / ctx->dst_width * 2.0f - 1.0f; /*v3.x*/ 513 ctx->vertices[3][0][1] = (float)y2 / ctx->dst_height * 2.0f - 1.0f; /*v3.y*/ 514 515 for (i = 0; i < 4; i++) 516 ctx->vertices[i][0][2] = depth; /*z*/ 517 518 /* viewport */ 519 ctx->viewport.scale[0] = 0.5f * ctx->dst_width; 520 ctx->viewport.scale[1] = 0.5f * ctx->dst_height; 521 ctx->viewport.scale[2] = 1.0f; 522 ctx->viewport.scale[3] = 1.0f; 523 ctx->viewport.translate[0] = 0.5f * ctx->dst_width; 524 ctx->viewport.translate[1] = 0.5f * ctx->dst_height; 525 ctx->viewport.translate[2] = 0.0f; 526 ctx->viewport.translate[3] = 0.0f; 527 ctx->base.pipe->set_viewport_state(ctx->base.pipe, &ctx->viewport); 528} 529 530static void blitter_set_clear_color(struct blitter_context_priv *ctx, 531 const union pipe_color_union *color) 532{ 533 int i; 534 535 if (color) { 536 for (i = 0; i < 4; i++) { 537 uint32_t *uiverts = (uint32_t *)ctx->vertices[i][1]; 538 uiverts[0] = color->ui[0]; 539 uiverts[1] = color->ui[1]; 540 uiverts[2] = color->ui[2]; 541 uiverts[3] = color->ui[3]; 542 } 543 } else { 544 for (i = 0; i < 4; i++) { 545 ctx->vertices[i][1][0] = 0; 546 ctx->vertices[i][1][1] = 0; 547 ctx->vertices[i][1][2] = 0; 548 ctx->vertices[i][1][3] = 0; 549 } 550 } 551} 552 553static void get_texcoords(struct pipe_sampler_view *src, 554 unsigned src_width0, unsigned src_height0, 555 unsigned x1, unsigned y1, 556 unsigned x2, unsigned y2, 557 float out[4]) 558{ 559 struct pipe_resource *tex = src->texture; 560 unsigned level = src->u.tex.first_level; 561 boolean normalized = tex->target != PIPE_TEXTURE_RECT && 562 tex->nr_samples <= 1; 563 564 if (normalized) { 565 out[0] = x1 / (float)u_minify(src_width0, level); 566 out[1] = y1 / (float)u_minify(src_height0, level); 567 out[2] = x2 / (float)u_minify(src_width0, level); 568 out[3] = y2 / (float)u_minify(src_height0, level); 569 } else { 570 out[0] = x1; 571 out[1] = y1; 572 out[2] = x2; 573 out[3] = y2; 574 } 575} 576 577static void set_texcoords_in_vertices(const float coord[4], 578 float *out, unsigned stride) 579{ 580 out[0] = coord[0]; /*t0.s*/ 581 out[1] = coord[1]; /*t0.t*/ 582 out += stride; 583 out[0] = coord[2]; /*t1.s*/ 584 out[1] = coord[1]; /*t1.t*/ 585 out += stride; 586 out[0] = coord[2]; /*t2.s*/ 587 out[1] = coord[3]; /*t2.t*/ 588 out += stride; 589 out[0] = coord[0]; /*t3.s*/ 590 out[1] = coord[3]; /*t3.t*/ 591} 592 593static void blitter_set_texcoords(struct blitter_context_priv *ctx, 594 struct pipe_sampler_view *src, 595 unsigned src_width0, unsigned src_height0, 596 unsigned layer, unsigned sample, 597 unsigned x1, unsigned y1, 598 unsigned x2, unsigned y2) 599{ 600 unsigned i; 601 float coord[4]; 602 float face_coord[4][2]; 603 604 get_texcoords(src, src_width0, src_height0, x1, y1, x2, y2, coord); 605 606 if (src->texture->target == PIPE_TEXTURE_CUBE) { 607 set_texcoords_in_vertices(coord, &face_coord[0][0], 2); 608 util_map_texcoords2d_onto_cubemap(layer, 609 /* pointer, stride in floats */ 610 &face_coord[0][0], 2, 611 &ctx->vertices[0][1][0], 8); 612 } else { 613 set_texcoords_in_vertices(coord, &ctx->vertices[0][1][0], 8); 614 } 615 616 /* Set the layer. */ 617 switch (src->texture->target) { 618 case PIPE_TEXTURE_3D: 619 { 620 float r = layer / (float)u_minify(src->texture->depth0, 621 src->u.tex.first_level); 622 for (i = 0; i < 4; i++) 623 ctx->vertices[i][1][2] = r; /*r*/ 624 } 625 break; 626 627 case PIPE_TEXTURE_1D_ARRAY: 628 for (i = 0; i < 4; i++) 629 ctx->vertices[i][1][1] = layer; /*t*/ 630 break; 631 632 case PIPE_TEXTURE_2D_ARRAY: 633 for (i = 0; i < 4; i++) { 634 ctx->vertices[i][1][2] = layer; /*r*/ 635 ctx->vertices[i][1][3] = sample; /*q*/ 636 } 637 break; 638 639 case PIPE_TEXTURE_2D: 640 for (i = 0; i < 4; i++) { 641 ctx->vertices[i][1][2] = sample; /*r*/ 642 } 643 break; 644 645 default:; 646 } 647} 648 649static void blitter_set_dst_dimensions(struct blitter_context_priv *ctx, 650 unsigned width, unsigned height) 651{ 652 ctx->dst_width = width; 653 ctx->dst_height = height; 654} 655 656static INLINE 657void *blitter_get_fs_col(struct blitter_context_priv *ctx, unsigned num_cbufs, 658 boolean int_format) 659{ 660 struct pipe_context *pipe = ctx->base.pipe; 661 662 assert(num_cbufs <= PIPE_MAX_COLOR_BUFS); 663 664 if (int_format) { 665 if (!ctx->fs_col_int[num_cbufs]) 666 ctx->fs_col_int[num_cbufs] = 667 util_make_fragment_cloneinput_shader(pipe, num_cbufs, 668 TGSI_SEMANTIC_GENERIC, 669 TGSI_INTERPOLATE_CONSTANT); 670 return ctx->fs_col_int[num_cbufs]; 671 } else { 672 if (!ctx->fs_col[num_cbufs]) 673 ctx->fs_col[num_cbufs] = 674 util_make_fragment_cloneinput_shader(pipe, num_cbufs, 675 TGSI_SEMANTIC_GENERIC, 676 TGSI_INTERPOLATE_LINEAR); 677 return ctx->fs_col[num_cbufs]; 678 } 679} 680 681static INLINE 682void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx, 683 struct pipe_resource *tex) 684{ 685 struct pipe_context *pipe = ctx->base.pipe; 686 687 assert(tex->target < PIPE_MAX_TEXTURE_TYPES); 688 689 if (tex->nr_samples > 1) { 690 void **shader = &ctx->fs_texfetch_col_msaa[tex->target]; 691 692 /* Create the fragment shader on-demand. */ 693 if (!*shader) { 694 unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(tex->target, 695 tex->nr_samples); 696 697 *shader = util_make_fs_blit_msaa_color(pipe, tgsi_tex); 698 } 699 700 return *shader; 701 } else { 702 void **shader = &ctx->fs_texfetch_col[tex->target]; 703 704 /* Create the fragment shader on-demand. */ 705 if (!*shader) { 706 unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(tex->target, 0); 707 708 *shader = 709 util_make_fragment_tex_shader(pipe, tgsi_tex, 710 TGSI_INTERPOLATE_LINEAR); 711 } 712 713 return *shader; 714 } 715} 716 717static INLINE 718void *blitter_get_fs_texfetch_depth(struct blitter_context_priv *ctx, 719 struct pipe_resource *tex) 720{ 721 struct pipe_context *pipe = ctx->base.pipe; 722 723 assert(tex->target < PIPE_MAX_TEXTURE_TYPES); 724 725 if (tex->nr_samples > 1) { 726 void **shader = &ctx->fs_texfetch_depth_msaa[tex->target]; 727 728 /* Create the fragment shader on-demand. */ 729 if (!*shader) { 730 unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(tex->target, 731 tex->nr_samples); 732 733 *shader = 734 util_make_fs_blit_msaa_depth(pipe, tgsi_tex); 735 } 736 737 return *shader; 738 } else { 739 void **shader = &ctx->fs_texfetch_depth[tex->target]; 740 741 /* Create the fragment shader on-demand. */ 742 if (!*shader) { 743 unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(tex->target, 0); 744 745 *shader = 746 util_make_fragment_tex_shader_writedepth(pipe, tgsi_tex, 747 TGSI_INTERPOLATE_LINEAR); 748 } 749 750 return *shader; 751 } 752} 753 754static INLINE 755void *blitter_get_fs_texfetch_depthstencil(struct blitter_context_priv *ctx, 756 struct pipe_resource *tex) 757{ 758 struct pipe_context *pipe = ctx->base.pipe; 759 760 assert(tex->target < PIPE_MAX_TEXTURE_TYPES); 761 762 if (tex->nr_samples > 1) { 763 void **shader = &ctx->fs_texfetch_depthstencil_msaa[tex->target]; 764 765 /* Create the fragment shader on-demand. */ 766 if (!*shader) { 767 unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(tex->target, 768 tex->nr_samples); 769 770 *shader = 771 util_make_fs_blit_msaa_depthstencil(pipe, tgsi_tex); 772 } 773 774 return *shader; 775 } else { 776 void **shader = &ctx->fs_texfetch_depthstencil[tex->target]; 777 778 /* Create the fragment shader on-demand. */ 779 if (!*shader) { 780 unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(tex->target, 0); 781 782 *shader = 783 util_make_fragment_tex_shader_writedepthstencil(pipe, tgsi_tex, 784 TGSI_INTERPOLATE_LINEAR); 785 } 786 787 return *shader; 788 } 789} 790 791static INLINE 792void *blitter_get_fs_texfetch_stencil(struct blitter_context_priv *ctx, 793 struct pipe_resource *tex) 794{ 795 struct pipe_context *pipe = ctx->base.pipe; 796 797 assert(tex->target < PIPE_MAX_TEXTURE_TYPES); 798 799 if (tex->nr_samples > 1) { 800 void **shader = &ctx->fs_texfetch_stencil_msaa[tex->target]; 801 802 /* Create the fragment shader on-demand. */ 803 if (!*shader) { 804 unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(tex->target, 805 tex->nr_samples); 806 807 *shader = 808 util_make_fs_blit_msaa_stencil(pipe, tgsi_tex); 809 } 810 811 return *shader; 812 } else { 813 void **shader = &ctx->fs_texfetch_stencil[tex->target]; 814 815 /* Create the fragment shader on-demand. */ 816 if (!*shader) { 817 unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(tex->target, 0); 818 819 *shader = 820 util_make_fragment_tex_shader_writestencil(pipe, tgsi_tex, 821 TGSI_INTERPOLATE_LINEAR); 822 } 823 824 return *shader; 825 } 826} 827 828static void blitter_set_common_draw_rect_state(struct blitter_context_priv *ctx) 829{ 830 struct pipe_context *pipe = ctx->base.pipe; 831 832 pipe->bind_rasterizer_state(pipe, ctx->rs_state); 833 pipe->bind_vs_state(pipe, ctx->vs); 834 if (ctx->has_geometry_shader) 835 pipe->bind_gs_state(pipe, NULL); 836 if (ctx->has_stream_out) 837 pipe->set_stream_output_targets(pipe, 0, NULL, 0); 838} 839 840static void blitter_draw(struct blitter_context_priv *ctx, 841 unsigned x1, unsigned y1, 842 unsigned x2, unsigned y2, 843 float depth) 844{ 845 struct pipe_resource *buf = NULL; 846 unsigned offset = 0; 847 848 blitter_set_rectangle(ctx, x1, y1, x2, y2, depth); 849 850 u_upload_data(ctx->upload, 0, sizeof(ctx->vertices), ctx->vertices, 851 &offset, &buf); 852 u_upload_unmap(ctx->upload); 853 util_draw_vertex_buffer(ctx->base.pipe, NULL, buf, offset, 854 PIPE_PRIM_TRIANGLE_FAN, 4, 2); 855 pipe_resource_reference(&buf, NULL); 856} 857 858void util_blitter_draw_rectangle(struct blitter_context *blitter, 859 unsigned x1, unsigned y1, 860 unsigned x2, unsigned y2, 861 float depth, 862 enum blitter_attrib_type type, 863 const union pipe_color_union *attrib) 864{ 865 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 866 867 switch (type) { 868 case UTIL_BLITTER_ATTRIB_COLOR: 869 blitter_set_clear_color(ctx, attrib); 870 break; 871 872 case UTIL_BLITTER_ATTRIB_TEXCOORD: 873 set_texcoords_in_vertices(attrib->f, &ctx->vertices[0][1][0], 8); 874 break; 875 876 default:; 877 } 878 879 blitter_draw(ctx, x1, y1, x2, y2, depth); 880} 881 882static void util_blitter_clear_custom(struct blitter_context *blitter, 883 unsigned width, unsigned height, 884 unsigned num_cbufs, 885 unsigned clear_buffers, 886 enum pipe_format cbuf_format, 887 const union pipe_color_union *color, 888 double depth, unsigned stencil, 889 void *custom_blend, void *custom_dsa) 890{ 891 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 892 struct pipe_context *pipe = ctx->base.pipe; 893 struct pipe_stencil_ref sr = { { 0 } }; 894 boolean int_format = util_format_is_pure_integer(cbuf_format); 895 assert(num_cbufs <= PIPE_MAX_COLOR_BUFS); 896 897 blitter_set_running_flag(ctx); 898 blitter_check_saved_vertex_states(ctx); 899 blitter_check_saved_fragment_states(ctx); 900 901 /* bind states */ 902 if (custom_blend) { 903 pipe->bind_blend_state(pipe, custom_blend); 904 } else if (clear_buffers & PIPE_CLEAR_COLOR) { 905 pipe->bind_blend_state(pipe, ctx->blend_write_color); 906 } else { 907 pipe->bind_blend_state(pipe, ctx->blend_keep_color); 908 } 909 910 if (custom_dsa) { 911 pipe->bind_depth_stencil_alpha_state(pipe, custom_dsa); 912 } else if ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) { 913 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil); 914 } else if (clear_buffers & PIPE_CLEAR_DEPTH) { 915 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil); 916 } else if (clear_buffers & PIPE_CLEAR_STENCIL) { 917 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil); 918 } else { 919 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 920 } 921 922 sr.ref_value[0] = stencil & 0xff; 923 pipe->set_stencil_ref(pipe, &sr); 924 925 if (util_format_is_pure_sint(cbuf_format)) { 926 pipe->bind_vertex_elements_state(pipe, ctx->velem_sint_state); 927 } else if (util_format_is_pure_uint(cbuf_format)) { 928 pipe->bind_vertex_elements_state(pipe, ctx->velem_uint_state); 929 } else { 930 pipe->bind_vertex_elements_state(pipe, ctx->velem_state); 931 } 932 pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, num_cbufs, int_format)); 933 pipe->set_sample_mask(pipe, ~0); 934 935 blitter_set_common_draw_rect_state(ctx); 936 blitter_set_dst_dimensions(ctx, width, height); 937 blitter->draw_rectangle(blitter, 0, 0, width, height, depth, 938 UTIL_BLITTER_ATTRIB_COLOR, color); 939 940 blitter_restore_vertex_states(ctx); 941 blitter_restore_fragment_states(ctx); 942 blitter_unset_running_flag(ctx); 943} 944 945void util_blitter_clear(struct blitter_context *blitter, 946 unsigned width, unsigned height, 947 unsigned num_cbufs, 948 unsigned clear_buffers, 949 enum pipe_format cbuf_format, 950 const union pipe_color_union *color, 951 double depth, unsigned stencil) 952{ 953 util_blitter_clear_custom(blitter, width, height, num_cbufs, 954 clear_buffers, cbuf_format, color, depth, stencil, 955 NULL, NULL); 956} 957 958void util_blitter_custom_clear_depth(struct blitter_context *blitter, 959 unsigned width, unsigned height, 960 double depth, void *custom_dsa) 961{ 962 static const union pipe_color_union color; 963 util_blitter_clear_custom(blitter, width, height, 0, 964 0, PIPE_FORMAT_NONE, &color, depth, 0, NULL, custom_dsa); 965} 966 967static 968boolean is_overlap(unsigned dstx, unsigned dsty, unsigned dstz, 969 const struct pipe_box *srcbox) 970{ 971 struct pipe_box src = *srcbox; 972 973 if (src.width < 0) { 974 src.x += src.width; 975 src.width = -src.width; 976 } 977 if (src.height < 0) { 978 src.y += src.height; 979 src.height = -src.height; 980 } 981 if (src.depth < 0) { 982 src.z += src.depth; 983 src.depth = -src.depth; 984 } 985 return src.x < dstx+src.width && src.x+src.width > dstx && 986 src.y < dsty+src.height && src.y+src.height > dsty && 987 src.z < dstz+src.depth && src.z+src.depth > dstz; 988} 989 990void util_blitter_default_dst_texture(struct pipe_surface *dst_templ, 991 struct pipe_resource *dst, 992 unsigned dstlevel, 993 unsigned dstz, 994 const struct pipe_box *srcbox) 995{ 996 memset(dst_templ, 0, sizeof(*dst_templ)); 997 dst_templ->format = dst->format; 998 if (util_format_is_depth_or_stencil(dst->format)) { 999 dst_templ->usage = PIPE_BIND_DEPTH_STENCIL; 1000 } else { 1001 dst_templ->usage = PIPE_BIND_RENDER_TARGET; 1002 } 1003 dst_templ->format = util_format_linear(dst->format); 1004 dst_templ->u.tex.level = dstlevel; 1005 dst_templ->u.tex.first_layer = dstz; 1006 dst_templ->u.tex.last_layer = dstz + srcbox->depth - 1; 1007} 1008 1009void util_blitter_default_src_texture(struct pipe_sampler_view *src_templ, 1010 struct pipe_resource *src, 1011 unsigned srclevel) 1012{ 1013 memset(src_templ, 0, sizeof(*src_templ)); 1014 src_templ->format = util_format_linear(src->format); 1015 src_templ->u.tex.first_level = srclevel; 1016 src_templ->u.tex.last_level = srclevel; 1017 src_templ->u.tex.first_layer = 0; 1018 src_templ->u.tex.last_layer = 1019 src->target == PIPE_TEXTURE_3D ? u_minify(src->depth0, srclevel) - 1 1020 : src->array_size - 1; 1021 src_templ->swizzle_r = PIPE_SWIZZLE_RED; 1022 src_templ->swizzle_g = PIPE_SWIZZLE_GREEN; 1023 src_templ->swizzle_b = PIPE_SWIZZLE_BLUE; 1024 src_templ->swizzle_a = PIPE_SWIZZLE_ALPHA; 1025} 1026 1027boolean util_blitter_is_copy_supported(struct blitter_context *blitter, 1028 const struct pipe_resource *dst, 1029 const struct pipe_resource *src, 1030 unsigned mask) 1031{ 1032 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 1033 struct pipe_screen *screen = ctx->base.pipe->screen; 1034 1035 if (dst) { 1036 unsigned bind; 1037 boolean is_stencil; 1038 const struct util_format_description *desc = 1039 util_format_description(dst->format); 1040 1041 is_stencil = util_format_has_stencil(desc); 1042 1043 /* Stencil export must be supported for stencil copy. */ 1044 if ((mask & PIPE_MASK_S) && is_stencil && !ctx->has_stencil_export) { 1045 return FALSE; 1046 } 1047 1048 if (is_stencil || util_format_has_depth(desc)) 1049 bind = PIPE_BIND_DEPTH_STENCIL; 1050 else 1051 bind = PIPE_BIND_RENDER_TARGET; 1052 1053 if (!screen->is_format_supported(screen, dst->format, dst->target, 1054 dst->nr_samples, bind)) { 1055 return FALSE; 1056 } 1057 } 1058 1059 if (src) { 1060 if (!screen->is_format_supported(screen, src->format, src->target, 1061 src->nr_samples, PIPE_BIND_SAMPLER_VIEW)) { 1062 return FALSE; 1063 } 1064 1065 /* Check stencil sampler support for stencil copy. */ 1066 if (util_format_has_stencil(util_format_description(src->format))) { 1067 enum pipe_format stencil_format = 1068 util_format_stencil_only(src->format); 1069 assert(stencil_format != PIPE_FORMAT_NONE); 1070 1071 if (stencil_format != src->format && 1072 !screen->is_format_supported(screen, stencil_format, src->target, 1073 src->nr_samples, PIPE_BIND_SAMPLER_VIEW)) { 1074 return FALSE; 1075 } 1076 } 1077 } 1078 1079 return TRUE; 1080} 1081 1082void util_blitter_copy_texture(struct blitter_context *blitter, 1083 struct pipe_resource *dst, 1084 unsigned dst_level, unsigned dst_sample_mask, 1085 unsigned dstx, unsigned dsty, unsigned dstz, 1086 struct pipe_resource *src, 1087 unsigned src_level, unsigned src_sample, 1088 const struct pipe_box *srcbox) 1089{ 1090 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 1091 struct pipe_context *pipe = ctx->base.pipe; 1092 struct pipe_surface *dst_view, dst_templ; 1093 struct pipe_sampler_view src_templ, *src_view; 1094 1095 assert(dst && src); 1096 assert(src->target < PIPE_MAX_TEXTURE_TYPES); 1097 1098 /* Initialize the surface. */ 1099 util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz, srcbox); 1100 dst_view = pipe->create_surface(pipe, dst, &dst_templ); 1101 1102 /* Initialize the sampler view. */ 1103 util_blitter_default_src_texture(&src_templ, src, src_level); 1104 src_view = pipe->create_sampler_view(pipe, src, &src_templ); 1105 1106 /* Copy. */ 1107 util_blitter_copy_texture_view(blitter, dst_view, dst_sample_mask, dstx, 1108 dsty, src_view, src_sample, srcbox, 1109 src->width0, src->height0, PIPE_MASK_RGBAZS); 1110 1111 pipe_surface_reference(&dst_view, NULL); 1112 pipe_sampler_view_reference(&src_view, NULL); 1113} 1114 1115void util_blitter_copy_texture_view(struct blitter_context *blitter, 1116 struct pipe_surface *dst, 1117 unsigned dst_sample_mask, 1118 unsigned dstx, unsigned dsty, 1119 struct pipe_sampler_view *src, 1120 unsigned src_sample, 1121 const struct pipe_box *srcbox, 1122 unsigned src_width0, unsigned src_height0, 1123 unsigned mask) 1124{ 1125 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 1126 struct pipe_context *pipe = ctx->base.pipe; 1127 struct pipe_framebuffer_state fb_state; 1128 enum pipe_texture_target src_target = src->texture->target; 1129 int abs_width = abs(srcbox->width); 1130 int abs_height = abs(srcbox->height); 1131 boolean blit_stencil, blit_depth; 1132 const struct util_format_description *src_desc = 1133 util_format_description(src->format); 1134 1135 blit_depth = util_format_has_depth(src_desc) && (mask & PIPE_MASK_Z); 1136 blit_stencil = util_format_has_stencil(src_desc) && (mask & PIPE_MASK_S); 1137 1138 /* If you want a fallback for stencil copies, 1139 * use util_blitter_copy_texture. */ 1140 if (blit_stencil && !ctx->has_stencil_export) { 1141 blit_stencil = FALSE; 1142 1143 if (!blit_depth) 1144 return; 1145 } 1146 1147 /* Sanity checks. */ 1148 if (dst->texture == src->texture && 1149 dst->u.tex.level == src->u.tex.first_level) { 1150 assert(!is_overlap(dstx, dsty, 0, srcbox)); 1151 } 1152 /* XXX should handle 3d regions */ 1153 assert(srcbox->depth == 1); 1154 1155 /* Check whether the states are properly saved. */ 1156 blitter_set_running_flag(ctx); 1157 blitter_check_saved_vertex_states(ctx); 1158 blitter_check_saved_fragment_states(ctx); 1159 blitter_check_saved_textures(ctx); 1160 blitter_check_saved_fb_state(ctx); 1161 1162 /* Initialize framebuffer state. */ 1163 fb_state.width = dst->width; 1164 fb_state.height = dst->height; 1165 1166 if (blit_depth || blit_stencil) { 1167 pipe->bind_blend_state(pipe, ctx->blend_keep_color); 1168 1169 if (blit_depth && blit_stencil) { 1170 pipe->bind_depth_stencil_alpha_state(pipe, 1171 ctx->dsa_write_depth_stencil); 1172 pipe->bind_fs_state(pipe, 1173 blitter_get_fs_texfetch_depthstencil(ctx, src->texture)); 1174 } else if (blit_depth) { 1175 pipe->bind_depth_stencil_alpha_state(pipe, 1176 ctx->dsa_write_depth_keep_stencil); 1177 pipe->bind_fs_state(pipe, 1178 blitter_get_fs_texfetch_depth(ctx, src->texture)); 1179 } else { /* is_stencil */ 1180 pipe->bind_depth_stencil_alpha_state(pipe, 1181 ctx->dsa_keep_depth_write_stencil); 1182 pipe->bind_fs_state(pipe, 1183 blitter_get_fs_texfetch_stencil(ctx, src->texture)); 1184 } 1185 1186 fb_state.nr_cbufs = 0; 1187 fb_state.zsbuf = dst; 1188 } else { 1189 pipe->bind_blend_state(pipe, ctx->blend_write_color); 1190 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 1191 pipe->bind_fs_state(pipe, 1192 blitter_get_fs_texfetch_col(ctx, src->texture)); 1193 1194 fb_state.nr_cbufs = 1; 1195 fb_state.cbufs[0] = dst; 1196 fb_state.zsbuf = 0; 1197 } 1198 1199 if (blit_depth && blit_stencil) { 1200 /* Setup two samplers, one for depth and the other one for stencil. */ 1201 struct pipe_sampler_view templ; 1202 struct pipe_sampler_view *views[2]; 1203 void *samplers[2] = {ctx->sampler_state, ctx->sampler_state}; 1204 1205 templ = *src; 1206 templ.format = util_format_stencil_only(templ.format); 1207 assert(templ.format != PIPE_FORMAT_NONE); 1208 1209 views[0] = src; 1210 views[1] = pipe->create_sampler_view(pipe, src->texture, &templ); 1211 1212 pipe->set_fragment_sampler_views(pipe, 2, views); 1213 pipe->bind_fragment_sampler_states(pipe, 2, samplers); 1214 1215 pipe_sampler_view_reference(&views[1], NULL); 1216 } else if (blit_stencil) { 1217 /* Set a stencil-only sampler view for it not to sample depth instead. */ 1218 struct pipe_sampler_view templ; 1219 struct pipe_sampler_view *view; 1220 1221 templ = *src; 1222 templ.format = util_format_stencil_only(templ.format); 1223 assert(templ.format != PIPE_FORMAT_NONE); 1224 1225 view = pipe->create_sampler_view(pipe, src->texture, &templ); 1226 1227 pipe->set_fragment_sampler_views(pipe, 1, &view); 1228 pipe->bind_fragment_sampler_states(pipe, 1, &ctx->sampler_state); 1229 1230 pipe_sampler_view_reference(&view, NULL); 1231 } else { 1232 pipe->set_fragment_sampler_views(pipe, 1, &src); 1233 pipe->bind_fragment_sampler_states(pipe, 1, &ctx->sampler_state); 1234 } 1235 1236 pipe->bind_vertex_elements_state(pipe, ctx->velem_state); 1237 pipe->set_framebuffer_state(pipe, &fb_state); 1238 pipe->set_sample_mask(pipe, dst_sample_mask); 1239 1240 blitter_set_common_draw_rect_state(ctx); 1241 blitter_set_dst_dimensions(ctx, dst->width, dst->height); 1242 1243 if ((src_target == PIPE_TEXTURE_1D || 1244 src_target == PIPE_TEXTURE_2D || 1245 src_target == PIPE_TEXTURE_RECT) && 1246 src->texture->nr_samples <= 1) { 1247 /* Draw the quad with the draw_rectangle callback. */ 1248 1249 /* Set texture coordinates. - use a pipe color union 1250 * for interface purposes. 1251 * XXX pipe_color_union is a wrong name since we use that to set 1252 * texture coordinates too. 1253 */ 1254 union pipe_color_union coord; 1255 get_texcoords(src, src_width0, src_height0, srcbox->x, srcbox->y, 1256 srcbox->x+srcbox->width, srcbox->y+srcbox->height, coord.f); 1257 1258 /* Draw. */ 1259 blitter->draw_rectangle(blitter, dstx, dsty, dstx+abs_width, dsty+abs_height, 0, 1260 UTIL_BLITTER_ATTRIB_TEXCOORD, &coord); 1261 } else { 1262 /* Draw the quad with the generic codepath. */ 1263 blitter_set_texcoords(ctx, src, src_width0, src_height0, srcbox->z, 1264 src_sample, 1265 srcbox->x, srcbox->y, 1266 srcbox->x + srcbox->width, srcbox->y + srcbox->height); 1267 blitter_draw(ctx, dstx, dsty, dstx+abs_width, dsty+abs_height, 0); 1268 } 1269 1270 blitter_restore_vertex_states(ctx); 1271 blitter_restore_fragment_states(ctx); 1272 blitter_restore_textures(ctx); 1273 blitter_restore_fb_state(ctx); 1274 blitter_unset_running_flag(ctx); 1275} 1276 1277/* Clear a region of a color surface to a constant value. */ 1278void util_blitter_clear_render_target(struct blitter_context *blitter, 1279 struct pipe_surface *dstsurf, 1280 const union pipe_color_union *color, 1281 unsigned dstx, unsigned dsty, 1282 unsigned width, unsigned height) 1283{ 1284 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 1285 struct pipe_context *pipe = ctx->base.pipe; 1286 struct pipe_framebuffer_state fb_state; 1287 1288 assert(dstsurf->texture); 1289 if (!dstsurf->texture) 1290 return; 1291 1292 /* check the saved state */ 1293 blitter_set_running_flag(ctx); 1294 blitter_check_saved_vertex_states(ctx); 1295 blitter_check_saved_fragment_states(ctx); 1296 blitter_check_saved_fb_state(ctx); 1297 1298 /* bind states */ 1299 pipe->bind_blend_state(pipe, ctx->blend_write_color); 1300 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 1301 pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 1, FALSE)); 1302 pipe->bind_vertex_elements_state(pipe, ctx->velem_state); 1303 1304 /* set a framebuffer state */ 1305 fb_state.width = dstsurf->width; 1306 fb_state.height = dstsurf->height; 1307 fb_state.nr_cbufs = 1; 1308 fb_state.cbufs[0] = dstsurf; 1309 fb_state.zsbuf = 0; 1310 pipe->set_framebuffer_state(pipe, &fb_state); 1311 pipe->set_sample_mask(pipe, ~0); 1312 1313 blitter_set_common_draw_rect_state(ctx); 1314 blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height); 1315 blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, 0, 1316 UTIL_BLITTER_ATTRIB_COLOR, color); 1317 1318 blitter_restore_vertex_states(ctx); 1319 blitter_restore_fragment_states(ctx); 1320 blitter_restore_fb_state(ctx); 1321 blitter_unset_running_flag(ctx); 1322} 1323 1324/* Clear a region of a depth stencil surface. */ 1325void util_blitter_clear_depth_stencil(struct blitter_context *blitter, 1326 struct pipe_surface *dstsurf, 1327 unsigned clear_flags, 1328 double depth, 1329 unsigned stencil, 1330 unsigned dstx, unsigned dsty, 1331 unsigned width, unsigned height) 1332{ 1333 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 1334 struct pipe_context *pipe = ctx->base.pipe; 1335 struct pipe_framebuffer_state fb_state; 1336 struct pipe_stencil_ref sr = { { 0 } }; 1337 1338 assert(dstsurf->texture); 1339 if (!dstsurf->texture) 1340 return; 1341 1342 /* check the saved state */ 1343 blitter_set_running_flag(ctx); 1344 blitter_check_saved_vertex_states(ctx); 1345 blitter_check_saved_fragment_states(ctx); 1346 blitter_check_saved_fb_state(ctx); 1347 1348 /* bind states */ 1349 pipe->bind_blend_state(pipe, ctx->blend_keep_color); 1350 if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) { 1351 sr.ref_value[0] = stencil & 0xff; 1352 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil); 1353 pipe->set_stencil_ref(pipe, &sr); 1354 } 1355 else if (clear_flags & PIPE_CLEAR_DEPTH) { 1356 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil); 1357 } 1358 else if (clear_flags & PIPE_CLEAR_STENCIL) { 1359 sr.ref_value[0] = stencil & 0xff; 1360 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil); 1361 pipe->set_stencil_ref(pipe, &sr); 1362 } 1363 else 1364 /* hmm that should be illegal probably, or make it a no-op somewhere */ 1365 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 1366 1367 pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 0, FALSE)); 1368 pipe->bind_vertex_elements_state(pipe, ctx->velem_state); 1369 1370 /* set a framebuffer state */ 1371 fb_state.width = dstsurf->width; 1372 fb_state.height = dstsurf->height; 1373 fb_state.nr_cbufs = 0; 1374 fb_state.cbufs[0] = 0; 1375 fb_state.zsbuf = dstsurf; 1376 pipe->set_framebuffer_state(pipe, &fb_state); 1377 pipe->set_sample_mask(pipe, ~0); 1378 1379 blitter_set_common_draw_rect_state(ctx); 1380 blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height); 1381 blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, depth, 1382 UTIL_BLITTER_ATTRIB_NONE, NULL); 1383 1384 blitter_restore_vertex_states(ctx); 1385 blitter_restore_fragment_states(ctx); 1386 blitter_restore_fb_state(ctx); 1387 blitter_unset_running_flag(ctx); 1388} 1389 1390/* draw a rectangle across a region using a custom dsa stage - for r600g */ 1391void util_blitter_custom_depth_stencil(struct blitter_context *blitter, 1392 struct pipe_surface *zsurf, 1393 struct pipe_surface *cbsurf, 1394 unsigned sample_mask, 1395 void *dsa_stage, float depth) 1396{ 1397 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 1398 struct pipe_context *pipe = ctx->base.pipe; 1399 struct pipe_framebuffer_state fb_state; 1400 1401 assert(zsurf->texture); 1402 if (!zsurf->texture) 1403 return; 1404 1405 /* check the saved state */ 1406 blitter_set_running_flag(ctx); 1407 blitter_check_saved_vertex_states(ctx); 1408 blitter_check_saved_fragment_states(ctx); 1409 blitter_check_saved_fb_state(ctx); 1410 1411 /* bind states */ 1412 pipe->bind_blend_state(pipe, ctx->blend_write_color); 1413 pipe->bind_depth_stencil_alpha_state(pipe, dsa_stage); 1414 pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 0, FALSE)); 1415 pipe->bind_vertex_elements_state(pipe, ctx->velem_state); 1416 1417 /* set a framebuffer state */ 1418 fb_state.width = zsurf->width; 1419 fb_state.height = zsurf->height; 1420 fb_state.nr_cbufs = 1; 1421 if (cbsurf) { 1422 fb_state.cbufs[0] = cbsurf; 1423 fb_state.nr_cbufs = 1; 1424 } else { 1425 fb_state.cbufs[0] = NULL; 1426 fb_state.nr_cbufs = 0; 1427 } 1428 fb_state.zsbuf = zsurf; 1429 pipe->set_framebuffer_state(pipe, &fb_state); 1430 pipe->set_sample_mask(pipe, sample_mask); 1431 1432 blitter_set_common_draw_rect_state(ctx); 1433 blitter_set_dst_dimensions(ctx, zsurf->width, zsurf->height); 1434 blitter->draw_rectangle(blitter, 0, 0, zsurf->width, zsurf->height, depth, 1435 UTIL_BLITTER_ATTRIB_NONE, NULL); 1436 1437 blitter_restore_vertex_states(ctx); 1438 blitter_restore_fragment_states(ctx); 1439 blitter_restore_fb_state(ctx); 1440 blitter_unset_running_flag(ctx); 1441} 1442 1443void util_blitter_copy_buffer(struct blitter_context *blitter, 1444 struct pipe_resource *dst, 1445 unsigned dstx, 1446 struct pipe_resource *src, 1447 unsigned srcx, 1448 unsigned size) 1449{ 1450 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 1451 struct pipe_context *pipe = ctx->base.pipe; 1452 struct pipe_vertex_buffer vb; 1453 struct pipe_stream_output_target *so_target; 1454 1455 if (srcx >= src->width0 || 1456 dstx >= dst->width0) { 1457 return; 1458 } 1459 if (srcx + size > src->width0) { 1460 size = src->width0 - srcx; 1461 } 1462 if (dstx + size > dst->width0) { 1463 size = dst->width0 - dstx; 1464 } 1465 1466 /* Drivers not capable of Stream Out should not call this function 1467 * in the first place. */ 1468 assert(ctx->has_stream_out); 1469 1470 /* Some alignment is required. */ 1471 if (srcx % 4 != 0 || dstx % 4 != 0 || size % 4 != 0 || 1472 !ctx->has_stream_out) { 1473 struct pipe_box box; 1474 u_box_1d(srcx, size, &box); 1475 util_resource_copy_region(pipe, dst, 0, dstx, 0, 0, src, 0, &box); 1476 return; 1477 } 1478 1479 blitter_set_running_flag(ctx); 1480 blitter_check_saved_vertex_states(ctx); 1481 1482 vb.buffer = src; 1483 vb.buffer_offset = srcx; 1484 vb.stride = 4; 1485 1486 pipe->set_vertex_buffers(pipe, 1, &vb); 1487 pipe->bind_vertex_elements_state(pipe, ctx->velem_state_readbuf); 1488 pipe->bind_vs_state(pipe, ctx->vs_pos_only); 1489 if (ctx->has_geometry_shader) 1490 pipe->bind_gs_state(pipe, NULL); 1491 pipe->bind_rasterizer_state(pipe, ctx->rs_discard_state); 1492 1493 so_target = pipe->create_stream_output_target(pipe, dst, dstx, size); 1494 pipe->set_stream_output_targets(pipe, 1, &so_target, 0); 1495 1496 util_draw_arrays(pipe, PIPE_PRIM_POINTS, 0, size / 4); 1497 1498 blitter_restore_vertex_states(ctx); 1499 blitter_unset_running_flag(ctx); 1500 pipe_so_target_reference(&so_target, NULL); 1501} 1502 1503/* probably radeon specific */ 1504void util_blitter_custom_resolve_color(struct blitter_context *blitter, 1505 struct pipe_resource *dst, 1506 unsigned dst_level, 1507 unsigned dst_layer, 1508 struct pipe_resource *src, 1509 unsigned src_layer, 1510 unsigned sample_mask, 1511 void *custom_blend) 1512{ 1513 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 1514 struct pipe_context *pipe = ctx->base.pipe; 1515 struct pipe_framebuffer_state fb_state; 1516 struct pipe_surface *srcsurf, *dstsurf, surf_tmpl; 1517 1518 blitter_set_running_flag(ctx); 1519 blitter_check_saved_vertex_states(ctx); 1520 blitter_check_saved_fragment_states(ctx); 1521 1522 /* bind states */ 1523 pipe->bind_blend_state(pipe, custom_blend); 1524 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 1525 pipe->bind_vertex_elements_state(pipe, ctx->velem_state); 1526 pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 1, FALSE)); 1527 pipe->set_sample_mask(pipe, sample_mask); 1528 1529 memset(&surf_tmpl, 0, sizeof(surf_tmpl)); 1530 surf_tmpl.format = dst->format; 1531 surf_tmpl.u.tex.level = dst_level; 1532 surf_tmpl.u.tex.first_layer = dst_layer; 1533 surf_tmpl.u.tex.last_layer = dst_layer; 1534 surf_tmpl.usage = PIPE_BIND_RENDER_TARGET; 1535 1536 dstsurf = pipe->create_surface(pipe, dst, &surf_tmpl); 1537 1538 surf_tmpl.u.tex.level = 0; 1539 surf_tmpl.u.tex.first_layer = src_layer; 1540 surf_tmpl.u.tex.last_layer = src_layer; 1541 1542 srcsurf = pipe->create_surface(pipe, src, &surf_tmpl); 1543 1544 /* set a framebuffer state */ 1545 fb_state.width = src->width0; 1546 fb_state.height = src->height0; 1547 fb_state.nr_cbufs = 2; 1548 fb_state.cbufs[0] = srcsurf; 1549 fb_state.cbufs[1] = dstsurf; 1550 fb_state.zsbuf = NULL; 1551 pipe->set_framebuffer_state(pipe, &fb_state); 1552 1553 blitter_set_common_draw_rect_state(ctx); 1554 blitter_set_dst_dimensions(ctx, src->width0, src->height0); 1555 blitter->draw_rectangle(blitter, 0, 0, src->width0, src->height0, 1556 0, 0, NULL); 1557 blitter_restore_fb_state(ctx); 1558 blitter_restore_vertex_states(ctx); 1559 blitter_restore_fragment_states(ctx); 1560 blitter_unset_running_flag(ctx); 1561 1562 pipe_surface_reference(&srcsurf, NULL); 1563 pipe_surface_reference(&dstsurf, NULL); 1564} 1565 1566void util_blitter_custom_color(struct blitter_context *blitter, 1567 struct pipe_surface *dstsurf, 1568 void *custom_blend) 1569{ 1570 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 1571 struct pipe_context *pipe = ctx->base.pipe; 1572 struct pipe_framebuffer_state fb_state; 1573 1574 assert(dstsurf->texture); 1575 if (!dstsurf->texture) 1576 return; 1577 1578 /* check the saved state */ 1579 blitter_set_running_flag(ctx); 1580 blitter_check_saved_vertex_states(ctx); 1581 blitter_check_saved_fragment_states(ctx); 1582 blitter_check_saved_fb_state(ctx); 1583 1584 /* bind states */ 1585 pipe->bind_blend_state(pipe, custom_blend); 1586 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 1587 pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 1, FALSE)); 1588 pipe->bind_vertex_elements_state(pipe, ctx->velem_state); 1589 pipe->set_sample_mask(pipe, (1ull << MAX2(1, dstsurf->texture->nr_samples)) - 1); 1590 1591 /* set a framebuffer state */ 1592 fb_state.width = dstsurf->width; 1593 fb_state.height = dstsurf->height; 1594 fb_state.nr_cbufs = 1; 1595 fb_state.cbufs[0] = dstsurf; 1596 fb_state.zsbuf = 0; 1597 pipe->set_framebuffer_state(pipe, &fb_state); 1598 pipe->set_sample_mask(pipe, ~0); 1599 1600 blitter_set_common_draw_rect_state(ctx); 1601 blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height); 1602 blitter->draw_rectangle(blitter, 0, 0, dstsurf->width, dstsurf->height, 1603 0, 0, NULL); 1604 1605 blitter_restore_vertex_states(ctx); 1606 blitter_restore_fragment_states(ctx); 1607 blitter_restore_fb_state(ctx); 1608 blitter_unset_running_flag(ctx); 1609} 1610