zink: add a fs base key, fix optimal fs key packing

the optimal fs key gets at most 16 bits, so it's crucial to only use
the ones that are needed in order to conserve bits for things needed
by all drivers

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20585>
This commit is contained in:
Mike Blumenkrantz
2023-01-04 14:54:25 -05:00
committed by Marge Bot
parent 8772651aa0
commit b20df1abeb
7 changed files with 57 additions and 28 deletions

View File

@@ -2852,7 +2852,7 @@ zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, nir_shad
need_optimize = true;
}
if (!zink_fs_key(key)->samples &&
if (!zink_fs_key_base(key)->samples &&
nir->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_SAMPLE_MASK)) {
/* VK will always use gl_SampleMask[] values even if sample count is 0,
* so we need to skip this write here to mimic GL's behavior of ignoring it
@@ -2865,14 +2865,14 @@ zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, nir_shad
NIR_PASS_V(nir, nir_remove_dead_variables, nir_var_shader_temp, NULL);
need_optimize = true;
}
if (zink_fs_key(key)->force_dual_color_blend && nir->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_DATA1)) {
if (zink_fs_key_base(key)->force_dual_color_blend && nir->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_DATA1)) {
NIR_PASS_V(nir, lower_dual_blend);
}
if (zink_fs_key(key)->coord_replace_bits) {
NIR_PASS_V(nir, nir_lower_texcoord_replace, zink_fs_key(key)->coord_replace_bits,
false, zink_fs_key(key)->coord_replace_yinvert);
if (zink_fs_key_base(key)->coord_replace_bits) {
NIR_PASS_V(nir, nir_lower_texcoord_replace, zink_fs_key_base(key)->coord_replace_bits,
false, zink_fs_key_base(key)->coord_replace_yinvert);
}
if (zink_fs_key(key)->force_persample_interp || zink_fs_key(key)->fbfetch_ms) {
if (zink_fs_key_base(key)->force_persample_interp || zink_fs_key_base(key)->fbfetch_ms) {
nir_foreach_shader_in_variable(var, nir)
var->data.sample = true;
nir->info.fs.uses_sample_qualifier = true;
@@ -2880,7 +2880,7 @@ zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, nir_shad
}
if (nir->info.fs.uses_fbfetch_output) {
nir_variable *fbfetch = NULL;
NIR_PASS_V(nir, lower_fbfetch, &fbfetch, zink_fs_key(key)->fbfetch_ms);
NIR_PASS_V(nir, lower_fbfetch, &fbfetch, zink_fs_key_base(key)->fbfetch_ms);
/* old variable must be deleted to avoid spirv errors */
fbfetch->data.mode = nir_var_shader_temp;
nir_fixup_deref_modes(nir);

View File

@@ -2299,8 +2299,8 @@ zink_update_fbfetch(struct zink_context *ctx)
ctx->di.fbfetch.imageView = zink_csurface(ctx->fb_state.cbufs[0])->image_view;
bool fbfetch_ms = ctx->fb_state.cbufs[0]->texture->nr_samples > 1;
if (zink_get_fs_key(ctx)->fbfetch_ms != fbfetch_ms)
zink_set_fs_key(ctx)->fbfetch_ms = fbfetch_ms;
if (zink_get_fs_base_key(ctx)->fbfetch_ms != fbfetch_ms)
zink_set_fs_base_key(ctx)->fbfetch_ms = fbfetch_ms;
}
ctx->di.fbfetch.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
if (changed) {

View File

@@ -1425,9 +1425,9 @@ zink_update_fs_key_samples(struct zink_context *ctx)
return;
nir_shader *nir = ctx->gfx_stages[MESA_SHADER_FRAGMENT]->nir;
if (nir->info.outputs_written & (1 << FRAG_RESULT_SAMPLE_MASK)) {
bool samples = zink_get_fs_key(ctx)->samples;
bool samples = zink_get_fs_base_key(ctx)->samples;
if (samples != (ctx->fb_state.samples > 1))
zink_set_fs_key(ctx)->samples = ctx->fb_state.samples > 1;
zink_set_fs_base_key(ctx)->samples = ctx->fb_state.samples > 1;
}
}

View File

@@ -240,21 +240,36 @@ zink_program_has_descriptors(const struct zink_program *pg)
return pg->num_dsl > 0;
}
static inline struct zink_fs_key *
zink_set_fs_key(struct zink_context *ctx)
static inline struct zink_fs_key_base *
zink_set_fs_base_key(struct zink_context *ctx)
{
ctx->dirty_gfx_stages |= BITFIELD_BIT(MESA_SHADER_FRAGMENT);
return zink_screen(ctx->base.screen)->optimal_keys ?
&ctx->gfx_pipeline_state.shader_keys_optimal.key.fs :
&ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_FRAGMENT].key.fs;
&ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_FRAGMENT].key.fs.base;
}
static inline const struct zink_fs_key_base *
zink_get_fs_base_key(struct zink_context *ctx)
{
return zink_screen(ctx->base.screen)->optimal_keys ?
&ctx->gfx_pipeline_state.shader_keys_optimal.key.fs :
&ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_FRAGMENT].key.fs.base;
}
static inline struct zink_fs_key *
zink_set_fs_key(struct zink_context *ctx)
{
assert(!zink_screen(ctx->base.screen)->optimal_keys);
ctx->dirty_gfx_stages |= BITFIELD_BIT(MESA_SHADER_FRAGMENT);
return &ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_FRAGMENT].key.fs;
}
static inline const struct zink_fs_key *
zink_get_fs_key(struct zink_context *ctx)
{
return zink_screen(ctx->base.screen)->optimal_keys ?
&ctx->gfx_pipeline_state.shader_keys_optimal.key.fs :
&ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_FRAGMENT].key.fs;
assert(!zink_screen(ctx->base.screen)->optimal_keys);
return &ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_FRAGMENT].key.fs;
}
static inline struct zink_gs_key *
@@ -330,13 +345,13 @@ zink_get_last_vertex_key(struct zink_context *ctx)
static inline void
zink_set_fs_point_coord_key(struct zink_context *ctx)
{
const struct zink_fs_key *fs = zink_get_fs_key(ctx);
const struct zink_fs_key_base *fs = zink_get_fs_base_key(ctx);
bool disable = ctx->gfx_pipeline_state.rast_prim != PIPE_PRIM_POINTS || !ctx->rast_state->base.sprite_coord_enable;
uint8_t coord_replace_bits = disable ? 0 : ctx->rast_state->base.sprite_coord_enable;
bool coord_replace_yinvert = disable ? false : !!ctx->rast_state->base.sprite_coord_mode;
if (fs->coord_replace_bits != coord_replace_bits || fs->coord_replace_yinvert != coord_replace_yinvert) {
zink_set_fs_key(ctx)->coord_replace_bits = coord_replace_bits;
zink_set_fs_key(ctx)->coord_replace_yinvert = coord_replace_yinvert;
zink_set_fs_base_key(ctx)->coord_replace_bits = coord_replace_bits;
zink_set_fs_base_key(ctx)->coord_replace_yinvert = coord_replace_yinvert;
}
}

View File

@@ -253,7 +253,7 @@ zink_get_gfx_pipeline(struct zink_context *ctx,
!ctx->gfx_pipeline_state.render_pass &&
/* TODO: is sample shading even possible to handle with GPL? */
!ctx->gfx_stages[MESA_SHADER_FRAGMENT]->nir->info.fs.uses_sample_shading &&
!zink_get_fs_key(ctx)->fbfetch_ms &&
!zink_get_fs_base_key(ctx)->fbfetch_ms &&
!ctx->gfx_pipeline_state.force_persample_interp &&
!ctx->gfx_pipeline_state.min_samples) {
/* this is the graphics pipeline library path: find/construct all partial pipelines */

View File

@@ -66,16 +66,22 @@ struct zink_gs_key {
unsigned size;
};
struct zink_fs_key {
struct zink_fs_key_base {
bool coord_replace_yinvert : 1;
bool samples : 1;
bool force_dual_color_blend : 1;
bool force_persample_interp : 1;
bool fbfetch_ms : 1;
uint8_t pad : 3;
uint8_t coord_replace_bits;
};
struct zink_fs_key {
struct zink_fs_key_base base;
/* non-optimal bits after this point */
bool lower_line_stipple : 1;
bool lower_line_smooth : 1;
uint8_t pad : 1;
uint8_t coord_replace_bits;
uint16_t pad2 : 14;
};
struct zink_tcs_key {
@@ -100,6 +106,7 @@ struct zink_shader_key {
struct zink_tcs_key tcs;
struct zink_gs_key gs;
struct zink_fs_key fs;
struct zink_fs_key_base fs_base;
} key;
struct zink_shader_key_base base;
unsigned inline_uniforms:1;
@@ -110,7 +117,7 @@ union zink_shader_key_optimal {
struct {
struct zink_vs_key_base vs_base;
struct zink_tcs_key tcs;
struct zink_fs_key fs;
struct zink_fs_key_base fs;
};
struct {
uint8_t vs_bits;
@@ -120,6 +127,13 @@ union zink_shader_key_optimal {
uint32_t val;
};
static inline const struct zink_fs_key_base *
zink_fs_key_base(const struct zink_shader_key *key)
{
assert(key);
return &key->key.fs.base;
}
static inline const struct zink_fs_key *
zink_fs_key(const struct zink_shader_key *key)
{

View File

@@ -434,8 +434,8 @@ zink_bind_blend_state(struct pipe_context *pctx, void *cso)
state->dirty |= !zink_screen(pctx->screen)->have_full_ds3;
bool force_dual_color_blend = zink_screen(pctx->screen)->driconf.dual_color_blend_by_location &&
blend && blend->dual_src_blend && state->blend_state->attachments[0].blendEnable;
if (force_dual_color_blend != zink_get_fs_key(ctx)->force_dual_color_blend)
zink_set_fs_key(ctx)->force_dual_color_blend = force_dual_color_blend;
if (force_dual_color_blend != zink_get_fs_base_key(ctx)->force_dual_color_blend)
zink_set_fs_base_key(ctx)->force_dual_color_blend = force_dual_color_blend;
ctx->blend_state_changed = true;
}
}
@@ -702,7 +702,7 @@ zink_bind_rasterizer_state(struct pipe_context *pctx, void *cso)
ctx->scissor_changed = true;
if (ctx->rast_state->base.force_persample_interp != force_persample_interp) {
zink_set_fs_key(ctx)->force_persample_interp = ctx->rast_state->base.force_persample_interp;
zink_set_fs_base_key(ctx)->force_persample_interp = ctx->rast_state->base.force_persample_interp;
ctx->gfx_pipeline_state.dirty = true;
}
ctx->gfx_pipeline_state.force_persample_interp = ctx->rast_state->base.force_persample_interp;