panfrost: Don't flip scanout
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Thu, 23 May 2019 03:01:32 +0000 (03:01 +0000)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Wed, 5 Jun 2019 21:35:48 +0000 (14:35 -0700)
The mesa/st flips the viewport, so we respect that rather than
trying to flip the framebuffer itself and ignoring the viewport and
using a messy heuristic.

However, this brings an underlying disagreement about the interpretation
of winding order to light. The blob uses a different strategy than Mesa
for handling viewport Y flipping, so the meanings of the winding order
bit are flipped for it. To keep things clean on our end, we rename to
explicitly use Gallium (rather than flipped OpenGL) conventions.

Fixes upside-down Xwayland/egl windows.

v2: Adjust lowering configuration to correctly flip gl_PointCoord.y and
gl_FragCoord.y. v1 was R-b'd by Tomeu, but then retracted due to these
regressions which are not fixed.

Suggested-by: Rob Clark <robdclark@chromium.org>
Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Sort-of-reviewed-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
src/gallium/drivers/panfrost/include/panfrost-job.h
src/gallium/drivers/panfrost/midgard/midgard_compile.h
src/gallium/drivers/panfrost/pan_context.c
src/gallium/drivers/panfrost/pan_context.h
src/gallium/drivers/panfrost/pan_fragment.c
src/gallium/drivers/panfrost/pan_mfbd.c
src/gallium/drivers/panfrost/pan_screen.c
src/gallium/drivers/panfrost/pan_sfbd.c
src/gallium/drivers/panfrost/pandecode/decode.c

index f4f145890de224db30c0ad74e1084a5b31677dbf..8a4a7644070c2462e3fa9dfe07fad558be2835df 100644 (file)
@@ -73,9 +73,11 @@ enum mali_draw_mode {
 #define MALI_OCCLUSION_QUERY    (1 << 3)
 #define MALI_OCCLUSION_PRECISE  (1 << 4)
 
-#define MALI_FRONT_FACE(v)      (v << 5)
-#define MALI_CCW (0)
-#define MALI_CW  (1)
+/* Set for a glFrontFace(GL_CCW) in a Y=0=TOP coordinate system (like Gallium).
+ * In OpenGL, this would corresponds to glFrontFace(GL_CW). Mesa and the blob
+ * disagree about how to do viewport flipping, so the blob actually sets this
+ * for GL_CW but then has a negative viewport stride */
+#define MALI_FRONT_CCW_TOP      (1 << 5)
 
 #define MALI_CULL_FACE_FRONT    (1 << 6)
 #define MALI_CULL_FACE_BACK     (1 << 7)
index 6f02b3662f63c0a0ae0751682bc34efa43fb2803..9e6ac02f84fdab733be939c7d9532030642b3e0e 100644 (file)
@@ -99,6 +99,8 @@ static const nir_shader_compiler_options midgard_nir_options = {
         .lower_fpow = true,
         .lower_find_lsb = true,
 
+        .lower_wpos_pntc = true,
+
         /* TODO: We have native ops to help here, which we'll want to look into
          * eventually */
         .lower_fsign = true,
index 6dab13de1f2b2db5c9b21b8fbf2aeb4ec28d9448..337faaca0f73caebf350a7f8fa8ec2b2f561e508 100644 (file)
@@ -1174,15 +1174,6 @@ panfrost_emit_for_draw(struct panfrost_context *ctx, bool with_vertex_data)
 
         const struct pipe_viewport_state *vp = &ctx->pipe_viewport;
 
-        /* For flipped-Y buffers (signaled by negative scale), the translate is
-         * flipped as well */
-
-        bool invert_y = vp->scale[1] < 0.0;
-        float translate_y = vp->translate[1];
-
-        if (invert_y)
-                translate_y = ctx->pipe_framebuffer.height - translate_y;
-
         for (int i = 0; i <= PIPE_SHADER_FRAGMENT; ++i) {
                 struct panfrost_constant_buffer *buf = &ctx->constant_buffer[i];
 
@@ -1202,11 +1193,11 @@ panfrost_emit_for_draw(struct panfrost_context *ctx, bool with_vertex_data)
 
                         if (sysval == PAN_SYSVAL_VIEWPORT_SCALE) {
                                 uniforms[4*i + 0] = vp->scale[0];
-                                uniforms[4*i + 1] = fabsf(vp->scale[1]);
+                                uniforms[4*i + 1] = vp->scale[1];
                                 uniforms[4*i + 2] = vp->scale[2];
                         } else if (sysval == PAN_SYSVAL_VIEWPORT_OFFSET) {
                                 uniforms[4*i + 0] = vp->translate[0];
-                                uniforms[4*i + 1] = translate_y;
+                                uniforms[4*i + 1] = vp->translate[1];
                                 uniforms[4*i + 2] = vp->translate[2];
                         } else {
                                 assert(0);
@@ -1276,24 +1267,28 @@ panfrost_emit_for_draw(struct panfrost_context *ctx, bool with_vertex_data)
         view.viewport0[0] = (int) (vp->translate[0] - vp->scale[0]);
         view.viewport1[0] = MALI_POSITIVE((int) (vp->translate[0] + vp->scale[0]));
 
-        view.viewport0[1] = (int) (translate_y - fabs(vp->scale[1]));
-        view.viewport1[1] = MALI_POSITIVE((int) (translate_y + fabs(vp->scale[1])));
+        int miny = (int) (vp->translate[1] - vp->scale[1]);
+        int maxy = (int) (vp->translate[1] + vp->scale[1]);
 
         if (ss && ctx->rasterizer && ctx->rasterizer->base.scissor) {
-                /* Invert scissor if needed */
-                unsigned miny = invert_y ?
-                        ctx->pipe_framebuffer.height - ss->maxy : ss->miny;
-
-                unsigned maxy = invert_y ?
-                        ctx->pipe_framebuffer.height - ss->miny : ss->maxy;
-
-                /* Set the actual scissor */
                 view.viewport0[0] = ss->minx;
-                view.viewport0[1] = miny;
                 view.viewport1[0] = MALI_POSITIVE(ss->maxx);
-                view.viewport1[1] = MALI_POSITIVE(maxy);
+
+                miny = ss->miny;
+                maxy = ss->maxy;
         } 
 
+        /* Hardware needs the min/max to be strictly ordered, so flip if we
+         * need to */
+        if (miny > maxy) {
+                int temp = miny;
+                miny = maxy;
+                maxy = temp;
+        }
+
+        view.viewport0[1] = miny;
+        view.viewport1[1] = MALI_POSITIVE(maxy);
+
         ctx->payload_tiler.postfix.viewport =
                 panfrost_upload_transient(ctx,
                                 &view,
@@ -1583,8 +1578,8 @@ panfrost_create_rasterizer_state(
         /* Bitmask, unknown meaning of the start value */
         so->tiler_gl_enables = ctx->is_t6xx ? 0x105 : 0x7;
 
-        so->tiler_gl_enables |= MALI_FRONT_FACE(
-                                        cso->front_ccw ? MALI_CCW : MALI_CW);
+        if (cso->front_ccw)
+                so->tiler_gl_enables |= MALI_FRONT_CCW_TOP;
 
         if (cso->cull_face & PIPE_FACE_FRONT)
                 so->tiler_gl_enables |= MALI_CULL_FACE_FRONT;
@@ -2288,15 +2283,6 @@ panfrost_set_viewport_states(struct pipe_context *pipe,
         assert(num_viewports == 1);
 
         ctx->pipe_viewport = *viewports;
-
-#if 0
-        /* TODO: What if not centered? */
-        float w = abs(viewports->scale[0]) * 2.0;
-        float h = abs(viewports->scale[1]) * 2.0;
-
-        ctx->viewport.viewport1[0] = MALI_POSITIVE((int) w);
-        ctx->viewport.viewport1[1] = MALI_POSITIVE((int) h);
-#endif
 }
 
 static void
index e3dc07059b5a1c5e7a77ef1ed1cb9ab9cad2ef56..c65ffb8deb98de487dd6de40d1fa234a80763ea9 100644 (file)
@@ -340,11 +340,8 @@ panfrost_flush(
 bool
 panfrost_is_scanout(struct panfrost_context *ctx);
 
-mali_ptr
-panfrost_sfbd_fragment(struct panfrost_context *ctx, bool flip_y);
-
-mali_ptr
-panfrost_mfbd_fragment(struct panfrost_context *ctx, bool flip_y);
+mali_ptr panfrost_sfbd_fragment(struct panfrost_context *ctx);
+mali_ptr panfrost_mfbd_fragment(struct panfrost_context *ctx);
 
 struct bifrost_framebuffer
 panfrost_emit_mfbd(struct panfrost_context *ctx);
index 0dc15c2d23513a58f3fa174db4799d44380379ea..16405a4ed21cf557fe421333c5a5ae22c1ae6fb9 100644 (file)
 mali_ptr
 panfrost_fragment_job(struct panfrost_context *ctx)
 {
-        /* TODO: Check viewport or something */
-        bool flip_y = panfrost_is_scanout(ctx);
-
         mali_ptr framebuffer = ctx->require_sfbd ?
-                panfrost_sfbd_fragment(ctx, flip_y) :
-                panfrost_mfbd_fragment(ctx, flip_y);
+                panfrost_sfbd_fragment(ctx) :
+                panfrost_mfbd_fragment(ctx);
 
         struct mali_job_descriptor_header header = {
                 .job_type = JOB_TYPE_FRAGMENT,
index 6986992012f02bcb6effa8797bce5abc404166d9..78d676511d67b85208ace9e630f28bbc939ba876 100644 (file)
@@ -85,8 +85,7 @@ panfrost_mfbd_clear(
 static void
 panfrost_mfbd_set_cbuf(
                 struct bifrost_render_target *rt,
-                struct pipe_surface *surf,
-                bool flip_y)
+                struct pipe_surface *surf)
 {
         struct panfrost_resource *rsrc = pan_resource(surf->texture);
         int stride = rsrc->bo->slices[0].stride;
@@ -96,14 +95,7 @@ panfrost_mfbd_set_cbuf(
         /* Now, we set the layout specific pieces */
 
         if (rsrc->bo->layout == PAN_LINEAR) {
-                mali_ptr framebuffer = rsrc->bo->gpu;
-
-                if (flip_y) {
-                        framebuffer += stride * (surf->texture->height0 - 1);
-                        stride = -stride;
-                }
-
-                rt->framebuffer = framebuffer;
+                rt->framebuffer = rsrc->bo->gpu;
                 rt->framebuffer_stride = stride / 16;
         } else if (rsrc->bo->layout == PAN_AFBC) {
                 rt->afbc.metadata = rsrc->bo->afbc_slab.gpu;
@@ -211,7 +203,7 @@ panfrost_mfbd_upload(
 /* Creates an MFBD for the FRAGMENT section of the bound framebuffer */
 
 mali_ptr
-panfrost_mfbd_fragment(struct panfrost_context *ctx, bool flip_y)
+panfrost_mfbd_fragment(struct panfrost_context *ctx)
 {
         struct panfrost_job *job = panfrost_get_job_for_fbo(ctx);
 
@@ -228,7 +220,7 @@ panfrost_mfbd_fragment(struct panfrost_context *ctx, bool flip_y)
 
         for (int cb = 0; cb < ctx->pipe_framebuffer.nr_cbufs; ++cb) {
                 struct pipe_surface *surf = ctx->pipe_framebuffer.cbufs[cb];
-                panfrost_mfbd_set_cbuf(&rts[cb], surf, flip_y);
+                panfrost_mfbd_set_cbuf(&rts[cb], surf);
         }
 
         if (ctx->pipe_framebuffer.zsbuf) {
index b24bdffc2da7e1d054e3f3bb8ec5311550b265bf..c956ba439fae485171460c14cdbb0367921b5d9e 100644 (file)
@@ -132,8 +132,12 @@ panfrost_get_param(struct pipe_screen *screen, enum pipe_cap param)
         case PIPE_CAP_INDEP_BLEND_FUNC:
                 return 1;
 
-        case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
         case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
+                /* Hardware is natively upper left */
+                return 0;
+
+        case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
+                return 1;
         case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
         case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
                 return 1;
index 4235c198199d34c5f0cace513e63700e3fc012c5..6989cd925a83d3f0a94a423670c8da338155837d 100644 (file)
@@ -87,8 +87,7 @@ panfrost_sfbd_clear(
 static void
 panfrost_sfbd_set_cbuf(
                 struct mali_single_framebuffer *fb,
-                struct pipe_surface *surf,
-                bool flip_y)
+                struct pipe_surface *surf)
 {
         struct panfrost_resource *rsrc = pan_resource(surf->texture);
 
@@ -97,15 +96,7 @@ panfrost_sfbd_set_cbuf(
         fb->format = panfrost_sfbd_format(surf);
 
         if (rsrc->bo->layout == PAN_LINEAR) {
-                mali_ptr framebuffer = rsrc->bo->gpu;
-
-                /* The default is upside down from OpenGL's perspective. */
-                if (flip_y) {
-                        framebuffer += stride * (surf->texture->height0 - 1);
-                        stride = -stride;
-                }
-
-                fb->framebuffer = framebuffer;
+                fb->framebuffer = rsrc->bo->gpu;
                 fb->stride = stride;
         } else {
                 fprintf(stderr, "Invalid render layout\n");
@@ -116,7 +107,7 @@ panfrost_sfbd_set_cbuf(
 /* Creates an SFBD for the FRAGMENT section of the bound framebuffer */
 
 mali_ptr
-panfrost_sfbd_fragment(struct panfrost_context *ctx, bool flip_y)
+panfrost_sfbd_fragment(struct panfrost_context *ctx)
 {
         struct panfrost_job *job = panfrost_get_job_for_fbo(ctx);
         struct mali_single_framebuffer fb = panfrost_emit_sfbd(ctx);
@@ -125,7 +116,7 @@ panfrost_sfbd_fragment(struct panfrost_context *ctx, bool flip_y)
 
         /* SFBD does not support MRT natively; sanity check */
         assert(ctx->pipe_framebuffer.nr_cbufs == 1);
-        panfrost_sfbd_set_cbuf(&fb, ctx->pipe_framebuffer.cbufs[0], flip_y);
+        panfrost_sfbd_set_cbuf(&fb, ctx->pipe_framebuffer.cbufs[0]);
 
         if (ctx->pipe_framebuffer.zsbuf) {
                 /* TODO */
index fa91094d1f0e8c218b98e8d7e0523cd265b6ea72..dac27c366848a4c01bf4e7d7d3cc18e8145aba4d 100644 (file)
@@ -147,10 +147,11 @@ pandecode_log_decoded_flags(const struct pandecode_flag_info *flag_info,
 
 #define FLAG_INFO(flag) { MALI_##flag, "MALI_" #flag }
 static const struct pandecode_flag_info gl_enable_flag_info[] = {
-        FLAG_INFO(CULL_FACE_FRONT),
-        FLAG_INFO(CULL_FACE_BACK),
         FLAG_INFO(OCCLUSION_QUERY),
         FLAG_INFO(OCCLUSION_PRECISE),
+        FLAG_INFO(FRONT_CCW_TOP),
+        FLAG_INFO(CULL_FACE_FRONT),
+        FLAG_INFO(CULL_FACE_BACK),
         {}
 };
 #undef FLAG_INFO
@@ -1763,13 +1764,6 @@ pandecode_replay_gl_enables(uint32_t gl_enables, int job_type)
 {
         pandecode_log(".gl_enables = ");
 
-        if (job_type == JOB_TYPE_TILER) {
-                pandecode_log_cont("MALI_FRONT_FACE(MALI_%s) | ",
-                                 gl_enables & MALI_FRONT_FACE(MALI_CW) ? "CW" : "CCW");
-
-                gl_enables &= ~(MALI_FRONT_FACE(1));
-        }
-
         pandecode_log_decoded_flags(gl_enable_flag_info, gl_enables);
 
         pandecode_log_cont(",\n");