nouveau_ws_bo_destroy(push->bo);
}
+static void
+nouveau_ws_push_valid(struct nouveau_ws_push *push) {
+ uint32_t *cur = push->orig_map;
+
+ /* submitting empty push buffers is probably a bug */
+ assert(push->map != push->orig_map);
+
+ /* make sure we don't overrun the bo */
+ assert(push->map <= push->end);
+
+ /* parse all the headers to see if we get to push->map */
+ while (cur < push->map) {
+ uint32_t hdr = *cur;
+ uint32_t mthd = hdr >> 29;
+
+ switch (mthd) {
+ /* immd */
+ case 4:
+ break;
+ case 1:
+ case 3:
+ case 5: {
+ uint32_t count = (hdr >> 16) & 0x1fff;
+ assert(count);
+ cur += count;
+ break;
+ }
+ default:
+ assert(!"unknown method found");
+ }
+
+ cur++;
+ assert(cur <= push->map);
+ }
+}
+
int
nouveau_ws_push_submit(
struct nouveau_ws_push *push,
struct drm_nouveau_gem_pushbuf req = {};
struct drm_nouveau_gem_pushbuf_push req_push = {};
+ if (push->map == push->orig_map)
+ return 0;
+
+ /* make sure we don't submit nonsense */
+ nouveau_ws_push_valid(push);
+
int i = 0;
util_dynarray_foreach(&push->bos, struct nouveau_ws_push_bo, push_bo) {
struct nouveau_ws_bo *bo = push_bo->bo;
}
static inline void
+__push_verify(struct nouveau_ws_push *push)
+{
+ if (!push->last_size)
+ return;
+
+ /* make sure we don't add a new method if the last one wasn't used */
+ uint32_t last_hdr = *push->last_size;
+
+ /* check for immd */
+ if (last_hdr >> 29 == 4)
+ return;
+
+ UNUSED uint32_t last_count = (last_hdr & 0x1fff0000);
+ assert(last_count);
+}
+
+static inline void
__push_mthd(struct nouveau_ws_push *push, int subc, uint32_t mthd)
{
+ __push_verify(push);
push->last_size = push->map;
*push->map = NVC0_FIFO_PKHDR_SQ(subc, mthd, 0);
push->map++;
static inline void
__push_immd(struct nouveau_ws_push *push, int subc, uint32_t mthd, uint32_t val)
{
+ __push_verify(push);
push->last_size = push->map;
*push->map = NVC0_FIFO_PKHDR_IL(subc, mthd, val);
push->map++;
static inline void
__push_1inc(struct nouveau_ws_push *push, int subc, uint32_t mthd)
{
+ __push_verify(push);
push->last_size = push->map;
*push->map = NVC0_FIFO_PKHDR_1I(subc, mthd, 0);
push->map++;
static inline void
__push_0inc(struct nouveau_ws_push *push, int subc, uint32_t mthd)
{
+ __push_verify(push);
push->last_size = push->map;
*push->map = NVC0_FIFO_PKHDR_0I(subc, mthd, 0);
push->map++;
assert(last_hdr_val);
assert(!is_immd);
assert(last_method == idx);
+ assert(push->map < push->end);
P_INLINE_DATA(push, val);
}