freedreno: add global_bindings state
[mesa.git] / src / gallium / drivers / freedreno / freedreno_state.c
index dd42aa02e7597a792a65c34b48086f2fd853235d..05717da95995e5cec6a50a2194e440c45d8ca234 100644 (file)
@@ -495,15 +495,53 @@ fd_set_compute_resources(struct pipe_context *pctx,
        // TODO
 }
 
+/* used by clover to bind global objects, returning the bo address
+ * via handles[n]
+ */
 static void
 fd_set_global_binding(struct pipe_context *pctx,
                unsigned first, unsigned count, struct pipe_resource **prscs,
                uint32_t **handles)
 {
-       /* TODO only used by clover.. seems to need us to return the actual
-        * gpuaddr of the buffer.. which isn't really exposed to mesa atm.
-        * How is this used?
-        */
+       struct fd_context *ctx = fd_context(pctx);
+       struct fd_global_bindings_stateobj *so = &ctx->global_bindings;
+       unsigned mask = 0;
+
+       if (prscs) {
+               for (unsigned i = 0; i < count; i++) {
+                       unsigned n = i + first;
+
+                       mask |= BIT(n);
+
+                       pipe_resource_reference(&so->buf[n], prscs[i]);
+
+                       if (so->buf[n]) {
+                               struct fd_resource *rsc = fd_resource(so->buf[n]);
+                               uint64_t iova = fd_bo_get_iova(rsc->bo);
+                               // TODO need to scream if iova > 32b or fix gallium API..
+                               *handles[i] += iova;
+                       }
+
+                       if (prscs[i])
+                               so->enabled_mask |= BIT(n);
+                       else
+                               so->enabled_mask &= ~BIT(n);
+               }
+       } else {
+               mask = (BIT(count) - 1) << first;
+
+               for (unsigned i = 0; i < count; i++) {
+                       unsigned n = i + first;
+                       if (so->buf[n]) {
+                               struct fd_resource *rsc = fd_resource(so->buf[n]);
+                               fd_bo_put_iova(rsc->bo);
+                       }
+                       pipe_resource_reference(&so->buf[n], NULL);
+               }
+
+               so->enabled_mask &= ~mask;
+       }
+
 }
 
 void