freedreno/ir3: insert nop between sfu/mem operations
[mesa.git] / src / gallium / drivers / freedreno / ir3 / ir3_shader.h
index 628c09e1be3f8b963da086fcd46397bdf20cfde8..e5410bf88b292da228ef8c2a0f62207a95b14d21 100644 (file)
@@ -69,14 +69,10 @@ struct ir3_shader_key {
                         */
                        unsigned color_two_side : 1;
                        unsigned half_precision : 1;
-                       /* For rendering to alpha, we need a bit of special handling
-                        * since the hw always takes gl_FragColor starting from x
-                        * component, rather than figuring out to take the w component.
-                        * We could be more clever and generate variants for other
-                        * render target formats (ie. luminance formats are xxx1), but
-                        * let's start with this and see how it goes:
+                       /* used when shader needs to handle flat varyings (a4xx),
+                        * for TGSI_INTERPOLATE_COLOR:
                         */
-                       unsigned alpha : 1;
+                       unsigned rasterflat : 1;
                };
                uint32_t global;
        };
@@ -91,6 +87,9 @@ struct ir3_shader_key {
         */
        uint16_t fsaturate_s, fsaturate_t, fsaturate_r;
 
+       /* bitmask of sampler which produces integer outputs:
+        */
+       uint16_t vinteger_s, finteger_s;
 };
 
 static inline bool
@@ -111,7 +110,8 @@ struct ir3_shader_variant {
        struct ir3 *ir;
 
        /* the instructions length is in units of instruction groups
-        * (4 instructions, 8 dwords):
+        * (4 instructions for a3xx, 16 instructions for a4xx.. each
+        * instruction is 2 dwords):
         */
        unsigned instrlen;
 
@@ -133,7 +133,7 @@ struct ir3_shader_variant {
         * to bary.f instructions
         */
        uint8_t pos_regid;
-       bool frag_coord, frag_face;
+       bool frag_coord, frag_face, color0_mrt;
 
        /* varyings/outputs: */
        unsigned outputs_count;
@@ -171,10 +171,14 @@ struct ir3_shader_variant {
        /* do we have one or more texture sample instructions: */
        bool has_samp;
 
+       /* do we have kill instructions: */
+       bool has_kill;
+
        /* const reg # of first immediate, ie. 1 == c1
         * (not regid, because TGSI thinks in terms of vec4 registers,
         * not scalar registers)
         */
+       unsigned first_driver_param;
        unsigned first_immediate;
        unsigned immediates_count;
        struct {
@@ -200,15 +204,74 @@ struct ir3_shader {
        /* so far, only used for blit_prog shader.. values for
         * VPC_VARYING_PS_REPL[i].MODE
         */
-       uint32_t vpsrepl[4];
+       uint32_t vpsrepl[8];
 };
 
+void * ir3_shader_assemble(struct ir3_shader_variant *v, uint32_t gpu_id);
 
 struct ir3_shader * ir3_shader_create(struct pipe_context *pctx,
                const struct tgsi_token *tokens, enum shader_t type);
 void ir3_shader_destroy(struct ir3_shader *shader);
-
+uint32_t ir3_shader_gpuid(struct ir3_shader *shader);
 struct ir3_shader_variant * ir3_shader_variant(struct ir3_shader *shader,
                struct ir3_shader_key key);
 
+/*
+ * Helper/util:
+ */
+
+static inline int
+ir3_find_output(const struct ir3_shader_variant *so, ir3_semantic semantic)
+{
+       int j;
+
+       for (j = 0; j < so->outputs_count; j++)
+               if (so->outputs[j].semantic == semantic)
+                       return j;
+
+       /* it seems optional to have a OUT.BCOLOR[n] for each OUT.COLOR[n]
+        * in the vertex shader.. but the fragment shader doesn't know this
+        * so  it will always have both IN.COLOR[n] and IN.BCOLOR[n].  So
+        * at link time if there is no matching OUT.BCOLOR[n], we must map
+        * OUT.COLOR[n] to IN.BCOLOR[n].  And visa versa if there is only
+        * a OUT.BCOLOR[n] but no matching OUT.COLOR[n]
+        */
+       if (sem2name(semantic) == TGSI_SEMANTIC_BCOLOR) {
+               unsigned idx = sem2idx(semantic);
+               semantic = ir3_semantic_name(TGSI_SEMANTIC_COLOR, idx);
+       } else if (sem2name(semantic) == TGSI_SEMANTIC_COLOR) {
+               unsigned idx = sem2idx(semantic);
+               semantic = ir3_semantic_name(TGSI_SEMANTIC_BCOLOR, idx);
+       } else {
+               return 0;
+       }
+
+       for (j = 0; j < so->outputs_count; j++)
+               if (so->outputs[j].semantic == semantic)
+                       return j;
+
+       debug_assert(0);
+
+       return 0;
+}
+
+static inline int
+ir3_next_varying(const struct ir3_shader_variant *so, int i)
+{
+       while (++i < so->inputs_count)
+               if (so->inputs[i].compmask && so->inputs[i].bary)
+                       break;
+       return i;
+}
+
+static inline uint32_t
+ir3_find_output_regid(const struct ir3_shader_variant *so, ir3_semantic semantic)
+{
+       int j;
+       for (j = 0; j < so->outputs_count; j++)
+               if (so->outputs[j].semantic == semantic)
+                       return so->outputs[j].regid;
+       return regid(63, 0);
+}
+
 #endif /* IR3_SHADER_H_ */