v3d: Set the SO offsets correctly if we have to re-emit.
This should fix TF across a glFlush() or TF pause/restart. Fixes dEQP-GLES3.functional.transform_feedback.array.interleaved.lines.highp_float and many, many others.
This commit is contained in:
@@ -189,6 +189,8 @@ struct v3d_vertex_stateobj {
|
|||||||
|
|
||||||
struct v3d_streamout_stateobj {
|
struct v3d_streamout_stateobj {
|
||||||
struct pipe_stream_output_target *targets[PIPE_MAX_SO_BUFFERS];
|
struct pipe_stream_output_target *targets[PIPE_MAX_SO_BUFFERS];
|
||||||
|
/* Number of vertices we've written into the buffer so far. */
|
||||||
|
uint32_t offsets[PIPE_MAX_SO_BUFFERS];
|
||||||
unsigned num_targets;
|
unsigned num_targets;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -152,6 +152,8 @@ v3d_set_transform_feedback_outputs(struct v3d_uncompiled_shader *so,
|
|||||||
vpm_start_offset += write_size;
|
vpm_start_offset += write_size;
|
||||||
vpm_size -= write_size;
|
vpm_size -= write_size;
|
||||||
}
|
}
|
||||||
|
so->base.stream_output.stride[buffer] =
|
||||||
|
stream_output->stride[buffer];
|
||||||
}
|
}
|
||||||
|
|
||||||
so->num_tf_outputs = slot_count;
|
so->num_tf_outputs = slot_count;
|
||||||
|
@@ -557,6 +557,12 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
|
|||||||
}
|
}
|
||||||
job->draw_calls_queued++;
|
job->draw_calls_queued++;
|
||||||
|
|
||||||
|
/* Increment the TF offsets by how many verts we wrote. XXX: This
|
||||||
|
* needs some clamping to the buffer size.
|
||||||
|
*/
|
||||||
|
for (int i = 0; i < v3d->streamout.num_targets; i++)
|
||||||
|
v3d->streamout.offsets[i] += info->count;
|
||||||
|
|
||||||
if (v3d->zsa && job->zsbuf &&
|
if (v3d->zsa && job->zsbuf &&
|
||||||
(v3d->zsa->base.depth.enabled ||
|
(v3d->zsa->base.depth.enabled ||
|
||||||
v3d->zsa->base.stencil[0].enabled)) {
|
v3d->zsa->base.stencil[0].enabled)) {
|
||||||
|
@@ -694,6 +694,10 @@ v3dX(emit_state)(struct pipe_context *pctx)
|
|||||||
so->targets[i];
|
so->targets[i];
|
||||||
struct v3d_resource *rsc = target ?
|
struct v3d_resource *rsc = target ?
|
||||||
v3d_resource(target->buffer) : NULL;
|
v3d_resource(target->buffer) : NULL;
|
||||||
|
struct pipe_shader_state *vs = &v3d->prog.bind_vs->base;
|
||||||
|
struct pipe_stream_output_info *info = &vs->stream_output;
|
||||||
|
uint32_t offset = (v3d->streamout.offsets[i] *
|
||||||
|
info->stride[i] * 4);
|
||||||
|
|
||||||
#if V3D_VERSION >= 40
|
#if V3D_VERSION >= 40
|
||||||
if (!target)
|
if (!target)
|
||||||
@@ -702,9 +706,10 @@ v3dX(emit_state)(struct pipe_context *pctx)
|
|||||||
cl_emit(&job->bcl, TRANSFORM_FEEDBACK_BUFFER, output) {
|
cl_emit(&job->bcl, TRANSFORM_FEEDBACK_BUFFER, output) {
|
||||||
output.buffer_address =
|
output.buffer_address =
|
||||||
cl_address(rsc->bo,
|
cl_address(rsc->bo,
|
||||||
target->buffer_offset);
|
target->buffer_offset +
|
||||||
|
offset);
|
||||||
output.buffer_size_in_32_bit_words =
|
output.buffer_size_in_32_bit_words =
|
||||||
target->buffer_size >> 2;
|
(target->buffer_size - offset) >> 2;
|
||||||
output.buffer_number = i;
|
output.buffer_number = i;
|
||||||
}
|
}
|
||||||
#else /* V3D_VERSION < 40 */
|
#else /* V3D_VERSION < 40 */
|
||||||
@@ -712,7 +717,8 @@ v3dX(emit_state)(struct pipe_context *pctx)
|
|||||||
if (target) {
|
if (target) {
|
||||||
output.address =
|
output.address =
|
||||||
cl_address(rsc->bo,
|
cl_address(rsc->bo,
|
||||||
target->buffer_offset);
|
target->buffer_offset +
|
||||||
|
offset);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif /* V3D_VERSION < 40 */
|
#endif /* V3D_VERSION < 40 */
|
||||||
|
@@ -902,8 +902,12 @@ v3d_set_stream_output_targets(struct pipe_context *pctx,
|
|||||||
|
|
||||||
assert(num_targets <= ARRAY_SIZE(so->targets));
|
assert(num_targets <= ARRAY_SIZE(so->targets));
|
||||||
|
|
||||||
for (i = 0; i < num_targets; i++)
|
for (i = 0; i < num_targets; i++) {
|
||||||
|
if (offsets[i] != -1)
|
||||||
|
so->offsets[i] = offsets[i];
|
||||||
|
|
||||||
pipe_so_target_reference(&so->targets[i], targets[i]);
|
pipe_so_target_reference(&so->targets[i], targets[i]);
|
||||||
|
}
|
||||||
|
|
||||||
for (; i < so->num_targets; i++)
|
for (; i < so->num_targets; i++)
|
||||||
pipe_so_target_reference(&so->targets[i], NULL);
|
pipe_so_target_reference(&so->targets[i], NULL);
|
||||||
|
Reference in New Issue
Block a user