mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-04 18:28:12 +02:00
u_blitter: cleanup checking for and restoring saved states
This commit is contained in:
parent
5baa33a738
commit
c12c05c198
2 changed files with 175 additions and 101 deletions
|
|
@ -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 &&
|
||||
ctx->base.saved_vs != INVALID_PTR &&
|
||||
ctx->base.saved_velem_state != INVALID_PTR);
|
||||
}
|
||||
|
||||
static void blitter_restore_CSOs(struct blitter_context_priv *ctx)
|
||||
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_rs_state != INVALID_PTR);
|
||||
}
|
||||
|
||||
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);
|
||||
pipe->bind_vertex_elements_state(pipe, ctx->base.saved_velem_state);
|
||||
/* Vertex buffers. */
|
||||
pipe->set_vertex_buffers(pipe,
|
||||
ctx->base.saved_num_vertex_buffers,
|
||||
ctx->base.saved_vertex_buffers);
|
||||
|
||||
ctx->base.saved_rs_state = INVALID_PTR;
|
||||
ctx->base.saved_vs = INVALID_PTR;
|
||||
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;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
/* Vertex shader. */
|
||||
pipe->bind_vs_state(pipe, ctx->base.saved_vs);
|
||||
ctx->base.saved_vs = 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;
|
||||
|
||||
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);
|
||||
pipe->set_framebuffer_state(pipe, &ctx->base.saved_fb_state);
|
||||
util_unreference_framebuffer_state(&ctx->base.saved_fb_state);
|
||||
}
|
||||
|
||||
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_check_saved_textures(struct blitter_context_priv *ctx)
|
||||
{
|
||||
assert(ctx->base.saved_num_sampler_states != ~0 &&
|
||||
ctx->base.saved_num_sampler_views != ~0);
|
||||
}
|
||||
|
||||
ctx->base.saved_num_sampler_views = ~0;
|
||||
}
|
||||
static void blitter_restore_textures(struct blitter_context_priv *ctx)
|
||||
{
|
||||
struct pipe_context *pipe = ctx->base.pipe;
|
||||
unsigned i;
|
||||
|
||||
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 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;
|
||||
|
||||
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;
|
||||
}
|
||||
/* Fragment sampler views. */
|
||||
pipe->set_fragment_sampler_views(pipe,
|
||||
ctx->base.saved_num_sampler_views,
|
||||
ctx->base.saved_sampler_views);
|
||||
|
||||
if (!ctx->base.running) {
|
||||
_debug_printf("u_blitter: Caught recursion on restore. "
|
||||
"This is a driver bug.\n");
|
||||
}
|
||||
ctx->base.running = FALSE;
|
||||
for (i = 0; i < ctx->base.saved_num_sampler_views; i++)
|
||||
pipe_sampler_view_reference(&ctx->base.saved_sampler_views[i], NULL);
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue