+void
+nvc0_screen_bind_cb_3d(struct nvc0_screen *screen, bool *can_serialize,
+ int stage, int index, int size, uint64_t addr)
+{
+ assert(stage != 5);
+
+ struct nouveau_pushbuf *push = screen->base.pushbuf;
+
+ if (screen->base.class_3d >= GM107_3D_CLASS) {
+ struct nvc0_cb_binding *binding = &screen->cb_bindings[stage][index];
+
+ // TODO: Better figure out the conditions in which this is needed
+ bool serialize = binding->addr == addr && binding->size != size;
+ if (can_serialize)
+ serialize = serialize && *can_serialize;
+ if (serialize) {
+ IMMED_NVC0(push, NVC0_3D(SERIALIZE), 0);
+ if (can_serialize)
+ *can_serialize = false;
+ }
+
+ binding->addr = addr;
+ binding->size = size;
+ }
+
+ if (size >= 0) {
+ BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
+ PUSH_DATA (push, size);
+ PUSH_DATAh(push, addr);
+ PUSH_DATA (push, addr);
+ }
+ IMMED_NVC0(push, NVC0_3D(CB_BIND(stage)), (index << 4) | (size >= 0));
+}
+