diff options
-rw-r--r-- | libdrm/nouveau/nouveau_private.h | 3 | ||||
-rw-r--r-- | libdrm/nouveau/nouveau_pushbuf.c | 53 | ||||
-rw-r--r-- | libdrm/nouveau/nouveau_pushbuf.h | 53 |
3 files changed, 90 insertions, 19 deletions
diff --git a/libdrm/nouveau/nouveau_private.h b/libdrm/nouveau/nouveau_private.h index 743c8314..784afc91 100644 --- a/libdrm/nouveau/nouveau_private.h +++ b/libdrm/nouveau/nouveau_private.h | |||
@@ -52,6 +52,9 @@ struct nouveau_pushbuf_priv { | |||
52 | unsigned *pushbuf; | 52 | unsigned *pushbuf; |
53 | unsigned size; | 53 | unsigned size; |
54 | 54 | ||
55 | unsigned marker; | ||
56 | unsigned marker_relocs; | ||
57 | |||
55 | struct drm_nouveau_gem_pushbuf_bo *buffers; | 58 | struct drm_nouveau_gem_pushbuf_bo *buffers; |
56 | unsigned nr_buffers; | 59 | unsigned nr_buffers; |
57 | struct drm_nouveau_gem_pushbuf_reloc *relocs; | 60 | struct drm_nouveau_gem_pushbuf_reloc *relocs; |
diff --git a/libdrm/nouveau/nouveau_pushbuf.c b/libdrm/nouveau/nouveau_pushbuf.c index af181b2e..df43effc 100644 --- a/libdrm/nouveau/nouveau_pushbuf.c +++ b/libdrm/nouveau/nouveau_pushbuf.c | |||
@@ -67,7 +67,6 @@ nouveau_pushbuf_emit_reloc(struct nouveau_channel *chan, void *ptr, | |||
67 | 67 | ||
68 | if (nvpb->nr_relocs >= NOUVEAU_GEM_MAX_RELOCS) { | 68 | if (nvpb->nr_relocs >= NOUVEAU_GEM_MAX_RELOCS) { |
69 | fprintf(stderr, "too many relocs!!\n"); | 69 | fprintf(stderr, "too many relocs!!\n"); |
70 | assert(0); | ||
71 | return -ENOMEM; | 70 | return -ENOMEM; |
72 | } | 71 | } |
73 | 72 | ||
@@ -79,7 +78,6 @@ nouveau_pushbuf_emit_reloc(struct nouveau_channel *chan, void *ptr, | |||
79 | pbbo = nouveau_bo_emit_buffer(chan, bo); | 78 | pbbo = nouveau_bo_emit_buffer(chan, bo); |
80 | if (!pbbo) { | 79 | if (!pbbo) { |
81 | fprintf(stderr, "buffer emit fail :(\n"); | 80 | fprintf(stderr, "buffer emit fail :(\n"); |
82 | assert(0); | ||
83 | return -ENOMEM; | 81 | return -ENOMEM; |
84 | } | 82 | } |
85 | 83 | ||
@@ -353,6 +351,57 @@ restart_push: | |||
353 | if (chan->flush_notify) | 351 | if (chan->flush_notify) |
354 | chan->flush_notify(chan); | 352 | chan->flush_notify(chan); |
355 | 353 | ||
354 | nvpb->marker = 0; | ||
356 | return ret; | 355 | return ret; |
357 | } | 356 | } |
358 | 357 | ||
358 | int | ||
359 | nouveau_pushbuf_marker_emit(struct nouveau_channel *chan, | ||
360 | unsigned wait_dwords, unsigned wait_relocs) | ||
361 | { | ||
362 | struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(chan->pushbuf); | ||
363 | |||
364 | if (AVAIL_RING(chan) < wait_dwords) | ||
365 | return nouveau_pushbuf_flush(chan, wait_dwords); | ||
366 | |||
367 | if (nvpb->nr_relocs + wait_relocs >= NOUVEAU_GEM_MAX_RELOCS) | ||
368 | return nouveau_pushbuf_flush(chan, wait_dwords); | ||
369 | |||
370 | nvpb->marker = nvpb->base.cur - nvpb->pushbuf; | ||
371 | nvpb->marker_relocs = nvpb->nr_relocs; | ||
372 | return 0; | ||
373 | } | ||
374 | |||
375 | void | ||
376 | nouveau_pushbuf_marker_undo(struct nouveau_channel *chan) | ||
377 | { | ||
378 | struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(chan->pushbuf); | ||
379 | unsigned i; | ||
380 | |||
381 | if (!nvpb->marker) | ||
382 | return; | ||
383 | |||
384 | /* undo any relocs/buffers added to the list since last marker */ | ||
385 | for (i = nvpb->marker_relocs; i < nvpb->nr_relocs; i++) { | ||
386 | struct drm_nouveau_gem_pushbuf_reloc *r = &nvpb->relocs[i]; | ||
387 | struct drm_nouveau_gem_pushbuf_bo *pbbo = | ||
388 | &nvpb->buffers[r->bo_index]; | ||
389 | struct nouveau_bo *bo = (void *)(unsigned long)pbbo->user_priv; | ||
390 | struct nouveau_bo_priv *nvbo = nouveau_bo(bo); | ||
391 | |||
392 | if (--nvbo->pending_refcnt) | ||
393 | continue; | ||
394 | |||
395 | nvbo->pending = NULL; | ||
396 | nouveau_bo_ref(NULL, &bo); | ||
397 | nvpb->nr_buffers--; | ||
398 | } | ||
399 | nvpb->nr_relocs = nvpb->marker_relocs; | ||
400 | |||
401 | /* reset pushbuf back to last marker */ | ||
402 | nvpb->base.cur = nvpb->pushbuf + nvpb->marker; | ||
403 | nvpb->base.remaining = nvpb->size - nvpb->marker; | ||
404 | nvpb->marker = 0; | ||
405 | } | ||
406 | |||
407 | |||
diff --git a/libdrm/nouveau/nouveau_pushbuf.h b/libdrm/nouveau/nouveau_pushbuf.h index 3c746ed2..c7ac8c45 100644 --- a/libdrm/nouveau/nouveau_pushbuf.h +++ b/libdrm/nouveau/nouveau_pushbuf.h | |||
@@ -40,11 +40,30 @@ int | |||
40 | nouveau_pushbuf_flush(struct nouveau_channel *, unsigned min); | 40 | nouveau_pushbuf_flush(struct nouveau_channel *, unsigned min); |
41 | 41 | ||
42 | int | 42 | int |
43 | nouveau_pushbuf_marker_emit(struct nouveau_channel *chan, | ||
44 | unsigned wait_dwords, unsigned wait_relocs); | ||
45 | |||
46 | void | ||
47 | nouveau_pushbuf_marker_undo(struct nouveau_channel *chan); | ||
48 | |||
49 | int | ||
43 | nouveau_pushbuf_emit_reloc(struct nouveau_channel *, void *ptr, | 50 | nouveau_pushbuf_emit_reloc(struct nouveau_channel *, void *ptr, |
44 | struct nouveau_bo *, uint32_t data, uint32_t data2, | 51 | struct nouveau_bo *, uint32_t data, uint32_t data2, |
45 | uint32_t flags, uint32_t vor, uint32_t tor); | 52 | uint32_t flags, uint32_t vor, uint32_t tor); |
46 | 53 | ||
47 | /* Push buffer access macros */ | 54 | /* Push buffer access macros */ |
55 | static __inline__ int | ||
56 | MARK_RING(struct nouveau_channel *chan, unsigned dwords, unsigned relocs) | ||
57 | { | ||
58 | return nouveau_pushbuf_marker_emit(chan, dwords, relocs); | ||
59 | } | ||
60 | |||
61 | static __inline__ void | ||
62 | MARK_UNDO(struct nouveau_channel *chan) | ||
63 | { | ||
64 | nouveau_pushbuf_marker_undo(chan); | ||
65 | } | ||
66 | |||
48 | static __inline__ void | 67 | static __inline__ void |
49 | OUT_RING(struct nouveau_channel *chan, unsigned data) | 68 | OUT_RING(struct nouveau_channel *chan, unsigned data) |
50 | { | 69 | { |
@@ -116,62 +135,62 @@ BIND_RING(struct nouveau_channel *chan, struct nouveau_grobj *gr, unsigned sc) | |||
116 | OUT_RING (chan, gr->handle); | 135 | OUT_RING (chan, gr->handle); |
117 | } | 136 | } |
118 | 137 | ||
119 | static __inline__ void | 138 | static __inline__ int |
120 | OUT_RELOC(struct nouveau_channel *chan, struct nouveau_bo *bo, | 139 | OUT_RELOC(struct nouveau_channel *chan, struct nouveau_bo *bo, |
121 | unsigned data, unsigned flags, unsigned vor, unsigned tor) | 140 | unsigned data, unsigned flags, unsigned vor, unsigned tor) |
122 | { | 141 | { |
123 | nouveau_pushbuf_emit_reloc(chan, chan->pushbuf->cur++, bo, | 142 | return nouveau_pushbuf_emit_reloc(chan, chan->pushbuf->cur++, bo, |
124 | data, 0, flags, vor, tor); | 143 | data, 0, flags, vor, tor); |
125 | } | 144 | } |
126 | 145 | ||
127 | static __inline__ void | 146 | static __inline__ int |
128 | OUT_RELOC2(struct nouveau_channel *chan, struct nouveau_bo *bo, | 147 | OUT_RELOC2(struct nouveau_channel *chan, struct nouveau_bo *bo, |
129 | unsigned data, unsigned data2, unsigned flags, | 148 | unsigned data, unsigned data2, unsigned flags, |
130 | unsigned vor, unsigned tor) | 149 | unsigned vor, unsigned tor) |
131 | { | 150 | { |
132 | nouveau_pushbuf_emit_reloc(chan, chan->pushbuf->cur++, bo, | 151 | return nouveau_pushbuf_emit_reloc(chan, chan->pushbuf->cur++, bo, |
133 | data, data2, flags, vor, tor); | 152 | data, data2, flags, vor, tor); |
134 | } | 153 | } |
135 | 154 | ||
136 | /* Raw data + flags depending on FB/TT buffer */ | 155 | /* Raw data + flags depending on FB/TT buffer */ |
137 | static __inline__ void | 156 | static __inline__ int |
138 | OUT_RELOCd(struct nouveau_channel *chan, struct nouveau_bo *bo, | 157 | OUT_RELOCd(struct nouveau_channel *chan, struct nouveau_bo *bo, |
139 | unsigned data, unsigned flags, unsigned vor, unsigned tor) | 158 | unsigned data, unsigned flags, unsigned vor, unsigned tor) |
140 | { | 159 | { |
141 | OUT_RELOC(chan, bo, data, flags | NOUVEAU_BO_OR, vor, tor); | 160 | return OUT_RELOC(chan, bo, data, flags | NOUVEAU_BO_OR, vor, tor); |
142 | } | 161 | } |
143 | 162 | ||
144 | /* FB/TT object handle */ | 163 | /* FB/TT object handle */ |
145 | static __inline__ void | 164 | static __inline__ int |
146 | OUT_RELOCo(struct nouveau_channel *chan, struct nouveau_bo *bo, | 165 | OUT_RELOCo(struct nouveau_channel *chan, struct nouveau_bo *bo, |
147 | unsigned flags) | 166 | unsigned flags) |
148 | { | 167 | { |
149 | OUT_RELOC(chan, bo, 0, flags | NOUVEAU_BO_OR, | 168 | return OUT_RELOC(chan, bo, 0, flags | NOUVEAU_BO_OR, |
150 | chan->vram->handle, chan->gart->handle); | 169 | chan->vram->handle, chan->gart->handle); |
151 | } | 170 | } |
152 | 171 | ||
153 | /* Low 32-bits of offset */ | 172 | /* Low 32-bits of offset */ |
154 | static __inline__ void | 173 | static __inline__ int |
155 | OUT_RELOCl(struct nouveau_channel *chan, struct nouveau_bo *bo, | 174 | OUT_RELOCl(struct nouveau_channel *chan, struct nouveau_bo *bo, |
156 | unsigned delta, unsigned flags) | 175 | unsigned delta, unsigned flags) |
157 | { | 176 | { |
158 | OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_LOW, 0, 0); | 177 | return OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_LOW, 0, 0); |
159 | } | 178 | } |
160 | 179 | ||
161 | /* Low 32-bits of offset + GPU linear access range info */ | 180 | /* Low 32-bits of offset + GPU linear access range info */ |
162 | static __inline__ void | 181 | static __inline__ int |
163 | OUT_RELOCr(struct nouveau_channel *chan, struct nouveau_bo *bo, | 182 | OUT_RELOCr(struct nouveau_channel *chan, struct nouveau_bo *bo, |
164 | unsigned delta, unsigned size, unsigned flags) | 183 | unsigned delta, unsigned size, unsigned flags) |
165 | { | 184 | { |
166 | OUT_RELOC2(chan, bo, delta, size, flags | NOUVEAU_BO_LOW, 0, 0); | 185 | return OUT_RELOC2(chan, bo, delta, size, flags | NOUVEAU_BO_LOW, 0, 0); |
167 | } | 186 | } |
168 | 187 | ||
169 | /* High 32-bits of offset */ | 188 | /* High 32-bits of offset */ |
170 | static __inline__ void | 189 | static __inline__ int |
171 | OUT_RELOCh(struct nouveau_channel *chan, struct nouveau_bo *bo, | 190 | OUT_RELOCh(struct nouveau_channel *chan, struct nouveau_bo *bo, |
172 | unsigned delta, unsigned flags) | 191 | unsigned delta, unsigned flags) |
173 | { | 192 | { |
174 | OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_HIGH, 0, 0); | 193 | return OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_HIGH, 0, 0); |
175 | } | 194 | } |
176 | 195 | ||
177 | #endif | 196 | #endif |