mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-27 04:00:10 +01:00
zink: rework primitive rasterization type logic
There's a few things that depends on the primitive rasterization type, like point-sprite lowering and polygon offset. The effective state is a combination of several other states, and we currently kinda wing it a bit sometimes. This should improve the situation. In particular, we now go backwards through the pipeline, checking one overriding state at the time. The end result should be that we don't end up lowering point-coord replacement when not rendering with points. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19048>
This commit is contained in:
parent
811794f8d8
commit
659c39fafb
5 changed files with 84 additions and 70 deletions
|
|
@ -2731,48 +2731,6 @@ handle_bindless_var(nir_shader *nir, nir_variable *var, const struct glsl_type *
|
|||
var->data.mode = nir_var_shader_temp;
|
||||
}
|
||||
|
||||
static enum pipe_prim_type
|
||||
prim_to_pipe(enum shader_prim primitive_type)
|
||||
{
|
||||
switch (primitive_type) {
|
||||
case SHADER_PRIM_POINTS:
|
||||
return PIPE_PRIM_POINTS;
|
||||
case SHADER_PRIM_LINES:
|
||||
case SHADER_PRIM_LINE_LOOP:
|
||||
case SHADER_PRIM_LINE_STRIP:
|
||||
case SHADER_PRIM_LINES_ADJACENCY:
|
||||
case SHADER_PRIM_LINE_STRIP_ADJACENCY:
|
||||
return PIPE_PRIM_LINES;
|
||||
default:
|
||||
return PIPE_PRIM_TRIANGLES;
|
||||
}
|
||||
}
|
||||
|
||||
static enum pipe_prim_type
|
||||
tess_prim_to_pipe(enum tess_primitive_mode prim_mode)
|
||||
{
|
||||
switch (prim_mode) {
|
||||
case TESS_PRIMITIVE_ISOLINES:
|
||||
return PIPE_PRIM_LINES;
|
||||
default:
|
||||
return PIPE_PRIM_TRIANGLES;
|
||||
}
|
||||
}
|
||||
|
||||
static enum pipe_prim_type
|
||||
get_shader_base_prim_type(struct nir_shader *nir)
|
||||
{
|
||||
switch (nir->info.stage) {
|
||||
case MESA_SHADER_GEOMETRY:
|
||||
return prim_to_pipe(nir->info.gs.output_primitive);
|
||||
case MESA_SHADER_TESS_EVAL:
|
||||
return nir->info.tess.point_mode ? PIPE_PRIM_POINTS : tess_prim_to_pipe(nir->info.tess._primitive_mode);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return PIPE_PRIM_MAX;
|
||||
}
|
||||
|
||||
static bool
|
||||
convert_1d_shadow_tex(nir_builder *b, nir_instr *instr, void *data)
|
||||
{
|
||||
|
|
@ -3127,7 +3085,6 @@ zink_shader_create(struct zink_screen *screen, struct nir_shader *nir,
|
|||
ret->sinfo.have_vulkan_memory_model = screen->info.have_KHR_vulkan_memory_model;
|
||||
|
||||
ret->hash = _mesa_hash_pointer(ret);
|
||||
ret->reduced_prim = get_shader_base_prim_type(nir);
|
||||
|
||||
ret->programs = _mesa_pointer_set_create(NULL);
|
||||
simple_mtx_init(&ret->lock, mtx_plain);
|
||||
|
|
|
|||
|
|
@ -359,6 +359,16 @@ update_gfx_pipeline(struct zink_context *ctx, struct zink_batch_state *bs, enum
|
|||
return pipeline_changed;
|
||||
}
|
||||
|
||||
static enum pipe_prim_type
|
||||
zink_rast_prim(const struct zink_context *ctx,
|
||||
const struct pipe_draw_info *dinfo)
|
||||
{
|
||||
if (ctx->gfx_pipeline_state.shader_rast_prim != PIPE_PRIM_MAX)
|
||||
return ctx->gfx_pipeline_state.shader_rast_prim;
|
||||
|
||||
return u_reduced_prim((enum pipe_prim_type)dinfo->mode);
|
||||
}
|
||||
|
||||
template <zink_multidraw HAS_MULTIDRAW, zink_dynamic_state DYNAMIC_STATE, bool BATCH_CHANGED, bool DRAW_STATE>
|
||||
void
|
||||
zink_draw(struct pipe_context *pctx,
|
||||
|
|
@ -491,17 +501,21 @@ zink_draw(struct pipe_context *pctx,
|
|||
(HAS_MULTIDRAW && num_draws > 1 && !dinfo->increment_draw_id));
|
||||
if (drawid_broken != zink_get_last_vertex_key(ctx)->push_drawid)
|
||||
zink_set_last_vertex_key(ctx)->push_drawid = drawid_broken;
|
||||
if (mode_changed) {
|
||||
bool points_changed = false;
|
||||
if (mode == PIPE_PRIM_POINTS) {
|
||||
ctx->gfx_pipeline_state.has_points++;
|
||||
points_changed = true;
|
||||
} else if (ctx->gfx_pipeline_state.gfx_prim_mode == PIPE_PRIM_POINTS) {
|
||||
ctx->gfx_pipeline_state.has_points--;
|
||||
points_changed = true;
|
||||
|
||||
bool rast_prim_changed = false;
|
||||
if (mode_changed || ctx->gfx_pipeline_state.modules_changed) {
|
||||
enum pipe_prim_type rast_prim = zink_rast_prim(ctx, dinfo);
|
||||
if (rast_prim != ctx->gfx_pipeline_state.rast_prim) {
|
||||
bool points_changed =
|
||||
(ctx->gfx_pipeline_state.rast_prim == PIPE_PRIM_POINTS) !=
|
||||
(rast_prim == PIPE_PRIM_POINTS);
|
||||
|
||||
ctx->gfx_pipeline_state.rast_prim = rast_prim;
|
||||
rast_prim_changed = true;
|
||||
|
||||
if (points_changed && ctx->rast_state->base.point_quad_rasterization)
|
||||
zink_set_fs_point_coord_key(ctx);
|
||||
}
|
||||
if (points_changed && ctx->rast_state->base.point_quad_rasterization)
|
||||
zink_set_fs_point_coord_key(ctx);
|
||||
}
|
||||
ctx->gfx_pipeline_state.gfx_prim_mode = mode;
|
||||
|
||||
|
|
@ -666,13 +680,9 @@ zink_draw(struct pipe_context *pctx,
|
|||
}
|
||||
}
|
||||
|
||||
if (BATCH_CHANGED || rast_state_changed) {
|
||||
enum pipe_prim_type reduced_prim = ctx->last_vertex_stage->reduced_prim;
|
||||
if (reduced_prim == PIPE_PRIM_MAX)
|
||||
reduced_prim = u_reduced_prim(mode);
|
||||
|
||||
if (BATCH_CHANGED || rast_state_changed || rast_prim_changed) {
|
||||
bool depth_bias = false;
|
||||
switch (reduced_prim) {
|
||||
switch (ctx->gfx_pipeline_state.rast_prim) {
|
||||
case PIPE_PRIM_POINTS:
|
||||
depth_bias = rast_state->offset_point;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1314,6 +1314,56 @@ bind_gfx_stage(struct zink_context *ctx, gl_shader_stage stage, struct zink_shad
|
|||
}
|
||||
}
|
||||
|
||||
static enum pipe_prim_type
|
||||
gs_output_to_reduced_prim_type(struct shader_info *info)
|
||||
{
|
||||
switch (info->gs.output_primitive) {
|
||||
case SHADER_PRIM_POINTS:
|
||||
return PIPE_PRIM_POINTS;
|
||||
|
||||
case SHADER_PRIM_LINES:
|
||||
case SHADER_PRIM_LINE_LOOP:
|
||||
case SHADER_PRIM_LINE_STRIP:
|
||||
case SHADER_PRIM_LINES_ADJACENCY:
|
||||
case SHADER_PRIM_LINE_STRIP_ADJACENCY:
|
||||
return PIPE_PRIM_LINES;
|
||||
|
||||
case SHADER_PRIM_TRIANGLES:
|
||||
case SHADER_PRIM_TRIANGLE_STRIP:
|
||||
case SHADER_PRIM_TRIANGLE_FAN:
|
||||
case SHADER_PRIM_TRIANGLES_ADJACENCY:
|
||||
case SHADER_PRIM_TRIANGLE_STRIP_ADJACENCY:
|
||||
return PIPE_PRIM_TRIANGLES;
|
||||
|
||||
default:
|
||||
unreachable("unexpected output primitive type");
|
||||
}
|
||||
}
|
||||
|
||||
static enum pipe_prim_type
|
||||
update_rast_prim(struct zink_shader *shader)
|
||||
{
|
||||
struct shader_info *info = &shader->nir->info;
|
||||
if (info->stage == MESA_SHADER_GEOMETRY)
|
||||
return gs_output_to_reduced_prim_type(info);
|
||||
else if (info->stage == MESA_SHADER_TESS_EVAL) {
|
||||
if (info->tess.point_mode)
|
||||
return PIPE_PRIM_POINTS;
|
||||
else {
|
||||
switch (info->tess._primitive_mode) {
|
||||
case TESS_PRIMITIVE_ISOLINES:
|
||||
return PIPE_PRIM_LINES;
|
||||
case TESS_PRIMITIVE_TRIANGLES:
|
||||
case TESS_PRIMITIVE_QUADS:
|
||||
return PIPE_PRIM_TRIANGLES;
|
||||
default:
|
||||
return PIPE_PRIM_MAX;
|
||||
}
|
||||
}
|
||||
}
|
||||
return PIPE_PRIM_MAX;
|
||||
}
|
||||
|
||||
static void
|
||||
bind_last_vertex_stage(struct zink_context *ctx)
|
||||
{
|
||||
|
|
@ -1325,6 +1375,12 @@ bind_last_vertex_stage(struct zink_context *ctx)
|
|||
else
|
||||
ctx->last_vertex_stage = ctx->gfx_stages[MESA_SHADER_VERTEX];
|
||||
gl_shader_stage current = ctx->last_vertex_stage ? ctx->last_vertex_stage->nir->info.stage : MESA_SHADER_VERTEX;
|
||||
|
||||
/* update rast_prim */
|
||||
ctx->gfx_pipeline_state.shader_rast_prim =
|
||||
ctx->last_vertex_stage ? update_rast_prim(ctx->last_vertex_stage) :
|
||||
PIPE_PRIM_MAX;
|
||||
|
||||
if (old != current) {
|
||||
if (!zink_screen(ctx->base.screen)->optimal_keys) {
|
||||
if (old != MESA_SHADER_STAGES) {
|
||||
|
|
@ -1427,16 +1483,8 @@ zink_bind_gs_state(struct pipe_context *pctx,
|
|||
struct zink_context *ctx = zink_context(pctx);
|
||||
if (!cso && !ctx->gfx_stages[MESA_SHADER_GEOMETRY])
|
||||
return;
|
||||
bool had_points = ctx->gfx_stages[MESA_SHADER_GEOMETRY] ? ctx->gfx_stages[MESA_SHADER_GEOMETRY]->nir->info.gs.output_primitive == SHADER_PRIM_POINTS : false;
|
||||
bind_gfx_stage(ctx, MESA_SHADER_GEOMETRY, cso);
|
||||
bind_last_vertex_stage(ctx);
|
||||
if (cso) {
|
||||
if (!had_points && ctx->last_vertex_stage->nir->info.gs.output_primitive == SHADER_PRIM_POINTS)
|
||||
ctx->gfx_pipeline_state.has_points++;
|
||||
} else {
|
||||
if (had_points)
|
||||
ctx->gfx_pipeline_state.has_points--;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -315,7 +315,7 @@ static inline void
|
|||
zink_set_fs_point_coord_key(struct zink_context *ctx)
|
||||
{
|
||||
const struct zink_fs_key *fs = zink_get_fs_key(ctx);
|
||||
bool disable = !ctx->gfx_pipeline_state.has_points || !ctx->rast_state->base.sprite_coord_enable;
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -658,7 +658,6 @@ struct zink_shader {
|
|||
struct util_live_shader base;
|
||||
uint32_t hash;
|
||||
struct nir_shader *nir;
|
||||
enum pipe_prim_type reduced_prim; // PIPE_PRIM_MAX for vs
|
||||
|
||||
struct zink_shader_info sinfo;
|
||||
|
||||
|
|
@ -748,7 +747,7 @@ struct zink_gfx_pipeline_state {
|
|||
uint32_t vertex_strides[PIPE_MAX_ATTRIBS];
|
||||
struct zink_vertex_elements_hw_state *element_state;
|
||||
bool sample_locations_enabled;
|
||||
uint8_t has_points; //either gs outputs points or prim type is points
|
||||
enum pipe_prim_type shader_rast_prim, rast_prim; /* reduced type or max for unknown */
|
||||
union {
|
||||
struct {
|
||||
struct zink_shader_key key[5];
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue