diff --git a/src/gallium/drivers/panfrost/ci/deqp-panfrost-g52-fails.txt b/src/gallium/drivers/panfrost/ci/deqp-panfrost-g52-fails.txt index 9998751ea0b..c9c0d68cf06 100644 --- a/src/gallium/drivers/panfrost/ci/deqp-panfrost-g52-fails.txt +++ b/src/gallium/drivers/panfrost/ci/deqp-panfrost-g52-fails.txt @@ -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 diff --git a/src/panfrost/lib/pan_indirect_draw.c b/src/panfrost/lib/pan_indirect_draw.c index 531d3f4e43c..cd99ad4a2b1 100644 --- a/src/panfrost/lib/pan_indirect_draw.c +++ b/src/panfrost/lib/pan_indirect_draw.c @@ -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 */