panfrost/decode: Decode blend constant
authorAlyssa Rosenzweig <alyssa@rosenzweig.io>
Sat, 18 May 2019 20:48:43 +0000 (20:48 +0000)
committerAlyssa Rosenzweig <alyssa@rosenzweig.io>
Sun, 19 May 2019 17:41:23 +0000 (17:41 +0000)
This adds a forgotten decode line on Midgard and adds the field of a
blend constant on Bifrost. The Bifrost encoding is fairly weird; whereas
Midgard is just a regular 32-bit float, Bifrost uses a fancy
fixed-point-esque encoding. The decode logic here is experimentally
correct. The encode logic is a sort of "guesstimate", assuming that the
high byte is just int(f / 255.0) and then solving algebraicly for the
low byte. This might be slightly off in some cases.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Ryan Houdek <Sonicadvance1@gmail.com>
src/gallium/drivers/panfrost/include/panfrost-job.h
src/gallium/drivers/panfrost/pandecode/decode.c

index fb4a12fe1563aab17fc2688a5f296c640a87b91b..48b3a65a0b8da75664ced93e214b7d06beaa711f 100644 (file)
@@ -442,7 +442,21 @@ struct bifrost_blend_rt {
         /* This is likely an analogue of the flags on
          * midgard_blend_rt */
 
-        u32 unk1; // = 0x200
+        u16 flags; // = 0x200
+
+        /* Single-channel blend constants are encoded in a sort of
+         * fixed-point. Basically, the float is mapped to a byte, becoming
+         * a high byte, and then the lower-byte is added for precision.
+         * For the original float f:
+         *
+         * f = (constant_hi / 255) + (constant_lo / 65535)
+         *
+         * constant_hi = int(f / 255)
+         * constant_lo = 65535*f - (65535/255) * constant_hi
+         */
+
+        u16 constant;
+
         struct mali_blend_equation equation;
         /*
          * - 0x19 normally
index e70ebb7f660e3b3324cc5ec8c30d2d71d95238a4..fa91094d1f0e8c218b98e8d7e0523cd265b6ea72 100644 (file)
@@ -878,6 +878,17 @@ pandecode_replay_blend_equation(const struct mali_blend_equation *blend)
         pandecode_log("},\n");
 }
 
+/* Decodes a Bifrost blend constant. See the notes in bifrost_blend_rt */
+
+static unsigned
+decode_bifrost_constant(u16 constant)
+{
+        float lo = (float) (constant & 0xFF);
+        float hi = (float) (constant >> 8);
+
+        return (hi / 255.0) + (lo / 65535.0);
+}
+
 static mali_ptr
 pandecode_bifrost_blend(void *descs, int job_no, int rt_no)
 {
@@ -887,7 +898,10 @@ pandecode_bifrost_blend(void *descs, int job_no, int rt_no)
         pandecode_log("struct bifrost_blend_rt blend_rt_%d_%d = {\n", job_no, rt_no);
         pandecode_indent++;
 
-        pandecode_prop("unk1 = 0x%" PRIx32, b->unk1);
+        pandecode_prop("flags = 0x%" PRIx16, b->flags);
+        pandecode_prop("constant = 0x%" PRIx8 " /* %f */",
+                        b->constant, decode_bifrost_constant(b->constant));
+
         /* TODO figure out blend shader enable bit */
         pandecode_replay_blend_equation(&b->equation);
         pandecode_prop("unk2 = 0x%" PRIx16, b->unk2);
@@ -910,6 +924,7 @@ pandecode_midgard_blend(union midgard_blend *blend, bool is_shader)
                 pandecode_replay_shader_address("shader", blend->shader);
         } else {
                 pandecode_replay_blend_equation(&blend->equation);
+                pandecode_prop("constant = %f", blend->constant);
         }
 
         pandecode_indent--;