mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-09 17:00:13 +01:00
v3d: Update prim_counts when prims generated query in flight without TF
In order to implement GL_PRIMITIVES_GENERATED, v3d allocates a small
resource and adds a command to the job to store the prim counts to it.
However it was only doing this when TF was enabled which meant that if
the query was used with a geometry shader but no TF then the query would
always be zero. This patch makes the driver keep track of how many
PRIMITIVES_GENERATED queries are in flight and then enable writing the
prim count if its more than zero.
Fix dEQP-GLES31.functional.geometry_shading.query.primitives_generated_*
v2: Update CI expectations and references to fixed tests in commit log.
v3: - Add comment that GL_PRIMITIVES_GENERATED query is included because
OES_geometry_shader, but it is not part of OpenGL ES 3.1. (Iago)
- Update Fixes to commit introducing geometry shaders. (Iago)
Fixes: a1b7c084 ("v3d: fix primitive queries for geometry shaders")
Signed-off-by: Neil Roberts <nroberts@igalia.com>
Signed-off-by: Jose Maria Casanova Crespo <jmcasanova@igalia.com>
Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13712>
(cherry picked from commit bdaf185889)
This commit is contained in:
parent
a728b8a732
commit
fdc6d4dc95
8 changed files with 44 additions and 19 deletions
|
|
@ -1687,7 +1687,7 @@
|
|||
"description": "v3d: Update prim_counts when prims generated query in flight without TF",
|
||||
"nominated": true,
|
||||
"nomination_type": 1,
|
||||
"resolution": 0,
|
||||
"resolution": 1,
|
||||
"main_sha": null,
|
||||
"because_sha": "a1b7c0844ddcbdc5ab773cbe2f6312f34111bdd9"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,8 +1,3 @@
|
|||
dEQP-GLES31.functional.geometry_shading.query.primitives_generated_amplification,Fail
|
||||
dEQP-GLES31.functional.geometry_shading.query.primitives_generated_instanced,Fail
|
||||
dEQP-GLES31.functional.geometry_shading.query.primitives_generated_no_amplification,Fail
|
||||
dEQP-GLES31.functional.geometry_shading.query.primitives_generated_partial_primitives,Fail
|
||||
|
||||
glx@glx-make-current,Crash
|
||||
glx@glx-multi-window-single-context,Fail
|
||||
glx@glx-multithread-buffer,Fail
|
||||
|
|
|
|||
|
|
@ -193,6 +193,20 @@ v3d_get_real_line_width(struct v3d_context *v3d)
|
|||
return width;
|
||||
}
|
||||
|
||||
void
|
||||
v3d_ensure_prim_counts_allocated(struct v3d_context *ctx)
|
||||
{
|
||||
if (ctx->prim_counts)
|
||||
return;
|
||||
|
||||
/* Init all 7 counters and 1 padding to 0 */
|
||||
uint32_t zeroes[8] = { 0 };
|
||||
u_upload_data(ctx->uploader,
|
||||
0, sizeof(zeroes), 32, zeroes,
|
||||
&ctx->prim_counts_offset,
|
||||
&ctx->prim_counts);
|
||||
}
|
||||
|
||||
void
|
||||
v3d_flag_dirty_sampler_state(struct v3d_context *v3d,
|
||||
enum pipe_shader_type shader)
|
||||
|
|
|
|||
|
|
@ -447,6 +447,8 @@ struct v3d_job {
|
|||
*/
|
||||
bool tf_enabled;
|
||||
|
||||
bool needs_primitives_generated;
|
||||
|
||||
/**
|
||||
* Current EZ state for drawing. Updated at the start of draw after
|
||||
* we've decided on the shader being rendered.
|
||||
|
|
@ -574,6 +576,8 @@ struct v3d_context {
|
|||
uint32_t tf_prims_generated;
|
||||
uint32_t prims_generated;
|
||||
|
||||
uint32_t n_primitives_generated_queries_in_flight;
|
||||
|
||||
struct pipe_poly_stipple stipple;
|
||||
struct pipe_clip_state clip;
|
||||
struct pipe_viewport_state viewport;
|
||||
|
|
@ -764,6 +768,8 @@ bool v3d_line_smoothing_enabled(struct v3d_context *v3d);
|
|||
|
||||
float v3d_get_real_line_width(struct v3d_context *v3d);
|
||||
|
||||
void v3d_ensure_prim_counts_allocated(struct v3d_context *ctx);
|
||||
|
||||
void v3d_flag_dirty_sampler_state(struct v3d_context *v3d,
|
||||
enum pipe_shader_type shader);
|
||||
|
||||
|
|
|
|||
|
|
@ -482,6 +482,16 @@ v3d_job_submit(struct v3d_context *v3d, struct v3d_job *job)
|
|||
if (!job->needs_flush)
|
||||
goto done;
|
||||
|
||||
/* The GL_PRIMITIVES_GENERATED query is included with
|
||||
* OES_geometry_shader.
|
||||
*/
|
||||
job->needs_primitives_generated =
|
||||
v3d->n_primitives_generated_queries_in_flight > 0 &&
|
||||
v3d->prog.gs;
|
||||
|
||||
if (job->needs_primitives_generated)
|
||||
v3d_ensure_prim_counts_allocated(v3d);
|
||||
|
||||
if (screen->devinfo.ver >= 41)
|
||||
v3d41_emit_rcl(job);
|
||||
else
|
||||
|
|
@ -553,9 +563,11 @@ v3d_job_submit(struct v3d_context *v3d, struct v3d_job *job)
|
|||
}
|
||||
|
||||
/* If we are submitting a job in the middle of transform
|
||||
* feedback we need to read the primitive counts and accumulate
|
||||
* them, otherwise they will be reset at the start of the next
|
||||
* draw when we emit the Tile Binning Mode Configuration packet.
|
||||
* feedback or there is a primitives generated query with a
|
||||
* geometry shader then we need to read the primitive counts
|
||||
* and accumulate them, otherwise they will be reset at the
|
||||
* start of the next draw when we emit the Tile Binning Mode
|
||||
* Configuration packet.
|
||||
*
|
||||
* If the job doesn't have any TF draw calls, then we know
|
||||
* the primitive count must be zero and we can skip stalling
|
||||
|
|
@ -565,7 +577,9 @@ v3d_job_submit(struct v3d_context *v3d, struct v3d_job *job)
|
|||
* to us reading an obsolete (possibly non-zero) value from
|
||||
* the GPU counters.
|
||||
*/
|
||||
if (v3d->streamout.num_targets && job->tf_draw_calls_queued > 0)
|
||||
if (job->needs_primitives_generated ||
|
||||
(v3d->streamout.num_targets &&
|
||||
job->tf_draw_calls_queued > 0))
|
||||
v3d_read_and_accumulate_primitive_counters(v3d);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ v3d_begin_query_pipe(struct v3d_context *v3d, struct v3d_query *query)
|
|||
if (v3d->prog.gs)
|
||||
v3d_update_primitive_counters(v3d);
|
||||
pquery->start = v3d->prims_generated;
|
||||
v3d->n_primitives_generated_queries_in_flight++;
|
||||
break;
|
||||
case PIPE_QUERY_PRIMITIVES_EMITTED:
|
||||
/* If we are inside transform feedback we need to update the
|
||||
|
|
@ -109,6 +110,7 @@ v3d_end_query_pipe(struct v3d_context *v3d, struct v3d_query *query)
|
|||
if (v3d->prog.gs)
|
||||
v3d_update_primitive_counters(v3d);
|
||||
pquery->end = v3d->prims_generated;
|
||||
v3d->n_primitives_generated_queries_in_flight--;
|
||||
break;
|
||||
case PIPE_QUERY_PRIMITIVES_EMITTED:
|
||||
/* If transform feedback has ended, then we have already
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ void v3dX(bcl_epilogue)(struct v3d_context *v3d, struct v3d_job *job)
|
|||
#endif
|
||||
cl_packet_length(FLUSH));
|
||||
|
||||
if (job->tf_enabled) {
|
||||
if (job->tf_enabled || job->needs_primitives_generated) {
|
||||
/* Write primitive counts to memory. */
|
||||
assert(v3d->prim_counts);
|
||||
struct v3d_resource *rsc =
|
||||
|
|
|
|||
|
|
@ -1243,14 +1243,8 @@ v3d_set_stream_output_targets(struct pipe_context *pctx,
|
|||
so->num_targets = num_targets;
|
||||
|
||||
/* Create primitive counters BO if needed */
|
||||
if (num_targets > 0 && !ctx->prim_counts) {
|
||||
/* Init all 7 counters and 1 padding to 0 */
|
||||
uint32_t zeroes[8] = { 0 };
|
||||
u_upload_data(ctx->uploader,
|
||||
0, sizeof(zeroes), 32, zeroes,
|
||||
&ctx->prim_counts_offset,
|
||||
&ctx->prim_counts);
|
||||
}
|
||||
if (num_targets > 0)
|
||||
v3d_ensure_prim_counts_allocated(ctx);
|
||||
|
||||
ctx->dirty |= V3D_DIRTY_STREAMOUT;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue