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 notifier
= CALLOC_STRUCT(nouveau_notifier_t
);
21 notifier
->mem
= nouveau_mem_alloc(ctx
,
22 NOUVEAU_MEM_FB
| NOUVEAU_MEM_MAPPED
,
30 if (!nouveauCreateDmaObject(nmesa
, handle
, notifier
->mem
->offset
,
32 0 /* NV_DMA_TARGET_FB */,
33 0 /* NV_DMA_ACCESS_RW */)) {
34 nouveau_mem_free(ctx
, notifier
->mem
);
39 notifier
->handle
= handle
;
44 nouveau_notifier_destroy(GLcontext
*ctx
, nouveau_notifier
*notifier
)
46 /*XXX: free DMA object.. */
47 nouveau_mem_free(ctx
, notifier
->mem
);
52 nouveau_notifier_reset(nouveau_notifier
*notifier
)
54 volatile GLuint
*n
= notifier
->mem
->map
;
56 n
[NV_NOTIFY_TIME_0
/4] = 0x00000000;
57 n
[NV_NOTIFY_TIME_1
/4] = 0x00000000;
58 n
[NV_NOTIFY_RETURN_VALUE
/4] = 0x00000000;
59 n
[NV_NOTIFY_STATE
/4] = (NV_NOTIFY_STATE_STATUS_IN_PROCESS
<<
60 NV_NOTIFY_STATE_STATUS_SHIFT
);
64 nouveau_notifier_wait_status(nouveau_notifier
*notifier
, GLuint status
,
67 volatile GLuint
*n
= notifier
->mem
->map
;
68 unsigned int time
= 0;
70 while (time
<= timeout
) {
71 if (n
[NV_NOTIFY_STATE
/4] & NV_NOTIFY_STATE_ERROR_CODE_MASK
) {
72 MESSAGE("Notifier returned error: 0x%04x\n",
74 NV_NOTIFY_STATE_ERROR_CODE_MASK
);
78 if (((n
[NV_NOTIFY_STATE
/4] & NV_NOTIFY_STATE_STATUS_MASK
) >>
79 NV_NOTIFY_STATE_STATUS_SHIFT
) == status
)
88 MESSAGE("Notifier timed out\n");
93 nouveau_notifier_wait_nop(GLcontext
*ctx
, nouveau_notifier
*notifier
,
96 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
99 nouveau_notifier_reset(notifier
);
101 BEGIN_RING_SIZE(subc
, NV_NOTIFY
, 1);
102 OUT_RING (NV_NOTIFY_STYLE_WRITE_ONLY
);
103 BEGIN_RING_SIZE(subc
, NV_NOP
, 1);
107 ret
= nouveau_notifier_wait_status(notifier
,
108 NV_NOTIFY_STATE_STATUS_COMPLETED
,
110 if (ret
== GL_FALSE
) MESSAGE("wait on notifier failed\n");
113 GLboolean
nouveauSyncInitFuncs(GLcontext
*ctx
)
115 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
117 nmesa
->syncNotifier
= nouveau_notifier_new(ctx
, NvSyncNotify
);
118 if (!nmesa
->syncNotifier
) {
119 MESSAGE("Failed to create channel sync notifier\n");
123 /* 0x180 is SET_DMA_NOTIFY, should be correct for all supported 3D
126 BEGIN_RING_CACHE(NvSub3D
, 0x180, 1);
127 OUT_RING_CACHE (NvSyncNotify
);
128 #ifdef ALLOW_MULTI_SUBCHANNEL
129 BEGIN_RING_SIZE(NvSubMemFormat
,
130 NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY
, 1);
131 OUT_RING (NvSyncNotify
);