mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-20 16:00:08 +01:00
r600: Add shader precompile and shader-db support.
This should reduce draw-time jank, and was useful for me in evaluating NIR-to-TGSI's impact for r600. Acked-by: Gert Wollny <gert.wollny@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14427>
This commit is contained in:
parent
f07b8a0cac
commit
28d6a5af25
5 changed files with 78 additions and 6 deletions
|
|
@ -444,6 +444,13 @@ static void *evergreen_create_compute_state(struct pipe_context *ctx,
|
|||
if (shader->ir_type == PIPE_SHADER_IR_TGSI ||
|
||||
shader->ir_type == PIPE_SHADER_IR_NIR) {
|
||||
shader->sel = r600_create_shader_state_tokens(ctx, cso->prog, cso->ir_type, PIPE_SHADER_COMPUTE);
|
||||
|
||||
/* Precompile the shader with the expected shader key, to reduce jank at
|
||||
* draw time. Also produces output for shader-db.
|
||||
*/
|
||||
bool dirty;
|
||||
r600_shader_select(ctx, shader->sel, &dirty, true);
|
||||
|
||||
return shader;
|
||||
}
|
||||
#ifdef HAVE_OPENCL
|
||||
|
|
@ -506,7 +513,7 @@ static void evergreen_bind_compute_state(struct pipe_context *ctx, void *state)
|
|||
cstate->ir_type == PIPE_SHADER_IR_NIR) {
|
||||
bool compute_dirty;
|
||||
cstate->sel->ir_type = cstate->ir_type;
|
||||
if (r600_shader_select(ctx, cstate->sel, &compute_dirty))
|
||||
if (r600_shader_select(ctx, cstate->sel, &compute_dirty, false))
|
||||
R600_ERR("Failed to select compute shader\n");
|
||||
}
|
||||
|
||||
|
|
@ -736,7 +743,7 @@ static void compute_emit_cs(struct r600_context *rctx,
|
|||
|
||||
if (rctx->cs_shader_state.shader->ir_type == PIPE_SHADER_IR_TGSI||
|
||||
rctx->cs_shader_state.shader->ir_type == PIPE_SHADER_IR_NIR) {
|
||||
if (r600_shader_select(&rctx->b.b, rctx->cs_shader_state.shader->sel, &compute_dirty)) {
|
||||
if (r600_shader_select(&rctx->b.b, rctx->cs_shader_state.shader->sel, &compute_dirty, false)) {
|
||||
R600_ERR("Failed to select compute shader\n");
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1065,7 +1065,7 @@ struct r600_pipe_shader_selector *r600_create_shader_state_tokens(struct pipe_co
|
|||
unsigned pipe_shader_type);
|
||||
int r600_shader_select(struct pipe_context *ctx,
|
||||
struct r600_pipe_shader_selector* sel,
|
||||
bool *dirty);
|
||||
bool *dirty, bool precompile);
|
||||
|
||||
void r600_delete_shader_selector(struct pipe_context *ctx,
|
||||
struct r600_pipe_shader_selector *sel);
|
||||
|
|
|
|||
|
|
@ -372,6 +372,15 @@ int r600_pipe_shader_create(struct pipe_context *ctx,
|
|||
r = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
pipe_debug_message(&rctx->b.debug, SHADER_INFO, "%s shader: %d dw, %d gprs, %d loops, %d cf, %d stack",
|
||||
_mesa_shader_stage_to_abbrev(tgsi_processor_to_shader_stage(processor)),
|
||||
shader->shader.bc.ndw,
|
||||
shader->shader.bc.ngpr,
|
||||
shader->shader.num_loops,
|
||||
shader->shader.bc.ncf,
|
||||
shader->shader.bc.nstack);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
|
|
@ -3451,6 +3460,8 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
|
|||
shader->uses_helper_invocation = false;
|
||||
shader->uses_doubles = ctx.info.uses_doubles;
|
||||
shader->uses_atomics = ctx.info.file_mask[TGSI_FILE_HW_ATOMIC];
|
||||
shader->num_loops = ctx.info.opcode_count[TGSI_OPCODE_BGNLOOP];
|
||||
|
||||
shader->nsys_inputs = 0;
|
||||
|
||||
shader->uses_images = ctx.info.file_count[TGSI_FILE_IMAGE] > 0 ||
|
||||
|
|
|
|||
|
|
@ -114,6 +114,8 @@ struct r600_shader {
|
|||
unsigned tes_as_es;
|
||||
unsigned tcs_prim_mode;
|
||||
unsigned ps_prim_id_input;
|
||||
unsigned num_loops;
|
||||
|
||||
struct r600_shader_array * arrays;
|
||||
|
||||
boolean uses_doubles;
|
||||
|
|
|
|||
|
|
@ -867,16 +867,62 @@ static inline void r600_shader_selector_key(const struct pipe_context *ctx,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
r600_shader_precompile_key(const struct pipe_context *ctx,
|
||||
const struct r600_pipe_shader_selector *sel,
|
||||
union r600_shader_key *key)
|
||||
{
|
||||
memset(key, 0, sizeof(*key));
|
||||
|
||||
switch (sel->type) {
|
||||
case PIPE_SHADER_VERTEX:
|
||||
case PIPE_SHADER_TESS_EVAL:
|
||||
/* Assume no tess or GS for setting .as_es. In order to
|
||||
* precompile with es, we'd need the other shaders we're linked
|
||||
* with (see the link_shader screen method)
|
||||
*/
|
||||
break;
|
||||
|
||||
case PIPE_SHADER_GEOMETRY:
|
||||
break;
|
||||
|
||||
case PIPE_SHADER_FRAGMENT:
|
||||
key->ps.image_size_const_offset = sel->info.file_max[TGSI_FILE_IMAGE];
|
||||
|
||||
/* This is used for gl_FragColor output expansion to the number
|
||||
* of color buffers bound, but also with sb it'll drop outputs
|
||||
* to unused cbufs.
|
||||
*/
|
||||
key->ps.nr_cbufs = sel->info.file_max[TGSI_FILE_OUTPUT] + 1;
|
||||
break;
|
||||
|
||||
case PIPE_SHADER_TESS_CTRL:
|
||||
/* Prim mode comes from the TES, but we need some valid value. */
|
||||
key->tcs.prim_mode = PIPE_PRIM_TRIANGLES;
|
||||
break;
|
||||
|
||||
case PIPE_SHADER_COMPUTE:
|
||||
break;
|
||||
|
||||
default:
|
||||
unreachable("bad shader stage");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Select the hw shader variant depending on the current state.
|
||||
* (*dirty) is set to 1 if current variant was changed */
|
||||
int r600_shader_select(struct pipe_context *ctx,
|
||||
struct r600_pipe_shader_selector* sel,
|
||||
bool *dirty)
|
||||
bool *dirty, bool precompile)
|
||||
{
|
||||
union r600_shader_key key;
|
||||
struct r600_pipe_shader * shader = NULL;
|
||||
int r;
|
||||
|
||||
if (precompile)
|
||||
r600_shader_precompile_key(ctx, sel, &key);
|
||||
else
|
||||
r600_shader_selector_key(ctx, sel, &key);
|
||||
|
||||
/* Check if we don't need to change anything.
|
||||
|
|
@ -997,6 +1043,12 @@ static void *r600_create_shader_state(struct pipe_context *ctx,
|
|||
break;
|
||||
}
|
||||
|
||||
/* Precompile the shader with the expected shader key, to reduce jank at
|
||||
* draw time. Also produces output for shader-db.
|
||||
*/
|
||||
bool dirty;
|
||||
r600_shader_select(ctx, sel, &dirty, true);
|
||||
|
||||
return sel;
|
||||
}
|
||||
|
||||
|
|
@ -1771,7 +1823,7 @@ void r600_setup_scratch_buffers(struct r600_context *rctx) {
|
|||
}
|
||||
|
||||
#define SELECT_SHADER_OR_FAIL(x) do { \
|
||||
r600_shader_select(ctx, rctx->x##_shader, &x##_dirty); \
|
||||
r600_shader_select(ctx, rctx->x##_shader, &x##_dirty, false); \
|
||||
if (unlikely(!rctx->x##_shader->current)) \
|
||||
return false; \
|
||||
} while(0)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue