1 #include "vblank.h" /* for DO_USLEEP */
3 #include "nouveau_context.h"
4 #include "nouveau_buffers.h"
5 #include "nouveau_object.h"
6 #include "nouveau_fifo.h"
7 #include "nouveau_reg.h"
8 #include "nouveau_msg.h"
9 #include "nouveau_sync.h"
12 nouveau_notifier_new(GLcontext *ctx, GLuint handle)
14 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
15 nouveau_notifier *notifier;
17 #ifdef NOUVEAU_RING_DEBUG
21 notifier = CALLOC_STRUCT(nouveau_notifier_t);
25 notifier->mem = nouveau_mem_alloc(ctx,
26 NOUVEAU_MEM_FB | NOUVEAU_MEM_MAPPED,
34 if (!nouveauCreateDmaObject(nmesa, handle, notifier->mem->offset,
36 0 /* NV_DMA_TARGET_FB */,
37 0 /* NV_DMA_ACCESS_RW */)) {
38 nouveau_mem_free(ctx, notifier->mem);
43 notifier->handle = handle;
48 nouveau_notifier_destroy(GLcontext *ctx, nouveau_notifier *notifier)
50 /*XXX: free DMA object.. */
51 nouveau_mem_free(ctx, notifier->mem);
56 nouveau_notifier_reset(nouveau_notifier *notifier)
58 volatile GLuint *n = notifier->mem->map;
60 #ifdef NOUVEAU_RING_DEBUG
64 n[NV_NOTIFY_TIME_0 /4] = 0x00000000;
65 n[NV_NOTIFY_TIME_1 /4] = 0x00000000;
66 n[NV_NOTIFY_RETURN_VALUE/4] = 0x00000000;
67 n[NV_NOTIFY_STATE /4] = (NV_NOTIFY_STATE_STATUS_IN_PROCESS <<
68 NV_NOTIFY_STATE_STATUS_SHIFT);
72 nouveau_notifier_wait_status(nouveau_notifier *notifier, GLuint status,
75 volatile GLuint *n = notifier->mem->map;
76 unsigned int time = 0;
78 #ifdef NOUVEAU_RING_DEBUG
82 while (time <= timeout) {
83 if (n[NV_NOTIFY_STATE/4] & NV_NOTIFY_STATE_ERROR_CODE_MASK) {
84 MESSAGE("Notifier returned error: 0x%04x\n",
86 NV_NOTIFY_STATE_ERROR_CODE_MASK);
90 if (((n[NV_NOTIFY_STATE/4] & NV_NOTIFY_STATE_STATUS_MASK) >>
91 NV_NOTIFY_STATE_STATUS_SHIFT) == status)
100 MESSAGE("Notifier timed out\n");
105 nouveau_notifier_wait_nop(GLcontext *ctx, nouveau_notifier *notifier,
108 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
111 nouveau_notifier_reset(notifier);
113 BEGIN_RING_SIZE(subc, NV_NOTIFY, 1);
114 OUT_RING (NV_NOTIFY_STYLE_WRITE_ONLY);
115 BEGIN_RING_SIZE(subc, NV_NOP, 1);
119 ret = nouveau_notifier_wait_status(notifier,
120 NV_NOTIFY_STATE_STATUS_COMPLETED,
122 if (ret == GL_FALSE) MESSAGE("wait on notifier failed\n");
125 GLboolean nouveauSyncInitFuncs(GLcontext *ctx)
127 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
129 #ifdef NOUVEAU_RING_DEBUG
133 nmesa->syncNotifier = nouveau_notifier_new(ctx, NvSyncNotify);
134 if (!nmesa->syncNotifier) {
135 MESSAGE("Failed to create channel sync notifier\n");
139 /* 0x180 is SET_DMA_NOTIFY, should be correct for all supported 3D
142 BEGIN_RING_CACHE(NvSub3D, 0x180, 1);
143 OUT_RING_CACHE (NvSyncNotify);
144 #ifdef ALLOW_MULTI_SUBCHANNEL
145 BEGIN_RING_SIZE(NvSubMemFormat,
146 NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1);
147 OUT_RING (NvSyncNotify);