+
+ struct panfrost_transfer transfer = panfrost_pool_alloc(&batch->pool,
+ 4 * 4 * 6 * rsrc->damage.inverted_len);
+
+ for (unsigned i = 0; i < rsrc->damage.inverted_len; ++i) {
+ float *o = (float *) (transfer.cpu + (4 * 4 * 6 * i));
+ struct pan_rect r = rsrc->damage.inverted_rects[i];
+
+ float rect[] = {
+ r.minx, rsrc->base.height0 - r.miny, 0.0, 1.0,
+ r.maxx, rsrc->base.height0 - r.miny, 0.0, 1.0,
+ r.minx, rsrc->base.height0 - r.maxy, 0.0, 1.0,
+
+ r.maxx, rsrc->base.height0 - r.miny, 0.0, 1.0,
+ r.minx, rsrc->base.height0 - r.maxy, 0.0, 1.0,
+ r.maxx, rsrc->base.height0 - r.maxy, 0.0, 1.0,
+ };
+
+ assert(sizeof(rect) == 4 * 4 * 6);
+ memcpy(o, rect, sizeof(rect));
+ }
+
+ panfrost_load_midg(&batch->pool, &batch->scoreboard,
+ blend_shader,
+ batch->framebuffer.gpu, transfer.gpu,
+ rsrc->damage.inverted_len * 6,
+ &img, loc);
+
+ panfrost_batch_add_bo(batch, batch->pool.dev->blit_shaders.bo,
+ PAN_BO_ACCESS_SHARED | PAN_BO_ACCESS_READ | PAN_BO_ACCESS_FRAGMENT);
+}
+
+static void
+panfrost_batch_draw_wallpaper(struct panfrost_batch *batch)
+{
+ panfrost_batch_reserve_framebuffer(batch);
+
+ /* Assume combined. If either depth or stencil is written, they will
+ * both be written so we need to be careful for reloading */
+
+ unsigned draws = batch->draws;
+
+ if (draws & PIPE_CLEAR_DEPTHSTENCIL)
+ draws |= PIPE_CLEAR_DEPTHSTENCIL;
+
+ /* Mask of buffers which need reload since they are not cleared and
+ * they are drawn. (If they are cleared, reload is useless; if they are
+ * not drawn and also not cleared, we can generally omit the attachment
+ * at the framebuffer descriptor level */
+
+ unsigned reload = ~batch->clear & draws;
+
+ for (unsigned i = 0; i < batch->key.nr_cbufs; ++i) {
+ if (reload & (PIPE_CLEAR_COLOR0 << i))
+ panfrost_load_surface(batch, batch->key.cbufs[i], FRAG_RESULT_DATA0 + i);
+ }
+
+ if (reload & PIPE_CLEAR_DEPTH)
+ panfrost_load_surface(batch, batch->key.zsbuf, FRAG_RESULT_DEPTH);
+
+ if (reload & PIPE_CLEAR_STENCIL)
+ panfrost_load_surface(batch, batch->key.zsbuf, FRAG_RESULT_STENCIL);
+}
+
+static void
+panfrost_batch_record_bo(struct hash_entry *entry, unsigned *bo_handles, unsigned idx)
+{
+ struct panfrost_bo *bo = (struct panfrost_bo *)entry->key;
+ uint32_t flags = (uintptr_t)entry->data;
+
+ assert(bo->gem_handle > 0);
+ bo_handles[idx] = bo->gem_handle;
+
+ /* Update the BO access flags so that panfrost_bo_wait() knows
+ * about all pending accesses.
+ * We only keep the READ/WRITE info since this is all the BO
+ * wait logic cares about.
+ * We also preserve existing flags as this batch might not
+ * be the first one to access the BO.
+ */
+ bo->gpu_access |= flags & (PAN_BO_ACCESS_RW);