summaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/auxiliary/util')
-rw-r--r--src/gallium/auxiliary/util/u_blitter.c234
-rw-r--r--src/gallium/auxiliary/util/u_blitter.h36
2 files changed, 172 insertions, 98 deletions
diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c
index 58a52b3f2de..79853712c9a 100644
--- a/src/gallium/auxiliary/util/u_blitter.c
+++ b/src/gallium/auxiliary/util/u_blitter.c
@@ -263,100 +263,134 @@ void util_blitter_destroy(struct blitter_context *blitter)
FREE(ctx);
}
-static void blitter_check_saved_CSOs(struct blitter_context_priv *ctx)
+static void blitter_set_running_flag(struct blitter_context_priv *ctx)
{
if (ctx->base.running) {
- _debug_printf("u_blitter: Caught recursion on save. "
- "This is a driver bug.\n");
+ _debug_printf("u_blitter:%i: Caught recursion. This is a driver bug.\n",
+ __LINE__);
}
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_rs_state != INVALID_PTR &&
- ctx->base.saved_fs != INVALID_PTR &&
+static void blitter_unset_running_flag(struct blitter_context_priv *ctx)
+{
+ if (!ctx->base.running) {
+ _debug_printf("u_blitter:%i: Caught recursion. This is a driver bug.\n",
+ __LINE__);
+ }
+ ctx->base.running = FALSE;
+}
+
+static void blitter_check_saved_vertex_states(struct blitter_context_priv *ctx)
+{
+ assert(ctx->base.saved_num_vertex_buffers != ~0 &&
+ ctx->base.saved_velem_state != INVALID_PTR &&
ctx->base.saved_vs != INVALID_PTR &&
- ctx->base.saved_velem_state != INVALID_PTR);
+ ctx->base.saved_rs_state != INVALID_PTR);
}
-static void blitter_restore_CSOs(struct blitter_context_priv *ctx)
+static void blitter_restore_vertex_states(struct blitter_context_priv *ctx)
{
struct pipe_context *pipe = ctx->base.pipe;
unsigned i;
- /* restore the state objects which are always required to be saved */
- pipe->bind_rasterizer_state(pipe, ctx->base.saved_rs_state);
- pipe->bind_vs_state(pipe, ctx->base.saved_vs);
+ /* Vertex buffers. */
+ pipe->set_vertex_buffers(pipe,
+ ctx->base.saved_num_vertex_buffers,
+ ctx->base.saved_vertex_buffers);
+
+ for (i = 0; i < ctx->base.saved_num_vertex_buffers; i++) {
+ if (ctx->base.saved_vertex_buffers[i].buffer) {
+ pipe_resource_reference(&ctx->base.saved_vertex_buffers[i].buffer,
+ NULL);
+ }
+ }
+ ctx->base.saved_num_vertex_buffers = ~0;
+
+ /* Vertex elements. */
pipe->bind_vertex_elements_state(pipe, ctx->base.saved_velem_state);
+ ctx->base.saved_velem_state = INVALID_PTR;
- ctx->base.saved_rs_state = INVALID_PTR;
+ /* Vertex shader. */
+ pipe->bind_vs_state(pipe, ctx->base.saved_vs);
ctx->base.saved_vs = INVALID_PTR;
- ctx->base.saved_velem_state = INVALID_PTR;
- /* restore the state objects which are required to be saved for clear/copy
- */
- if (ctx->base.saved_blend_state != INVALID_PTR) {
- pipe->bind_blend_state(pipe, ctx->base.saved_blend_state);
- ctx->base.saved_blend_state = INVALID_PTR;
- }
- if (ctx->base.saved_dsa_state != INVALID_PTR) {
- pipe->bind_depth_stencil_alpha_state(pipe, ctx->base.saved_dsa_state);
- ctx->base.saved_dsa_state = INVALID_PTR;
- }
- if (ctx->base.saved_fs != INVALID_PTR) {
- pipe->bind_fs_state(pipe, ctx->base.saved_fs);
- ctx->base.saved_fs = INVALID_PTR;
- }
+ /* Rasterizer. */
+ pipe->bind_rasterizer_state(pipe, ctx->base.saved_rs_state);
+ ctx->base.saved_rs_state = INVALID_PTR;
+}
+
+static void blitter_check_saved_fragment_states(struct blitter_context_priv *ctx)
+{
+ assert(ctx->base.saved_fs != INVALID_PTR &&
+ ctx->base.saved_dsa_state != INVALID_PTR &&
+ ctx->base.saved_blend_state != INVALID_PTR);
+}
+
+static void blitter_restore_fragment_states(struct blitter_context_priv *ctx)
+{
+ struct pipe_context *pipe = ctx->base.pipe;
+
+ /* Fragment shader. */
+ pipe->bind_fs_state(pipe, ctx->base.saved_fs);
+ ctx->base.saved_fs = INVALID_PTR;
+
+ /* Depth, stencil, alpha. */
+ pipe->bind_depth_stencil_alpha_state(pipe, ctx->base.saved_dsa_state);
+ ctx->base.saved_dsa_state = INVALID_PTR;
+
+ /* Blend state. */
+ pipe->bind_blend_state(pipe, ctx->base.saved_blend_state);
+ ctx->base.saved_blend_state = INVALID_PTR;
+
+ /* Miscellaneous states. */
+ /* XXX check whether these are saved and whether they need to be restored
+ * (depending on the operation) */
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_unreference_framebuffer_state(&ctx->base.saved_fb_state);
- ctx->base.saved_fb_state.nr_cbufs = ~0;
- }
+static void blitter_check_saved_fb_state(struct blitter_context_priv *ctx)
+{
+ assert(ctx->base.saved_fb_state.nr_cbufs != ~0);
+}
- if (ctx->base.saved_num_sampler_states != ~0) {
- pipe->bind_fragment_sampler_states(pipe,
- ctx->base.saved_num_sampler_states,
- ctx->base.saved_sampler_states);
- ctx->base.saved_num_sampler_states = ~0;
- }
+static void blitter_restore_fb_state(struct blitter_context_priv *ctx)
+{
+ struct pipe_context *pipe = ctx->base.pipe;
+
+ pipe->set_framebuffer_state(pipe, &ctx->base.saved_fb_state);
+ util_unreference_framebuffer_state(&ctx->base.saved_fb_state);
+}
- if (ctx->base.saved_num_sampler_views != ~0) {
- pipe->set_fragment_sampler_views(pipe,
- ctx->base.saved_num_sampler_views,
- ctx->base.saved_sampler_views);
+static void blitter_check_saved_textures(struct blitter_context_priv *ctx)
+{
+ assert(ctx->base.saved_num_sampler_states != ~0 &&
+ ctx->base.saved_num_sampler_views != ~0);
+}
- for (i = 0; i < ctx->base.saved_num_sampler_views; i++)
- pipe_sampler_view_reference(&ctx->base.saved_sampler_views[i],
- NULL);
+static void blitter_restore_textures(struct blitter_context_priv *ctx)
+{
+ struct pipe_context *pipe = ctx->base.pipe;
+ unsigned i;
- ctx->base.saved_num_sampler_views = ~0;
- }
+ /* Fragment sampler states. */
+ pipe->bind_fragment_sampler_states(pipe,
+ ctx->base.saved_num_sampler_states,
+ ctx->base.saved_sampler_states);
+ ctx->base.saved_num_sampler_states = ~0;
- if (ctx->base.saved_num_vertex_buffers != ~0) {
- pipe->set_vertex_buffers(pipe,
- ctx->base.saved_num_vertex_buffers,
- ctx->base.saved_vertex_buffers);
+ /* Fragment sampler views. */
+ pipe->set_fragment_sampler_views(pipe,
+ ctx->base.saved_num_sampler_views,
+ ctx->base.saved_sampler_views);
- for (i = 0; i < ctx->base.saved_num_vertex_buffers; i++) {
- if (ctx->base.saved_vertex_buffers[i].buffer) {
- pipe_resource_reference(&ctx->base.saved_vertex_buffers[i].buffer,
- NULL);
- }
- }
- ctx->base.saved_num_vertex_buffers = ~0;
- }
+ for (i = 0; i < ctx->base.saved_num_sampler_views; i++)
+ pipe_sampler_view_reference(&ctx->base.saved_sampler_views[i], NULL);
- if (!ctx->base.running) {
- _debug_printf("u_blitter: Caught recursion on restore. "
- "This is a driver bug.\n");
- }
- ctx->base.running = FALSE;
+ ctx->base.saved_num_sampler_views = ~0;
}
static void blitter_set_rectangle(struct blitter_context_priv *ctx,
@@ -684,9 +718,11 @@ static void util_blitter_clear_custom(struct blitter_context *blitter,
assert(num_cbufs <= PIPE_MAX_COLOR_BUFS);
- blitter_check_saved_CSOs(ctx);
+ blitter_set_running_flag(ctx);
+ blitter_check_saved_vertex_states(ctx);
+ blitter_check_saved_fragment_states(ctx);
- /* bind CSOs */
+ /* bind states */
if (custom_blend) {
pipe->bind_blend_state(pipe, custom_blend);
} else if (clear_buffers & PIPE_CLEAR_COLOR) {
@@ -718,7 +754,10 @@ static void util_blitter_clear_custom(struct blitter_context *blitter,
blitter_set_dst_dimensions(ctx, width, height);
blitter->draw_rectangle(blitter, 0, 0, width, height, depth,
UTIL_BLITTER_ATTRIB_COLOR, color);
- blitter_restore_CSOs(ctx);
+
+ blitter_restore_vertex_states(ctx);
+ blitter_restore_fragment_states(ctx);
+ blitter_unset_running_flag(ctx);
}
void util_blitter_clear(struct blitter_context *blitter,
@@ -817,10 +856,11 @@ void util_blitter_copy_texture(struct blitter_context *blitter,
dstsurf = pipe->create_surface(pipe, dst, &surf_templ);
/* Check whether the states are properly saved. */
- blitter_check_saved_CSOs(ctx);
- assert(blitter->saved_fb_state.nr_cbufs != ~0);
- assert(blitter->saved_num_sampler_views != ~0);
- assert(blitter->saved_num_sampler_states != ~0);
+ blitter_set_running_flag(ctx);
+ blitter_check_saved_vertex_states(ctx);
+ blitter_check_saved_fragment_states(ctx);
+ blitter_check_saved_textures(ctx);
+ blitter_check_saved_fb_state(ctx);
/* Initialize framebuffer state. */
fb_state.width = dstsurf->width;
@@ -918,7 +958,11 @@ void util_blitter_copy_texture(struct blitter_context *blitter,
break;
}
- blitter_restore_CSOs(ctx);
+ blitter_restore_vertex_states(ctx);
+ blitter_restore_fragment_states(ctx);
+ blitter_restore_textures(ctx);
+ blitter_restore_fb_state(ctx);
+ blitter_unset_running_flag(ctx);
pipe_surface_reference(&dstsurf, NULL);
pipe_sampler_view_reference(&view, NULL);
@@ -940,10 +984,12 @@ void util_blitter_clear_render_target(struct blitter_context *blitter,
return;
/* check the saved state */
- blitter_check_saved_CSOs(ctx);
- assert(blitter->saved_fb_state.nr_cbufs != ~0);
+ blitter_set_running_flag(ctx);
+ blitter_check_saved_vertex_states(ctx);
+ blitter_check_saved_fragment_states(ctx);
+ blitter_check_saved_fb_state(ctx);
- /* bind CSOs */
+ /* bind states */
pipe->bind_blend_state(pipe, ctx->blend_write_color);
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
pipe->bind_rasterizer_state(pipe, ctx->rs_state);
@@ -962,7 +1008,11 @@ void util_blitter_clear_render_target(struct blitter_context *blitter,
blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, 0,
UTIL_BLITTER_ATTRIB_COLOR, color);
- blitter_restore_CSOs(ctx);
+
+ blitter_restore_vertex_states(ctx);
+ blitter_restore_fragment_states(ctx);
+ blitter_restore_fb_state(ctx);
+ blitter_unset_running_flag(ctx);
}
/* Clear a region of a depth stencil surface. */
@@ -984,10 +1034,12 @@ void util_blitter_clear_depth_stencil(struct blitter_context *blitter,
return;
/* check the saved state */
- blitter_check_saved_CSOs(ctx);
- assert(blitter->saved_fb_state.nr_cbufs != ~0);
+ blitter_set_running_flag(ctx);
+ blitter_check_saved_vertex_states(ctx);
+ blitter_check_saved_fragment_states(ctx);
+ blitter_check_saved_fb_state(ctx);
- /* bind CSOs */
+ /* bind states */
pipe->bind_blend_state(pipe, ctx->blend_keep_color);
if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) {
sr.ref_value[0] = stencil & 0xff;
@@ -1022,7 +1074,11 @@ void util_blitter_clear_depth_stencil(struct blitter_context *blitter,
blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, depth,
UTIL_BLITTER_ATTRIB_NONE, NULL);
- blitter_restore_CSOs(ctx);
+
+ blitter_restore_vertex_states(ctx);
+ blitter_restore_fragment_states(ctx);
+ blitter_restore_fb_state(ctx);
+ blitter_unset_running_flag(ctx);
}
/* draw a rectangle across a region using a custom dsa stage - for r600g */
@@ -1040,10 +1096,12 @@ void util_blitter_custom_depth_stencil(struct blitter_context *blitter,
return;
/* check the saved state */
- blitter_check_saved_CSOs(ctx);
- assert(blitter->saved_fb_state.nr_cbufs != ~0);
+ blitter_set_running_flag(ctx);
+ blitter_check_saved_vertex_states(ctx);
+ blitter_check_saved_fragment_states(ctx);
+ blitter_check_saved_fb_state(ctx);
- /* bind CSOs */
+ /* bind states */
pipe->bind_blend_state(pipe, ctx->blend_write_color);
pipe->bind_depth_stencil_alpha_state(pipe, dsa_stage);
@@ -1069,5 +1127,9 @@ void util_blitter_custom_depth_stencil(struct blitter_context *blitter,
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);
+
+ blitter_restore_vertex_states(ctx);
+ blitter_restore_fragment_states(ctx);
+ blitter_restore_fb_state(ctx);
+ blitter_unset_running_flag(ctx);
}
diff --git a/src/gallium/auxiliary/util/u_blitter.h b/src/gallium/auxiliary/util/u_blitter.h
index a9ad023644c..9fe7952951d 100644
--- a/src/gallium/auxiliary/util/u_blitter.h
+++ b/src/gallium/auxiliary/util/u_blitter.h
@@ -126,19 +126,21 @@ struct pipe_context *util_blitter_get_pipe(struct blitter_context *blitter)
}
/*
- * These states must be saved before any of the following functions is called:
- * - blend state
- * - depth stencil alpha state
- * - rasterizer state
- * - vertex shader
- * - any other shader??? (XXX)
- * - fragment shader
+ * These states must be saved before any of the following functions are called:
* - vertex buffers
* - vertex elements
+ * - vertex shader
+ * - rasterizer state
*/
/**
* Clear a specified set of currently bound buffers to specified values.
+ *
+ * These states must be saved in the blitter in addition to the state objects
+ * already required to be saved:
+ * - fragment shader
+ * - depth stencil alpha state
+ * - blend state
*/
void util_blitter_clear(struct blitter_context *blitter,
unsigned width, unsigned height,
@@ -155,7 +157,7 @@ void util_blitter_clear_depth_custom(struct blitter_context *blitter,
* Copy a block of pixels from one surface to another.
*
* You can copy from any color format to any other color format provided
- * the former can be sampled and the latter can be rendered to. Otherwise,
+ * the former can be sampled from and the latter can be rendered to. Otherwise,
* a software fallback path is taken and both surfaces must be of the same
* format.
*
@@ -163,14 +165,18 @@ void util_blitter_clear_depth_custom(struct blitter_context *blitter,
* cannot be copied unless you set ignore_stencil to FALSE. In that case,
* a software fallback path is taken and both surfaces must be of the same
* format.
+ * XXX implement hw-accel stencil copy using shader stencil export.
*
* Use pipe_screen->is_format_supported to know your options.
*
* These states must be saved in the blitter in addition to the state objects
* already required to be saved:
- * - framebuffer state
+ * - fragment shader
+ * - depth stencil alpha state
+ * - blend state
* - fragment sampler states
* - fragment sampler textures
+ * - framebuffer state
*/
void util_blitter_copy_texture(struct blitter_context *blitter,
struct pipe_resource *dst,
@@ -186,6 +192,9 @@ void util_blitter_copy_texture(struct blitter_context *blitter,
*
* These states must be saved in the blitter in addition to the state objects
* already required to be saved:
+ * - fragment shader
+ * - depth stencil alpha state
+ * - blend state
* - framebuffer state
*/
void util_blitter_clear_render_target(struct blitter_context *blitter,
@@ -200,6 +209,9 @@ void util_blitter_clear_render_target(struct blitter_context *blitter,
*
* These states must be saved in the blitter in addition to the state objects
* already required to be saved:
+ * - fragment shader
+ * - depth stencil alpha state
+ * - blend state
* - framebuffer state
*/
void util_blitter_clear_depth_stencil(struct blitter_context *blitter,
@@ -220,7 +232,7 @@ void util_blitter_custom_depth_stencil(struct blitter_context *blitter,
* of the util_blitter_{clear, copy_region, fill_region} functions and then
* forgotten.
*
- * CSOs not listed here are not affected by util_blitter. */
+ * States not listed here are not affected by util_blitter. */
static INLINE
void util_blitter_save_blend(struct blitter_context *blitter,
@@ -322,8 +334,8 @@ util_blitter_save_fragment_sampler_views(struct blitter_context *blitter,
static INLINE void
util_blitter_save_vertex_buffers(struct blitter_context *blitter,
- int num_vertex_buffers,
- struct pipe_vertex_buffer *vertex_buffers)
+ int num_vertex_buffers,
+ struct pipe_vertex_buffer *vertex_buffers)
{
assert(num_vertex_buffers <= Elements(blitter->saved_vertex_buffers));