/* Constant state objects. */
/* Vertex shaders. */
- void *vs_col; /**< Vertex shader which passes {pos, color} to the output */
- void *vs_tex; /**< Vertex shader which passes {pos, texcoord} to the output.*/
+ void *vs; /**< Vertex shader which passes {pos, generic} to the output.*/
/* Fragment shaders. */
/* The shader at index i outputs color to color buffers 0,1,...,i-1. */
void *velem_state;
/* Sampler state for clamping to a miplevel. */
- void *sampler_state[PIPE_MAX_TEXTURE_LEVELS];
+ void *sampler_state[PIPE_MAX_TEXTURE_LEVELS * 2];
/* Rasterizer state. */
void *rs_state;
unsigned dst_height;
};
+static void blitter_draw_rectangle(struct blitter_context *blitter,
+ unsigned x, unsigned y,
+ unsigned width, unsigned height,
+ float depth,
+ enum blitter_attrib_type type,
+ const float attrib[4]);
+
+
struct blitter_context *util_blitter_create(struct pipe_context *pipe)
{
struct blitter_context_priv *ctx;
return NULL;
ctx->base.pipe = pipe;
+ ctx->base.draw_rectangle = blitter_draw_rectangle;
/* init state objects for them to be considered invalid */
ctx->base.saved_blend_state = INVALID_PTR;
/* fragment shaders are created on-demand */
- /* vertex shaders */
- {
- const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
- TGSI_SEMANTIC_COLOR };
- const uint semantic_indices[] = { 0, 0 };
- ctx->vs_col =
- util_make_vertex_passthrough_shader(pipe, 2, semantic_names,
- semantic_indices);
- }
+ /* vertex shader */
{
const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
TGSI_SEMANTIC_GENERIC };
const uint semantic_indices[] = { 0, 0 };
- ctx->vs_tex =
+ ctx->vs =
util_make_vertex_passthrough_shader(pipe, 2, semantic_names,
semantic_indices);
}
ctx->vertices[i][0][3] = 1; /*v.w*/
/* create the vertex buffer */
- ctx->vbuf = pipe_buffer_create(ctx->base.pipe->screen,
- PIPE_BIND_VERTEX_BUFFER,
- sizeof(ctx->vertices));
+ ctx->vbuf = pipe_user_buffer_create(ctx->base.pipe->screen,
+ ctx->vertices,
+ sizeof(ctx->vertices),
+ PIPE_BIND_VERTEX_BUFFER);
return &ctx->base;
}
pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
pipe->delete_rasterizer_state(pipe, ctx->rs_state);
- pipe->delete_vs_state(pipe, ctx->vs_col);
- pipe->delete_vs_state(pipe, ctx->vs_tex);
+ pipe->delete_vs_state(pipe, ctx->vs);
pipe->delete_vertex_elements_state(pipe, ctx->velem_state);
for (i = 0; i < PIPE_MAX_TEXTURE_TYPES; i++) {
pipe->delete_fs_state(pipe, ctx->fs_texfetch_depth[i]);
}
- for (i = 0; i <= PIPE_MAX_COLOR_BUFS && ctx->fs_col[i]; i++)
+ for (i = 0; i <= PIPE_MAX_COLOR_BUFS; i++)
if (ctx->fs_col[i])
pipe->delete_fs_state(pipe, ctx->fs_col[i]);
- for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++)
+ for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS * 2; i++)
if (ctx->sampler_state[i])
pipe->delete_sampler_state(pipe, ctx->sampler_state[i]);
static void blitter_check_saved_CSOs(struct blitter_context_priv *ctx)
{
+ if (ctx->base.running) {
+ _debug_printf("u_blitter: Caught recursion on save. "
+ "This is a driver bug.\n");
+ }
+ ctx->base.running = TRUE;
+
/* make sure these CSOs have been saved */
assert(ctx->base.saved_blend_state != INVALID_PTR &&
ctx->base.saved_dsa_state != INVALID_PTR &&
ctx->base.saved_velem_state = INVALID_PTR;
pipe->set_stencil_ref(pipe, &ctx->base.saved_stencil_ref);
-
pipe->set_viewport_state(pipe, &ctx->base.saved_viewport);
pipe->set_clip_state(pipe, &ctx->base.saved_clip);
*/
if (ctx->base.saved_fb_state.nr_cbufs != ~0) {
pipe->set_framebuffer_state(pipe, &ctx->base.saved_fb_state);
- util_assign_framebuffer_state(&ctx->base.saved_fb_state, NULL);
+ util_unreference_framebuffer_state(&ctx->base.saved_fb_state);
ctx->base.saved_fb_state.nr_cbufs = ~0;
}
}
ctx->base.saved_num_vertex_buffers = ~0;
}
+
+ if (!ctx->base.running) {
+ _debug_printf("u_blitter: Caught recursion on restore. "
+ "This is a driver bug.\n");
+ }
+ ctx->base.running = FALSE;
}
static void blitter_set_rectangle(struct blitter_context_priv *ctx,
}
}
-static void get_normalized_texcoords(struct pipe_resource *src,
- struct pipe_subresource subsrc,
- unsigned x1, unsigned y1,
- unsigned x2, unsigned y2,
- float out[4])
+static void get_texcoords(struct pipe_resource *src,
+ unsigned level,
+ unsigned x1, unsigned y1,
+ unsigned x2, unsigned y2,
+ boolean normalized, float out[4])
{
- out[0] = x1 / (float)u_minify(src->width0, subsrc.level);
- out[1] = y1 / (float)u_minify(src->height0, subsrc.level);
- out[2] = x2 / (float)u_minify(src->width0, subsrc.level);
- out[3] = y2 / (float)u_minify(src->height0, subsrc.level);
+ if(normalized)
+ {
+ out[0] = x1 / (float)u_minify(src->width0, level);
+ out[1] = y1 / (float)u_minify(src->height0, level);
+ out[2] = x2 / (float)u_minify(src->width0, level);
+ out[3] = y2 / (float)u_minify(src->height0, level);
+ }
+ else
+ {
+ out[0] = x1;
+ out[1] = y1;
+ out[2] = x2;
+ out[3] = y2;
+ }
}
static void set_texcoords_in_vertices(const float coord[4],
static void blitter_set_texcoords_2d(struct blitter_context_priv *ctx,
struct pipe_resource *src,
- struct pipe_subresource subsrc,
+ unsigned level,
unsigned x1, unsigned y1,
unsigned x2, unsigned y2)
{
unsigned i;
float coord[4];
- get_normalized_texcoords(src, subsrc, x1, y1, x2, y2, coord);
+ get_texcoords(src, level, x1, y1, x2, y2, TRUE, coord);
set_texcoords_in_vertices(coord, &ctx->vertices[0][1][0], 8);
for (i = 0; i < 4; i++) {
static void blitter_set_texcoords_3d(struct blitter_context_priv *ctx,
struct pipe_resource *src,
- struct pipe_subresource subsrc,
+ unsigned level,
unsigned zslice,
unsigned x1, unsigned y1,
unsigned x2, unsigned y2)
{
int i;
- float r = zslice / (float)u_minify(src->depth0, subsrc.level);
+ float r = zslice / (float)u_minify(src->depth0, level);
- blitter_set_texcoords_2d(ctx, src, subsrc, x1, y1, x2, y2);
+ blitter_set_texcoords_2d(ctx, src, level, x1, y1, x2, y2);
for (i = 0; i < 4; i++)
ctx->vertices[i][1][2] = r; /*r*/
static void blitter_set_texcoords_cube(struct blitter_context_priv *ctx,
struct pipe_resource *src,
- struct pipe_subresource subsrc,
+ unsigned level, unsigned face,
unsigned x1, unsigned y1,
unsigned x2, unsigned y2)
{
float coord[4];
float st[4][2];
- get_normalized_texcoords(src, subsrc, x1, y1, x2, y2, coord);
+ get_texcoords(src, level, x1, y1, x2, y2, TRUE, coord);
set_texcoords_in_vertices(coord, &st[0][0], 2);
- util_map_texcoords2d_onto_cubemap(subsrc.face,
+ util_map_texcoords2d_onto_cubemap(face,
/* pointer, stride in floats */
&st[0][0], 2,
&ctx->vertices[0][1][0], 8);
ctx->dst_height = height;
}
-static void blitter_draw_quad(struct blitter_context_priv *ctx)
-{
- struct pipe_context *pipe = ctx->base.pipe;
-
- /* write vertices and draw them */
- pipe_buffer_write(pipe, ctx->vbuf,
- 0, sizeof(ctx->vertices), ctx->vertices);
-
- util_draw_vertex_buffer(pipe, ctx->vbuf, 0, PIPE_PRIM_TRIANGLE_FAN,
- 4, /* verts */
- 2); /* attribs/vert */
-}
-
static INLINE
void **blitter_get_sampler_state(struct blitter_context_priv *ctx,
- int miplevel)
+ int miplevel, boolean normalized)
{
struct pipe_context *pipe = ctx->base.pipe;
struct pipe_sampler_state *sampler_state = &ctx->template_sampler_state;
assert(miplevel < PIPE_MAX_TEXTURE_LEVELS);
/* Create the sampler state on-demand. */
- if (!ctx->sampler_state[miplevel]) {
+ if (!ctx->sampler_state[miplevel * 2 + normalized]) {
sampler_state->lod_bias = miplevel;
sampler_state->min_lod = miplevel;
sampler_state->max_lod = miplevel;
+ sampler_state->normalized_coords = normalized;
- ctx->sampler_state[miplevel] = pipe->create_sampler_state(pipe,
+ ctx->sampler_state[miplevel * 2 + normalized] = pipe->create_sampler_state(pipe,
sampler_state);
}
/* Return void** so that it can be passed to bind_fragment_sampler_states
* directly. */
- return &ctx->sampler_state[miplevel];
+ return &ctx->sampler_state[miplevel * 2 + normalized];
}
static INLINE
if (!ctx->fs_col[num_cbufs])
ctx->fs_col[num_cbufs] =
- util_make_fragment_clonecolor_shader(pipe, num_cbufs);
+ util_make_fragment_cloneinput_shader(pipe, num_cbufs,
+ TGSI_SEMANTIC_GENERIC,
+ TGSI_INTERPOLATE_LINEAR);
return ctx->fs_col[num_cbufs];
}
return TGSI_TEXTURE_1D;
case PIPE_TEXTURE_2D:
return TGSI_TEXTURE_2D;
+ case PIPE_TEXTURE_RECT:
+ return TGSI_TEXTURE_RECT;
case PIPE_TEXTURE_3D:
return TGSI_TEXTURE_3D;
case PIPE_TEXTURE_CUBE:
return ctx->fs_texfetch_depth[tex_target];
}
-void util_blitter_clear(struct blitter_context *blitter,
- unsigned width, unsigned height,
- unsigned num_cbufs,
- unsigned clear_buffers,
- const float *rgba,
- double depth, unsigned stencil)
+static void blitter_draw_rectangle(struct blitter_context *blitter,
+ unsigned x1, unsigned y1,
+ unsigned x2, unsigned y2,
+ float depth,
+ enum blitter_attrib_type type,
+ const float attrib[4])
+{
+ struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
+
+ switch (type) {
+ case UTIL_BLITTER_ATTRIB_COLOR:
+ blitter_set_clear_color(ctx, attrib);
+ break;
+
+ case UTIL_BLITTER_ATTRIB_TEXCOORD:
+ set_texcoords_in_vertices(attrib, &ctx->vertices[0][1][0], 8);
+ break;
+
+ default:;
+ }
+
+ blitter_set_rectangle(ctx, x1, y1, x2, y2, depth);
+ ctx->base.pipe->redefine_user_buffer(ctx->base.pipe, ctx->vbuf,
+ 0, ctx->vbuf->width0);
+ util_draw_vertex_buffer(ctx->base.pipe, NULL, ctx->vbuf, 0,
+ PIPE_PRIM_TRIANGLE_FAN, 4, 2);
+}
+
+static void util_blitter_clear_custom(struct blitter_context *blitter,
+ unsigned width, unsigned height,
+ unsigned num_cbufs,
+ unsigned clear_buffers,
+ const float *rgba,
+ double depth, unsigned stencil,
+ void *custom_blend, void *custom_dsa)
{
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
struct pipe_context *pipe = ctx->base.pipe;
blitter_check_saved_CSOs(ctx);
/* bind CSOs */
- if (clear_buffers & PIPE_CLEAR_COLOR)
+ if (custom_blend) {
+ pipe->bind_blend_state(pipe, custom_blend);
+ } else if (clear_buffers & PIPE_CLEAR_COLOR) {
pipe->bind_blend_state(pipe, ctx->blend_write_color);
- else
+ } else {
pipe->bind_blend_state(pipe, ctx->blend_keep_color);
+ }
- if ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) {
- sr.ref_value[0] = stencil & 0xff;
+ if (custom_dsa) {
+ pipe->bind_depth_stencil_alpha_state(pipe, custom_dsa);
+ } else if ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) {
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
- pipe->set_stencil_ref(pipe, &sr);
- }
- else if (clear_buffers & PIPE_CLEAR_DEPTH) {
+ } else if (clear_buffers & PIPE_CLEAR_DEPTH) {
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil);
- }
- else if (clear_buffers & PIPE_CLEAR_STENCIL) {
- sr.ref_value[0] = stencil & 0xff;
+ } else if (clear_buffers & PIPE_CLEAR_STENCIL) {
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
- pipe->set_stencil_ref(pipe, &sr);
- }
- else
+ } else {
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
+ }
+
+ sr.ref_value[0] = stencil & 0xff;
+ pipe->set_stencil_ref(pipe, &sr);
pipe->bind_rasterizer_state(pipe, ctx->rs_state);
pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, num_cbufs));
- pipe->bind_vs_state(pipe, ctx->vs_col);
+ pipe->bind_vs_state(pipe, ctx->vs);
blitter_set_dst_dimensions(ctx, width, height);
- blitter_set_clear_color(ctx, rgba);
- blitter_set_rectangle(ctx, 0, 0, width, height, depth);
- blitter_draw_quad(ctx);
+ blitter->draw_rectangle(blitter, 0, 0, width, height, depth,
+ UTIL_BLITTER_ATTRIB_COLOR, rgba);
blitter_restore_CSOs(ctx);
}
+void util_blitter_clear(struct blitter_context *blitter,
+ unsigned width, unsigned height,
+ unsigned num_cbufs,
+ unsigned clear_buffers,
+ const float *rgba,
+ double depth, unsigned stencil)
+{
+ util_blitter_clear_custom(blitter, width, height, num_cbufs,
+ clear_buffers, rgba, depth, stencil,
+ NULL, NULL);
+}
+
+void util_blitter_clear_depth_custom(struct blitter_context *blitter,
+ unsigned width, unsigned height,
+ double depth, void *custom_dsa)
+{
+ const float rgba[4] = {0, 0, 0, 0};
+ util_blitter_clear_custom(blitter, width, height, 0,
+ 0, rgba, depth, 0, NULL, custom_dsa);
+}
+
static
boolean is_overlap(unsigned sx1, unsigned sx2, unsigned sy1, unsigned sy2,
unsigned dx1, unsigned dx2, unsigned dy1, unsigned dy2)
void util_blitter_copy_region(struct blitter_context *blitter,
struct pipe_resource *dst,
- struct pipe_subresource subdst,
+ unsigned dstlevel,
unsigned dstx, unsigned dsty, unsigned dstz,
struct pipe_resource *src,
- struct pipe_subresource subsrc,
- unsigned srcx, unsigned srcy, unsigned srcz,
- unsigned width, unsigned height,
+ unsigned srclevel,
+ const struct pipe_box *srcbox,
boolean ignore_stencil)
{
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
struct pipe_context *pipe = ctx->base.pipe;
struct pipe_screen *screen = pipe->screen;
- struct pipe_surface *dstsurf;
+ struct pipe_surface *dstsurf, surf_templ;
struct pipe_framebuffer_state fb_state;
struct pipe_sampler_view viewTempl, *view;
unsigned bind;
+ unsigned width = srcbox->width;
+ unsigned height = srcbox->height;
boolean is_stencil, is_depth;
+ boolean normalized;
/* Give up if textures are not set. */
assert(dst && src);
/* Sanity checks. */
if (dst == src) {
- assert(!is_overlap(srcx, srcx + width, srcy, srcy + height,
+ assert(!is_overlap(srcbox->x, srcbox->x + width, srcbox->y, srcbox->y + height,
dstx, dstx + width, dsty, dsty + height));
- } else {
- assert(dst->format == src->format);
}
assert(src->target < PIPE_MAX_TEXTURE_TYPES);
+ /* XXX should handle 3d regions */
+ assert(srcbox->depth == 1);
/* Is this a ZS format? */
is_depth = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0;
dst->nr_samples, bind, 0) ||
!screen->is_format_supported(screen, src->format, src->target,
src->nr_samples, PIPE_BIND_SAMPLER_VIEW, 0)) {
- util_resource_copy_region(pipe, dst, subdst, dstx, dsty, dstz,
- src, subsrc, srcx, srcy, srcz, width, height);
+ ctx->base.running = TRUE;
+ util_resource_copy_region(pipe, dst, dstlevel, dstx, dsty, dstz,
+ src, srclevel, srcbox);
+ ctx->base.running = FALSE;
return;
}
- /* Get surfaces. */
- dstsurf = screen->get_tex_surface(screen, dst,
- subdst.face, subdst.level, dstz,
- bind);
+ /* Get surface. */
+ memset(&surf_templ, 0, sizeof(surf_templ));
+ u_surface_default_template(&surf_templ, dst, bind);
+ surf_templ.u.tex.level = dstlevel;
+ surf_templ.u.tex.first_layer = dstz;
+ surf_templ.u.tex.last_layer = dstz;
+ dstsurf = pipe->create_surface(pipe, dst, &surf_templ);
/* Check whether the states are properly saved. */
blitter_check_saved_CSOs(ctx);
fb_state.zsbuf = 0;
}
+ normalized = src->target != PIPE_TEXTURE_RECT;
+
/* Initialize sampler view. */
u_sampler_view_default_template(&viewTempl, src, src->format);
view = pipe->create_sampler_view(pipe, src, &viewTempl);
/* Set rasterizer state, shaders, and textures. */
pipe->bind_rasterizer_state(pipe, ctx->rs_state);
- pipe->bind_vs_state(pipe, ctx->vs_tex);
+ pipe->bind_vs_state(pipe, ctx->vs);
pipe->bind_fragment_sampler_states(pipe, 1,
- blitter_get_sampler_state(ctx, subsrc.level));
+ blitter_get_sampler_state(ctx, srclevel, normalized));
pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
pipe->set_fragment_sampler_views(pipe, 1, &view);
pipe->set_framebuffer_state(pipe, &fb_state);
- /* Set texture coordinates. */
+ blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
+
switch (src->target) {
+ /* Draw the quad with the draw_rectangle callback. */
case PIPE_TEXTURE_1D:
case PIPE_TEXTURE_2D:
- blitter_set_texcoords_2d(ctx, src, subsrc,
- srcx, srcy, srcx+width, srcy+height);
+ case PIPE_TEXTURE_RECT:
+ {
+ /* Set texture coordinates. */
+ float coord[4];
+ get_texcoords(src, srclevel, srcbox->x, srcbox->y,
+ srcbox->x+width, srcbox->y+height, normalized, coord);
+
+ /* Draw. */
+ blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, 0,
+ UTIL_BLITTER_ATTRIB_TEXCOORD, coord);
+ }
break;
+
+ /* Draw the quad with the generic codepath. */
case PIPE_TEXTURE_3D:
- blitter_set_texcoords_3d(ctx, src, subsrc, srcz,
- srcx, srcy, srcx+width, srcy+height);
- break;
case PIPE_TEXTURE_CUBE:
- blitter_set_texcoords_cube(ctx, src, subsrc,
- srcx, srcy, srcx+width, srcy+height);
+ /* Set texture coordinates. */
+ if (src->target == PIPE_TEXTURE_3D)
+ blitter_set_texcoords_3d(ctx, src, srclevel, srcbox->z,
+ srcbox->x, srcbox->y,
+ srcbox->x + width, srcbox->y + height);
+ else
+ blitter_set_texcoords_cube(ctx, src, srclevel, srcbox->z,
+ srcbox->x, srcbox->y,
+ srcbox->x + width, srcbox->y + height);
+
+ /* Draw. */
+ blitter_set_rectangle(ctx, dstx, dsty, dstx+width, dsty+height, 0);
+ ctx->base.pipe->redefine_user_buffer(ctx->base.pipe, ctx->vbuf,
+ 0, ctx->vbuf->width0);
+ util_draw_vertex_buffer(ctx->base.pipe, NULL, ctx->vbuf, 0,
+ PIPE_PRIM_TRIANGLE_FAN, 4, 2);
break;
+
default:
assert(0);
return;
}
- blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
- blitter_set_rectangle(ctx, dstx, dsty, dstx+width, dsty+height, 0);
- blitter_draw_quad(ctx);
blitter_restore_CSOs(ctx);
pipe_surface_reference(&dstsurf, NULL);
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
pipe->bind_rasterizer_state(pipe, ctx->rs_state);
pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 1));
- pipe->bind_vs_state(pipe, ctx->vs_col);
+ pipe->bind_vs_state(pipe, ctx->vs);
pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
/* set a framebuffer state */
pipe->set_framebuffer_state(pipe, &fb_state);
blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
- blitter_set_clear_color(ctx, rgba);
- blitter_set_rectangle(ctx, dstx, dsty, dstx+width, dsty+height, 0);
- blitter_draw_quad(ctx);
+ blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, 0,
+ UTIL_BLITTER_ATTRIB_COLOR, rgba);
blitter_restore_CSOs(ctx);
}
pipe->bind_rasterizer_state(pipe, ctx->rs_state);
pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 0));
- pipe->bind_vs_state(pipe, ctx->vs_col);
+ pipe->bind_vs_state(pipe, ctx->vs);
pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
/* set a framebuffer state */
pipe->set_framebuffer_state(pipe, &fb_state);
blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
- blitter_set_rectangle(ctx, dstx, dsty, dstx+width, dsty+height, depth);
- blitter_draw_quad(ctx);
+ blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, depth,
+ UTIL_BLITTER_ATTRIB_NONE, NULL);
+ blitter_restore_CSOs(ctx);
+}
+
+/* draw a rectangle across a region using a custom dsa stage - for r600g */
+void util_blitter_custom_depth_stencil(struct blitter_context *blitter,
+ struct pipe_surface *zsurf,
+ struct pipe_surface *cbsurf,
+ void *dsa_stage, float depth)
+{
+ struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
+ struct pipe_context *pipe = ctx->base.pipe;
+ struct pipe_framebuffer_state fb_state;
+
+ assert(zsurf->texture);
+ if (!zsurf->texture)
+ return;
+
+ /* check the saved state */
+ blitter_check_saved_CSOs(ctx);
+ assert(blitter->saved_fb_state.nr_cbufs != ~0);
+
+ /* bind CSOs */
+ pipe->bind_blend_state(pipe, ctx->blend_write_color);
+ pipe->bind_depth_stencil_alpha_state(pipe, dsa_stage);
+
+ pipe->bind_rasterizer_state(pipe, ctx->rs_state);
+ pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 0));
+ pipe->bind_vs_state(pipe, ctx->vs);
+ pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
+
+ /* set a framebuffer state */
+ fb_state.width = zsurf->width;
+ fb_state.height = zsurf->height;
+ fb_state.nr_cbufs = 1;
+ if (cbsurf) {
+ fb_state.cbufs[0] = cbsurf;
+ fb_state.nr_cbufs = 1;
+ } else {
+ fb_state.cbufs[0] = NULL;
+ fb_state.nr_cbufs = 0;
+ }
+ fb_state.zsbuf = zsurf;
+ pipe->set_framebuffer_state(pipe, &fb_state);
+
+ blitter_set_dst_dimensions(ctx, zsurf->width, zsurf->height);
+ blitter->draw_rectangle(blitter, 0, 0, zsurf->width, zsurf->height, depth,
+ UTIL_BLITTER_ATTRIB_NONE, NULL);
blitter_restore_CSOs(ctx);
}