diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c index 2b3caa8717d..1c57322a0b3 100644 --- a/src/gallium/drivers/zink/zink_compiler.c +++ b/src/gallium/drivers/zink/zink_compiler.c @@ -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); diff --git a/src/gallium/drivers/zink/zink_draw.cpp b/src/gallium/drivers/zink/zink_draw.cpp index 16f2d1bd93e..d8c9c3f08ea 100644 --- a/src/gallium/drivers/zink/zink_draw.cpp +++ b/src/gallium/drivers/zink/zink_draw.cpp @@ -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 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; diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c index 6102ee4cd0a..7a20ae69881 100644 --- a/src/gallium/drivers/zink/zink_program.c +++ b/src/gallium/drivers/zink/zink_program.c @@ -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 diff --git a/src/gallium/drivers/zink/zink_program.h b/src/gallium/drivers/zink/zink_program.h index 9b2848a7fcb..df7aa5d30ac 100644 --- a/src/gallium/drivers/zink/zink_program.h +++ b/src/gallium/drivers/zink/zink_program.h @@ -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) { diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h index d6a9a2fac3e..05c056c86fd 100644 --- a/src/gallium/drivers/zink/zink_types.h +++ b/src/gallium/drivers/zink/zink_types.h @@ -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];