summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAxel Davy <davyaxel0@gmail.com>2021-03-13 11:23:26 +0100
committerMarge Bot <eric+marge@anholt.net>2021-03-13 21:23:24 +0000
commitc23c3b7a7726a282e271374cd553a33bdb649d83 (patch)
tree4b0981f4191fddf92450cb3d6b64aeeb22621f77
parent205201c968cceeef1e8d3685851dcfd7e9e806c3 (diff)
st/nine: detect worker threads syncs for systemmem
If we detect too many syncs, use the stream_uploader, which avoid syncs. Signed-off-by: Axel Davy <davyaxel0@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9451>
-rw-r--r--src/gallium/frontends/nine/buffer9.c20
-rw-r--r--src/gallium/frontends/nine/buffer9.h1
-rw-r--r--src/gallium/frontends/nine/device9.c7
3 files changed, 16 insertions, 12 deletions
diff --git a/src/gallium/frontends/nine/buffer9.c b/src/gallium/frontends/nine/buffer9.c
index 92d95a27358..ed2f4ac9a2e 100644
--- a/src/gallium/frontends/nine/buffer9.c
+++ b/src/gallium/frontends/nine/buffer9.c
@@ -172,6 +172,7 @@ NineBuffer9_ctor( struct NineBuffer9 *This,
u_box_1d(0, 0, &This->managed.required_valid_region);
u_box_1d(0, 0, &This->managed.filled_region);
This->managed.can_unsynchronized = true;
+ This->managed.num_worker_thread_syncs = 0;
list_inithead(&This->managed.list);
list_inithead(&This->managed.list2);
list_add(&This->managed.list2, &pParams->device->managed_buffers);
@@ -309,6 +310,10 @@ NineBuffer9_Lock( struct NineBuffer9 *This,
} else {
if (!(Flags & (D3DLOCK_READONLY|D3DLOCK_NOOVERWRITE)) &&
p_atomic_read(&This->managed.pending_upload)) {
+ This->managed.num_worker_thread_syncs++;
+ /* If we sync too often, pick the vertex_uploader path */
+ if (This->managed.num_worker_thread_syncs >= 3)
+ This->managed.can_unsynchronized = false;
nine_csmt_process(This->base.base.device);
/* Note: AS DISCARD is not relevant for SYSTEMMEM,
* NOOVERWRITE might have a similar meaning as what is
@@ -620,12 +625,15 @@ NineBuffer9_Upload( struct NineBuffer9 *This )
* . The region to upload is very small compared to the filled region and
* at the start of the buffer (hints at round usage starting again)
* . The region to upload is very big compared to the required region
- * . We have not discarded yet this frame */
- if (filled_region->width > (This->size / 2) ||
- (10 * box_upload.width < filled_region->width &&
- box_upload.x < (filled_region->x + filled_region->width)/2) ||
- box_upload.width > 2 * required_valid_region->width ||
- This->managed.frame_count_last_discard != device->frame_count) {
+ * . We have not discarded yet this frame
+ * If the buffer use pattern seems to sync the worker thread too often,
+ * revert to the vertex_uploader */
+ if (This->managed.num_worker_thread_syncs < 3 &&
+ (filled_region->width > (This->size / 2) ||
+ (10 * box_upload.width < filled_region->width &&
+ box_upload.x < (filled_region->x + filled_region->width)/2) ||
+ box_upload.width > 2 * required_valid_region->width ||
+ This->managed.frame_count_last_discard != device->frame_count)) {
/* Avoid DISCARDING too much by discarding only if most of the buffer
* has been used */
DBG_FLAG(DBG_INDEXBUFFER|DBG_VERTEXBUFFER,
diff --git a/src/gallium/frontends/nine/buffer9.h b/src/gallium/frontends/nine/buffer9.h
index 275b03bf1b3..7d679700afb 100644
--- a/src/gallium/frontends/nine/buffer9.h
+++ b/src/gallium/frontends/nine/buffer9.h
@@ -76,6 +76,7 @@ struct NineBuffer9
struct pipe_box valid_region; /* Region in the GPU buffer with valid content */
struct pipe_box required_valid_region; /* Region that needs to be valid right now. */
struct pipe_box filled_region; /* Region in the GPU buffer filled since last discard */
+ unsigned num_worker_thread_syncs;
unsigned frame_count_last_discard;
} managed;
};
diff --git a/src/gallium/frontends/nine/device9.c b/src/gallium/frontends/nine/device9.c
index bb4f5c6e075..26f09944d54 100644
--- a/src/gallium/frontends/nine/device9.c
+++ b/src/gallium/frontends/nine/device9.c
@@ -300,12 +300,7 @@ NineDevice9_ctor( struct NineDevice9 *This,
/* r600, radeonsi and iris are thread safe. */
if (pCTX->csmt_force == 1)
This->csmt_active = true;
- else if (pCTX->csmt_force == 0 ||
- This->params.BehaviorFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING)
- /* We disable csmt for software vertex processing because for now
- * the csmt thread is too much synced for these due to the vertex
- * buffer implementation. These buffers are typically locked
- * without NOOVERWRITE between each draw call. */
+ else if (pCTX->csmt_force == 0)
This->csmt_active = false;
else if (strstr(pScreen->get_name(pScreen), "AMD") != NULL)
This->csmt_active = true;