mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 04:48:08 +02:00
nouveau: send back a debug message when waiting for a fence to complete
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
This commit is contained in:
parent
4f6cd5fad0
commit
ba093a099a
10 changed files with 30 additions and 16 deletions
|
|
@ -225,21 +225,22 @@ nouveau_transfer_write(struct nouveau_context *nv, struct nouveau_transfer *tx,
|
|||
* for write/read by waiting on the buffer's relevant fences.
|
||||
*/
|
||||
static inline bool
|
||||
nouveau_buffer_sync(struct nv04_resource *buf, unsigned rw)
|
||||
nouveau_buffer_sync(struct nouveau_context *nv,
|
||||
struct nv04_resource *buf, unsigned rw)
|
||||
{
|
||||
if (rw == PIPE_TRANSFER_READ) {
|
||||
if (!buf->fence_wr)
|
||||
return true;
|
||||
NOUVEAU_DRV_STAT_RES(buf, buf_non_kernel_fence_sync_count,
|
||||
!nouveau_fence_signalled(buf->fence_wr));
|
||||
if (!nouveau_fence_wait(buf->fence_wr))
|
||||
if (!nouveau_fence_wait(buf->fence_wr, &nv->debug))
|
||||
return false;
|
||||
} else {
|
||||
if (!buf->fence)
|
||||
return true;
|
||||
NOUVEAU_DRV_STAT_RES(buf, buf_non_kernel_fence_sync_count,
|
||||
!nouveau_fence_signalled(buf->fence));
|
||||
if (!nouveau_fence_wait(buf->fence))
|
||||
if (!nouveau_fence_wait(buf->fence, &nv->debug))
|
||||
return false;
|
||||
|
||||
nouveau_fence_ref(NULL, &buf->fence);
|
||||
|
|
@ -478,7 +479,7 @@ nouveau_buffer_transfer_map(struct pipe_context *pipe,
|
|||
if (unlikely(usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE)) {
|
||||
/* Discarding was not possible, must sync because
|
||||
* subsequent transfers might use UNSYNCHRONIZED. */
|
||||
nouveau_buffer_sync(buf, usage & PIPE_TRANSFER_READ_WRITE);
|
||||
nouveau_buffer_sync(nv, buf, usage & PIPE_TRANSFER_READ_WRITE);
|
||||
} else
|
||||
if (usage & PIPE_TRANSFER_DISCARD_RANGE) {
|
||||
/* The whole range is being discarded, so it doesn't matter what was
|
||||
|
|
@ -490,7 +491,7 @@ nouveau_buffer_transfer_map(struct pipe_context *pipe,
|
|||
if (usage & PIPE_TRANSFER_DONTBLOCK)
|
||||
map = NULL;
|
||||
else
|
||||
nouveau_buffer_sync(buf, usage & PIPE_TRANSFER_READ_WRITE);
|
||||
nouveau_buffer_sync(nv, buf, usage & PIPE_TRANSFER_READ_WRITE);
|
||||
} else {
|
||||
/* It is expected that the returned buffer be a representation of the
|
||||
* data in question, so we must copy it over from the buffer. */
|
||||
|
|
@ -615,7 +616,7 @@ nouveau_resource_map_offset(struct nouveau_context *nv,
|
|||
if (res->mm) {
|
||||
unsigned rw;
|
||||
rw = (flags & NOUVEAU_BO_WR) ? PIPE_TRANSFER_WRITE : PIPE_TRANSFER_READ;
|
||||
nouveau_buffer_sync(res, rw);
|
||||
nouveau_buffer_sync(nv, res, rw);
|
||||
if (nouveau_bo_map(res->bo, 0, NULL))
|
||||
return NULL;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#define __NOUVEAU_CONTEXT_H__
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_state.h"
|
||||
#include <nouveau.h>
|
||||
|
||||
#define NOUVEAU_MAX_SCRATCH_BUFS 4
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "nouveau_screen.h"
|
||||
#include "nouveau_winsys.h"
|
||||
#include "nouveau_fence.h"
|
||||
#include "os/os_time.h"
|
||||
|
||||
#ifdef PIPE_OS_UNIX
|
||||
#include <sched.h>
|
||||
|
|
@ -182,10 +183,11 @@ nouveau_fence_signalled(struct nouveau_fence *fence)
|
|||
}
|
||||
|
||||
bool
|
||||
nouveau_fence_wait(struct nouveau_fence *fence)
|
||||
nouveau_fence_wait(struct nouveau_fence *fence, struct pipe_debug_callback *debug)
|
||||
{
|
||||
struct nouveau_screen *screen = fence->screen;
|
||||
uint32_t spins = 0;
|
||||
int64_t start = 0;
|
||||
|
||||
/* wtf, someone is waiting on a fence in flush_notify handler? */
|
||||
assert(fence->state != NOUVEAU_FENCE_STATE_EMITTING);
|
||||
|
|
@ -206,11 +208,19 @@ nouveau_fence_wait(struct nouveau_fence *fence)
|
|||
if (fence == screen->fence.current)
|
||||
nouveau_fence_next(screen);
|
||||
|
||||
if (debug && debug->debug_message)
|
||||
start = os_time_get_nano();
|
||||
|
||||
do {
|
||||
nouveau_fence_update(screen, false);
|
||||
|
||||
if (fence->state == NOUVEAU_FENCE_STATE_SIGNALLED)
|
||||
if (fence->state == NOUVEAU_FENCE_STATE_SIGNALLED) {
|
||||
if (debug && debug->debug_message)
|
||||
pipe_debug_message(debug, PERF_INFO,
|
||||
"stalled %.3f ms waiting for fence",
|
||||
(os_time_get_nano() - start) / 1000000.f);
|
||||
return true;
|
||||
}
|
||||
if (!spins)
|
||||
NOUVEAU_DRV_STAT(screen, any_non_kernel_fence_sync_count, 1);
|
||||
spins++;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@
|
|||
#define NOUVEAU_FENCE_STATE_FLUSHED 3
|
||||
#define NOUVEAU_FENCE_STATE_SIGNALLED 4
|
||||
|
||||
struct pipe_debug_callback;
|
||||
|
||||
struct nouveau_fence_work {
|
||||
struct list_head list;
|
||||
void (*func)(void *);
|
||||
|
|
@ -34,7 +36,7 @@ bool nouveau_fence_new(struct nouveau_screen *, struct nouveau_fence **,
|
|||
bool nouveau_fence_work(struct nouveau_fence *, void (*)(void *), void *);
|
||||
void nouveau_fence_update(struct nouveau_screen *, bool flushed);
|
||||
void nouveau_fence_next(struct nouveau_screen *);
|
||||
bool nouveau_fence_wait(struct nouveau_fence *);
|
||||
bool nouveau_fence_wait(struct nouveau_fence *, struct pipe_debug_callback *);
|
||||
bool nouveau_fence_signalled(struct nouveau_fence *);
|
||||
|
||||
void nouveau_fence_unref_bo(void *data); /* generic unref bo callback */
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ nouveau_screen_fence_finish(struct pipe_screen *screen,
|
|||
if (!timeout)
|
||||
return nouveau_fence_signalled(nouveau_fence(pfence));
|
||||
|
||||
return nouveau_fence_wait(nouveau_fence(pfence));
|
||||
return nouveau_fence_wait(nouveau_fence(pfence), NULL);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -383,7 +383,7 @@ nv30_screen_destroy(struct pipe_screen *pscreen)
|
|||
* _current_ one, and remove both.
|
||||
*/
|
||||
nouveau_fence_ref(screen->base.fence.current, ¤t);
|
||||
nouveau_fence_wait(current);
|
||||
nouveau_fence_wait(current, NULL);
|
||||
nouveau_fence_ref(NULL, ¤t);
|
||||
nouveau_fence_ref(NULL, &screen->base.fence.current);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -350,7 +350,7 @@ nv50_screen_destroy(struct pipe_screen *pscreen)
|
|||
* _current_ one, and remove both.
|
||||
*/
|
||||
nouveau_fence_ref(screen->base.fence.current, ¤t);
|
||||
nouveau_fence_wait(current);
|
||||
nouveau_fence_wait(current, NULL);
|
||||
nouveau_fence_ref(NULL, ¤t);
|
||||
nouveau_fence_ref(NULL, &screen->base.fence.current);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -636,7 +636,7 @@ nv50_draw_elements(struct nv50_context *nv50, bool shorten,
|
|||
* pushbuf submit, but it's probably not a big performance difference.
|
||||
*/
|
||||
if (buf->fence_wr && !nouveau_fence_signalled(buf->fence_wr))
|
||||
nouveau_fence_wait(buf->fence_wr);
|
||||
nouveau_fence_wait(buf->fence_wr, &nv50->base.debug);
|
||||
|
||||
while (instance_count--) {
|
||||
BEGIN_NV04(push, NV50_3D(VERTEX_BEGIN_GL), 1);
|
||||
|
|
|
|||
|
|
@ -415,7 +415,7 @@ nvc0_screen_destroy(struct pipe_screen *pscreen)
|
|||
* _current_ one, and remove both.
|
||||
*/
|
||||
nouveau_fence_ref(screen->base.fence.current, ¤t);
|
||||
nouveau_fence_wait(current);
|
||||
nouveau_fence_wait(current, NULL);
|
||||
nouveau_fence_ref(NULL, ¤t);
|
||||
nouveau_fence_ref(NULL, &screen->base.fence.current);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -340,8 +340,8 @@ nvc0_mt_sync(struct nvc0_context *nvc0, struct nv50_miptree *mt, unsigned usage)
|
|||
return !nouveau_bo_wait(mt->base.bo, access, nvc0->base.client);
|
||||
}
|
||||
if (usage & PIPE_TRANSFER_WRITE)
|
||||
return !mt->base.fence || nouveau_fence_wait(mt->base.fence);
|
||||
return !mt->base.fence_wr || nouveau_fence_wait(mt->base.fence_wr);
|
||||
return !mt->base.fence || nouveau_fence_wait(mt->base.fence, &nvc0->base.debug);
|
||||
return !mt->base.fence_wr || nouveau_fence_wait(mt->base.fence_wr, &nvc0->base.debug);
|
||||
}
|
||||
|
||||
void *
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue