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