freedreno/a4xx: better workaround for astc+srgb
[mesa.git] / src / gallium / drivers / freedreno / ir3 / ir3_shader.h
index 4cb252053243c2114b0aa561973ccbf7d6a97369..e81e80d328f261fba66a0b1460104b63b33a5fbe 100644 (file)
@@ -30,6 +30,7 @@
 #define IR3_SHADER_H_
 
 #include "pipe/p_state.h"
+#include "compiler/shader_enums.h"
 
 #include "ir3.h"
 #include "disasm.h"
 /* driver param indices: */
 enum ir3_driver_param {
        IR3_DP_VTXID_BASE = 0,
+       IR3_DP_VTXCNT_MAX = 1,
+       /* user-clip-plane components, up to 8x vec4's: */
+       IR3_DP_UCP0_X     = 4,
+       /* .... */
+       IR3_DP_UCP7_W     = 35,
+       IR3_DP_COUNT      = 36   /* must be aligned to vec4 */
 };
 
-/* internal semantic used for passing vtxcnt to vertex shader to
- * implement transform feedback:
+/* Layout of constant registers:
+ *
+ *    num_uniform * vec4  -  user consts
+ *    4 * vec4            -  UBO addresses
+ *    if (vertex shader) {
+ *        N * vec4        -  driver params (IR3_DP_*)
+ *        1 * vec4        -  stream-out addresses
+ *    }
+ *
+ * TODO this could be made more dynamic, to at least skip sections
+ * that we don't need..
  */
-#define IR3_SEMANTIC_VTXCNT (TGSI_SEMANTIC_COUNT + 0)
-
-typedef uint16_t ir3_semantic;  /* semantic name + index */
-static inline ir3_semantic
-ir3_semantic_name(uint8_t name, uint16_t index)
-{
-       return (name << 8) | (index & 0xff);
-}
-
-static inline uint8_t sem2name(ir3_semantic sem)
-{
-       return sem >> 8;
-}
-
-static inline uint16_t sem2idx(ir3_semantic sem)
-{
-       return sem & 0xff;
-}
+#define IR3_UBOS_OFF         0  /* UBOs after user consts */
+#define IR3_DRIVER_PARAM_OFF 4  /* driver params after UBOs */
+#define IR3_TFBOS_OFF       (IR3_DRIVER_PARAM_OFF + IR3_DP_COUNT/4)
 
 /* Configuration key used to identify a shader variant.. different
  * shader variants can be used to implement features not supported
@@ -68,6 +69,11 @@ static inline uint16_t sem2idx(ir3_semantic sem)
 struct ir3_shader_key {
        union {
                struct {
+                       /*
+                        * Combined Vertex/Fragment shader parameters:
+                        */
+                       unsigned ucp_enables : 8;
+
                        /* do we need to check {v,f}saturate_{s,t,r}? */
                        unsigned has_per_samp : 1;
 
@@ -81,8 +87,8 @@ struct ir3_shader_key {
                         */
                        unsigned color_two_side : 1;
                        unsigned half_precision : 1;
-                       /* used when shader needs to handle flat varyings (a4xx),
-                        * for TGSI_INTERPOLATE_COLOR:
+                       /* used when shader needs to handle flat varyings (a4xx)
+                        * for front/back color inputs to frag shader:
                         */
                        unsigned rasterflat : 1;
                };
@@ -98,6 +104,9 @@ struct ir3_shader_key {
         * shader:
         */
        uint16_t fsaturate_s, fsaturate_t, fsaturate_r;
+
+       /* bitmask of samplers which need astc srgb workaround: */
+       uint16_t vastc_srgb, fastc_srgb;
 };
 
 static inline bool
@@ -146,18 +155,26 @@ struct ir3_shader_variant {
        uint8_t pos_regid;
        bool frag_coord, frag_face, color0_mrt;
 
+       /* NOTE: for input/outputs, slot is:
+        *   gl_vert_attrib  - for VS inputs
+        *   gl_varying_slot - for VS output / FS input
+        *   gl_frag_result  - for FS output
+        */
+
        /* varyings/outputs: */
        unsigned outputs_count;
        struct {
-               ir3_semantic semantic;
+               uint8_t slot;
                uint8_t regid;
        } outputs[16 + 2];  /* +POSITION +PSIZE */
        bool writes_pos, writes_psize;
 
-       /* vertices/inputs: */
+       /* attributes (VS) / varyings (FS):
+        * Note that sysval's should come *after* normal inputs.
+        */
        unsigned inputs_count;
        struct {
-               ir3_semantic semantic;
+               uint8_t slot;
                uint8_t regid;
                uint8_t compmask;
                uint8_t ncomp;
@@ -173,11 +190,23 @@ struct ir3_shader_variant {
                 * spots where inloc is used.
                 */
                uint8_t inloc;
-               uint8_t bary;
-               uint8_t interpolate;
+               /* vertex shader specific: */
+               bool    sysval     : 1;   /* slot is a gl_system_value */
+               /* fragment shader specific: */
+               bool    bary       : 1;   /* fetched varying (vs one loaded into reg) */
+               bool    rasterflat : 1;   /* special handling for emit->rasterflat */
+               enum glsl_interp_qualifier interpolate;
        } inputs[16 + 2];  /* +POSITION +FACE */
 
-       unsigned total_in;       /* sum of inputs (scalar) */
+       /* sum of input components (scalar).  For frag shaders, it only counts
+        * the varying inputs:
+        */
+       unsigned total_in;
+
+       /* For frag shaders, the total number of inputs (not scalar,
+        * ie. SP_VS_PARAM_REG.TOTALVSOUTVAR)
+        */
+       unsigned varying_in;
 
        /* do we have one or more texture sample instructions: */
        bool has_samp;
@@ -196,6 +225,14 @@ struct ir3_shader_variant {
                uint32_t val[4];
        } immediates[64];
 
+       /* for astc srgb workaround, the number/base of additional
+        * alpha tex states we need, and index of original tex states
+        */
+       struct {
+               unsigned base, count;
+               unsigned orig_idx[16];
+       } astc_srgb;
+
        /* shader variants form a linked list: */
        struct ir3_shader_variant *next;
 
@@ -204,6 +241,8 @@ struct ir3_shader_variant {
        struct ir3_shader *shader;
 };
 
+typedef struct nir_shader nir_shader;
+
 struct ir3_shader {
        enum shader_t type;
 
@@ -213,21 +252,15 @@ struct ir3_shader {
 
        struct ir3_compiler *compiler;
 
-       struct pipe_context *pctx;
-       const struct tgsi_token *tokens;
+       nir_shader *nir;
        struct pipe_stream_output_info stream_output;
 
        struct ir3_shader_variant *variants;
-
-       /* so far, only used for blit_prog shader.. values for
-        * VPC_VARYING_PS_REPL[i].MODE
-        */
-       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,
+struct ir3_shader * ir3_shader_create(struct ir3_compiler *compiler,
                const struct pipe_shader_state *cso, enum shader_t type);
 void ir3_shader_destroy(struct ir3_shader *shader);
 struct ir3_shader_variant * ir3_shader_variant(struct ir3_shader *shader,
@@ -235,8 +268,9 @@ struct ir3_shader_variant * ir3_shader_variant(struct ir3_shader *shader,
 void ir3_shader_disasm(struct ir3_shader_variant *so, uint32_t *bin);
 
 struct fd_ringbuffer;
-void ir3_emit_consts(struct ir3_shader_variant *v, struct fd_ringbuffer *ring,
-               const struct pipe_draw_info *info, uint32_t dirty);
+struct fd_context;
+void ir3_emit_consts(const struct ir3_shader_variant *v, struct fd_ringbuffer *ring,
+               struct fd_context *ctx, const struct pipe_draw_info *info, uint32_t dirty);
 
 static inline const char *
 ir3_shader_stage(struct ir3_shader *shader)
@@ -258,12 +292,12 @@ ir3_shader_stage(struct ir3_shader *shader)
 #include "pipe/p_shader_tokens.h"
 
 static inline int
-ir3_find_output(const struct ir3_shader_variant *so, ir3_semantic semantic)
+ir3_find_output(const struct ir3_shader_variant *so, gl_varying_slot slot)
 {
        int j;
 
        for (j = 0; j < so->outputs_count; j++)
-               if (so->outputs[j].semantic == semantic)
+               if (so->outputs[j].slot == slot)
                        return j;
 
        /* it seems optional to have a OUT.BCOLOR[n] for each OUT.COLOR[n]
@@ -273,18 +307,20 @@ ir3_find_output(const struct ir3_shader_variant *so, ir3_semantic semantic)
         * 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);
+       if (slot == VARYING_SLOT_BFC0) {
+               slot = VARYING_SLOT_COL0;
+       } else if (slot == VARYING_SLOT_BFC1) {
+               slot = VARYING_SLOT_COL1;
+       } else if (slot == VARYING_SLOT_COL0) {
+               slot = VARYING_SLOT_BFC0;
+       } else if (slot == VARYING_SLOT_COL1) {
+               slot = VARYING_SLOT_BFC1;
        } else {
                return 0;
        }
 
        for (j = 0; j < so->outputs_count; j++)
-               if (so->outputs[j].semantic == semantic)
+               if (so->outputs[j].slot == slot)
                        return j;
 
        debug_assert(0);
@@ -302,11 +338,11 @@ ir3_next_varying(const struct ir3_shader_variant *so, int i)
 }
 
 static inline uint32_t
-ir3_find_output_regid(const struct ir3_shader_variant *so, ir3_semantic semantic)
+ir3_find_output_regid(const struct ir3_shader_variant *so, unsigned slot)
 {
        int j;
        for (j = 0; j < so->outputs_count; j++)
-               if (so->outputs[j].semantic == semantic)
+               if (so->outputs[j].slot == slot)
                        return so->outputs[j].regid;
        return regid(63, 0);
 }