From: Marek Olšák Date: Fri, 7 Oct 2011 17:10:41 +0000 (+0200) Subject: u_blitter: cleanup checking for and restoring saved states X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c12c05c198f1cfd63eb52eeeb3c6e22dcb169b32;p=mesa.git u_blitter: cleanup checking for and restoring saved states --- 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));