aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/panfrost/pan_context.c9
-rw-r--r--src/gallium/drivers/panfrost/pan_fragment.c21
-rw-r--r--src/gallium/drivers/panfrost/pan_resource.c12
-rw-r--r--src/gallium/drivers/panfrost/pan_resource.h3
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 {