panfrost: Set custom stride for textures when necessary
authorAlyssa Rosenzweig <alyssa@rosenzweig.io>
Tue, 14 May 2019 23:18:18 +0000 (23:18 +0000)
committerAlyssa Rosenzweig <alyssa@rosenzweig.io>
Thu, 16 May 2019 01:16:36 +0000 (01:16 +0000)
From Gallium (and our) perspective, the stride of a BO is arbitrary. For
internal buffers, we can make it something nice, but for imported linear
buffers (e.g. EGL clients), we don't always have that luxury. To cope,
we calculate the expected stride of a texture, compare it to the BO's
actual reported stride, and if they differ, set the latter as a custom
stride.

Fixes rendering of windows not on tile boundaries (noticeable in Weston
with es2gears_wayland, for instance). Also, this should fix stride
issues with bufer reloading.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
src/gallium/drivers/panfrost/pan_context.c

index cab7c89ac8b75c1c9d67a0f62abb7aa63b91c429..c4bb57d782eb14335987b75e5a4f9c4ea49bcf5d 100644 (file)
@@ -1115,6 +1115,17 @@ panfrost_emit_for_draw(struct panfrost_context *ctx, bool with_vertex_data)
                                         }
                                 }
 
+                                /* Inject the strides */
+                                unsigned usage2 = ctx->sampler_views[t][i]->hw.format.usage2;
+
+                                if (usage2 & MALI_TEX_MANUAL_STRIDE) {
+                                        unsigned idx = tex_rsrc->last_level * tex_rsrc->array_size;
+                                        idx += tex_rsrc->array_size;
+
+                                        ctx->sampler_views[t][i]->hw.swizzled_bitmaps[idx] =
+                                                rsrc->bo->slices[0].stride;
+                                }
+
                                 trampolines[i] = panfrost_upload_transient(ctx, &ctx->sampler_views[t][i]->hw, sizeof(struct mali_texture_descriptor));
                         }
 
@@ -1951,6 +1962,7 @@ panfrost_create_sampler_view(
         pipe_reference(NULL, &texture->reference);
 
         struct panfrost_resource *prsrc = (struct panfrost_resource *) texture;
+        assert(prsrc->bo);
 
         so->base = *template;
         so->base.texture = texture;
@@ -1995,6 +2007,19 @@ panfrost_create_sampler_view(
                         break;
         }
 
+        /* Check if we need to set a custom stride by computing the "expected"
+         * stride and comparing it to what the BO actually wants. Only applies
+         * to linear textures TODO: Mipmap? */
+
+        unsigned actual_stride = prsrc->bo->slices[0].stride;
+
+        if (prsrc->bo->layout == PAN_LINEAR &&
+            template->u.tex.last_level == 0 &&
+            template->u.tex.first_level == 0 &&
+            (texture->width0 * bytes_per_pixel) != actual_stride) {
+                usage2_layout |= MALI_TEX_MANUAL_STRIDE;
+        }
+
         struct mali_texture_descriptor texture_descriptor = {
                 .width = MALI_POSITIVE(texture->width0),
                 .height = MALI_POSITIVE(texture->height0),