anv: Completely rework descriptor set layouts
[mesa.git] / src / vulkan / anv_compiler.cpp
index 4cbf98afa1e30eba44c0ccc200f6d57b0dc7cf48..bf931fe886f53be895bba449c45dc16a1cd91401 100644 (file)
@@ -26,6 +26,7 @@
 #include <fcntl.h>
 
 #include "anv_private.h"
+#include "anv_nir.h"
 
 #include <brw_context.h>
 #include <brw_wm.h> /* brw_new_shader_program is here */
@@ -34,6 +35,7 @@
 #include <brw_vs.h>
 #include <brw_gs.h>
 #include <brw_cs.h>
+#include "brw_vec4_gs_visitor.h"
 
 #include <mesa/main/shaderobj.h>
 #include <mesa/main/fbobject.h>
@@ -90,13 +92,20 @@ set_binding_table_layout(struct brw_stage_prog_data *prog_data,
 
    k = bias;
    map = prog_data->map_entries;
-   for (uint32_t i = 0; i < layout->num_sets; i++) {
-      prog_data->bind_map[i].index = map;
-      for (uint32_t j = 0; j < layout->set[i].layout->stage[stage].surface_count; j++)
-         *map++ = k++;
+   for (uint32_t set = 0; set < layout->num_sets; set++) {
+      prog_data->bind_map[set].index = map;
+      unsigned index_count = 0;
+      for (uint32_t b = 0; b < layout->set[set].layout->binding_count; b++) {
+         if (layout->set[set].layout->binding[b].stage[stage].surface_index < 0)
+            continue;
+
+         unsigned array_size = layout->set[set].layout->binding[b].array_size;
+         for (uint32_t i = 0; i < array_size; i++)
+            *map++ = k++;
+         index_count += array_size;
+      }
 
-      prog_data->bind_map[i].index_count =
-         layout->set[i].layout->stage[stage].surface_count;
+      prog_data->bind_map[set].index_count = index_count;
    }
 
    return VK_SUCCESS;
@@ -115,6 +124,108 @@ upload_kernel(struct anv_pipeline *pipeline, const void *data, size_t size)
    return state.offset;
 }
 
+static void
+create_params_array(struct anv_pipeline *pipeline,
+                    struct gl_shader *shader,
+                    struct brw_stage_prog_data *prog_data)
+{
+   VkShaderStage stage = anv_vk_shader_stage_for_mesa_stage(shader->Stage);
+   unsigned num_params = 0;
+
+   if (shader->num_uniform_components) {
+      /* If the shader uses any push constants at all, we'll just give
+       * them the maximum possible number
+       */
+      num_params += MAX_PUSH_CONSTANTS_SIZE / sizeof(float);
+   }
+
+   if (pipeline->layout && pipeline->layout->stage[stage].has_dynamic_offsets)
+      num_params += MAX_DYNAMIC_BUFFERS;
+
+   if (num_params == 0)
+      return;
+
+   prog_data->param = (const gl_constant_value **)
+      anv_device_alloc(pipeline->device,
+                       num_params * sizeof(gl_constant_value *),
+                       8, VK_SYSTEM_ALLOC_TYPE_INTERNAL_SHADER);
+
+   /* We now set the param values to be offsets into a
+    * anv_push_constant_data structure.  Since the compiler doesn't
+    * actually dereference any of the gl_constant_value pointers in the
+    * params array, it doesn't really matter what we put here.
+    */
+   struct anv_push_constants *null_data = NULL;
+   for (unsigned i = 0; i < num_params; i++)
+      prog_data->param[i] =
+         (const gl_constant_value *)&null_data->client_data[i * sizeof(float)];
+}
+
+/**
+ * Return a bitfield where bit n is set if barycentric interpolation mode n
+ * (see enum brw_wm_barycentric_interp_mode) is needed by the fragment shader.
+ */
+unsigned
+brw_compute_barycentric_interp_modes(const struct brw_device_info *devinfo,
+                                     bool shade_model_flat,
+                                     bool persample_shading,
+                                     nir_shader *shader)
+{
+   unsigned barycentric_interp_modes = 0;
+
+   nir_foreach_variable(var, &shader->inputs) {
+      enum glsl_interp_qualifier interp_qualifier =
+         (enum glsl_interp_qualifier) var->data.interpolation;
+      bool is_centroid = var->data.centroid && !persample_shading;
+      bool is_sample = var->data.sample || persample_shading;
+      bool is_gl_Color = (var->data.location == VARYING_SLOT_COL0) ||
+                         (var->data.location == VARYING_SLOT_COL1);
+
+      /* Ignore WPOS and FACE, because they don't require interpolation. */
+      if (var->data.location == VARYING_SLOT_POS ||
+          var->data.location == VARYING_SLOT_FACE)
+         continue;
+
+      /* Determine the set (or sets) of barycentric coordinates needed to
+       * interpolate this variable.  Note that when
+       * brw->needs_unlit_centroid_workaround is set, centroid interpolation
+       * uses PIXEL interpolation for unlit pixels and CENTROID interpolation
+       * for lit pixels, so we need both sets of barycentric coordinates.
+       */
+      if (interp_qualifier == INTERP_QUALIFIER_NOPERSPECTIVE) {
+         if (is_centroid) {
+            barycentric_interp_modes |=
+               1 << BRW_WM_NONPERSPECTIVE_CENTROID_BARYCENTRIC;
+         } else if (is_sample) {
+            barycentric_interp_modes |=
+               1 << BRW_WM_NONPERSPECTIVE_SAMPLE_BARYCENTRIC;
+         }
+         if ((!is_centroid && !is_sample) ||
+             devinfo->needs_unlit_centroid_workaround) {
+            barycentric_interp_modes |=
+               1 << BRW_WM_NONPERSPECTIVE_PIXEL_BARYCENTRIC;
+         }
+      } else if (interp_qualifier == INTERP_QUALIFIER_SMOOTH ||
+                 (!(shade_model_flat && is_gl_Color) &&
+                  interp_qualifier == INTERP_QUALIFIER_NONE)) {
+         if (is_centroid) {
+            barycentric_interp_modes |=
+               1 << BRW_WM_PERSPECTIVE_CENTROID_BARYCENTRIC;
+         } else if (is_sample) {
+            barycentric_interp_modes |=
+               1 << BRW_WM_PERSPECTIVE_SAMPLE_BARYCENTRIC;
+         }
+         if ((!is_centroid && !is_sample) ||
+             devinfo->needs_unlit_centroid_workaround) {
+            barycentric_interp_modes |=
+               1 << BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC;
+         }
+      }
+   }
+
+   return barycentric_interp_modes;
+}
+
 static void
 brw_vs_populate_key(struct brw_context *brw,
                     struct brw_vertex_program *vp,
@@ -129,9 +240,7 @@ brw_vs_populate_key(struct brw_context *brw,
    /* Just upload the program verbatim for now.  Always send it all
     * the inputs it asks for, whether they are varying or not.
     */
-   key->base.program_string_id = vp->id;
-   brw_setup_vue_key_clip_info(brw, &key->base,
-                               vp->program.Base.UsesClipDistanceOut);
+   key->program_string_id = vp->id;
 
    /* _NEW_POLYGON */
    if (brw->gen < 6) {
@@ -152,10 +261,6 @@ brw_vs_populate_key(struct brw_context *brw,
             key->point_coord_replace |= (1 << i);
       }
    }
-
-   /* _NEW_TEXTURE */
-   brw_populate_sampler_prog_key_data(ctx, prog, brw->vs.base.sampler_count,
-                                      &key->base.tex);
 }
 
 static bool
@@ -167,7 +272,6 @@ really_do_vs_prog(struct brw_context *brw,
    GLuint program_size;
    const GLuint *program;
    struct brw_vs_prog_data *prog_data = &pipeline->vs_prog_data;
-   struct brw_stage_prog_data *stage_prog_data = &prog_data->base.base;
    void *mem_ctx;
    struct gl_shader *vs = NULL;
 
@@ -178,34 +282,9 @@ really_do_vs_prog(struct brw_context *brw,
 
    mem_ctx = ralloc_context(NULL);
 
-   /* Allocate the references to the uniforms that will end up in the
-    * prog_data associated with the compiled program, and which will be freed
-    * by the state cache.
-    */
-   int param_count;
-   if (vs) {
-      /* We add padding around uniform values below vec4 size, with the worst
-       * case being a float value that gets blown up to a vec4, so be
-       * conservative here.
-       */
-      param_count = vs->num_uniform_components * 4;
-
-   } else {
-      param_count = vp->program.Base.Parameters->NumParameters * 4;
-   }
-   /* vec4_visitor::setup_uniform_clipplane_values() also uploads user clip
-    * planes as uniforms.
-    */
-   param_count += key->base.nr_userclip_plane_consts * 4;
-
-   /* Setting nr_params here NOT to the size of the param and pull_param
-    * arrays, but to the number of uniform components vec4_visitor
-    * needs. vec4_visitor::setup_uniforms() will set it back to a proper value.
-    */
-   stage_prog_data->nr_params = ALIGN(param_count, 4) / 4;
-   if (vs) {
-      stage_prog_data->nr_params += vs->num_samplers;
-   }
+   create_params_array(pipeline, vs, &prog_data->base.base);
+   anv_nir_apply_dynamic_offsets(pipeline, vs->Program->nir,
+                                 &prog_data->base.base);
 
    GLbitfield64 outputs_written = vp->program.Base.OutputsWritten;
    prog_data->inputs_read = vp->program.Base.InputsRead;
@@ -238,21 +317,22 @@ really_do_vs_prog(struct brw_context *brw,
     * distance varying slots whenever clipping is enabled, even if the vertex
     * shader doesn't write to gl_ClipDistance.
     */
-   if (key->base.userclip_active) {
+   if (key->nr_userclip_plane_consts) {
       outputs_written |= BITFIELD64_BIT(VARYING_SLOT_CLIP_DIST0);
       outputs_written |= BITFIELD64_BIT(VARYING_SLOT_CLIP_DIST1);
    }
 
    brw_compute_vue_map(brw->intelScreen->devinfo,
-                       &prog_data->base.vue_map, outputs_written);
-\
+                       &prog_data->base.vue_map, outputs_written,
+                       prog ? prog->SeparateShader : false);
+
    set_binding_table_layout(&prog_data->base.base, pipeline,
                             VK_SHADER_STAGE_VERTEX);
 
    /* Emit GEN4 code.
     */
    program = brw_vs_emit(brw, mem_ctx, key, prog_data, &vp->program,
-                         prog, &program_size);
+                         prog, -1, &program_size);
    if (program == NULL) {
       ralloc_free(mem_ctx);
       return false;
@@ -277,7 +357,6 @@ void brw_wm_populate_key(struct brw_context *brw,
                          struct brw_wm_prog_key *key)
 {
    struct gl_context *ctx = &brw->ctx;
-   struct gl_program *prog = (struct gl_program *) brw->fragment_program;
    GLuint lookup = 0;
    GLuint line_aa;
    bool program_uses_dfdy = fp->program.UsesDFdy;
@@ -372,10 +451,6 @@ void brw_wm_populate_key(struct brw_context *brw,
    /* _NEW_FRAG_CLAMP | _NEW_BUFFERS */
    key->clamp_fragment_color = ctx->Color._ClampFragmentColor;
 
-   /* _NEW_TEXTURE */
-   brw_populate_sampler_prog_key_data(ctx, prog, brw->wm.base.sampler_count,
-                                      &key->tex);
-
    /* _NEW_BUFFERS */
    /*
     * Include the draw buffer origin and height so that we can calculate
@@ -476,7 +551,6 @@ really_do_wm_prog(struct brw_context *brw,
                   struct brw_fragment_program *fp,
                   struct brw_wm_prog_key *key, struct anv_pipeline *pipeline)
 {
-   struct gl_context *ctx = &brw->ctx;
    void *mem_ctx = ralloc_context(NULL);
    struct brw_wm_prog_data *prog_data = &pipeline->wm_prog_data;
    struct gl_shader *fs = NULL;
@@ -495,28 +569,14 @@ really_do_wm_prog(struct brw_context *brw,
 
    prog_data->computed_depth_mode = computed_depth_mode(&fp->program);
 
-   /* Allocate the references to the uniforms that will end up in the
-    * prog_data associated with the compiled program, and which will be freed
-    * by the state cache.
-    */
-   int param_count;
-   if (fs) {
-      param_count = fs->num_uniform_components;
-   } else {
-      param_count = fp->program.Base.Parameters->NumParameters * 4;
-   }
-   /* The backend also sometimes adds params for texture size. */
-   param_count += 2 * ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits;
-   prog_data->base.param =
-      rzalloc_array(NULL, const gl_constant_value *, param_count);
-   prog_data->base.pull_param =
-      rzalloc_array(NULL, const gl_constant_value *, param_count);
-   prog_data->base.nr_params = param_count;
+   create_params_array(pipeline, fs, &prog_data->base);
+   anv_nir_apply_dynamic_offsets(pipeline, fs->Program->nir, &prog_data->base);
 
    prog_data->barycentric_interp_modes =
-      brw_compute_barycentric_interp_modes(brw, key->flat_shade,
+      brw_compute_barycentric_interp_modes(brw->intelScreen->devinfo,
+                                           key->flat_shade,
                                            key->persample_shading,
-                                           &fp->program);
+                                           fp->program.Base.nir);
 
    set_binding_table_layout(&prog_data->base, pipeline,
                             VK_SHADER_STAGE_FRAGMENT);
@@ -526,7 +586,7 @@ really_do_wm_prog(struct brw_context *brw,
    prog_data->binding_table.render_target_start = 0;
 
    program = brw_wm_fs_emit(brw, mem_ctx, key, prog_data,
-                            &fp->program, prog, &program_size);
+                            &fp->program, prog, -1, -1, &program_size);
    if (program == NULL) {
       ralloc_free(mem_ctx);
       return false;
@@ -550,51 +610,260 @@ really_do_wm_prog(struct brw_context *brw,
    return true;
 }
 
-static void
-brw_gs_populate_key(struct brw_context *brw,
-                    struct anv_pipeline *pipeline,
+bool
+anv_codegen_gs_prog(struct brw_context *brw,
+                    struct gl_shader_program *prog,
                     struct brw_geometry_program *gp,
-                    struct brw_gs_prog_key *key)
+                    struct brw_gs_prog_key *key,
+                    struct anv_pipeline *pipeline)
 {
-   struct gl_context *ctx = &brw->ctx;
-   struct brw_stage_state *stage_state = &brw->gs.base;
-   struct gl_program *prog = &gp->program.Base;
+   struct brw_gs_compile c;
 
-   memset(key, 0, sizeof(*key));
+   memset(&c, 0, sizeof(c));
+   c.key = *key;
+   c.gp = gp;
 
-   key->base.program_string_id = gp->id;
-   brw_setup_vue_key_clip_info(brw, &key->base,
-                               gp->program.Base.UsesClipDistanceOut);
+   c.prog_data.include_primitive_id =
+      (gp->program.Base.InputsRead & VARYING_BIT_PRIMITIVE_ID) != 0;
 
-   /* _NEW_TEXTURE */
-   brw_populate_sampler_prog_key_data(ctx, prog, stage_state->sampler_count,
-                                      &key->base.tex);
+   c.prog_data.invocations = gp->program.Invocations;
 
-   struct brw_vs_prog_data *prog_data = &pipeline->vs_prog_data;
+   set_binding_table_layout(&c.prog_data.base.base,
+                            pipeline, VK_SHADER_STAGE_GEOMETRY);
 
-   /* BRW_NEW_VUE_MAP_VS */
-   key->input_varyings = prog_data->base.vue_map.slots_valid;
-}
+   /* Allocate the references to the uniforms that will end up in the
+    * prog_data associated with the compiled program, and which will be freed
+    * by the state cache.
+    *
+    * Note: param_count needs to be num_uniform_components * 4, since we add
+    * padding around uniform values below vec4 size, so the worst case is that
+    * every uniform is a float which gets padded to the size of a vec4.
+    */
+   struct gl_shader *gs = prog->_LinkedShaders[MESA_SHADER_GEOMETRY];
+   int param_count = gp->program.Base.nir->num_uniforms * 4;
 
-static bool
-really_do_gs_prog(struct brw_context *brw,
-                  struct gl_shader_program *prog,
-                  struct brw_geometry_program *gp,
-                  struct brw_gs_prog_key *key, struct anv_pipeline *pipeline)
-{
-   struct brw_gs_compile_output output;
+   c.prog_data.base.base.param =
+      rzalloc_array(NULL, const gl_constant_value *, param_count);
+   c.prog_data.base.base.pull_param =
+      rzalloc_array(NULL, const gl_constant_value *, param_count);
+   c.prog_data.base.base.image_param =
+      rzalloc_array(NULL, struct brw_image_param, gs->NumImages);
+   c.prog_data.base.base.nr_params = param_count;
+   c.prog_data.base.base.nr_image_params = gs->NumImages;
 
-   /* FIXME: We pass the bind map to the compile in the output struct. Need
-    * something better. */
-   set_binding_table_layout(&output.prog_data.base.base,
-                            pipeline, VK_SHADER_STAGE_GEOMETRY);
+   brw_nir_setup_glsl_uniforms(gp->program.Base.nir, prog, &gp->program.Base,
+                               &c.prog_data.base.base, false);
+
+   if (brw->gen >= 8) {
+      c.prog_data.static_vertex_count = !gp->program.Base.nir ? -1 :
+         nir_gs_count_vertices(gp->program.Base.nir);
+   }
+
+   if (brw->gen >= 7) {
+      if (gp->program.OutputType == GL_POINTS) {
+         /* When the output type is points, the geometry shader may output data
+          * to multiple streams, and EndPrimitive() has no effect.  So we
+          * configure the hardware to interpret the control data as stream ID.
+          */
+         c.prog_data.control_data_format = GEN7_GS_CONTROL_DATA_FORMAT_GSCTL_SID;
+
+         /* We only have to emit control bits if we are using streams */
+         if (prog->Geom.UsesStreams)
+            c.control_data_bits_per_vertex = 2;
+         else
+            c.control_data_bits_per_vertex = 0;
+      } else {
+         /* When the output type is triangle_strip or line_strip, EndPrimitive()
+          * may be used to terminate the current strip and start a new one
+          * (similar to primitive restart), and outputting data to multiple
+          * streams is not supported.  So we configure the hardware to interpret
+          * the control data as EndPrimitive information (a.k.a. "cut bits").
+          */
+         c.prog_data.control_data_format = GEN7_GS_CONTROL_DATA_FORMAT_GSCTL_CUT;
+
+         /* We only need to output control data if the shader actually calls
+          * EndPrimitive().
+          */
+         c.control_data_bits_per_vertex = gp->program.UsesEndPrimitive ? 1 : 0;
+      }
+   } else {
+      /* There are no control data bits in gen6. */
+      c.control_data_bits_per_vertex = 0;
+
+      /* If it is using transform feedback, enable it */
+      if (prog->TransformFeedback.NumVarying)
+         c.prog_data.gen6_xfb_enabled = true;
+      else
+         c.prog_data.gen6_xfb_enabled = false;
+   }
+   c.control_data_header_size_bits =
+      gp->program.VerticesOut * c.control_data_bits_per_vertex;
+
+   /* 1 HWORD = 32 bytes = 256 bits */
+   c.prog_data.control_data_header_size_hwords =
+      ALIGN(c.control_data_header_size_bits, 256) / 256;
+
+   GLbitfield64 outputs_written = gp->program.Base.OutputsWritten;
+
+   brw_compute_vue_map(brw->intelScreen->devinfo,
+                       &c.prog_data.base.vue_map, outputs_written,
+                       prog ? prog->SeparateShader : false);
+
+   /* Compute the output vertex size.
+    *
+    * From the Ivy Bridge PRM, Vol2 Part1 7.2.1.1 STATE_GS - Output Vertex
+    * Size (p168):
+    *
+    *     [0,62] indicating [1,63] 16B units
+    *
+    *     Specifies the size of each vertex stored in the GS output entry
+    *     (following any Control Header data) as a number of 128-bit units
+    *     (minus one).
+    *
+    *     Programming Restrictions: The vertex size must be programmed as a
+    *     multiple of 32B units with the following exception: Rendering is
+    *     disabled (as per SOL stage state) and the vertex size output by the
+    *     GS thread is 16B.
+    *
+    *     If rendering is enabled (as per SOL state) the vertex size must be
+    *     programmed as a multiple of 32B units. In other words, the only time
+    *     software can program a vertex size with an odd number of 16B units
+    *     is when rendering is disabled.
+    *
+    * Note: B=bytes in the above text.
+    *
+    * It doesn't seem worth the extra trouble to optimize the case where the
+    * vertex size is 16B (especially since this would require special-casing
+    * the GEN assembly that writes to the URB).  So we just set the vertex
+    * size to a multiple of 32B (2 vec4's) in all cases.
+    *
+    * The maximum output vertex size is 62*16 = 992 bytes (31 hwords).  We
+    * budget that as follows:
+    *
+    *   512 bytes for varyings (a varying component is 4 bytes and
+    *             gl_MaxGeometryOutputComponents = 128)
+    *    16 bytes overhead for VARYING_SLOT_PSIZ (each varying slot is 16
+    *             bytes)
+    *    16 bytes overhead for gl_Position (we allocate it a slot in the VUE
+    *             even if it's not used)
+    *    32 bytes overhead for gl_ClipDistance (we allocate it 2 VUE slots
+    *             whenever clip planes are enabled, even if the shader doesn't
+    *             write to gl_ClipDistance)
+    *    16 bytes overhead since the VUE size must be a multiple of 32 bytes
+    *             (see below)--this causes up to 1 VUE slot to be wasted
+    *   400 bytes available for varying packing overhead
+    *
+    * Worst-case varying packing overhead is 3/4 of a varying slot (12 bytes)
+    * per interpolation type, so this is plenty.
+    *
+    */
+   unsigned output_vertex_size_bytes = c.prog_data.base.vue_map.num_slots * 16;
+   assert(brw->gen == 6 ||
+          output_vertex_size_bytes <= GEN7_MAX_GS_OUTPUT_VERTEX_SIZE_BYTES);
+   c.prog_data.output_vertex_size_hwords =
+      ALIGN(output_vertex_size_bytes, 32) / 32;
+
+   /* Compute URB entry size.  The maximum allowed URB entry size is 32k.
+    * That divides up as follows:
+    *
+    *     64 bytes for the control data header (cut indices or StreamID bits)
+    *   4096 bytes for varyings (a varying component is 4 bytes and
+    *              gl_MaxGeometryTotalOutputComponents = 1024)
+    *   4096 bytes overhead for VARYING_SLOT_PSIZ (each varying slot is 16
+    *              bytes/vertex and gl_MaxGeometryOutputVertices is 256)
+    *   4096 bytes overhead for gl_Position (we allocate it a slot in the VUE
+    *              even if it's not used)
+    *   8192 bytes overhead for gl_ClipDistance (we allocate it 2 VUE slots
+    *              whenever clip planes are enabled, even if the shader doesn't
+    *              write to gl_ClipDistance)
+    *   4096 bytes overhead since the VUE size must be a multiple of 32
+    *              bytes (see above)--this causes up to 1 VUE slot to be wasted
+    *   8128 bytes available for varying packing overhead
+    *
+    * Worst-case varying packing overhead is 3/4 of a varying slot per
+    * interpolation type, which works out to 3072 bytes, so this would allow
+    * us to accommodate 2 interpolation types without any danger of running
+    * out of URB space.
+    *
+    * In practice, the risk of running out of URB space is very small, since
+    * the above figures are all worst-case, and most of them scale with the
+    * number of output vertices.  So we'll just calculate the amount of space
+    * we need, and if it's too large, fail to compile.
+    *
+    * The above is for gen7+ where we have a single URB entry that will hold
+    * all the output. In gen6, we will have to allocate URB entries for every
+    * vertex we emit, so our URB entries only need to be large enough to hold
+    * a single vertex. Also, gen6 does not have a control data header.
+    */
+   unsigned output_size_bytes;
+   if (brw->gen >= 7) {
+      output_size_bytes =
+         c.prog_data.output_vertex_size_hwords * 32 * gp->program.VerticesOut;
+      output_size_bytes += 32 * c.prog_data.control_data_header_size_hwords;
+   } else {
+      output_size_bytes = c.prog_data.output_vertex_size_hwords * 32;
+   }
+
+   /* Broadwell stores "Vertex Count" as a full 8 DWord (32 byte) URB output,
+    * which comes before the control header.
+    */
+   if (brw->gen >= 8)
+      output_size_bytes += 32;
+
+   assert(output_size_bytes >= 1);
+   int max_output_size_bytes = GEN7_MAX_GS_URB_ENTRY_SIZE_BYTES;
+   if (brw->gen == 6)
+      max_output_size_bytes = GEN6_MAX_GS_URB_ENTRY_SIZE_BYTES;
+   if (output_size_bytes > max_output_size_bytes)
+      return false;
+
+
+   /* URB entry sizes are stored as a multiple of 64 bytes in gen7+ and
+    * a multiple of 128 bytes in gen6.
+    */
+   if (brw->gen >= 7)
+      c.prog_data.base.urb_entry_size = ALIGN(output_size_bytes, 64) / 64;
+   else
+      c.prog_data.base.urb_entry_size = ALIGN(output_size_bytes, 128) / 128;
+
+   /* FIXME: Need to pull this from nir shader. */
+   c.prog_data.output_topology = _3DPRIM_TRISTRIP;
+
+   /* The GLSL linker will have already matched up GS inputs and the outputs
+    * of prior stages.  The driver does extend VS outputs in some cases, but
+    * only for legacy OpenGL or Gen4-5 hardware, neither of which offer
+    * geometry shader support.  So we can safely ignore that.
+    *
+    * For SSO pipelines, we use a fixed VUE map layout based on variable
+    * locations, so we can rely on rendezvous-by-location making this work.
+    *
+    * However, we need to ignore VARYING_SLOT_PRIMITIVE_ID, as it's not
+    * written by previous stages and shows up via payload magic.
+    */
+   GLbitfield64 inputs_read =
+      gp->program.Base.InputsRead & ~VARYING_BIT_PRIMITIVE_ID;
+   brw_compute_vue_map(brw->intelScreen->devinfo,
+                       &c.input_vue_map, inputs_read,
+                       prog->SeparateShader);
 
-   brw_compile_gs_prog(brw, prog, gp, key, &output);
+   /* GS inputs are read from the VUE 256 bits (2 vec4's) at a time, so we
+    * need to program a URB read length of ceiling(num_slots / 2).
+    */
+   c.prog_data.base.urb_read_length = (c.input_vue_map.num_slots + 1) / 2;
+
+   void *mem_ctx = ralloc_context(NULL);
+   unsigned program_size;
+   const unsigned *program =
+      brw_gs_emit(brw, prog, &c, mem_ctx, -1, &program_size);
+   if (program == NULL) {
+      ralloc_free(mem_ctx);
+      return false;
+   }
 
-   pipeline->gs_vec4 = upload_kernel(pipeline, output.program, output.program_size);
+   pipeline->gs_vec4 = upload_kernel(pipeline, program, program_size);
    pipeline->gs_vertex_count = gp->program.VerticesIn;
 
-   ralloc_free(output.mem_ctx);
+   ralloc_free(mem_ctx);
 
    return true;
 }
@@ -605,7 +874,6 @@ brw_codegen_cs_prog(struct brw_context *brw,
                     struct brw_compute_program *cp,
                     struct brw_cs_prog_key *key, struct anv_pipeline *pipeline)
 {
-   struct gl_context *ctx = &brw->ctx;
    const GLuint *program;
    void *mem_ctx = ralloc_context(NULL);
    GLuint program_size;
@@ -618,22 +886,11 @@ brw_codegen_cs_prog(struct brw_context *brw,
 
    set_binding_table_layout(&prog_data->base, pipeline, VK_SHADER_STAGE_COMPUTE);
 
-   /* Allocate the references to the uniforms that will end up in the
-    * prog_data associated with the compiled program, and which will be freed
-    * by the state cache.
-    */
-   int param_count = cs->num_uniform_components;
-
-   /* The backend also sometimes adds params for texture size. */
-   param_count += 2 * ctx->Const.Program[MESA_SHADER_COMPUTE].MaxTextureImageUnits;
-   prog_data->base.param =
-      rzalloc_array(NULL, const gl_constant_value *, param_count);
-   prog_data->base.pull_param =
-      rzalloc_array(NULL, const gl_constant_value *, param_count);
-   prog_data->base.nr_params = param_count;
+   create_params_array(pipeline, cs, &prog_data->base);
+   anv_nir_apply_dynamic_offsets(pipeline, cs->Program->nir, &prog_data->base);
 
    program = brw_cs_emit(brw, mem_ctx, key, prog_data,
-                         &cp->program, prog, &program_size);
+                         &cp->program, prog, -1, &program_size);
    if (program == NULL) {
       ralloc_free(mem_ctx);
       return false;
@@ -659,21 +916,6 @@ brw_cs_populate_key(struct brw_context *brw,
    key->program_string_id = bcp->id;
 }
 
-static void
-fail_on_compile_error(int status, const char *msg)
-{
-   int source, line, column;
-   char error[256];
-
-   if (status)
-      return;
-
-   if (sscanf(msg, "%d:%d(%d): error: %255[^\n]", &source, &line, &column, error) == 4)
-      fail_if(!status, "%d:%s\n", line, error);
-   else
-      fail_if(!status, "%s\n", msg);
-}
-
 struct anv_compiler {
    struct anv_device *device;
    struct intel_screen *screen;
@@ -704,8 +946,6 @@ anv_compiler_create(struct anv_device *device)
 
    compiler->device = device;
 
-   compiler->brw->optionCache.info = NULL;
-   compiler->brw->bufmgr = NULL;
    compiler->brw->gen = devinfo->gen;
    compiler->brw->is_g4x = devinfo->is_g4x;
    compiler->brw->is_baytrail = devinfo->is_baytrail;
@@ -730,26 +970,16 @@ anv_compiler_create(struct anv_device *device)
    compiler->brw->intelScreen = compiler->screen;
    compiler->screen->devinfo = &device->info;
 
-   brw_process_intel_debug_variable(compiler->screen);
+   brw_process_intel_debug_variable();
 
    compiler->screen->compiler = brw_compiler_create(compiler, &device->info);
 
    ctx = &compiler->brw->ctx;
    _mesa_init_shader_object_functions(&ctx->Driver);
 
-   _mesa_init_constants(&ctx->Const, API_OPENGL_CORE);
-
-   brw_initialize_context_constants(compiler->brw);
-
-   intelInitExtensions(ctx);
-
-   /* Set dd::NewShader */
-   brwInitFragProgFuncs(&ctx->Driver);
-
+   /* brw_select_clip_planes() needs this for bogus reasons. */
    ctx->_Shader = &compiler->pipeline;
 
-   compiler->brw->precompile = false;
-
    return compiler;
 
  fail:
@@ -911,58 +1141,33 @@ struct spirv_header{
    uint32_t gen_magic;
 };
 
-static const char *
-src_as_glsl(const char *data)
-{
-   const struct spirv_header *as_spirv = (const struct spirv_header *)data;
-
-   /* Check alignment */
-   if ((intptr_t)data & 0x3) {
-      return data;
-   }
-
-   if (as_spirv->magic == SPIR_V_MAGIC_NUMBER) {
-      /* LunarG back-door */
-      if (as_spirv->version == 0)
-         return data + 12;
-      else
-         return NULL;
-   } else {
-      return data;
-   }
-}
-
-static void
-anv_compile_shader_glsl(struct anv_compiler *compiler,
-                   struct gl_shader_program *program,
-                   struct anv_pipeline *pipeline, uint32_t stage)
-{
-   struct brw_context *brw = compiler->brw;
-   struct gl_shader *shader;
-   int name = 0;
-
-   shader = brw_new_shader(&brw->ctx, name, stage_info[stage].token);
-   fail_if(shader == NULL, "failed to create %s shader\n", stage_info[stage].name);
-
-   shader->Source = strdup(src_as_glsl(pipeline->shaders[stage]->module->data));
-   _mesa_glsl_compile_shader(&brw->ctx, shader, false, false);
-   fail_on_compile_error(shader->CompileStatus, shader->InfoLog);
-
-   program->Shaders[program->NumShaders] = shader;
-   program->NumShaders++;
-}
-
 static void
-setup_nir_io(struct gl_program *prog,
+setup_nir_io(struct gl_shader *mesa_shader,
              nir_shader *shader)
 {
+   struct gl_program *prog = mesa_shader->Program;
    foreach_list_typed(nir_variable, var, node, &shader->inputs) {
       prog->InputsRead |= BITFIELD64_BIT(var->data.location);
+      if (shader->stage == MESA_SHADER_FRAGMENT) {
+         struct gl_fragment_program *fprog = (struct gl_fragment_program *)prog;
+
+         fprog->InterpQualifier[var->data.location] =
+            (glsl_interp_qualifier)var->data.interpolation;
+         if (var->data.centroid)
+            fprog->IsCentroid |= BITFIELD64_BIT(var->data.location);
+         if (var->data.sample)
+            fprog->IsSample |= BITFIELD64_BIT(var->data.location);
+      }
    }
 
    foreach_list_typed(nir_variable, var, node, &shader->outputs) {
       prog->OutputsWritten |= BITFIELD64_BIT(var->data.location);
    }
+
+   shader->info.inputs_read = prog->InputsRead;
+   shader->info.outputs_written = prog->OutputsWritten;
+
+   mesa_shader->num_uniform_components = shader->num_uniforms;
 }
 
 static void
@@ -979,20 +1184,32 @@ anv_compile_shader_spirv(struct anv_compiler *compiler,
    fail_if(mesa_shader == NULL,
            "failed to create %s shader\n", stage_info[stage].name);
 
+#define CREATE_PROGRAM(stage) \
+   _mesa_init_##stage##_program(&brw->ctx, &ralloc(mesa_shader, struct brw_##stage##_program)->program, 0, 0)
+
+   bool is_scalar;
+   struct gl_program *prog;
    switch (stage) {
    case VK_SHADER_STAGE_VERTEX:
-      mesa_shader->Program = &rzalloc(mesa_shader, struct brw_vertex_program)->program.Base;
+      prog = CREATE_PROGRAM(vertex);
+      is_scalar = compiler->screen->compiler->scalar_vs;
       break;
    case VK_SHADER_STAGE_GEOMETRY:
-      mesa_shader->Program = &rzalloc(mesa_shader, struct brw_geometry_program)->program.Base;
+      prog = CREATE_PROGRAM(geometry);
+      is_scalar = false;
       break;
    case VK_SHADER_STAGE_FRAGMENT:
-      mesa_shader->Program = &rzalloc(mesa_shader, struct brw_fragment_program)->program.Base;
+      prog = CREATE_PROGRAM(fragment);
+      is_scalar = true;
       break;
    case VK_SHADER_STAGE_COMPUTE:
-      mesa_shader->Program = &rzalloc(mesa_shader, struct brw_compute_program)->program.Base;
+      prog = CREATE_PROGRAM(compute);
+      is_scalar = true;
       break;
+   default:
+      unreachable("Unsupported shader stage");
    }
+   _mesa_reference_program(&brw->ctx, &mesa_shader->Program, prog);
 
    mesa_shader->Program->Parameters =
       rzalloc(mesa_shader, struct gl_program_parameter_list);
@@ -1000,26 +1217,37 @@ anv_compile_shader_spirv(struct anv_compiler *compiler,
    mesa_shader->Type = stage_info[stage].token;
    mesa_shader->Stage = stage_info[stage].stage;
 
-   assert(shader->module->size % 4 == 0);
-
    struct gl_shader_compiler_options *glsl_options =
       &compiler->screen->compiler->glsl_compiler_options[stage_info[stage].stage];
 
-   mesa_shader->Program->nir =
-      spirv_to_nir((uint32_t *)shader->module->data, shader->module->size / 4,
-                   stage_info[stage].stage, glsl_options->NirOptions);
+   if (shader->module->nir) {
+      /* Some things such as our meta clear/blit code will give us a NIR
+       * shader directly.  In that case, we just ignore the SPIR-V entirely
+       * and just use the NIR shader */
+      mesa_shader->Program->nir = shader->module->nir;
+      mesa_shader->Program->nir->options = glsl_options->NirOptions;
+   } else {
+      uint32_t *spirv = (uint32_t *) shader->module->data;
+      assert(spirv[0] == SPIR_V_MAGIC_NUMBER);
+      assert(shader->module->size % 4 == 0);
+
+      mesa_shader->Program->nir =
+         spirv_to_nir(spirv, shader->module->size / 4,
+                      stage_info[stage].stage, glsl_options->NirOptions);
+   }
    nir_validate_shader(mesa_shader->Program->nir);
 
    brw_process_nir(mesa_shader->Program->nir,
                    compiler->screen->devinfo,
-                   NULL, mesa_shader->Stage, false);
+                   NULL, mesa_shader->Stage, is_scalar);
 
-   setup_nir_io(mesa_shader->Program, mesa_shader->Program->nir);
+   setup_nir_io(mesa_shader, mesa_shader->Program->nir);
 
    fail_if(mesa_shader->Program->nir == NULL,
            "failed to translate SPIR-V to NIR\n");
 
-   program->Shaders[program->NumShaders] = mesa_shader;
+   _mesa_reference_shader(&brw->ctx, &program->Shaders[program->NumShaders],
+                          mesa_shader);
    program->NumShaders++;
 }
 
@@ -1063,47 +1291,20 @@ anv_compiler_run(struct anv_compiler *compiler, struct anv_pipeline *pipeline)
    brw->use_rep_send = pipeline->use_repclear;
    brw->no_simd8 = pipeline->use_repclear;
 
-   program = brw->ctx.Driver.NewShaderProgram(name);
+   program = _mesa_new_shader_program(name);
    program->Shaders = (struct gl_shader **)
       calloc(VK_SHADER_STAGE_NUM, sizeof(struct gl_shader *));
    fail_if(program == NULL || program->Shaders == NULL,
            "failed to create program\n");
 
-   bool all_spirv = true;
    for (unsigned i = 0; i < VK_SHADER_STAGE_NUM; i++) {
-      if (pipeline->shaders[i] == NULL)
-         continue;
-
-      /* You need at least this much for "void main() { }" anyway */
-      assert(pipeline->shaders[i]->module->size >= 12);
-
-      if (src_as_glsl(pipeline->shaders[i]->module->data)) {
-         all_spirv = false;
-         break;
-      }
-
-      assert(pipeline->shaders[i]->module->size % 4 == 0);
+      if (pipeline->shaders[i])
+         anv_compile_shader_spirv(compiler, program, pipeline, i);
    }
 
-   if (all_spirv) {
-      for (unsigned i = 0; i < VK_SHADER_STAGE_NUM; i++) {
-         if (pipeline->shaders[i])
-            anv_compile_shader_spirv(compiler, program, pipeline, i);
-      }
-
-      for (unsigned i = 0; i < program->NumShaders; i++) {
-         struct gl_shader *shader = program->Shaders[i];
-         program->_LinkedShaders[shader->Stage] = shader;
-      }
-   } else {
-      for (unsigned i = 0; i < VK_SHADER_STAGE_NUM; i++) {
-         if (pipeline->shaders[i])
-            anv_compile_shader_glsl(compiler, program, pipeline, i);
-      }
-
-      _mesa_glsl_link_shader(&brw->ctx, program);
-      fail_on_compile_error(program->LinkStatus,
-                            program->InfoLog);
+   for (unsigned i = 0; i < program->NumShaders; i++) {
+      struct gl_shader *shader = program->Shaders[i];
+      program->_LinkedShaders[shader->Stage] = shader;
    }
 
    bool success;
@@ -1138,9 +1339,7 @@ anv_compiler_run(struct anv_compiler *compiler, struct anv_pipeline *pipeline)
          program->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program;
       struct brw_geometry_program *bgp = brw_geometry_program(gp);
 
-      brw_gs_populate_key(brw, pipeline, bgp, &gs_key);
-
-      success = really_do_gs_prog(brw, program, bgp, &gs_key, pipeline);
+      success = anv_codegen_gs_prog(brw, program, bgp, &gs_key, pipeline);
       fail_if(!success, "do_gs_prog failed\n");
       add_compiled_stage(pipeline, VK_SHADER_STAGE_GEOMETRY,
                          &pipeline->gs_prog_data.base.base);
@@ -1179,11 +1378,7 @@ anv_compiler_run(struct anv_compiler *compiler, struct anv_pipeline *pipeline)
                          &pipeline->cs_prog_data.base);
    }
 
-   /* XXX: Deleting the shader is broken with our current SPIR-V hacks.  We
-    * need to fix this ASAP.
-    */
-   if (!all_spirv)
-      brw->ctx.Driver.DeleteShaderProgram(&brw->ctx, program);
+   _mesa_delete_shader_program(&brw->ctx, program);
 
    struct anv_device *device = compiler->device;
    while (device->scratch_block_pool.bo.size < pipeline->total_scratch)
@@ -1203,8 +1398,10 @@ anv_compiler_free(struct anv_pipeline *pipeline)
    for (uint32_t stage = 0; stage < VK_SHADER_STAGE_NUM; stage++) {
       if (pipeline->prog_data[stage]) {
          free(pipeline->prog_data[stage]->map_entries);
-         ralloc_free(pipeline->prog_data[stage]->param);
-         ralloc_free(pipeline->prog_data[stage]->pull_param);
+         /* We only ever set up the params array because we don't do
+          * non-UBO pull constants
+          */
+         anv_device_free(pipeline->device, pipeline->prog_data[stage]->param);
       }
    }
 }