Mesa (master): iris: Fix zeroing of transform feedback offsets in strange cases.
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Sat Apr 27 08:07:54 UTC 2019
Module: Mesa
Branch: master
Commit: 6bd4cb920e9c0b431df3ab2f5878b2b24182fd00
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=6bd4cb920e9c0b431df3ab2f5878b2b24182fd00
Author: Kenneth Graunke <kenneth at whitecape.org>
Date: Sat Apr 27 00:24:05 2019 -0700
iris: Fix zeroing of transform feedback offsets in strange cases.
Some of the dEQP.functional.transform_feedback tests end up doing
the following sequence of operations:
1. BeginTransformFeedback
2. PauseTransformFeedback
3. Draw
4. ResumeTransformFeedback
At step 1, we'd pack 3DSTATE_SO_BUFFER commands saying to zero the
SO_WRITE_OFFSET registers. At step 2, we disable streamout, so step 3
doesn't bother emitting those commands. Then, step 4 re-packs new
3DSTATE_SO_BUFFER commands with offset = 0xFFFFFFFF, saying to continue
appending at the existing offset. This loads the value from the BO as
the offsets - but we never actually zeroed it.
So, just maintain a flag saying "we actually emitted the commands",
and stomp offset back to zero until we emit some.
---
src/gallium/drivers/iris/iris_context.h | 3 +++
src/gallium/drivers/iris/iris_state.c | 19 +++++++++++++++----
2 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/src/gallium/drivers/iris/iris_context.h b/src/gallium/drivers/iris/iris_context.h
index 1153cb84bb9..51bbdb681e7 100644
--- a/src/gallium/drivers/iris/iris_context.h
+++ b/src/gallium/drivers/iris/iris_context.h
@@ -332,6 +332,9 @@ struct iris_stream_output_target {
/** Stride (dwords-per-vertex) during this transform feedback operation */
uint16_t stride;
+
+ /** Has 3DSTATE_SO_BUFFER actually been emitted, zeroing the offsets? */
+ bool zeroed;
};
/**
diff --git a/src/gallium/drivers/iris/iris_state.c b/src/gallium/drivers/iris/iris_state.c
index 04766716bc0..479703f30fa 100644
--- a/src/gallium/drivers/iris/iris_state.c
+++ b/src/gallium/drivers/iris/iris_state.c
@@ -2984,20 +2984,30 @@ iris_set_stream_output_targets(struct pipe_context *ctx,
for (unsigned i = 0; i < 4; i++,
so_buffers += GENX(3DSTATE_SO_BUFFER_length)) {
- if (i >= num_targets || !targets[i]) {
+ struct iris_stream_output_target *tgt = (void *) ice->state.so_target[i];
+ unsigned offset = offsets[i];
+
+ if (!tgt) {
iris_pack_command(GENX(3DSTATE_SO_BUFFER), so_buffers, sob)
sob.SOBufferIndex = i;
continue;
}
- struct iris_stream_output_target *tgt = (void *) targets[i];
struct iris_resource *res = (void *) tgt->base.buffer;
/* Note that offsets[i] will either be 0, causing us to zero
* the value in the buffer, or 0xFFFFFFFF, which happens to mean
* "continue appending at the existing offset."
*/
- assert(offsets[i] == 0 || offsets[i] == 0xFFFFFFFF);
+ assert(offset == 0 || offset == 0xFFFFFFFF);
+
+ /* We might be called by Begin (offset = 0), Pause, then Resume
+ * (offset = 0xFFFFFFFF) before ever drawing (where these commands
+ * will actually be sent to the GPU). In this case, we don't want
+ * to append - we still want to do our initial zeroing.
+ */
+ if (!tgt->zeroed)
+ offset = 0;
iris_pack_command(GENX(3DSTATE_SO_BUFFER), so_buffers, sob) {
sob.SurfaceBaseAddress =
@@ -3010,7 +3020,7 @@ iris_set_stream_output_targets(struct pipe_context *ctx,
sob.SurfaceSize = MAX2(tgt->base.buffer_size / 4, 1) - 1;
sob.SOBufferIndex = i;
- sob.StreamOffset = offsets[i];
+ sob.StreamOffset = offset;
sob.StreamOutputBufferOffsetAddress =
rw_bo(NULL, iris_resource_bo(tgt->offset.res)->gtt_offset +
tgt->offset.offset);
@@ -4717,6 +4727,7 @@ iris_upload_dirty_render_state(struct iris_context *ice,
struct iris_stream_output_target *tgt =
(void *) ice->state.so_target[i];
if (tgt) {
+ tgt->zeroed = true;
iris_use_pinned_bo(batch, iris_resource_bo(tgt->base.buffer),
true);
iris_use_pinned_bo(batch, iris_resource_bo(tgt->offset.res),
More information about the mesa-commit
mailing list