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