u_blitter.c revision 4e28e6f6c777841b9ffe7a7ad1e865e2595f70f9
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 51#define INVALID_PTR ((void*)~0) 52 53struct blitter_context_priv 54{ 55 struct blitter_context base; 56 57 struct pipe_resource *vbuf; /**< quad */ 58 59 float vertices[4][2][4]; /**< {pos, color} or {pos, texcoord} */ 60 61 /* Templates for various state objects. */ 62 struct pipe_sampler_state template_sampler_state; 63 64 /* Constant state objects. */ 65 /* Vertex shaders. */ 66 void *vs; /**< Vertex shader which passes {pos, generic} to the output.*/ 67 68 /* Fragment shaders. */ 69 /* The shader at index i outputs color to color buffers 0,1,...,i-1. */ 70 void *fs_col[PIPE_MAX_COLOR_BUFS+1]; 71 void *fs_col_int[PIPE_MAX_COLOR_BUFS+1]; 72 73 /* FS which outputs a color from a texture, 74 where the index is PIPE_TEXTURE_* to be sampled. */ 75 void *fs_texfetch_col[PIPE_MAX_TEXTURE_TYPES]; 76 77 /* FS which outputs a depth from a texture, 78 where the index is PIPE_TEXTURE_* to be sampled. */ 79 void *fs_texfetch_depth[PIPE_MAX_TEXTURE_TYPES]; 80 81 /* Blend state. */ 82 void *blend_write_color; /**< blend state with writemask of RGBA */ 83 void *blend_keep_color; /**< blend state with writemask of 0 */ 84 85 /* Depth stencil alpha state. */ 86 void *dsa_write_depth_stencil; 87 void *dsa_write_depth_keep_stencil; 88 void *dsa_keep_depth_stencil; 89 void *dsa_keep_depth_write_stencil; 90 91 void *velem_state; 92 void *velem_uint_state; 93 void *velem_sint_state; 94 95 /* Sampler state for clamping to a miplevel. */ 96 void *sampler_state[PIPE_MAX_TEXTURE_LEVELS * 2]; 97 98 /* Rasterizer state. */ 99 void *rs_state; 100 101 /* Viewport state. */ 102 struct pipe_viewport_state viewport; 103 104 /* Clip state. */ 105 struct pipe_clip_state clip; 106 107 /* Destination surface dimensions. */ 108 unsigned dst_width; 109 unsigned dst_height; 110 111 boolean has_geometry_shader; 112}; 113 114static void blitter_draw_rectangle(struct blitter_context *blitter, 115 unsigned x, unsigned y, 116 unsigned width, unsigned height, 117 float depth, 118 enum blitter_attrib_type type, 119 const union pipe_color_union *attrib); 120 121 122struct blitter_context *util_blitter_create(struct pipe_context *pipe) 123{ 124 struct blitter_context_priv *ctx; 125 struct pipe_blend_state blend; 126 struct pipe_depth_stencil_alpha_state dsa; 127 struct pipe_rasterizer_state rs_state; 128 struct pipe_sampler_state *sampler_state; 129 struct pipe_vertex_element velem[2]; 130 unsigned i; 131 132 ctx = CALLOC_STRUCT(blitter_context_priv); 133 if (!ctx) 134 return NULL; 135 136 ctx->base.pipe = pipe; 137 ctx->base.draw_rectangle = blitter_draw_rectangle; 138 139 /* init state objects for them to be considered invalid */ 140 ctx->base.saved_blend_state = INVALID_PTR; 141 ctx->base.saved_dsa_state = INVALID_PTR; 142 ctx->base.saved_rs_state = INVALID_PTR; 143 ctx->base.saved_fs = INVALID_PTR; 144 ctx->base.saved_vs = INVALID_PTR; 145 ctx->base.saved_gs = INVALID_PTR; 146 ctx->base.saved_velem_state = INVALID_PTR; 147 ctx->base.saved_fb_state.nr_cbufs = ~0; 148 ctx->base.saved_num_sampler_views = ~0; 149 ctx->base.saved_num_sampler_states = ~0; 150 ctx->base.saved_num_vertex_buffers = ~0; 151 152 ctx->has_geometry_shader = 153 pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_GEOMETRY, 154 PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0; 155 156 /* blend state objects */ 157 memset(&blend, 0, sizeof(blend)); 158 ctx->blend_keep_color = pipe->create_blend_state(pipe, &blend); 159 160 blend.rt[0].colormask = PIPE_MASK_RGBA; 161 ctx->blend_write_color = pipe->create_blend_state(pipe, &blend); 162 163 /* depth stencil alpha state objects */ 164 memset(&dsa, 0, sizeof(dsa)); 165 ctx->dsa_keep_depth_stencil = 166 pipe->create_depth_stencil_alpha_state(pipe, &dsa); 167 168 dsa.depth.enabled = 1; 169 dsa.depth.writemask = 1; 170 dsa.depth.func = PIPE_FUNC_ALWAYS; 171 ctx->dsa_write_depth_keep_stencil = 172 pipe->create_depth_stencil_alpha_state(pipe, &dsa); 173 174 dsa.stencil[0].enabled = 1; 175 dsa.stencil[0].func = PIPE_FUNC_ALWAYS; 176 dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE; 177 dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE; 178 dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE; 179 dsa.stencil[0].valuemask = 0xff; 180 dsa.stencil[0].writemask = 0xff; 181 ctx->dsa_write_depth_stencil = 182 pipe->create_depth_stencil_alpha_state(pipe, &dsa); 183 184 185 dsa.depth.enabled = 0; 186 dsa.depth.writemask = 0; 187 ctx->dsa_keep_depth_write_stencil = 188 pipe->create_depth_stencil_alpha_state(pipe, &dsa); 189 190 /* sampler state */ 191 sampler_state = &ctx->template_sampler_state; 192 sampler_state->wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 193 sampler_state->wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 194 sampler_state->wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 195 sampler_state->normalized_coords = TRUE; 196 /* The sampler state objects which sample from a specified mipmap level 197 * are created on-demand. */ 198 199 /* rasterizer state */ 200 memset(&rs_state, 0, sizeof(rs_state)); 201 rs_state.cull_face = PIPE_FACE_NONE; 202 rs_state.gl_rasterization_rules = 1; 203 rs_state.flatshade = 1; 204 ctx->rs_state = pipe->create_rasterizer_state(pipe, &rs_state); 205 206 /* vertex elements state */ 207 memset(&velem[0], 0, sizeof(velem[0]) * 2); 208 for (i = 0; i < 2; i++) { 209 velem[i].src_offset = i * 4 * sizeof(float); 210 velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 211 } 212 ctx->velem_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]); 213 214 memset(&velem[0], 0, sizeof(velem[0]) * 2); 215 for (i = 0; i < 2; i++) { 216 velem[i].src_offset = i * 4 * sizeof(float); 217 if (i == 0) { 218 velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 219 } else { 220 velem[i].src_format = PIPE_FORMAT_R32G32B32A32_SINT; 221 } 222 } 223 ctx->velem_sint_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]); 224 225 memset(&velem[0], 0, sizeof(velem[0]) * 2); 226 for (i = 0; i < 2; i++) { 227 velem[i].src_offset = i * 4 * sizeof(float); 228 if (i == 0) { 229 velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 230 } else { 231 velem[i].src_format = PIPE_FORMAT_R32G32B32A32_UINT; 232 } 233 } 234 ctx->velem_uint_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]); 235 /* fragment shaders are created on-demand */ 236 237 /* vertex shader */ 238 { 239 const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, 240 TGSI_SEMANTIC_GENERIC }; 241 const uint semantic_indices[] = { 0, 0 }; 242 ctx->vs = 243 util_make_vertex_passthrough_shader(pipe, 2, semantic_names, 244 semantic_indices); 245 } 246 247 /* set invariant vertex coordinates */ 248 for (i = 0; i < 4; i++) 249 ctx->vertices[i][0][3] = 1; /*v.w*/ 250 251 /* create the vertex buffer */ 252 ctx->vbuf = pipe_user_buffer_create(ctx->base.pipe->screen, 253 ctx->vertices, 254 sizeof(ctx->vertices), 255 PIPE_BIND_VERTEX_BUFFER); 256 257 return &ctx->base; 258} 259 260void util_blitter_destroy(struct blitter_context *blitter) 261{ 262 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 263 struct pipe_context *pipe = blitter->pipe; 264 int i; 265 266 pipe->delete_blend_state(pipe, ctx->blend_write_color); 267 pipe->delete_blend_state(pipe, ctx->blend_keep_color); 268 pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 269 pipe->delete_depth_stencil_alpha_state(pipe, 270 ctx->dsa_write_depth_keep_stencil); 271 pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil); 272 pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil); 273 274 pipe->delete_rasterizer_state(pipe, ctx->rs_state); 275 pipe->delete_vs_state(pipe, ctx->vs); 276 pipe->delete_vertex_elements_state(pipe, ctx->velem_state); 277 pipe->delete_vertex_elements_state(pipe, ctx->velem_sint_state); 278 pipe->delete_vertex_elements_state(pipe, ctx->velem_uint_state); 279 280 for (i = 0; i < PIPE_MAX_TEXTURE_TYPES; i++) { 281 if (ctx->fs_texfetch_col[i]) 282 pipe->delete_fs_state(pipe, ctx->fs_texfetch_col[i]); 283 if (ctx->fs_texfetch_depth[i]) 284 pipe->delete_fs_state(pipe, ctx->fs_texfetch_depth[i]); 285 } 286 287 for (i = 0; i <= PIPE_MAX_COLOR_BUFS; i++) { 288 if (ctx->fs_col[i]) 289 pipe->delete_fs_state(pipe, ctx->fs_col[i]); 290 if (ctx->fs_col_int[i]) 291 pipe->delete_fs_state(pipe, ctx->fs_col_int[i]); 292 } 293 294 for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS * 2; i++) 295 if (ctx->sampler_state[i]) 296 pipe->delete_sampler_state(pipe, ctx->sampler_state[i]); 297 298 pipe_resource_reference(&ctx->vbuf, NULL); 299 FREE(ctx); 300} 301 302static void blitter_set_running_flag(struct blitter_context_priv *ctx) 303{ 304 if (ctx->base.running) { 305 _debug_printf("u_blitter:%i: Caught recursion. This is a driver bug.\n", 306 __LINE__); 307 } 308 ctx->base.running = TRUE; 309} 310 311static void blitter_unset_running_flag(struct blitter_context_priv *ctx) 312{ 313 if (!ctx->base.running) { 314 _debug_printf("u_blitter:%i: Caught recursion. This is a driver bug.\n", 315 __LINE__); 316 } 317 ctx->base.running = FALSE; 318} 319 320static void blitter_check_saved_vertex_states(struct blitter_context_priv *ctx) 321{ 322 assert(ctx->base.saved_num_vertex_buffers != ~0 && 323 ctx->base.saved_velem_state != INVALID_PTR && 324 ctx->base.saved_vs != INVALID_PTR && 325 (!ctx->has_geometry_shader || ctx->base.saved_gs != INVALID_PTR) && 326 ctx->base.saved_rs_state != INVALID_PTR); 327} 328 329static void blitter_restore_vertex_states(struct blitter_context_priv *ctx) 330{ 331 struct pipe_context *pipe = ctx->base.pipe; 332 unsigned i; 333 334 /* Vertex buffers. */ 335 pipe->set_vertex_buffers(pipe, 336 ctx->base.saved_num_vertex_buffers, 337 ctx->base.saved_vertex_buffers); 338 339 for (i = 0; i < ctx->base.saved_num_vertex_buffers; i++) { 340 if (ctx->base.saved_vertex_buffers[i].buffer) { 341 pipe_resource_reference(&ctx->base.saved_vertex_buffers[i].buffer, 342 NULL); 343 } 344 } 345 ctx->base.saved_num_vertex_buffers = ~0; 346 347 /* Vertex elements. */ 348 pipe->bind_vertex_elements_state(pipe, ctx->base.saved_velem_state); 349 ctx->base.saved_velem_state = INVALID_PTR; 350 351 /* Vertex shader. */ 352 pipe->bind_vs_state(pipe, ctx->base.saved_vs); 353 ctx->base.saved_vs = INVALID_PTR; 354 355 /* Geometry shader. */ 356 if (ctx->has_geometry_shader) { 357 pipe->bind_gs_state(pipe, ctx->base.saved_gs); 358 ctx->base.saved_gs = INVALID_PTR; 359 } 360 361 /* Rasterizer. */ 362 pipe->bind_rasterizer_state(pipe, ctx->base.saved_rs_state); 363 ctx->base.saved_rs_state = INVALID_PTR; 364} 365 366static void blitter_check_saved_fragment_states(struct blitter_context_priv *ctx) 367{ 368 assert(ctx->base.saved_fs != INVALID_PTR && 369 ctx->base.saved_dsa_state != INVALID_PTR && 370 ctx->base.saved_blend_state != INVALID_PTR); 371} 372 373static void blitter_restore_fragment_states(struct blitter_context_priv *ctx) 374{ 375 struct pipe_context *pipe = ctx->base.pipe; 376 377 /* Fragment shader. */ 378 pipe->bind_fs_state(pipe, ctx->base.saved_fs); 379 ctx->base.saved_fs = INVALID_PTR; 380 381 /* Depth, stencil, alpha. */ 382 pipe->bind_depth_stencil_alpha_state(pipe, ctx->base.saved_dsa_state); 383 ctx->base.saved_dsa_state = INVALID_PTR; 384 385 /* Blend state. */ 386 pipe->bind_blend_state(pipe, ctx->base.saved_blend_state); 387 ctx->base.saved_blend_state = INVALID_PTR; 388 389 /* Miscellaneous states. */ 390 /* XXX check whether these are saved and whether they need to be restored 391 * (depending on the operation) */ 392 pipe->set_stencil_ref(pipe, &ctx->base.saved_stencil_ref); 393 pipe->set_viewport_state(pipe, &ctx->base.saved_viewport); 394 pipe->set_clip_state(pipe, &ctx->base.saved_clip); 395} 396 397static void blitter_check_saved_fb_state(struct blitter_context_priv *ctx) 398{ 399 assert(ctx->base.saved_fb_state.nr_cbufs != ~0); 400} 401 402static void blitter_restore_fb_state(struct blitter_context_priv *ctx) 403{ 404 struct pipe_context *pipe = ctx->base.pipe; 405 406 pipe->set_framebuffer_state(pipe, &ctx->base.saved_fb_state); 407 util_unreference_framebuffer_state(&ctx->base.saved_fb_state); 408} 409 410static void blitter_check_saved_textures(struct blitter_context_priv *ctx) 411{ 412 assert(ctx->base.saved_num_sampler_states != ~0 && 413 ctx->base.saved_num_sampler_views != ~0); 414} 415 416static void blitter_restore_textures(struct blitter_context_priv *ctx) 417{ 418 struct pipe_context *pipe = ctx->base.pipe; 419 unsigned i; 420 421 /* Fragment sampler states. */ 422 pipe->bind_fragment_sampler_states(pipe, 423 ctx->base.saved_num_sampler_states, 424 ctx->base.saved_sampler_states); 425 ctx->base.saved_num_sampler_states = ~0; 426 427 /* Fragment sampler views. */ 428 pipe->set_fragment_sampler_views(pipe, 429 ctx->base.saved_num_sampler_views, 430 ctx->base.saved_sampler_views); 431 432 for (i = 0; i < ctx->base.saved_num_sampler_views; i++) 433 pipe_sampler_view_reference(&ctx->base.saved_sampler_views[i], NULL); 434 435 ctx->base.saved_num_sampler_views = ~0; 436} 437 438static void blitter_set_rectangle(struct blitter_context_priv *ctx, 439 unsigned x1, unsigned y1, 440 unsigned x2, unsigned y2, 441 float depth) 442{ 443 int i; 444 445 /* set vertex positions */ 446 ctx->vertices[0][0][0] = (float)x1 / ctx->dst_width * 2.0f - 1.0f; /*v0.x*/ 447 ctx->vertices[0][0][1] = (float)y1 / ctx->dst_height * 2.0f - 1.0f; /*v0.y*/ 448 449 ctx->vertices[1][0][0] = (float)x2 / ctx->dst_width * 2.0f - 1.0f; /*v1.x*/ 450 ctx->vertices[1][0][1] = (float)y1 / ctx->dst_height * 2.0f - 1.0f; /*v1.y*/ 451 452 ctx->vertices[2][0][0] = (float)x2 / ctx->dst_width * 2.0f - 1.0f; /*v2.x*/ 453 ctx->vertices[2][0][1] = (float)y2 / ctx->dst_height * 2.0f - 1.0f; /*v2.y*/ 454 455 ctx->vertices[3][0][0] = (float)x1 / ctx->dst_width * 2.0f - 1.0f; /*v3.x*/ 456 ctx->vertices[3][0][1] = (float)y2 / ctx->dst_height * 2.0f - 1.0f; /*v3.y*/ 457 458 for (i = 0; i < 4; i++) 459 ctx->vertices[i][0][2] = depth; /*z*/ 460 461 /* viewport */ 462 ctx->viewport.scale[0] = 0.5f * ctx->dst_width; 463 ctx->viewport.scale[1] = 0.5f * ctx->dst_height; 464 ctx->viewport.scale[2] = 1.0f; 465 ctx->viewport.scale[3] = 1.0f; 466 ctx->viewport.translate[0] = 0.5f * ctx->dst_width; 467 ctx->viewport.translate[1] = 0.5f * ctx->dst_height; 468 ctx->viewport.translate[2] = 0.0f; 469 ctx->viewport.translate[3] = 0.0f; 470 ctx->base.pipe->set_viewport_state(ctx->base.pipe, &ctx->viewport); 471 472 /* clip */ 473 ctx->base.pipe->set_clip_state(ctx->base.pipe, &ctx->clip); 474} 475 476static void blitter_set_clear_color(struct blitter_context_priv *ctx, 477 const union pipe_color_union *color) 478{ 479 int i; 480 481 if (color) { 482 for (i = 0; i < 4; i++) { 483 uint32_t *uiverts = (uint32_t *)ctx->vertices[i][1]; 484 uiverts[0] = color->ui[0]; 485 uiverts[1] = color->ui[1]; 486 uiverts[2] = color->ui[2]; 487 uiverts[3] = color->ui[3]; 488 } 489 } else { 490 for (i = 0; i < 4; i++) { 491 ctx->vertices[i][1][0] = 0; 492 ctx->vertices[i][1][1] = 0; 493 ctx->vertices[i][1][2] = 0; 494 ctx->vertices[i][1][3] = 0; 495 } 496 } 497} 498 499static void get_texcoords(struct pipe_resource *src, 500 unsigned level, 501 unsigned x1, unsigned y1, 502 unsigned x2, unsigned y2, 503 boolean normalized, float out[4]) 504{ 505 if(normalized) 506 { 507 out[0] = x1 / (float)u_minify(src->width0, level); 508 out[1] = y1 / (float)u_minify(src->height0, level); 509 out[2] = x2 / (float)u_minify(src->width0, level); 510 out[3] = y2 / (float)u_minify(src->height0, level); 511 } 512 else 513 { 514 out[0] = x1; 515 out[1] = y1; 516 out[2] = x2; 517 out[3] = y2; 518 } 519} 520 521static void set_texcoords_in_vertices(const float coord[4], 522 float *out, unsigned stride) 523{ 524 out[0] = coord[0]; /*t0.s*/ 525 out[1] = coord[1]; /*t0.t*/ 526 out += stride; 527 out[0] = coord[2]; /*t1.s*/ 528 out[1] = coord[1]; /*t1.t*/ 529 out += stride; 530 out[0] = coord[2]; /*t2.s*/ 531 out[1] = coord[3]; /*t2.t*/ 532 out += stride; 533 out[0] = coord[0]; /*t3.s*/ 534 out[1] = coord[3]; /*t3.t*/ 535} 536 537static void blitter_set_texcoords_2d(struct blitter_context_priv *ctx, 538 struct pipe_resource *src, 539 unsigned level, 540 unsigned x1, unsigned y1, 541 unsigned x2, unsigned y2) 542{ 543 unsigned i; 544 float coord[4]; 545 546 get_texcoords(src, level, x1, y1, x2, y2, TRUE, coord); 547 set_texcoords_in_vertices(coord, &ctx->vertices[0][1][0], 8); 548 549 for (i = 0; i < 4; i++) { 550 ctx->vertices[i][1][2] = 0; /*r*/ 551 ctx->vertices[i][1][3] = 1; /*q*/ 552 } 553} 554 555static void blitter_set_texcoords_3d(struct blitter_context_priv *ctx, 556 struct pipe_resource *src, 557 unsigned level, 558 unsigned zslice, 559 unsigned x1, unsigned y1, 560 unsigned x2, unsigned y2, 561 boolean normalized) 562{ 563 int i; 564 float r = normalized ? zslice / (float)u_minify(src->depth0, level) : zslice; 565 566 blitter_set_texcoords_2d(ctx, src, level, x1, y1, x2, y2); 567 568 for (i = 0; i < 4; i++) 569 ctx->vertices[i][1][2] = r; /*r*/ 570} 571 572static void blitter_set_texcoords_1d_array(struct blitter_context_priv *ctx, 573 struct pipe_resource *src, 574 unsigned level, 575 unsigned zslice, 576 unsigned x1, unsigned x2) 577{ 578 int i; 579 float r = zslice; 580 581 blitter_set_texcoords_2d(ctx, src, level, x1, 0, x2, 0); 582 583 for (i = 0; i < 4; i++) 584 ctx->vertices[i][1][1] = r; /*r*/ 585} 586 587static void blitter_set_texcoords_cube(struct blitter_context_priv *ctx, 588 struct pipe_resource *src, 589 unsigned level, unsigned face, 590 unsigned x1, unsigned y1, 591 unsigned x2, unsigned y2) 592{ 593 int i; 594 float coord[4]; 595 float st[4][2]; 596 597 get_texcoords(src, level, x1, y1, x2, y2, TRUE, coord); 598 set_texcoords_in_vertices(coord, &st[0][0], 2); 599 600 util_map_texcoords2d_onto_cubemap(face, 601 /* pointer, stride in floats */ 602 &st[0][0], 2, 603 &ctx->vertices[0][1][0], 8); 604 605 for (i = 0; i < 4; i++) 606 ctx->vertices[i][1][3] = 1; /*q*/ 607} 608 609static void blitter_set_dst_dimensions(struct blitter_context_priv *ctx, 610 unsigned width, unsigned height) 611{ 612 ctx->dst_width = width; 613 ctx->dst_height = height; 614} 615 616static INLINE 617void **blitter_get_sampler_state(struct blitter_context_priv *ctx, 618 int miplevel, boolean normalized) 619{ 620 struct pipe_context *pipe = ctx->base.pipe; 621 struct pipe_sampler_state *sampler_state = &ctx->template_sampler_state; 622 623 assert(miplevel < PIPE_MAX_TEXTURE_LEVELS); 624 625 /* Create the sampler state on-demand. */ 626 if (!ctx->sampler_state[miplevel * 2 + normalized]) { 627 sampler_state->lod_bias = miplevel; 628 sampler_state->min_lod = miplevel; 629 sampler_state->max_lod = miplevel; 630 sampler_state->normalized_coords = normalized; 631 632 ctx->sampler_state[miplevel * 2 + normalized] = pipe->create_sampler_state(pipe, 633 sampler_state); 634 } 635 636 /* Return void** so that it can be passed to bind_fragment_sampler_states 637 * directly. */ 638 return &ctx->sampler_state[miplevel * 2 + normalized]; 639} 640 641static INLINE 642void *blitter_get_fs_col(struct blitter_context_priv *ctx, unsigned num_cbufs, 643 boolean int_format) 644{ 645 struct pipe_context *pipe = ctx->base.pipe; 646 647 assert(num_cbufs <= PIPE_MAX_COLOR_BUFS); 648 649 if (int_format) { 650 if (!ctx->fs_col_int[num_cbufs]) 651 ctx->fs_col_int[num_cbufs] = 652 util_make_fragment_cloneinput_shader(pipe, num_cbufs, 653 TGSI_SEMANTIC_GENERIC, 654 TGSI_INTERPOLATE_CONSTANT); 655 return ctx->fs_col_int[num_cbufs]; 656 } else { 657 if (!ctx->fs_col[num_cbufs]) 658 ctx->fs_col[num_cbufs] = 659 util_make_fragment_cloneinput_shader(pipe, num_cbufs, 660 TGSI_SEMANTIC_GENERIC, 661 TGSI_INTERPOLATE_LINEAR); 662 return ctx->fs_col[num_cbufs]; 663 } 664} 665 666/** Convert PIPE_TEXTURE_x to TGSI_TEXTURE_x */ 667static unsigned 668pipe_tex_to_tgsi_tex(enum pipe_texture_target pipe_tex_target) 669{ 670 switch (pipe_tex_target) { 671 case PIPE_TEXTURE_1D: 672 return TGSI_TEXTURE_1D; 673 case PIPE_TEXTURE_2D: 674 return TGSI_TEXTURE_2D; 675 case PIPE_TEXTURE_RECT: 676 return TGSI_TEXTURE_RECT; 677 case PIPE_TEXTURE_3D: 678 return TGSI_TEXTURE_3D; 679 case PIPE_TEXTURE_CUBE: 680 return TGSI_TEXTURE_CUBE; 681 case PIPE_TEXTURE_1D_ARRAY: 682 return TGSI_TEXTURE_1D_ARRAY; 683 case PIPE_TEXTURE_2D_ARRAY: 684 return TGSI_TEXTURE_2D_ARRAY; 685 default: 686 assert(0 && "unexpected texture target"); 687 return TGSI_TEXTURE_UNKNOWN; 688 } 689} 690 691 692static INLINE 693void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx, 694 unsigned tex_target) 695{ 696 struct pipe_context *pipe = ctx->base.pipe; 697 698 assert(tex_target < PIPE_MAX_TEXTURE_TYPES); 699 700 /* Create the fragment shader on-demand. */ 701 if (!ctx->fs_texfetch_col[tex_target]) { 702 unsigned tgsi_tex = pipe_tex_to_tgsi_tex(tex_target); 703 704 ctx->fs_texfetch_col[tex_target] = 705 util_make_fragment_tex_shader(pipe, tgsi_tex, TGSI_INTERPOLATE_LINEAR); 706 } 707 708 return ctx->fs_texfetch_col[tex_target]; 709} 710 711static INLINE 712void *blitter_get_fs_texfetch_depth(struct blitter_context_priv *ctx, 713 unsigned tex_target) 714{ 715 struct pipe_context *pipe = ctx->base.pipe; 716 717 assert(tex_target < PIPE_MAX_TEXTURE_TYPES); 718 719 /* Create the fragment shader on-demand. */ 720 if (!ctx->fs_texfetch_depth[tex_target]) { 721 unsigned tgsi_tex = pipe_tex_to_tgsi_tex(tex_target); 722 723 ctx->fs_texfetch_depth[tex_target] = 724 util_make_fragment_tex_shader_writedepth(pipe, tgsi_tex, 725 TGSI_INTERPOLATE_LINEAR); 726 } 727 728 return ctx->fs_texfetch_depth[tex_target]; 729} 730 731static void blitter_draw_rectangle(struct blitter_context *blitter, 732 unsigned x1, unsigned y1, 733 unsigned x2, unsigned y2, 734 float depth, 735 enum blitter_attrib_type type, 736 const union pipe_color_union *attrib) 737{ 738 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 739 740 switch (type) { 741 case UTIL_BLITTER_ATTRIB_COLOR: 742 blitter_set_clear_color(ctx, attrib); 743 break; 744 745 case UTIL_BLITTER_ATTRIB_TEXCOORD: 746 set_texcoords_in_vertices(attrib->f, &ctx->vertices[0][1][0], 8); 747 break; 748 749 default:; 750 } 751 752 blitter_set_rectangle(ctx, x1, y1, x2, y2, depth); 753 ctx->base.pipe->redefine_user_buffer(ctx->base.pipe, ctx->vbuf, 754 0, ctx->vbuf->width0); 755 util_draw_vertex_buffer(ctx->base.pipe, NULL, ctx->vbuf, 0, 756 PIPE_PRIM_TRIANGLE_FAN, 4, 2); 757} 758 759static void util_blitter_clear_custom(struct blitter_context *blitter, 760 unsigned width, unsigned height, 761 unsigned num_cbufs, 762 unsigned clear_buffers, 763 enum pipe_format cbuf_format, 764 const union pipe_color_union *color, 765 double depth, unsigned stencil, 766 void *custom_blend, void *custom_dsa) 767{ 768 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 769 struct pipe_context *pipe = ctx->base.pipe; 770 struct pipe_stencil_ref sr = { { 0 } }; 771 boolean int_format = util_format_is_pure_integer(cbuf_format); 772 assert(num_cbufs <= PIPE_MAX_COLOR_BUFS); 773 774 blitter_set_running_flag(ctx); 775 blitter_check_saved_vertex_states(ctx); 776 blitter_check_saved_fragment_states(ctx); 777 778 /* bind states */ 779 if (custom_blend) { 780 pipe->bind_blend_state(pipe, custom_blend); 781 } else if (clear_buffers & PIPE_CLEAR_COLOR) { 782 pipe->bind_blend_state(pipe, ctx->blend_write_color); 783 } else { 784 pipe->bind_blend_state(pipe, ctx->blend_keep_color); 785 } 786 787 if (custom_dsa) { 788 pipe->bind_depth_stencil_alpha_state(pipe, custom_dsa); 789 } else if ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) { 790 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil); 791 } else if (clear_buffers & PIPE_CLEAR_DEPTH) { 792 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil); 793 } else if (clear_buffers & PIPE_CLEAR_STENCIL) { 794 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil); 795 } else { 796 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 797 } 798 799 sr.ref_value[0] = stencil & 0xff; 800 pipe->set_stencil_ref(pipe, &sr); 801 802 pipe->bind_rasterizer_state(pipe, ctx->rs_state); 803 if (util_format_is_pure_sint(cbuf_format)) { 804 pipe->bind_vertex_elements_state(pipe, ctx->velem_sint_state); 805 } else if (util_format_is_pure_uint(cbuf_format)) { 806 pipe->bind_vertex_elements_state(pipe, ctx->velem_uint_state); 807 } else { 808 pipe->bind_vertex_elements_state(pipe, ctx->velem_state); 809 } 810 pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, num_cbufs, int_format)); 811 pipe->bind_vs_state(pipe, ctx->vs); 812 if (ctx->has_geometry_shader) 813 pipe->bind_gs_state(pipe, NULL); 814 815 blitter_set_dst_dimensions(ctx, width, height); 816 blitter->draw_rectangle(blitter, 0, 0, width, height, depth, 817 UTIL_BLITTER_ATTRIB_COLOR, color); 818 819 blitter_restore_vertex_states(ctx); 820 blitter_restore_fragment_states(ctx); 821 blitter_unset_running_flag(ctx); 822} 823 824void util_blitter_clear(struct blitter_context *blitter, 825 unsigned width, unsigned height, 826 unsigned num_cbufs, 827 unsigned clear_buffers, 828 enum pipe_format cbuf_format, 829 const union pipe_color_union *color, 830 double depth, unsigned stencil) 831{ 832 util_blitter_clear_custom(blitter, width, height, num_cbufs, 833 clear_buffers, cbuf_format, color, depth, stencil, 834 NULL, NULL); 835} 836 837void util_blitter_clear_depth_custom(struct blitter_context *blitter, 838 unsigned width, unsigned height, 839 double depth, void *custom_dsa) 840{ 841 static const union pipe_color_union color; 842 util_blitter_clear_custom(blitter, width, height, 0, 843 0, PIPE_FORMAT_NONE, &color, depth, 0, NULL, custom_dsa); 844} 845 846static 847boolean is_overlap(unsigned sx1, unsigned sx2, unsigned sy1, unsigned sy2, 848 unsigned dx1, unsigned dx2, unsigned dy1, unsigned dy2) 849{ 850 return sx1 < dx2 && sx2 > dx1 && sy1 < dy2 && sy2 > dy1; 851} 852 853void util_blitter_copy_texture(struct blitter_context *blitter, 854 struct pipe_resource *dst, 855 unsigned dstlevel, 856 unsigned dstx, unsigned dsty, unsigned dstz, 857 struct pipe_resource *src, 858 unsigned srclevel, 859 const struct pipe_box *srcbox, 860 boolean ignore_stencil) 861{ 862 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 863 struct pipe_context *pipe = ctx->base.pipe; 864 struct pipe_screen *screen = pipe->screen; 865 struct pipe_surface *dstsurf, surf_templ; 866 struct pipe_framebuffer_state fb_state; 867 struct pipe_sampler_view viewTempl, *view; 868 unsigned bind; 869 unsigned width = srcbox->width; 870 unsigned height = srcbox->height; 871 boolean is_stencil, is_depth; 872 boolean normalized; 873 874 /* Give up if textures are not set. */ 875 assert(dst && src); 876 if (!dst || !src) 877 return; 878 879 /* Sanity checks. */ 880 if (dst == src) { 881 assert(!is_overlap(srcbox->x, srcbox->x + width, srcbox->y, srcbox->y + height, 882 dstx, dstx + width, dsty, dsty + height)); 883 } 884 assert(src->target < PIPE_MAX_TEXTURE_TYPES); 885 /* XXX should handle 3d regions */ 886 assert(srcbox->depth == 1); 887 888 /* Is this a ZS format? */ 889 is_depth = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0; 890 is_stencil = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 1) != 0; 891 892 if (is_depth || is_stencil) 893 bind = PIPE_BIND_DEPTH_STENCIL; 894 else 895 bind = PIPE_BIND_RENDER_TARGET; 896 897 /* Check if we can sample from and render to the surfaces. */ 898 /* (assuming copying a stencil buffer is not possible) */ 899 if ((!ignore_stencil && is_stencil) || 900 !screen->is_format_supported(screen, dst->format, dst->target, 901 dst->nr_samples, bind) || 902 !screen->is_format_supported(screen, src->format, src->target, 903 src->nr_samples, PIPE_BIND_SAMPLER_VIEW)) { 904 ctx->base.running = TRUE; 905 util_resource_copy_region(pipe, dst, dstlevel, dstx, dsty, dstz, 906 src, srclevel, srcbox); 907 ctx->base.running = FALSE; 908 return; 909 } 910 911 /* Get surface. */ 912 memset(&surf_templ, 0, sizeof(surf_templ)); 913 u_surface_default_template(&surf_templ, dst, bind); 914 surf_templ.format = util_format_linear(dst->format); 915 surf_templ.u.tex.level = dstlevel; 916 surf_templ.u.tex.first_layer = dstz; 917 surf_templ.u.tex.last_layer = dstz; 918 dstsurf = pipe->create_surface(pipe, dst, &surf_templ); 919 920 /* Check whether the states are properly saved. */ 921 blitter_set_running_flag(ctx); 922 blitter_check_saved_vertex_states(ctx); 923 blitter_check_saved_fragment_states(ctx); 924 blitter_check_saved_textures(ctx); 925 blitter_check_saved_fb_state(ctx); 926 927 /* Initialize framebuffer state. */ 928 fb_state.width = dstsurf->width; 929 fb_state.height = dstsurf->height; 930 931 if (is_depth) { 932 pipe->bind_blend_state(pipe, ctx->blend_keep_color); 933 pipe->bind_depth_stencil_alpha_state(pipe, 934 ctx->dsa_write_depth_keep_stencil); 935 pipe->bind_fs_state(pipe, 936 blitter_get_fs_texfetch_depth(ctx, src->target)); 937 938 fb_state.nr_cbufs = 0; 939 fb_state.zsbuf = dstsurf; 940 } else { 941 pipe->bind_blend_state(pipe, ctx->blend_write_color); 942 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 943 pipe->bind_fs_state(pipe, 944 blitter_get_fs_texfetch_col(ctx, src->target)); 945 946 fb_state.nr_cbufs = 1; 947 fb_state.cbufs[0] = dstsurf; 948 fb_state.zsbuf = 0; 949 } 950 951 normalized = src->target != PIPE_TEXTURE_RECT; 952 953 /* Initialize sampler view. */ 954 u_sampler_view_default_template(&viewTempl, src, util_format_linear(src->format)); 955 view = pipe->create_sampler_view(pipe, src, &viewTempl); 956 957 /* Set rasterizer state, shaders, and textures. */ 958 pipe->bind_rasterizer_state(pipe, ctx->rs_state); 959 pipe->bind_vs_state(pipe, ctx->vs); 960 if (ctx->has_geometry_shader) 961 pipe->bind_gs_state(pipe, NULL); 962 pipe->bind_fragment_sampler_states(pipe, 1, 963 blitter_get_sampler_state(ctx, srclevel, normalized)); 964 pipe->bind_vertex_elements_state(pipe, ctx->velem_state); 965 pipe->set_fragment_sampler_views(pipe, 1, &view); 966 pipe->set_framebuffer_state(pipe, &fb_state); 967 968 blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height); 969 970 switch (src->target) { 971 /* Draw the quad with the draw_rectangle callback. */ 972 case PIPE_TEXTURE_1D: 973 case PIPE_TEXTURE_2D: 974 case PIPE_TEXTURE_RECT: 975 { 976 /* Set texture coordinates. - use a pipe color union 977 * for interface purposes 978 */ 979 union pipe_color_union coord; 980 get_texcoords(src, srclevel, srcbox->x, srcbox->y, 981 srcbox->x+width, srcbox->y+height, normalized, coord.f); 982 983 /* Draw. */ 984 blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, 0, 985 UTIL_BLITTER_ATTRIB_TEXCOORD, &coord); 986 } 987 break; 988 989 /* Draw the quad with the generic codepath. */ 990 default: 991 /* Set texture coordinates. */ 992 switch (src->target) { 993 case PIPE_TEXTURE_1D_ARRAY: 994 blitter_set_texcoords_1d_array(ctx, src, srclevel, srcbox->y, 995 srcbox->x, srcbox->x + width); 996 break; 997 998 case PIPE_TEXTURE_2D_ARRAY: 999 case PIPE_TEXTURE_3D: 1000 blitter_set_texcoords_3d(ctx, src, srclevel, srcbox->z, 1001 srcbox->x, srcbox->y, 1002 srcbox->x + width, srcbox->y + height, 1003 src->target == PIPE_TEXTURE_3D); 1004 break; 1005 1006 case PIPE_TEXTURE_CUBE: 1007 blitter_set_texcoords_cube(ctx, src, srclevel, srcbox->z, 1008 srcbox->x, srcbox->y, 1009 srcbox->x + width, srcbox->y + height); 1010 break; 1011 1012 default: 1013 assert(0); 1014 } 1015 1016 /* Draw. */ 1017 blitter_set_rectangle(ctx, dstx, dsty, dstx+width, dsty+height, 0); 1018 ctx->base.pipe->redefine_user_buffer(ctx->base.pipe, ctx->vbuf, 1019 0, ctx->vbuf->width0); 1020 util_draw_vertex_buffer(ctx->base.pipe, NULL, ctx->vbuf, 0, 1021 PIPE_PRIM_TRIANGLE_FAN, 4, 2); 1022 break; 1023 } 1024 1025 blitter_restore_vertex_states(ctx); 1026 blitter_restore_fragment_states(ctx); 1027 blitter_restore_textures(ctx); 1028 blitter_restore_fb_state(ctx); 1029 blitter_unset_running_flag(ctx); 1030 1031 pipe_surface_reference(&dstsurf, NULL); 1032 pipe_sampler_view_reference(&view, NULL); 1033} 1034 1035/* Clear a region of a color surface to a constant value. */ 1036void util_blitter_clear_render_target(struct blitter_context *blitter, 1037 struct pipe_surface *dstsurf, 1038 const union pipe_color_union *color, 1039 unsigned dstx, unsigned dsty, 1040 unsigned width, unsigned height) 1041{ 1042 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 1043 struct pipe_context *pipe = ctx->base.pipe; 1044 struct pipe_framebuffer_state fb_state; 1045 1046 assert(dstsurf->texture); 1047 if (!dstsurf->texture) 1048 return; 1049 1050 /* check the saved state */ 1051 blitter_set_running_flag(ctx); 1052 blitter_check_saved_vertex_states(ctx); 1053 blitter_check_saved_fragment_states(ctx); 1054 blitter_check_saved_fb_state(ctx); 1055 1056 /* bind states */ 1057 pipe->bind_blend_state(pipe, ctx->blend_write_color); 1058 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 1059 pipe->bind_rasterizer_state(pipe, ctx->rs_state); 1060 pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 1, FALSE)); 1061 pipe->bind_vs_state(pipe, ctx->vs); 1062 if (ctx->has_geometry_shader) 1063 pipe->bind_gs_state(pipe, NULL); 1064 pipe->bind_vertex_elements_state(pipe, ctx->velem_state); 1065 1066 /* set a framebuffer state */ 1067 fb_state.width = dstsurf->width; 1068 fb_state.height = dstsurf->height; 1069 fb_state.nr_cbufs = 1; 1070 fb_state.cbufs[0] = dstsurf; 1071 fb_state.zsbuf = 0; 1072 pipe->set_framebuffer_state(pipe, &fb_state); 1073 1074 blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height); 1075 blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, 0, 1076 UTIL_BLITTER_ATTRIB_COLOR, color); 1077 1078 blitter_restore_vertex_states(ctx); 1079 blitter_restore_fragment_states(ctx); 1080 blitter_restore_fb_state(ctx); 1081 blitter_unset_running_flag(ctx); 1082} 1083 1084/* Clear a region of a depth stencil surface. */ 1085void util_blitter_clear_depth_stencil(struct blitter_context *blitter, 1086 struct pipe_surface *dstsurf, 1087 unsigned clear_flags, 1088 double depth, 1089 unsigned stencil, 1090 unsigned dstx, unsigned dsty, 1091 unsigned width, unsigned height) 1092{ 1093 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 1094 struct pipe_context *pipe = ctx->base.pipe; 1095 struct pipe_framebuffer_state fb_state; 1096 struct pipe_stencil_ref sr = { { 0 } }; 1097 1098 assert(dstsurf->texture); 1099 if (!dstsurf->texture) 1100 return; 1101 1102 /* check the saved state */ 1103 blitter_set_running_flag(ctx); 1104 blitter_check_saved_vertex_states(ctx); 1105 blitter_check_saved_fragment_states(ctx); 1106 blitter_check_saved_fb_state(ctx); 1107 1108 /* bind states */ 1109 pipe->bind_blend_state(pipe, ctx->blend_keep_color); 1110 if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) { 1111 sr.ref_value[0] = stencil & 0xff; 1112 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil); 1113 pipe->set_stencil_ref(pipe, &sr); 1114 } 1115 else if (clear_flags & PIPE_CLEAR_DEPTH) { 1116 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil); 1117 } 1118 else if (clear_flags & PIPE_CLEAR_STENCIL) { 1119 sr.ref_value[0] = stencil & 0xff; 1120 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil); 1121 pipe->set_stencil_ref(pipe, &sr); 1122 } 1123 else 1124 /* hmm that should be illegal probably, or make it a no-op somewhere */ 1125 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); 1126 1127 pipe->bind_rasterizer_state(pipe, ctx->rs_state); 1128 pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 0, FALSE)); 1129 pipe->bind_vs_state(pipe, ctx->vs); 1130 if (ctx->has_geometry_shader) 1131 pipe->bind_gs_state(pipe, NULL); 1132 pipe->bind_vertex_elements_state(pipe, ctx->velem_state); 1133 1134 /* set a framebuffer state */ 1135 fb_state.width = dstsurf->width; 1136 fb_state.height = dstsurf->height; 1137 fb_state.nr_cbufs = 0; 1138 fb_state.cbufs[0] = 0; 1139 fb_state.zsbuf = dstsurf; 1140 pipe->set_framebuffer_state(pipe, &fb_state); 1141 1142 blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height); 1143 blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, depth, 1144 UTIL_BLITTER_ATTRIB_NONE, NULL); 1145 1146 blitter_restore_vertex_states(ctx); 1147 blitter_restore_fragment_states(ctx); 1148 blitter_restore_fb_state(ctx); 1149 blitter_unset_running_flag(ctx); 1150} 1151 1152/* draw a rectangle across a region using a custom dsa stage - for r600g */ 1153void util_blitter_custom_depth_stencil(struct blitter_context *blitter, 1154 struct pipe_surface *zsurf, 1155 struct pipe_surface *cbsurf, 1156 void *dsa_stage, float depth) 1157{ 1158 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; 1159 struct pipe_context *pipe = ctx->base.pipe; 1160 struct pipe_framebuffer_state fb_state; 1161 1162 assert(zsurf->texture); 1163 if (!zsurf->texture) 1164 return; 1165 1166 /* check the saved state */ 1167 blitter_set_running_flag(ctx); 1168 blitter_check_saved_vertex_states(ctx); 1169 blitter_check_saved_fragment_states(ctx); 1170 blitter_check_saved_fb_state(ctx); 1171 1172 /* bind states */ 1173 pipe->bind_blend_state(pipe, ctx->blend_write_color); 1174 pipe->bind_depth_stencil_alpha_state(pipe, dsa_stage); 1175 1176 pipe->bind_rasterizer_state(pipe, ctx->rs_state); 1177 pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 0, FALSE)); 1178 pipe->bind_vs_state(pipe, ctx->vs); 1179 if (ctx->has_geometry_shader) 1180 pipe->bind_gs_state(pipe, NULL); 1181 pipe->bind_vertex_elements_state(pipe, ctx->velem_state); 1182 1183 /* set a framebuffer state */ 1184 fb_state.width = zsurf->width; 1185 fb_state.height = zsurf->height; 1186 fb_state.nr_cbufs = 1; 1187 if (cbsurf) { 1188 fb_state.cbufs[0] = cbsurf; 1189 fb_state.nr_cbufs = 1; 1190 } else { 1191 fb_state.cbufs[0] = NULL; 1192 fb_state.nr_cbufs = 0; 1193 } 1194 fb_state.zsbuf = zsurf; 1195 pipe->set_framebuffer_state(pipe, &fb_state); 1196 1197 blitter_set_dst_dimensions(ctx, zsurf->width, zsurf->height); 1198 blitter->draw_rectangle(blitter, 0, 0, zsurf->width, zsurf->height, depth, 1199 UTIL_BLITTER_ATTRIB_NONE, NULL); 1200 1201 blitter_restore_vertex_states(ctx); 1202 blitter_restore_fragment_states(ctx); 1203 blitter_restore_fb_state(ctx); 1204 blitter_unset_running_flag(ctx); 1205} 1206