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