From: Rohan Garg Date: Wed, 17 Jul 2019 16:50:13 +0000 (+0200) Subject: panfrost: Take into account a index_bias for glDrawElementsBaseVertex calls X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=16edd56fccad7ba0e1b938a60f0f5e927a104585;p=mesa.git panfrost: Take into account a index_bias for glDrawElementsBaseVertex calls Midgard does not accept a index_bias directly and relies instead on a bias correction offset (offset_bias_correction) in order to calculate the unbiased vertex index. We need to make sure we adjust offset_start and vertex_count in order to take into account the index_bias as required by a glDrawElementsBaseVertex call and then supply a additional offset_bias_correction to the hardware. Signed-off-by: Rohan Garg Reviewed-by: Alyssa Rosenzweig --- diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c index e9d18605dd0..284c246677d 100644 --- a/src/gallium/drivers/panfrost/pan_context.c +++ b/src/gallium/drivers/panfrost/pan_context.c @@ -672,7 +672,7 @@ panfrost_stage_attributes(struct panfrost_context *ctx) * QED. */ - unsigned start = ctx->payloads[PIPE_SHADER_VERTEX].draw_start; + unsigned start = ctx->payloads[PIPE_SHADER_VERTEX].offset_start; for (unsigned i = 0; i < so->num_elements; ++i) { unsigned vbi = so->pipe[i].vertex_buffer_index; @@ -1617,8 +1617,8 @@ panfrost_draw_vbo( if (panfrost_scissor_culls_everything(ctx)) return; - ctx->payloads[PIPE_SHADER_VERTEX].draw_start = info->start; - ctx->payloads[PIPE_SHADER_FRAGMENT].draw_start = info->start; + ctx->payloads[PIPE_SHADER_VERTEX].offset_start = info->start; + ctx->payloads[PIPE_SHADER_FRAGMENT].offset_start = info->start; int mode = info->mode; @@ -1655,7 +1655,8 @@ panfrost_draw_vbo( ctx->payloads[PIPE_SHADER_FRAGMENT].prefix.draw_mode = g2m_draw_mode(mode); - ctx->vertex_count = info->count; + /* Take into account a negative bias */ + ctx->vertex_count = info->count + abs(info->index_bias); ctx->instance_count = info->instance_count; /* For non-indexed draws, they're the same */ @@ -1704,14 +1705,13 @@ panfrost_draw_vbo( /* Use the corresponding values */ vertex_count = max_index - min_index + 1; - ctx->payloads[PIPE_SHADER_VERTEX].draw_start = min_index; - ctx->payloads[PIPE_SHADER_FRAGMENT].draw_start = min_index; + ctx->payloads[PIPE_SHADER_VERTEX].offset_start = min_index + info->index_bias; + ctx->payloads[PIPE_SHADER_FRAGMENT].offset_start = min_index + info->index_bias; - ctx->payloads[PIPE_SHADER_FRAGMENT].prefix.negative_start = -min_index; + ctx->payloads[PIPE_SHADER_FRAGMENT].prefix.offset_bias_correction = -min_index; ctx->payloads[PIPE_SHADER_FRAGMENT].prefix.index_count = MALI_POSITIVE(info->count); //assert(!info->restart_index); /* TODO: Research */ - assert(!info->index_bias); draw_flags |= panfrost_translate_index_size(info->index_size); ctx->payloads[PIPE_SHADER_FRAGMENT].prefix.indices = panfrost_get_index_buffer_mapped(ctx, info); @@ -1719,7 +1719,7 @@ panfrost_draw_vbo( /* Index count == vertex count, if no indexing is applied, as * if it is internally indexed in the expected order */ - ctx->payloads[PIPE_SHADER_FRAGMENT].prefix.negative_start = 0; + ctx->payloads[PIPE_SHADER_FRAGMENT].prefix.offset_bias_correction = 0; ctx->payloads[PIPE_SHADER_FRAGMENT].prefix.index_count = MALI_POSITIVE(ctx->vertex_count); /* Reverse index state */ diff --git a/src/panfrost/include/panfrost-job.h b/src/panfrost/include/panfrost-job.h index 9179ceff2ec..98d77e718fc 100644 --- a/src/panfrost/include/panfrost-job.h +++ b/src/panfrost/include/panfrost-job.h @@ -935,8 +935,23 @@ struct mali_vertex_tiler_prefix { u32 workgroups_x_shift_3 : 6; - /* Negative of draw_start for TILER jobs from what I've seen */ - int32_t negative_start; + /* Negative of min_index. This is used to compute + * the unbiased index in tiler/fragment shader runs. + * + * The hardware adds offset_bias_correction in each run, + * so that absent an index bias, the first vertex processed is + * genuinely the first vertex (0). But with an index bias, + * the first vertex process is numbered the same as the bias. + * + * To represent this more conviniently: + * unbiased_index = lower_bound_index + + * index_bias + + * offset_bias_correction + * + * This is done since the hardware doesn't accept a index_bias + * and this allows it to recover the unbiased index. + */ + int32_t offset_bias_correction; u32 zero1; /* Like many other strictly nonzero quantities, index_count is @@ -1080,7 +1095,7 @@ struct midgard_payload_vertex_tiler { u8 zero4; /* Offset for first vertex in buffer */ - u32 draw_start; + u32 offset_start; u64 zero5; diff --git a/src/panfrost/pandecode/decode.c b/src/panfrost/pandecode/decode.c index 080d650fc5a..78f6da6e56c 100644 --- a/src/panfrost/pandecode/decode.c +++ b/src/panfrost/pandecode/decode.c @@ -1334,8 +1334,8 @@ pandecode_vertex_tiler_prefix(struct mali_vertex_tiler_prefix *p, int job_no) if (p->index_count) pandecode_prop("index_count = MALI_POSITIVE(%" PRId32 ")", p->index_count + 1); - if (p->negative_start) - pandecode_prop("negative_start = %d", p->negative_start); + if (p->offset_bias_correction) + pandecode_prop("offset_bias_correction = %d", p->offset_bias_correction); DYN_MEMORY_PROP(p, job_no, indices); @@ -2181,8 +2181,8 @@ pandecode_vertex_or_tiler_job_mdg(const struct mali_job_descriptor_header *h, pandecode_padded_vertices(v->instance_shift, v->instance_odd); } - if (v->draw_start) - pandecode_prop("draw_start = %d", v->draw_start); + if (v->offset_start) + pandecode_prop("offset_start = %d", v->offset_start); if (v->zero5) { pandecode_msg("Zero tripped\n");