v3d: Fix polygon offset for Z16 buffers.
authorEric Anholt <eric@anholt.net>
Wed, 13 Jun 2018 20:44:01 +0000 (13:44 -0700)
committerEric Anholt <eric@anholt.net>
Fri, 15 Jun 2018 00:03:16 +0000 (17:03 -0700)
Fixes:
dEQP-GLES3.functional.polygon_offset.fixed16_displacement_with_units
dEQP-GLES3.functional.polygon_offset.fixed16_render_with_units

src/gallium/drivers/v3d/v3d_context.h
src/gallium/drivers/v3d/v3dx_emit.c
src/gallium/drivers/v3d/v3dx_state.c

index f74541f..c0de05d 100644 (file)
@@ -432,6 +432,11 @@ struct v3d_rasterizer_state {
          */
         uint16_t offset_units;
         /**
+         * The HW treats polygon offset units based on a Z24 buffer, so we
+         * need to scale up offset_units if we're only Z16.
+         */
+        uint16_t z16_offset_units;
+        /**
          * Half-float (1/8/7 bits) value of polygon offset scale for
          * VC5_PACKET_DEPTH_OFFSET
          */
index 161ce51..ac93bad 100644 (file)
@@ -431,8 +431,14 @@ v3dX(emit_state)(struct pipe_context *pctx)
                 cl_emit(&job->bcl, DEPTH_OFFSET, depth) {
                         depth.depth_offset_factor =
                                 v3d->rasterizer->offset_factor;
-                        depth.depth_offset_units =
-                                v3d->rasterizer->offset_units;
+                        if (job->zsbuf &&
+                            job->zsbuf->format == PIPE_FORMAT_Z16_UNORM) {
+                                depth.depth_offset_units =
+                                        v3d->rasterizer->z16_offset_units;
+                        } else {
+                                depth.depth_offset_units =
+                                        v3d->rasterizer->offset_units;
+                        }
                 }
         }
 
index 22a0ba9..ec6e8eb 100644 (file)
@@ -116,6 +116,7 @@ v3d_create_rasterizer_state(struct pipe_context *pctx,
 
         if (cso->offset_tri) {
                 so->offset_units = float_to_187_half(cso->offset_units);
+                so->z16_offset_units = float_to_187_half(cso->offset_units * 256.0);
                 so->offset_factor = float_to_187_half(cso->offset_scale);
         }