diff options
author | Lucas Stach <[email protected]> | 2017-05-18 18:20:12 +0200 |
---|---|---|
committer | Lucas Stach <[email protected]> | 2017-06-08 18:29:36 +0200 |
commit | c3b2c7a75f1ef6306d0218d92564319d22cfc8fe (patch) | |
tree | fd5519ca3dd83ae23662ebe4962b80dddcb15bed /src/gallium/drivers/etnaviv/etnaviv_transfer.c | |
parent | a276c32a08bd41ceb8fd9b604ba9ac8229d59b64 (diff) |
etnaviv: honor PIPE_TRANSFER_UNSYNCHRONIZED flag
This gets rid of quite a bit of CPU/GPU sync on frequent vertex buffer
uploads and I haven't seen any of the issues mentioned in the comment,
so this one seems stale.
Ignore the flag if there exists a temporary resource, as those ones are
never busy.
Signed-off-by: Lucas Stach <[email protected]>
Reviewed-by: Wladimir J. van der Laan <[email protected]>
Diffstat (limited to 'src/gallium/drivers/etnaviv/etnaviv_transfer.c')
-rw-r--r-- | src/gallium/drivers/etnaviv/etnaviv_transfer.c | 35 |
1 files changed, 23 insertions, 12 deletions
diff --git a/src/gallium/drivers/etnaviv/etnaviv_transfer.c b/src/gallium/drivers/etnaviv/etnaviv_transfer.c index 269bd498f89..4ead6dff7f4 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_transfer.c +++ b/src/gallium/drivers/etnaviv/etnaviv_transfer.c @@ -70,6 +70,10 @@ etna_transfer_unmap(struct pipe_context *pctx, struct pipe_transfer *ptrans) if (rsc->texture && !etna_resource_newer(rsc, etna_resource(rsc->texture))) rsc = etna_resource(rsc->texture); /* switch to using the texture resource */ + /* + * Temporary resources are always pulled into the CPU domain, must push them + * back into GPU domain before the RS execs the blit to the base resource. + */ if (trans->rsc) etna_bo_cpu_fini(etna_resource(trans->rsc)->bo); @@ -114,7 +118,12 @@ etna_transfer_unmap(struct pipe_context *pctx, struct pipe_transfer *ptrans) } } - if (!trans->rsc) + /* + * Transfers without a temporary are only pulled into the CPU domain if they + * are not mapped unsynchronized. If they are, must push them back into GPU + * domain after CPU access is finished. + */ + if (!trans->rsc && !(ptrans->usage & PIPE_TRANSFER_UNSYNCHRONIZED)) etna_bo_cpu_fini(rsc->bo); pipe_resource_reference(&trans->rsc, NULL); @@ -260,19 +269,21 @@ etna_transfer_map(struct pipe_context *pctx, struct pipe_resource *prsc, (rsc->layout == ETNA_LAYOUT_TILED && util_format_is_compressed(prsc->format)); - /* Ignore PIPE_TRANSFER_UNSYNCHRONIZED and PIPE_TRANSFER_DONTBLOCK here. - * It appears that Gallium operates the index/vertex buffers in a - * circular fashion, and the CPU can catch up with the GPU and starts - * overwriting yet-to-be-processed entries, causing rendering corruption. */ - uint32_t prep_flags = 0; + /* + * Pull resources into the CPU domain. Only skipped for unsynchronized + * transfers without a temporary resource. + */ + if (trans->rsc || !(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) { + uint32_t prep_flags = 0; - if (usage & PIPE_TRANSFER_READ) - prep_flags |= DRM_ETNA_PREP_READ; - if (usage & PIPE_TRANSFER_WRITE) - prep_flags |= DRM_ETNA_PREP_WRITE; + if (usage & PIPE_TRANSFER_READ) + prep_flags |= DRM_ETNA_PREP_READ; + if (usage & PIPE_TRANSFER_WRITE) + prep_flags |= DRM_ETNA_PREP_WRITE; - if (etna_bo_cpu_prep(rsc->bo, prep_flags)) - goto fail_prep; + if (etna_bo_cpu_prep(rsc->bo, prep_flags)) + goto fail_prep; + } /* map buffer object */ void *mapped = etna_bo_map(rsc->bo); |