freedreno/ir3: add new helper for shader linkage
authorRob Clark <robdclark@gmail.com>
Wed, 23 Nov 2016 14:46:15 +0000 (09:46 -0500)
committerRob Clark <robdclark@gmail.com>
Wed, 30 Nov 2016 17:25:48 +0000 (12:25 -0500)
Helps simplify things on a5xx, where pos/psize get added to the vs-out
map.  And anyways, simplifies a3xx and a4xx.

Signed-off-by: Rob Clark <robdclark@gmail.com>
src/gallium/drivers/freedreno/ir3/ir3_shader.h

index 8c9483e1bc751dc67a094a93b2598627974f9fec..c46b4522e3ce0fb987b2a02a8da1a053c6301fa2 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "pipe/p_state.h"
 #include "compiler/shader_enums.h"
+#include "util/bitscan.h"
 
 #include "ir3.h"
 #include "disasm.h"
@@ -344,6 +345,52 @@ ir3_next_varying(const struct ir3_shader_variant *so, int i)
        return i;
 }
 
+struct ir3_shader_linkage {
+       uint8_t max_loc;
+       uint8_t cnt;
+       struct {
+               uint8_t regid;
+               uint8_t compmask;
+               uint8_t loc;
+       } var[16];
+};
+
+static inline void
+ir3_link_add(struct ir3_shader_linkage *l, uint8_t regid, uint8_t compmask, uint8_t loc)
+{
+       int i = l->cnt++;
+
+       debug_assert(i < ARRAY_SIZE(l->var));
+
+       l->var[i].regid    = regid;
+       l->var[i].compmask = compmask;
+       l->var[i].loc      = loc;
+       l->max_loc = MAX2(l->max_loc, loc + util_last_bit(compmask));
+}
+
+static inline void
+ir3_link_shaders(struct ir3_shader_linkage *l,
+               const struct ir3_shader_variant *vs,
+               const struct ir3_shader_variant *fs)
+{
+       int j = -1, k;
+
+       while (l->cnt < ARRAY_SIZE(l->var)) {
+               j = ir3_next_varying(fs, j);
+
+               if (j >= fs->inputs_count)
+                       break;
+
+               if (fs->inputs[j].inloc >= fs->total_in)
+                       continue;
+
+               k = ir3_find_output(vs, fs->inputs[j].slot);
+
+               ir3_link_add(l, vs->outputs[k].regid,
+                       fs->inputs[j].compmask, fs->inputs[j].inloc);
+       }
+}
+
 static inline uint32_t
 ir3_find_output_regid(const struct ir3_shader_variant *so, unsigned slot)
 {