mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 11:28:05 +02:00
r600g: fix lockups with dual_src_blend v2
Disable blending when dual_src_blend is enabled and number of color exports in the current fragment shader is less than 2. Fixes lockups with ext_framebuffer_multisample- alpha-to-coverage-dual-src-blend piglit test. Signed-off-by: Vadim Girlin <vadimgirlin@gmail.com>
This commit is contained in:
parent
c4610e9f92
commit
8d1a9a984f
3 changed files with 45 additions and 9 deletions
|
|
@ -156,6 +156,9 @@ static void r600_destroy_context(struct pipe_context *context)
|
|||
{
|
||||
struct r600_context *rctx = (struct r600_context *)context;
|
||||
|
||||
if (rctx->no_blend) {
|
||||
rctx->context.delete_blend_state(&rctx->context, rctx->no_blend);
|
||||
}
|
||||
if (rctx->dummy_pixel_shader) {
|
||||
rctx->context.delete_fs_state(&rctx->context, rctx->dummy_pixel_shader);
|
||||
}
|
||||
|
|
@ -195,6 +198,7 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
|
|||
{
|
||||
struct r600_context *rctx = CALLOC_STRUCT(r600_context);
|
||||
struct r600_screen* rscreen = (struct r600_screen *)screen;
|
||||
struct pipe_blend_state no_blend = {};
|
||||
|
||||
if (rctx == NULL)
|
||||
return NULL;
|
||||
|
|
@ -296,6 +300,9 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
|
|||
TGSI_INTERPOLATE_CONSTANT);
|
||||
rctx->context.bind_fs_state(&rctx->context, rctx->dummy_pixel_shader);
|
||||
|
||||
no_blend.rt[0].colormask = 0xF;
|
||||
rctx->no_blend = rctx->context.create_blend_state(&rctx->context, &no_blend);
|
||||
|
||||
return &rctx->context;
|
||||
|
||||
fail:
|
||||
|
|
|
|||
|
|
@ -389,6 +389,14 @@ struct r600_context {
|
|||
struct r600_cs_shader_state cs_shader_state;
|
||||
struct r600_sample_mask sample_mask;
|
||||
|
||||
/* current external blend state (from state tracker) */
|
||||
struct r600_pipe_blend *blend;
|
||||
/* state with disabled blending - used internally with blend_override */
|
||||
struct r600_pipe_blend *no_blend;
|
||||
|
||||
/* 1 - override current blend state with no_blend, 0 - use external state */
|
||||
unsigned blend_override;
|
||||
|
||||
struct radeon_winsys_cs *cs;
|
||||
|
||||
struct r600_range *range;
|
||||
|
|
|
|||
|
|
@ -165,19 +165,15 @@ static bool r600_conv_pipe_prim(unsigned pprim, unsigned *prim)
|
|||
}
|
||||
|
||||
/* common state between evergreen and r600 */
|
||||
void r600_bind_blend_state(struct pipe_context *ctx, void *state)
|
||||
|
||||
static void r600_bind_blend_state_internal(struct r600_context *rctx,
|
||||
struct r600_pipe_blend *blend)
|
||||
{
|
||||
struct r600_context *rctx = (struct r600_context *)ctx;
|
||||
struct r600_pipe_blend *blend = (struct r600_pipe_blend *)state;
|
||||
struct r600_pipe_state *rstate;
|
||||
bool update_cb = false;
|
||||
|
||||
if (state == NULL)
|
||||
return;
|
||||
rstate = &blend->rstate;
|
||||
rctx->states[rstate->id] = rstate;
|
||||
rctx->dual_src_blend = blend->dual_src_blend;
|
||||
rctx->alpha_to_one = blend->alpha_to_one;
|
||||
r600_context_pipe_state_set(rctx, rstate);
|
||||
|
||||
if (rctx->cb_misc_state.blend_colormask != blend->cb_target_mask) {
|
||||
|
|
@ -198,6 +194,22 @@ void r600_bind_blend_state(struct pipe_context *ctx, void *state)
|
|||
}
|
||||
}
|
||||
|
||||
void r600_bind_blend_state(struct pipe_context *ctx, void *state)
|
||||
{
|
||||
struct r600_context *rctx = (struct r600_context *)ctx;
|
||||
struct r600_pipe_blend *blend = (struct r600_pipe_blend *)state;
|
||||
|
||||
if (blend == NULL)
|
||||
return;
|
||||
|
||||
rctx->blend = blend;
|
||||
rctx->alpha_to_one = blend->alpha_to_one;
|
||||
rctx->dual_src_blend = blend->dual_src_blend;
|
||||
|
||||
if (!rctx->blend_override)
|
||||
r600_bind_blend_state_internal(rctx, blend);
|
||||
}
|
||||
|
||||
void r600_set_blend_color(struct pipe_context *ctx,
|
||||
const struct pipe_blend_color *state)
|
||||
{
|
||||
|
|
@ -1024,7 +1036,7 @@ void r600_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask)
|
|||
static void r600_update_derived_state(struct r600_context *rctx)
|
||||
{
|
||||
struct pipe_context * ctx = (struct pipe_context*)rctx;
|
||||
unsigned ps_dirty = 0;
|
||||
unsigned ps_dirty = 0, blend_override;
|
||||
|
||||
if (!rctx->blitter->running) {
|
||||
/* Flush depth textures which need to be flushed. */
|
||||
|
|
@ -1052,7 +1064,16 @@ static void r600_update_derived_state(struct r600_context *rctx)
|
|||
|
||||
if (ps_dirty)
|
||||
r600_context_pipe_state_set(rctx, &rctx->ps_shader->current->rstate);
|
||||
|
||||
|
||||
blend_override = (rctx->dual_src_blend &&
|
||||
rctx->ps_shader->current->nr_ps_color_outputs < 2);
|
||||
|
||||
if (blend_override != rctx->blend_override) {
|
||||
rctx->blend_override = blend_override;
|
||||
r600_bind_blend_state_internal(rctx,
|
||||
blend_override ? rctx->no_blend : rctx->blend);
|
||||
}
|
||||
|
||||
if (rctx->chip_class >= EVERGREEN) {
|
||||
evergreen_update_dual_export_state(rctx);
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue