mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-03 15:50:17 +01:00
radeonsi: fix a Unigine Heaven hang when drirc is missing
Cc: 10.6 11.0 <mesa-stable@lists.freedesktop.org> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Acked-by: Christian König <christian.koenig@amd.com>
This commit is contained in:
parent
b1e5451211
commit
9b510a9652
4 changed files with 28 additions and 1 deletions
|
|
@ -190,6 +190,7 @@ struct si_shader_selector {
|
|||
uint64_t inputs_read;
|
||||
uint64_t outputs_written;
|
||||
uint32_t patch_outputs_written;
|
||||
uint32_t ps_colors_written;
|
||||
};
|
||||
|
||||
/* Valid shader configurations:
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "sid.h"
|
||||
#include "radeon/r600_cs.h"
|
||||
|
||||
#include "util/u_dual_blend.h"
|
||||
#include "util/u_format.h"
|
||||
#include "util/u_format_s3tc.h"
|
||||
#include "util/u_memory.h"
|
||||
|
|
@ -233,8 +234,10 @@ static unsigned si_pack_float_12p4(float x)
|
|||
* - The COLOR1 format isn't INVALID because of possible dual-source blending,
|
||||
* so COLOR1 is enabled pretty much all the time.
|
||||
* So CB_TARGET_MASK is the only register that can disable COLOR1.
|
||||
*
|
||||
* Another reason is to avoid a hang with dual source blending.
|
||||
*/
|
||||
static void si_update_fb_blend_state(struct si_context *sctx)
|
||||
void si_update_fb_blend_state(struct si_context *sctx)
|
||||
{
|
||||
struct si_pm4_state *pm4;
|
||||
struct si_state_blend *blend = sctx->queued.named.blend;
|
||||
|
|
@ -252,6 +255,16 @@ static void si_update_fb_blend_state(struct si_context *sctx)
|
|||
mask |= 0xf << (4*i);
|
||||
mask &= blend->cb_target_mask;
|
||||
|
||||
/* Avoid a hang that happens when dual source blending is enabled
|
||||
* but there is not enough color outputs. This is undefined behavior,
|
||||
* so disable color writes completely.
|
||||
*
|
||||
* Reproducible with Unigine Heaven 4.0 and drirc missing.
|
||||
*/
|
||||
if (blend->dual_src_blend &&
|
||||
(sctx->ps_shader->ps_colors_written & 0x3) != 0x3)
|
||||
mask = 0;
|
||||
|
||||
si_pm4_set_reg(pm4, R_028238_CB_TARGET_MASK, mask);
|
||||
si_pm4_set_state(sctx, fb_blend, pm4);
|
||||
}
|
||||
|
|
@ -343,6 +356,7 @@ static void *si_create_blend_state_mode(struct pipe_context *ctx,
|
|||
return NULL;
|
||||
|
||||
blend->alpha_to_one = state->alpha_to_one;
|
||||
blend->dual_src_blend = util_blend_state_is_dual(state, 0);
|
||||
|
||||
if (state->logicop_enable) {
|
||||
color_control |= S_028808_ROP3(state->logicop_func | (state->logicop_func << 4));
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ struct si_state_blend {
|
|||
struct si_pm4_state pm4;
|
||||
uint32_t cb_target_mask;
|
||||
bool alpha_to_one;
|
||||
bool dual_src_blend;
|
||||
};
|
||||
|
||||
struct si_state_sample_mask {
|
||||
|
|
@ -251,6 +252,7 @@ void si_shader_change_notify(struct si_context *sctx);
|
|||
/* si_state.c */
|
||||
struct si_shader_selector;
|
||||
|
||||
void si_update_fb_blend_state(struct si_context *sctx);
|
||||
boolean si_is_format_supported(struct pipe_screen *screen,
|
||||
enum pipe_format format,
|
||||
enum pipe_texture_target target,
|
||||
|
|
|
|||
|
|
@ -713,6 +713,15 @@ static void *si_create_shader_state(struct pipe_context *ctx,
|
|||
}
|
||||
}
|
||||
break;
|
||||
case PIPE_SHADER_FRAGMENT:
|
||||
for (i = 0; i < sel->info.num_outputs; i++) {
|
||||
unsigned name = sel->info.output_semantic_name[i];
|
||||
unsigned index = sel->info.output_semantic_index[i];
|
||||
|
||||
if (name == TGSI_SEMANTIC_COLOR)
|
||||
sel->ps_colors_written |= 1 << index;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (sscreen->b.debug_flags & DBG_PRECOMPILE)
|
||||
|
|
@ -840,6 +849,7 @@ static void si_bind_ps_shader(struct pipe_context *ctx, void *state)
|
|||
}
|
||||
|
||||
sctx->ps_shader = sel;
|
||||
si_update_fb_blend_state(sctx);
|
||||
}
|
||||
|
||||
static void si_delete_shader_selector(struct pipe_context *ctx,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue