iris: Support rebinding of stream output targets

This enables us to replace the backing storage of resources that have
been used as stream output targets, in case we're invalidating their
entire contents.  This can avoid stalls.  We simply hadn't supported it
because it was going to be tricky to re-emit 3DSTATE_SO_BUFFER without
screwing up "reset offset to zero" vs. "keep appending".  But that
should be working fine with the previous patch's refactor.

Reviewed-by: Zoltán Böszörményi <zboszor@gmail.com>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8964>
This commit is contained in:
Kenneth Graunke 2021-02-02 18:42:41 -08:00
parent 08e04ddd2c
commit ec0d61c14c
2 changed files with 18 additions and 6 deletions

View File

@ -1359,10 +1359,6 @@ iris_invalidate_resource(struct pipe_context *ctx,
if (res->bo->userptr)
return;
// XXX: We should support this.
if (res->bind_history & PIPE_BIND_STREAM_OUTPUT)
return;
struct iris_bo *old_bo = res->bo;
struct iris_bo *new_bo =
iris_bo_alloc(screen->bufmgr, res->bo->name, resource->width0,

View File

@ -7204,8 +7204,24 @@ iris_rebind_buffer(struct iris_context *ice,
*/
if (res->bind_history & PIPE_BIND_STREAM_OUTPUT) {
/* XXX: be careful about resetting vs appending... */
assert(false);
uint32_t *so_buffers = genx->so_buffers;
for (unsigned i = 0; i < 4; i++,
so_buffers += GENX(3DSTATE_SO_BUFFER_length)) {
/* There are no other fields in bits 127:64 */
uint64_t *addr = (uint64_t *) &so_buffers[2];
STATIC_ASSERT(GENX(3DSTATE_SO_BUFFER_SurfaceBaseAddress_start) == 66);
STATIC_ASSERT(GENX(3DSTATE_SO_BUFFER_SurfaceBaseAddress_bits) == 46);
struct pipe_stream_output_target *tgt = ice->state.so_target[i];
if (tgt) {
struct iris_bo *bo = iris_resource_bo(tgt->buffer);
if (*addr != bo->gtt_offset + tgt->buffer_offset) {
*addr = bo->gtt_offset + tgt->buffer_offset;
ice->state.dirty |= IRIS_DIRTY_SO_BUFFERS;
}
}
}
}
for (int s = MESA_SHADER_VERTEX; s < MESA_SHADER_STAGES; s++) {