mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 16:08:04 +02:00
asahi: Lower edge flags
With the common geometry shader based lowering added for zink. Fixes edge flag related piglits. Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26614>
This commit is contained in:
parent
f4a648c607
commit
23f216d6e7
7 changed files with 60 additions and 9 deletions
|
|
@ -2943,6 +2943,8 @@ agx_preprocess_nir(nir_shader *nir, const nir_shader *libagx,
|
|||
out->inputs_flat_shaded = masks.flat;
|
||||
out->inputs_linear_shaded = masks.linear;
|
||||
}
|
||||
} else if (nir->info.stage == MESA_SHADER_VERTEX) {
|
||||
out->has_edgeflags = nir->info.outputs_written & VARYING_BIT_EDGE;
|
||||
}
|
||||
|
||||
/* Clean up deref gunk after lowering I/O */
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ union agx_varyings {
|
|||
struct agx_uncompiled_shader_info {
|
||||
uint64_t inputs_flat_shaded;
|
||||
uint64_t inputs_linear_shaded;
|
||||
bool has_edgeflags;
|
||||
};
|
||||
|
||||
struct agx_shader_info {
|
||||
|
|
|
|||
|
|
@ -390,7 +390,12 @@ lower_id(nir_builder *b, nir_intrinsic_instr *intr, void *data)
|
|||
id = load_instance_id(b);
|
||||
else if (intr->intrinsic == nir_intrinsic_load_num_vertices)
|
||||
id = nir_channel(b, nir_load_num_workgroups(b), 0);
|
||||
else
|
||||
else if (intr->intrinsic == nir_intrinsic_load_flat_mask)
|
||||
id = load_geometry_param(b, flat_outputs);
|
||||
else if (intr->intrinsic == nir_intrinsic_load_provoking_last) {
|
||||
id = nir_b2b32(
|
||||
b, libagx_is_provoking_last(b, nir_load_input_assembly_buffer_agx(b)));
|
||||
} else
|
||||
return false;
|
||||
|
||||
b->cursor = nir_instr_remove(&intr->instr);
|
||||
|
|
|
|||
|
|
@ -463,3 +463,9 @@ libagx_prefix_sum(global uint *buffer, uint len, uint words, uint2 local_id)
|
|||
*ptr = count + sub_group_scan_exclusive_add(value) + value;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
libagx_is_provoking_last(global struct agx_ia_state *ia)
|
||||
{
|
||||
return !ia->flatshade_first;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,6 +131,9 @@ struct agx_geometry_params {
|
|||
*/
|
||||
uint32_t xfb_prims[MAX_VERTEX_STREAMS];
|
||||
|
||||
/* Location-indexed mask of flat outputs, used for lowering GL edge flags. */
|
||||
uint64_t flat_outputs;
|
||||
|
||||
/* Within an indirect GS draw, the grid used to dispatch the GS written out
|
||||
* by the GS indirect setup kernel. Unused for direct GS draws.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -409,6 +409,14 @@ agx_bind_rasterizer_state(struct pipe_context *pctx, void *cso)
|
|||
ctx->rast = so;
|
||||
}
|
||||
|
||||
static bool
|
||||
has_edgeflags(struct agx_context *ctx, enum mesa_prim mode)
|
||||
{
|
||||
return ctx->stage[PIPE_SHADER_VERTEX].shader->info.has_edgeflags &&
|
||||
mode == MESA_PRIM_TRIANGLES &&
|
||||
(ctx->rast->base.fill_front != PIPE_POLYGON_MODE_FILL);
|
||||
}
|
||||
|
||||
static enum agx_wrap
|
||||
agx_wrap_from_pipe(enum pipe_tex_wrap in)
|
||||
{
|
||||
|
|
@ -2318,9 +2326,13 @@ agx_delete_shader_state(struct pipe_context *ctx, void *cso)
|
|||
_mesa_hash_table_destroy(so->variants, agx_delete_compiled_shader);
|
||||
blob_finish(&so->serialized_nir);
|
||||
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(so->passthrough_progs); ++i) {
|
||||
if (so->passthrough_progs[i])
|
||||
agx_delete_shader_state(ctx, so->passthrough_progs[i]);
|
||||
for (unsigned i = 0; i < MESA_PRIM_COUNT; ++i) {
|
||||
for (unsigned j = 0; j < 3; ++j) {
|
||||
for (unsigned k = 0; k < 2; ++k) {
|
||||
if (so->passthrough_progs[i][j][k])
|
||||
agx_delete_shader_state(ctx, so->passthrough_progs[i][j][k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ralloc_free(so);
|
||||
|
|
@ -3466,6 +3478,8 @@ agx_batch_geometry_params(struct agx_batch *batch, uint64_t input_index_buffer,
|
|||
struct agx_geometry_params params = {
|
||||
.state = agx_batch_geometry_state(batch),
|
||||
.indirect_desc = batch->geom_indirect,
|
||||
.flat_outputs =
|
||||
batch->ctx->stage[PIPE_SHADER_FRAGMENT].shader->info.inputs_flat_shaded,
|
||||
};
|
||||
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(batch->ctx->streamout.targets); ++i) {
|
||||
|
|
@ -3800,17 +3814,37 @@ agx_needs_passthrough_gs(struct agx_context *ctx,
|
|||
ctx->streamout.num_targets)
|
||||
return true;
|
||||
|
||||
/* Edge flags are emulated with a geometry shader */
|
||||
if (has_edgeflags(ctx, info->mode))
|
||||
return true;
|
||||
|
||||
/* Otherwise, we don't need one */
|
||||
return false;
|
||||
}
|
||||
|
||||
static enum mesa_prim
|
||||
rast_prim(enum mesa_prim mode, unsigned fill_mode)
|
||||
{
|
||||
if (u_reduced_prim(mode) == MESA_PRIM_TRIANGLES) {
|
||||
if (fill_mode == PIPE_POLYGON_MODE_POINT)
|
||||
return MESA_PRIM_POINTS;
|
||||
else if (fill_mode == PIPE_POLYGON_MODE_LINE)
|
||||
return MESA_PRIM_LINES;
|
||||
}
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
static struct agx_uncompiled_shader *
|
||||
agx_get_passthrough_gs(struct agx_context *ctx,
|
||||
struct agx_uncompiled_shader *prev_cso,
|
||||
enum mesa_prim mode)
|
||||
{
|
||||
if (prev_cso->passthrough_progs[mode])
|
||||
return prev_cso->passthrough_progs[mode];
|
||||
bool edgeflags = has_edgeflags(ctx, mode);
|
||||
unsigned poly_mode = ctx->rast->base.fill_front;
|
||||
|
||||
if (prev_cso->passthrough_progs[mode][poly_mode][edgeflags])
|
||||
return prev_cso->passthrough_progs[mode][poly_mode][edgeflags];
|
||||
|
||||
struct blob_reader reader;
|
||||
blob_reader_init(&reader, prev_cso->early_serialized_nir.data,
|
||||
|
|
@ -3818,13 +3852,13 @@ agx_get_passthrough_gs(struct agx_context *ctx,
|
|||
nir_shader *prev = nir_deserialize(NULL, &agx_nir_options, &reader);
|
||||
|
||||
nir_shader *gs = nir_create_passthrough_gs(
|
||||
&agx_nir_options, prev, mode, mode, false /* emulate edge flags */,
|
||||
&agx_nir_options, prev, mode, rast_prim(mode, poly_mode), edgeflags,
|
||||
false /* force line strip out */);
|
||||
|
||||
ralloc_free(prev);
|
||||
|
||||
struct agx_uncompiled_shader *cso = pipe_shader_from_nir(&ctx->base, gs);
|
||||
prev_cso->passthrough_progs[mode] = cso;
|
||||
prev_cso->passthrough_progs[mode][poly_mode][edgeflags] = cso;
|
||||
return cso;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -198,7 +198,7 @@ struct agx_uncompiled_shader {
|
|||
uint8_t nir_sha1[20];
|
||||
struct agx_uncompiled_shader_info info;
|
||||
struct hash_table *variants;
|
||||
struct agx_uncompiled_shader *passthrough_progs[MESA_PRIM_COUNT];
|
||||
struct agx_uncompiled_shader *passthrough_progs[MESA_PRIM_COUNT][3][2];
|
||||
bool has_xfb_info;
|
||||
|
||||
/* Whether the shader accesses indexed samplers via the bindless heap */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue