diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/drivers/panfrost/pan_context.c | 9 | ||||
-rw-r--r-- | src/gallium/drivers/panfrost/pan_fragment.c | 21 | ||||
-rw-r--r-- | src/gallium/drivers/panfrost/pan_resource.c | 12 | ||||
-rw-r--r-- | src/gallium/drivers/panfrost/pan_resource.h | 3 |
4 files changed, 43 insertions, 2 deletions
diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c index d8c5510a31e..6257ffe2ac4 100644 --- a/src/gallium/drivers/panfrost/pan_context.c +++ b/src/gallium/drivers/panfrost/pan_context.c @@ -1397,6 +1397,15 @@ panfrost_draw_wallpaper(struct pipe_context *pipe) 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); diff --git a/src/gallium/drivers/panfrost/pan_fragment.c b/src/gallium/drivers/panfrost/pan_fragment.c index 70358fec3f3..d6b8afdc6b9 100644 --- a/src/gallium/drivers/panfrost/pan_fragment.c +++ b/src/gallium/drivers/panfrost/pan_fragment.c @@ -28,6 +28,17 @@ #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) */ @@ -38,6 +49,16 @@ panfrost_fragment_job(struct panfrost_context *ctx, bool has_draws) 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, diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c index a99840e4a52..1a4ce8ef297 100644 --- a/src/gallium/drivers/panfrost/pan_resource.c +++ b/src/gallium/drivers/panfrost/pan_resource.c @@ -71,6 +71,7 @@ panfrost_resource_from_handle(struct pipe_screen *pscreen, 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 = @@ -509,7 +510,7 @@ panfrost_transfer_map(struct pipe_context *pctx, 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) { @@ -528,6 +529,12 @@ panfrost_transfer_map(struct pipe_context *pctx, 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 @@ -549,11 +556,12 @@ panfrost_transfer_unmap(struct pipe_context *pctx, 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( diff --git a/src/gallium/drivers/panfrost/pan_resource.h b/src/gallium/drivers/panfrost/pan_resource.h index 114e283889b..632250fa2aa 100644 --- a/src/gallium/drivers/panfrost/pan_resource.h +++ b/src/gallium/drivers/panfrost/pan_resource.h @@ -43,6 +43,9 @@ enum panfrost_memory_layout { struct panfrost_slice { unsigned offset; unsigned stride; + + /* Has anything been written to this slice? */ + bool initialized; }; struct panfrost_bo { |