ir3: Add support for gl_ViewIndex in VS & FS
[mesa.git] / src / freedreno / ir3 / ir3_shader.h
index 0123af6763561f7f3c072228d92573ff073034e8..53be9a6833d87455c4c65c091e6e2238986abaf4 100644 (file)
@@ -33,8 +33,9 @@
 #include "compiler/shader_enums.h"
 #include "compiler/nir/nir.h"
 #include "util/bitscan.h"
+#include "util/disk_cache.h"
 
-#include "ir3.h"
+#include "ir3_compiler.h"
 
 struct glsl_type;
 
@@ -55,9 +56,10 @@ enum ir3_driver_param {
        IR3_DP_CS_COUNT   = 8,   /* must be aligned to vec4 */
 
        /* vertex shader driver params: */
-       IR3_DP_VTXID_BASE = 0,
-       IR3_DP_VTXCNT_MAX = 1,
+       IR3_DP_DRAWID = 0,
+       IR3_DP_VTXID_BASE = 1,
        IR3_DP_INSTID_BASE = 2,
+       IR3_DP_VTXCNT_MAX = 3,
        /* user-clip-plane components, up to 8x vec4's: */
        IR3_DP_UCP0_X     = 4,
        /* .... */
@@ -72,20 +74,43 @@ enum ir3_driver_param {
 #define IR3_MAX_SO_OUTPUTS       64
 #define IR3_MAX_UBO_PUSH_RANGES  32
 
+/* mirrors SYSTEM_VALUE_BARYCENTRIC_ but starting from 0 */
+enum ir3_bary {
+       IJ_PERSP_PIXEL,
+       IJ_PERSP_SAMPLE,
+       IJ_PERSP_CENTROID,
+       IJ_PERSP_SIZE,
+       IJ_LINEAR_PIXEL,
+       IJ_LINEAR_CENTROID,
+       IJ_LINEAR_SAMPLE,
+       IJ_COUNT,
+};
 
-struct ir3_ubo_range {
-       uint32_t offset; /* start offset to push in the const register file */
+/**
+ * Description of a lowered UBO.
+ */
+struct ir3_ubo_info {
        uint32_t block; /* Which constant block */
-       uint32_t start, end; /* range of block that's actually used */
        uint16_t bindless_base; /* For bindless, which base register is used */
        bool bindless;
 };
 
+/**
+ * Description of a range of a lowered UBO access.
+ *
+ * Drivers should not assume that there are not multiple disjoint
+ * lowered ranges of a single UBO.
+ */
+struct ir3_ubo_range {
+       struct ir3_ubo_info ubo;
+       uint32_t offset; /* start offset to push in the const register file */
+       uint32_t start, end; /* range of block that's actually used */
+};
+
 struct ir3_ubo_analysis_state {
        struct ir3_ubo_range range[IR3_MAX_UBO_PUSH_RANGES];
        uint32_t num_enabled;
        uint32_t size;
-       uint32_t lower_count;
        uint32_t cmdstream_size; /* for per-gen backend to stash required cmdstream size */
 };
 
@@ -130,7 +155,6 @@ struct ir3_ubo_analysis_state {
  */
 struct ir3_const_state {
        unsigned num_ubos;
-       unsigned num_reserved_user_consts;
        unsigned num_driver_params;   /* scalar */
 
        struct {
@@ -167,12 +191,9 @@ struct ir3_const_state {
                uint32_t off[IR3_MAX_SHADER_IMAGES];
        } image_dims;
 
-       unsigned immediate_idx;
        unsigned immediates_count;
        unsigned immediates_size;
-       struct {
-               uint32_t val[4];
-       } *immediates;
+       uint32_t *immediates;
 
        /* State of ubo access lowered to push consts: */
        struct ir3_ubo_analysis_state ubo_state;
@@ -288,6 +309,15 @@ struct ir3_shader_key {
                        unsigned tessellation : 2;
 
                        unsigned has_gs : 1;
+
+                       /* Whether this variant sticks to the "safe" maximum constlen,
+                        * which guarantees that the combined stages will never go over
+                        * the limit:
+                        */
+                       unsigned safe_constlen : 1;
+
+                       /* Whether gl_Layer must be forced to 0 because it isn't written. */
+                       unsigned layer_zero : 1;
                };
                uint32_t global;
        };
@@ -355,9 +385,15 @@ ir3_shader_key_changes_fs(struct ir3_shader_key *key, struct ir3_shader_key *las
        if (last_key->rasterflat != key->rasterflat)
                return true;
 
+       if (last_key->layer_zero != key->layer_zero)
+               return true;
+
        if (last_key->ucp_enables != key->ucp_enables)
                return true;
 
+       if (last_key->safe_constlen != key->safe_constlen)
+               return true;
+
        return false;
 }
 
@@ -380,6 +416,9 @@ ir3_shader_key_changes_vs(struct ir3_shader_key *key, struct ir3_shader_key *las
        if (last_key->ucp_enables != key->ucp_enables)
                return true;
 
+       if (last_key->safe_constlen != key->safe_constlen)
+               return true;
+
        return false;
 }
 
@@ -428,6 +467,10 @@ struct ir3_ibo_mapping {
 /* Represents half register in regid */
 #define HALF_REG_ID    0x100
 
+/**
+ * Shader variant which contains the actual hw shader instructions,
+ * and necessary info for shader state setup.
+ */
 struct ir3_shader_variant {
        struct fd_bo *bo;
 
@@ -445,12 +488,36 @@ struct ir3_shader_variant {
                struct ir3_shader_variant *nonbinning;
 //     };
 
-       struct ir3_info info;
-       struct ir3 *ir;
+       struct ir3 *ir;     /* freed after assembling machine instructions */
+
+       /* shader variants form a linked list: */
+       struct ir3_shader_variant *next;
+
+       /* replicated here to avoid passing extra ptrs everywhere: */
+       gl_shader_stage type;
+       struct ir3_shader *shader;
+
+       /*
+        * Below here is serialized when written to disk cache:
+        */
 
        /* The actual binary shader instructions, size given by info.sizedwords: */
        uint32_t *bin;
 
+       struct ir3_const_state *const_state;
+
+       /*
+        * The following macros are used by the shader disk cache save/
+        * restore paths to serialize/deserialize the variant.  Any
+        * pointers that require special handling in store_variant()
+        * and retrieve_variant() should go above here.
+        */
+#define VARIANT_CACHE_START    offsetof(struct ir3_shader_variant, info)
+#define VARIANT_CACHE_PTR(v)   (((char *)v) + VARIANT_CACHE_START)
+#define VARIANT_CACHE_SIZE     (sizeof(struct ir3_shader_variant) - VARIANT_CACHE_START)
+
+       struct ir3_info info;
+
        /* Levels of nesting of flow control:
         */
        unsigned branchstack;
@@ -494,7 +561,13 @@ struct ir3_shader_variant {
                uint8_t regid;
                bool    half : 1;
        } outputs[32 + 2];  /* +POSITION +PSIZE */
-       bool writes_pos, writes_smask, writes_psize;
+       bool writes_pos, writes_smask, writes_psize, writes_stencilref;
+
+       /* Size in dwords of all outputs for VS, size of entire patch for HS. */
+       uint32_t output_size;
+
+       /* Map from driver_location to byte offset in per-primitive storage */
+       unsigned output_loc[32];
 
        /* attributes (VS) / varyings (FS):
         * Note that sysval's should come *after* normal inputs.
@@ -579,13 +652,6 @@ struct ir3_shader_variant {
                unsigned orig_idx[16];
        } astc_srgb;
 
-       /* shader variants form a linked list: */
-       struct ir3_shader_variant *next;
-
-       /* replicated here to avoid passing extra ptrs everywhere: */
-       gl_shader_stage type;
-       struct ir3_shader *shader;
-
        /* texture sampler pre-dispatches */
        uint32_t num_sampler_prefetch;
        struct ir3_sampler_prefetch sampler_prefetch[IR3_MAX_SAMPLER_PREFETCH];
@@ -607,7 +673,22 @@ ir3_shader_stage(struct ir3_shader_variant *v)
        }
 }
 
+/* Currently we do not do binning for tess.  And for GS there is no
+ * cross-stage VS+GS optimization, so the full VS+GS is used in
+ * the binning pass.
+ */
+static inline bool
+ir3_has_binning_vs(const struct ir3_shader_key *key)
+{
+       if (key->tessellation || key->has_gs)
+               return false;
+       return true;
+}
 
+/**
+ * Represents a shader at the API level, before state-specific variants are
+ * generated.
+ */
 struct ir3_shader {
        gl_shader_stage type;
 
@@ -622,18 +703,16 @@ struct ir3_shader {
 
        struct ir3_compiler *compiler;
 
-       struct ir3_const_state const_state;
+       unsigned num_reserved_user_consts;
 
+       bool nir_finalized;
        struct nir_shader *nir;
        struct ir3_stream_output_info stream_output;
 
        struct ir3_shader_variant *variants;
        mtx_t variants_lock;
 
-       uint32_t output_size; /* Size in dwords of all outputs for VS, size of entire patch for HS. */
-
-       /* Map from driver_location to byte offset in per-primitive storage */
-       unsigned output_loc[32];
+       cache_key cache_key;     /* shader disk-cache key */
 
        /* Bitmask of bits of the shader key used by this shader.  Used to avoid
         * recompiles for GL NOS that doesn't actually apply to the shader.
@@ -641,10 +720,36 @@ struct ir3_shader {
        struct ir3_shader_key key_mask;
 };
 
+/**
+ * In order to use the same cmdstream, in particular constlen setup and const
+ * emit, for both binning and draw pass (a6xx+), the binning pass re-uses it's
+ * corresponding draw pass shaders const_state.
+ */
 static inline struct ir3_const_state *
 ir3_const_state(const struct ir3_shader_variant *v)
 {
-       return &v->shader->const_state;
+       if (v->binning_pass)
+               return v->nonbinning->const_state;
+       return v->const_state;
+}
+
+/* Given a variant, calculate the maximum constlen it can have.
+ */
+
+static inline unsigned
+ir3_max_const(const struct ir3_shader_variant *v)
+{
+       const struct ir3_compiler *compiler = v->shader->compiler;
+
+       if (v->shader->type == MESA_SHADER_COMPUTE) {
+               return compiler->max_const_compute;
+       } else if (v->key.safe_constlen) {
+               return compiler->max_const_safe;
+       } else if (v->shader->type == MESA_SHADER_FRAGMENT) {
+               return compiler->max_const_frag;
+       } else {
+               return compiler->max_const_geom;
+       }
 }
 
 void * ir3_shader_assemble(struct ir3_shader_variant *v);
@@ -652,6 +757,8 @@ struct ir3_shader_variant * ir3_shader_get_variant(struct ir3_shader *shader,
                const struct ir3_shader_key *key, bool binning_pass, bool *created);
 struct ir3_shader * ir3_shader_from_nir(struct ir3_compiler *compiler, nir_shader *nir,
                unsigned reserved_user_consts, struct ir3_stream_output_info *stream_output);
+uint32_t ir3_trim_constlen(struct ir3_shader_variant **variants,
+               const struct ir3_compiler *compiler);
 void ir3_shader_destroy(struct ir3_shader *shader);
 void ir3_shader_disasm(struct ir3_shader_variant *so, uint32_t *bin, FILE *out);
 uint64_t ir3_shader_outputs(const struct ir3_shader *so);
@@ -744,13 +851,14 @@ struct ir3_shader_linkage {
 
        /* location for fixed-function gl_PrimitiveID passthrough */
        uint8_t primid_loc;
+
+       /* location for fixed-function gl_ViewIndex passthrough */
+       uint8_t viewid_loc;
 };
 
 static inline void
 ir3_link_add(struct ir3_shader_linkage *l, uint8_t regid_, uint8_t compmask, uint8_t loc)
 {
-
-
        for (int j = 0; j < util_last_bit(compmask); j++) {
                uint8_t comploc = loc + j;
                l->varmask[comploc / 32] |= 1 << (comploc % 32);
@@ -786,6 +894,7 @@ ir3_link_shaders(struct ir3_shader_linkage *l,
        int j = -1, k;
 
        l->primid_loc = 0xff;
+       l->viewid_loc = 0xff;
 
        while (l->cnt < ARRAY_SIZE(l->var)) {
                j = ir3_next_varying(fs, j);
@@ -802,6 +911,11 @@ ir3_link_shaders(struct ir3_shader_linkage *l,
                        l->primid_loc = fs->inputs[j].inloc;
                }
 
+               if (fs->inputs[j].slot == VARYING_SLOT_VIEW_INDEX) {
+                       assert(k < 0);
+                       l->viewid_loc = fs->inputs[j].inloc;
+               }
+
                ir3_link_add(l, k >= 0 ? vs->outputs[k].regid : default_regid,
                        fs->inputs[j].compmask, fs->inputs[j].inloc);
        }