panfrost: Fix indirect draws when vertex or instance count is 0
In that case we should just skip the vertex/tiler jobs as done in the direct draw path. Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Acked-by: Alyssa Rosenzweig <alyssa@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12589>
This commit is contained in:
parent
7682a5de04
commit
43760a7b2f
|
@ -1,6 +1,5 @@
|
|||
# The shader assisted indirect draw path is buggy. The shader assisted indirect
|
||||
# draw path is disabled outside of CI due to these conformance issues.
|
||||
KHR-GLES31.core.compute_shader.pipeline-gen-draw-commands,Crash
|
||||
KHR-GLES31.core.draw_indirect.advanced-primitiveRestart-elements,Fail
|
||||
KHR-GLES31.core.draw_indirect.advanced-twoPass-transformFeedback-arrays,Crash
|
||||
KHR-GLES31.core.draw_indirect.advanced-twoPass-transformFeedback-arrays,Fail
|
||||
KHR-GLES31.core.draw_indirect.advanced-twoPass-transformFeedback-elements,Fail
|
||||
|
|
|
@ -801,6 +801,21 @@ update_jobs(struct indirect_draw_shader_builder *builder)
|
|||
update_job(builder, MALI_JOB_TYPE_TILER);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
set_null_job(struct indirect_draw_shader_builder *builder,
|
||||
nir_ssa_def *job_ptr)
|
||||
{
|
||||
nir_builder *b = &builder->b;
|
||||
nir_ssa_def *w4 = get_address_imm(b, job_ptr, WORD(4));
|
||||
nir_ssa_def *val = load_global(b, w4, 1, 32);
|
||||
|
||||
/* Set job type to NULL (AKA NOOP) */
|
||||
val = nir_ior(b, nir_iand_imm(b, val, 0xffffff01),
|
||||
nir_imm_int(b, MALI_JOB_TYPE_NULL << 1));
|
||||
store_global(b, w4, val, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
get_instance_size(struct indirect_draw_shader_builder *builder)
|
||||
{
|
||||
|
@ -928,34 +943,44 @@ patch(struct indirect_draw_shader_builder *builder)
|
|||
|
||||
assert(builder->draw.vertex_count->num_components);
|
||||
|
||||
get_instance_size(builder);
|
||||
nir_ssa_def *num_vertices =
|
||||
nir_imul(b, builder->draw.vertex_count, builder->draw.instance_count);
|
||||
|
||||
builder->instance_size.padded =
|
||||
get_padded_count(b, builder->instance_size.raw,
|
||||
&builder->instance_size.packed);
|
||||
IF (nir_ieq(b, num_vertices, nir_imm_int(b, 0))) {
|
||||
/* If there's nothing to draw, turn the vertex/tiler jobs into
|
||||
* null jobs.
|
||||
*/
|
||||
set_null_job(builder, builder->jobs.vertex_job);
|
||||
set_null_job(builder, builder->jobs.tiler_job);
|
||||
} ELSE {
|
||||
get_instance_size(builder);
|
||||
|
||||
update_varyings(builder);
|
||||
update_jobs(builder);
|
||||
update_vertex_attribs(builder);
|
||||
builder->instance_size.padded =
|
||||
get_padded_count(b, builder->instance_size.raw,
|
||||
&builder->instance_size.packed);
|
||||
|
||||
IF (nir_ine(b, builder->jobs.first_vertex_sysval, nir_imm_int64(b, 0))) {
|
||||
store_global(b, builder->jobs.first_vertex_sysval,
|
||||
builder->jobs.offset_start, 1);
|
||||
update_varyings(builder);
|
||||
update_jobs(builder);
|
||||
update_vertex_attribs(builder);
|
||||
|
||||
IF (nir_ine(b, builder->jobs.first_vertex_sysval, nir_imm_int64(b, 0))) {
|
||||
store_global(b, builder->jobs.first_vertex_sysval,
|
||||
builder->jobs.offset_start, 1);
|
||||
} ENDIF
|
||||
|
||||
IF (nir_ine(b, builder->jobs.base_vertex_sysval, nir_imm_int64(b, 0))) {
|
||||
store_global(b, builder->jobs.base_vertex_sysval,
|
||||
index_size ?
|
||||
builder->draw.index_bias :
|
||||
nir_imm_int(b, 0),
|
||||
1);
|
||||
} ENDIF
|
||||
|
||||
IF (nir_ine(b, builder->jobs.base_instance_sysval, nir_imm_int64(b, 0))) {
|
||||
store_global(b, builder->jobs.base_instance_sysval,
|
||||
builder->draw.start_instance, 1);
|
||||
} ENDIF
|
||||
} ENDIF
|
||||
|
||||
IF (nir_ine(b, builder->jobs.base_vertex_sysval, nir_imm_int64(b, 0))) {
|
||||
store_global(b, builder->jobs.base_vertex_sysval,
|
||||
index_size ?
|
||||
builder->draw.index_bias :
|
||||
nir_imm_int(b, 0),
|
||||
1);
|
||||
} ENDIF
|
||||
|
||||
IF (nir_ine(b, builder->jobs.base_instance_sysval, nir_imm_int64(b, 0))) {
|
||||
store_global(b, builder->jobs.base_instance_sysval,
|
||||
builder->draw.start_instance, 1);
|
||||
} ENDIF
|
||||
|
||||
}
|
||||
|
||||
/* Search the min/max index in the range covered by the indirect draw call */
|
||||
|
|
Loading…
Reference in New Issue