if (ctx->pipe_framebuffer.cbufs[0] == NULL)
return;
+ /* Check if the buffer has any content on it worth preserving */
+
+ struct pipe_surface *surf = ctx->pipe_framebuffer.cbufs[0];
+ struct panfrost_resource *rsrc = pan_resource(surf->texture);
+ unsigned level = surf->u.tex.level;
+
+ if (!rsrc->bo->slices[level].initialized)
+ return;
+
/* Save the batch */
struct panfrost_job *batch = panfrost_get_job_for_fbo(ctx);
#include "util/u_format.h"
+/* Mark a surface as written */
+
+static void
+panfrost_initialize_surface(struct pipe_surface *surf)
+{
+ unsigned level = surf->u.tex.level;
+ struct panfrost_resource *rsrc = pan_resource(surf->texture);
+
+ rsrc->bo->slices[level].initialized = true;
+}
+
/* Generate a fragment job. This should be called once per frame. (According to
* presentations, this is supposed to correspond to eglSwapBuffers) */
panfrost_sfbd_fragment(ctx, has_draws) :
panfrost_mfbd_fragment(ctx, has_draws);
+ /* Mark the affected buffers as initialized, since we're writing to it */
+ struct pipe_framebuffer_state *fb = &ctx->pipe_framebuffer;
+
+ for (unsigned i = 0; i < fb->nr_cbufs; ++i) {
+ panfrost_initialize_surface(fb->cbufs[i]);
+ }
+
+ if (fb->zsbuf)
+ panfrost_initialize_surface(fb->zsbuf);
+
struct mali_job_descriptor_header header = {
.job_type = JOB_TYPE_FRAGMENT,
.job_index = 1,
rsc->bo = screen->driver->import_bo(screen, whandle);
rsc->bo->slices[0].stride = whandle->stride;
+ rsc->bo->slices[0].initialized = true;
if (screen->ro) {
rsc->scanout =
transfer->map = rzalloc_size(transfer, transfer->base.layer_stride * box->depth);
assert(box->depth == 1);
- if (usage & PIPE_TRANSFER_READ) {
+ if ((usage & PIPE_TRANSFER_READ) && bo->slices[level].initialized) {
if (bo->layout == PAN_AFBC) {
DBG("Unimplemented: reads from AFBC");
} else if (bo->layout == PAN_TILED) {
transfer->base.stride = bo->slices[level].stride;
transfer->base.layer_stride = bo->cubemap_stride;
+ /* By mapping direct-write, we're implicitly already
+ * initialized (maybe), so be conservative */
+
+ if ((usage & PIPE_TRANSFER_WRITE) && (usage & PIPE_TRANSFER_MAP_DIRECTLY))
+ bo->slices[level].initialized = true;
+
return bo->cpu
+ bo->slices[level].offset
+ transfer->base.box.z * bo->cubemap_stride
struct panfrost_bo *bo = prsrc->bo;
if (transfer->usage & PIPE_TRANSFER_WRITE) {
+ unsigned level = transfer->level;
+ bo->slices[level].initialized = true;
if (bo->layout == PAN_AFBC) {
DBG("Unimplemented: writes to AFBC\n");
} else if (bo->layout == PAN_TILED) {
- unsigned level = transfer->level;
assert(transfer->box.depth == 1);
panfrost_store_tiled_image(