mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-04-25 13:30:38 +02:00
gallium: fix issues in recursive flushing
When flushing/rendering, some stages (like AA line/point) need to set pipe/driver state. Those driver functions often call draw_flush(). That leads to recursion. Use new draw->suspend_flush flag to explicitly prevent that in the key places. Remove the draw->vcache_flushing field. Reuse draw->flushing as a debug/assertion var.
This commit is contained in:
parent
8437f5c763
commit
14d1ca8d86
6 changed files with 42 additions and 11 deletions
|
|
@ -367,8 +367,10 @@ draw_set_mapped_element_buffer( struct draw_context *draw,
|
|||
*/
|
||||
void draw_do_flush( struct draw_context *draw, unsigned flags )
|
||||
{
|
||||
if (!draw->flushing && !draw->vcache_flushing)
|
||||
if (!draw->suspend_flushing)
|
||||
{
|
||||
assert(!draw->flushing); /* catch inadvertant recursion */
|
||||
|
||||
draw->flushing = TRUE;
|
||||
|
||||
draw_pipeline_flush( draw, flags );
|
||||
|
|
|
|||
|
|
@ -485,11 +485,16 @@ aaline_create_sampler(struct aaline_stage *aaline)
|
|||
static boolean
|
||||
bind_aaline_fragment_shader(struct aaline_stage *aaline)
|
||||
{
|
||||
struct draw_context *draw = aaline->stage.draw;
|
||||
|
||||
if (!aaline->fs->aaline_fs &&
|
||||
!generate_aaline_fs(aaline))
|
||||
return FALSE;
|
||||
|
||||
draw->suspend_flushing = TRUE;
|
||||
aaline->driver_bind_fs_state(aaline->pipe, aaline->fs->aaline_fs);
|
||||
draw->suspend_flushing = FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -663,8 +668,10 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header)
|
|||
pipe_texture_reference(&aaline->state.texture[aaline->fs->sampler_unit],
|
||||
aaline->texture);
|
||||
|
||||
draw->suspend_flushing = TRUE;
|
||||
aaline->driver_bind_sampler_states(pipe, num_samplers, aaline->state.sampler);
|
||||
aaline->driver_set_sampler_textures(pipe, num_samplers, aaline->state.texture);
|
||||
draw->suspend_flushing = FALSE;
|
||||
|
||||
/* now really draw first line */
|
||||
stage->line = aaline_line;
|
||||
|
|
@ -682,14 +689,14 @@ aaline_flush(struct draw_stage *stage, unsigned flags)
|
|||
stage->line = aaline_first_line;
|
||||
stage->next->flush( stage->next, flags );
|
||||
|
||||
/* restore original frag shader */
|
||||
/* restore original frag shader, texture, sampler state */
|
||||
draw->suspend_flushing = TRUE;
|
||||
aaline->driver_bind_fs_state(pipe, aaline->fs->driver_fs);
|
||||
|
||||
/* XXX restore original texture, sampler state */
|
||||
aaline->driver_bind_sampler_states(pipe, aaline->num_samplers,
|
||||
aaline->state.sampler);
|
||||
aaline->driver_set_sampler_textures(pipe, aaline->num_textures,
|
||||
aaline->state.texture);
|
||||
draw->suspend_flushing = FALSE;
|
||||
|
||||
draw->extra_vp_outputs.slot = 0;
|
||||
}
|
||||
|
|
@ -783,6 +790,7 @@ aaline_bind_fs_state(struct pipe_context *pipe, void *fs)
|
|||
{
|
||||
struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
|
||||
struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs;
|
||||
|
||||
/* save current */
|
||||
aaline->fs = aafs;
|
||||
/* pass-through */
|
||||
|
|
@ -807,9 +815,12 @@ aaline_bind_sampler_states(struct pipe_context *pipe,
|
|||
unsigned num, void **sampler)
|
||||
{
|
||||
struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
|
||||
struct draw_context *draw = aaline->stage.draw;
|
||||
|
||||
/* save current */
|
||||
memcpy(aaline->state.sampler, sampler, num * sizeof(void *));
|
||||
aaline->num_samplers = num;
|
||||
|
||||
/* pass-through */
|
||||
aaline->driver_bind_sampler_states(aaline->pipe, num, sampler);
|
||||
}
|
||||
|
|
@ -820,6 +831,7 @@ aaline_set_sampler_textures(struct pipe_context *pipe,
|
|||
unsigned num, struct pipe_texture **texture)
|
||||
{
|
||||
struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
|
||||
struct draw_context *draw = aaline->stage.draw;
|
||||
uint i;
|
||||
|
||||
/* save current */
|
||||
|
|
|
|||
|
|
@ -537,11 +537,16 @@ generate_aapoint_fs(struct aapoint_stage *aapoint)
|
|||
static boolean
|
||||
bind_aapoint_fragment_shader(struct aapoint_stage *aapoint)
|
||||
{
|
||||
struct draw_context *draw = aapoint->stage.draw;
|
||||
|
||||
if (!aapoint->fs->aapoint_fs &&
|
||||
!generate_aapoint_fs(aapoint))
|
||||
return FALSE;
|
||||
|
||||
draw->suspend_flushing = TRUE;
|
||||
aapoint->driver_bind_fs_state(aapoint->pipe, aapoint->fs->aapoint_fs);
|
||||
draw->suspend_flushing = FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -714,7 +719,9 @@ aapoint_flush(struct draw_stage *stage, unsigned flags)
|
|||
stage->next->flush( stage->next, flags );
|
||||
|
||||
/* restore original frag shader */
|
||||
draw->suspend_flushing = TRUE;
|
||||
aapoint->driver_bind_fs_state(pipe, aapoint->fs->driver_fs);
|
||||
draw->suspend_flushing = FALSE;
|
||||
|
||||
draw->extra_vp_outputs.slot = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -467,11 +467,14 @@ pstip_create_sampler(struct pstip_stage *pstip)
|
|||
static boolean
|
||||
bind_pstip_fragment_shader(struct pstip_stage *pstip)
|
||||
{
|
||||
struct draw_context *draw = pstip->stage.draw;
|
||||
if (!pstip->fs->pstip_fs &&
|
||||
!generate_pstip_fs(pstip))
|
||||
return FALSE;
|
||||
|
||||
draw->suspend_flushing = TRUE;
|
||||
pstip->driver_bind_fs_state(pstip->pipe, pstip->fs->pstip_fs);
|
||||
draw->suspend_flushing = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -488,6 +491,7 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header)
|
|||
{
|
||||
struct pstip_stage *pstip = pstip_stage(stage);
|
||||
struct pipe_context *pipe = pstip->pipe;
|
||||
struct draw_context *draw = stage->draw;
|
||||
uint num_samplers;
|
||||
|
||||
assert(stage->draw->rasterizer->poly_stipple_enable);
|
||||
|
|
@ -512,8 +516,10 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header)
|
|||
|
||||
assert(num_samplers <= PIPE_MAX_SAMPLERS);
|
||||
|
||||
draw->suspend_flushing = TRUE;
|
||||
pstip->driver_bind_sampler_states(pipe, num_samplers, pstip->state.samplers);
|
||||
pstip->driver_set_sampler_textures(pipe, num_samplers, pstip->state.textures);
|
||||
draw->suspend_flushing = FALSE;
|
||||
|
||||
/* now really draw first triangle */
|
||||
stage->tri = draw_pipe_passthrough_tri;
|
||||
|
|
@ -524,7 +530,7 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header)
|
|||
static void
|
||||
pstip_flush(struct draw_stage *stage, unsigned flags)
|
||||
{
|
||||
/*struct draw_context *draw = stage->draw;*/
|
||||
struct draw_context *draw = stage->draw;
|
||||
struct pstip_stage *pstip = pstip_stage(stage);
|
||||
struct pipe_context *pipe = pstip->pipe;
|
||||
|
||||
|
|
@ -534,11 +540,13 @@ pstip_flush(struct draw_stage *stage, unsigned flags)
|
|||
/* restore original frag shader */
|
||||
pstip->driver_bind_fs_state(pipe, pstip->fs->driver_fs);
|
||||
|
||||
/* XXX restore original texture, sampler state */
|
||||
/* restore original texture, sampler state */
|
||||
draw->suspend_flushing = TRUE;
|
||||
pstip->driver_bind_sampler_states(pipe, pstip->num_samplers,
|
||||
pstip->state.samplers);
|
||||
pstip->driver_set_sampler_textures(pipe, pstip->num_textures,
|
||||
pstip->state.textures);
|
||||
draw->suspend_flushing = FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -661,6 +669,7 @@ pstip_set_sampler_textures(struct pipe_context *pipe,
|
|||
unsigned num, struct pipe_texture **texture)
|
||||
{
|
||||
struct pstip_stage *pstip = pstip_stage_from_pipe(pipe);
|
||||
struct draw_context *draw = pstip->stage.draw;
|
||||
uint i;
|
||||
|
||||
/* save current */
|
||||
|
|
@ -683,8 +692,11 @@ pstip_set_polygon_stipple(struct pipe_context *pipe,
|
|||
const struct pipe_poly_stipple *stipple)
|
||||
{
|
||||
struct pstip_stage *pstip = pstip_stage_from_pipe(pipe);
|
||||
struct draw_context *draw = (struct draw_context *) pipe->draw;
|
||||
|
||||
/* save current */
|
||||
pstip->state.stipple = stipple;
|
||||
|
||||
/* pass-through */
|
||||
pstip->driver_set_polygon_stipple(pstip->pipe, stipple);
|
||||
|
||||
|
|
|
|||
|
|
@ -178,9 +178,9 @@ struct draw_context
|
|||
boolean bypass_clipping;
|
||||
} driver;
|
||||
|
||||
boolean flushing;
|
||||
boolean vcache_flushing;
|
||||
boolean bypass_clipping; /* set if either api or driver bypass_clipping true */
|
||||
boolean flushing; /**< debugging/sanity */
|
||||
boolean suspend_flushing; /**< internally set */
|
||||
boolean bypass_clipping; /**< set if either api or driver bypass_clipping true */
|
||||
|
||||
/* pipe state that we need: */
|
||||
const struct pipe_rasterizer_state *rasterizer;
|
||||
|
|
|
|||
|
|
@ -63,7 +63,6 @@ struct vcache_frontend {
|
|||
|
||||
static void vcache_flush( struct vcache_frontend *vcache )
|
||||
{
|
||||
vcache->draw->vcache_flushing = TRUE;
|
||||
if (vcache->draw_count) {
|
||||
vcache->middle->run( vcache->middle,
|
||||
vcache->fetch_elts,
|
||||
|
|
@ -75,7 +74,6 @@ static void vcache_flush( struct vcache_frontend *vcache )
|
|||
memset(vcache->in, ~0, sizeof(vcache->in));
|
||||
vcache->fetch_count = 0;
|
||||
vcache->draw_count = 0;
|
||||
vcache->draw->vcache_flushing = FALSE;
|
||||
}
|
||||
|
||||
static void vcache_check_flush( struct vcache_frontend *vcache )
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue