iris: Use wrappers for create_xs_state rather than a switch statement
[mesa.git] / src / gallium / drivers / iris / iris_program.c
index e2dcc73dab904f7fce2e13f49af4782d8be586aa..9fc98a971abf4d941a0a7e26f7e000fef7b64956 100644 (file)
@@ -145,9 +145,39 @@ iris_lower_storage_image_derefs(nir_shader *nir)
    }
 }
 
+// XXX: need unify_interfaces() at link time...
 
+static void
+update_so_info(struct pipe_stream_output_info *so_info)
+{
+   for (unsigned i = 0; i < so_info->num_outputs; i++) {
+      struct pipe_stream_output *output = &so_info->output[i];
+
+      /* The VUE header contains three scalar fields packed together:
+       * - gl_PointSize is stored in VARYING_SLOT_PSIZ.w
+       * - gl_Layer is stored in VARYING_SLOT_PSIZ.y
+       * - gl_ViewportIndex is stored in VARYING_SLOT_PSIZ.z
+       */
+      switch (output->register_index) {
+      case VARYING_SLOT_LAYER:
+         assert(output->num_components == 1);
+         output->register_index = VARYING_SLOT_PSIZ;
+         output->start_component = 1;
+         break;
+      case VARYING_SLOT_VIEWPORT:
+         assert(output->num_components == 1);
+         output->register_index = VARYING_SLOT_PSIZ;
+         output->start_component = 2;
+         break;
+      case VARYING_SLOT_PSIZ:
+         assert(output->num_components == 1);
+         output->start_component = 3;
+         break;
+      }
 
-// XXX: need unify_interfaces() at link time...
+      //info->outputs_written |= 1ull << output->register_index;
+   }
+}
 
 /**
  * The pipe->create_[stage]_state() driver hooks.
@@ -162,7 +192,6 @@ iris_create_uncompiled_shader(struct pipe_context *ctx,
                               nir_shader *nir,
                               const struct pipe_stream_output_info *so_info)
 {
-   //struct iris_context *ice = (struct iris_context *)ctx;
    struct iris_screen *screen = (struct iris_screen *)ctx->screen;
    const struct gen_device_info *devinfo = &screen->devinfo;
 
@@ -178,56 +207,15 @@ iris_create_uncompiled_shader(struct pipe_context *ctx,
 
    ish->program_id = get_new_program_id(screen);
    ish->nir = nir;
-   if (so_info)
+   if (so_info) {
       memcpy(&ish->stream_output, so_info, sizeof(*so_info));
-
-   switch (nir->info.stage) {
-   case MESA_SHADER_VERTEX:
-      /* User clip planes */
-      if (nir->info.clip_distance_array_size == 0)
-         ish->nos |= IRIS_NOS_RASTERIZER;
-      // XXX: NOS
-      break;
-   case MESA_SHADER_TESS_CTRL:
-      // XXX: NOS
-      break;
-   case MESA_SHADER_TESS_EVAL:
-      // XXX: NOS
-      break;
-   case MESA_SHADER_GEOMETRY:
-      // XXX: NOS
-      break;
-   case MESA_SHADER_FRAGMENT:
-      ish->nos |= IRIS_NOS_FRAMEBUFFER |
-                  IRIS_NOS_DEPTH_STENCIL_ALPHA |
-                  IRIS_NOS_RASTERIZER |
-                  IRIS_NOS_BLEND;
-
-      /* The program key needs the VUE map if there are > 16 inputs */
-      if (util_bitcount64(ish->nir->info.inputs_read &
-                          BRW_FS_VARYING_INPUT_MASK) > 16) {
-         ish->nos |= IRIS_NOS_LAST_VUE_MAP;
-      }
-      break;
-   case MESA_SHADER_COMPUTE:
-      // XXX: NOS
-      break;
-   default:
-      break;
+      update_so_info(&ish->stream_output);
    }
 
-   // XXX: precompile!
-   // XXX: disallow more than 64KB of shared variables
-
    return ish;
 }
 
-/**
- * The pipe->delete_[stage]_state() driver hooks.
- *
- * Frees the iris_uncompiled_shader.
- */
-static void *
+static struct iris_uncompiled_shader *
 iris_create_shader_state(struct pipe_context *ctx,
                          const struct pipe_shader_state *state)
 {
@@ -237,15 +225,91 @@ iris_create_shader_state(struct pipe_context *ctx,
                                         &state->stream_output);
 }
 
+static void *
+iris_create_vs_state(struct pipe_context *ctx,
+                     const struct pipe_shader_state *state)
+{
+   struct iris_uncompiled_shader *ish = iris_create_shader_state(ctx, state);
+
+   /* User clip planes */
+   if (ish->nir->info.clip_distance_array_size == 0)
+      ish->nos |= IRIS_NOS_RASTERIZER;
+
+   return ish;
+}
+
+static void *
+iris_create_tcs_state(struct pipe_context *ctx,
+                      const struct pipe_shader_state *state)
+{
+   struct iris_uncompiled_shader *ish = iris_create_shader_state(ctx, state);
+
+   // XXX: NOS?
+
+   return ish;
+}
+
+static void *
+iris_create_tes_state(struct pipe_context *ctx,
+                     const struct pipe_shader_state *state)
+{
+   struct iris_uncompiled_shader *ish = iris_create_shader_state(ctx, state);
+
+   // XXX: NOS?
+
+   return ish;
+}
+
+static void *
+iris_create_gs_state(struct pipe_context *ctx,
+                     const struct pipe_shader_state *state)
+{
+   struct iris_uncompiled_shader *ish = iris_create_shader_state(ctx, state);
+
+   // XXX: NOS?
+
+   return ish;
+}
+
+static void *
+iris_create_fs_state(struct pipe_context *ctx,
+                     const struct pipe_shader_state *state)
+{
+   struct iris_uncompiled_shader *ish = iris_create_shader_state(ctx, state);
+
+   ish->nos |= IRIS_NOS_FRAMEBUFFER |
+               IRIS_NOS_DEPTH_STENCIL_ALPHA |
+               IRIS_NOS_RASTERIZER |
+               IRIS_NOS_BLEND;
+
+   /* The program key needs the VUE map if there are > 16 inputs */
+   if (util_bitcount64(ish->nir->info.inputs_read &
+                       BRW_FS_VARYING_INPUT_MASK) > 16) {
+      ish->nos |= IRIS_NOS_LAST_VUE_MAP;
+   }
+
+   return ish;
+}
+
 static void *
 iris_create_compute_state(struct pipe_context *ctx,
                           const struct pipe_compute_state *state)
 {
    assert(state->ir_type == PIPE_SHADER_IR_NIR);
 
-   return iris_create_uncompiled_shader(ctx, (void *) state->prog, NULL);
+   // XXX: disallow more than 64KB of shared variables
+
+   struct iris_uncompiled_shader *ish =
+      iris_create_uncompiled_shader(ctx, (void *) state->prog, NULL);
+
+   return ish;
 }
 
+/**
+ * The pipe->delete_[stage]_state() driver hooks.
+ *
+ * Frees the iris_uncompiled_shader.
+ */
 static void
 iris_delete_shader_state(struct pipe_context *ctx, void *state)
 {
@@ -343,7 +407,8 @@ static uint32_t
 assign_common_binding_table_offsets(const struct gen_device_info *devinfo,
                                     const struct nir_shader *nir,
                                     struct brw_stage_prog_data *prog_data,
-                                    uint32_t next_binding_table_offset)
+                                    uint32_t next_binding_table_offset,
+                                    unsigned num_system_values)
 {
    const struct shader_info *info = &nir->info;
 
@@ -363,7 +428,8 @@ assign_common_binding_table_offsets(const struct gen_device_info *devinfo,
       prog_data->binding_table.image_start = 0xd0d0d0d0;
    }
 
-   int num_ubos = info->num_ubos + (nir->num_uniforms > 0 ? 1 : 0);
+   int num_ubos = info->num_ubos +
+                  ((nir->num_uniforms || num_system_values) ? 1 : 0);
 
    if (num_ubos) {
       //assert(info->num_ubos <= BRW_MAX_UBO);
@@ -415,6 +481,13 @@ iris_setup_uniforms(const struct brw_compiler *compiler,
                     enum brw_param_builtin **out_system_values,
                     unsigned *out_num_system_values)
 {
+   /* We don't use params[], but fs_visitor::nir_setup_uniforms() asserts
+    * about it for compute shaders, so go ahead and make some fake ones
+    * which the backend will dead code eliminate.
+    */
+   prog_data->nr_params = nir->num_uniforms;
+   prog_data->param = rzalloc_array(mem_ctx, uint32_t, prog_data->nr_params);
+
    /* The intel compiler assumes that num_uniforms is in bytes. For
     * scalar that means 4 bytes per uniform slot.
     *
@@ -422,9 +495,6 @@ iris_setup_uniforms(const struct brw_compiler *compiler,
     */
    nir->num_uniforms *= 4;
 
-   prog_data->nr_params = 0;
-   prog_data->param = rzalloc_array(mem_ctx, uint32_t, 1);
-
    const unsigned IRIS_MAX_SYSTEM_VALUES = 32;
    enum brw_param_builtin *system_values =
       rzalloc_array(mem_ctx, enum brw_param_builtin, IRIS_MAX_SYSTEM_VALUES);
@@ -559,14 +629,17 @@ iris_compile_vs(struct iris_context *ice,
       nir_lower_io_to_temporaries(nir, impl, true, false);
       nir_lower_global_vars_to_local(nir);
       nir_lower_vars_to_ssa(nir);
+      nir_shader_gather_info(nir, impl);
    }
 
    // XXX: alt mode
-   assign_common_binding_table_offsets(devinfo, nir, prog_data, 0);
 
    iris_setup_uniforms(compiler, mem_ctx, nir, prog_data, &system_values,
                        &num_system_values);
 
+   assign_common_binding_table_offsets(devinfo, nir, prog_data, 0,
+                                       num_system_values);
+
    brw_compute_vue_map(devinfo,
                        &vue_prog_data->vue_map, nir->info.outputs_written,
                        nir->info.separate_shader);
@@ -638,11 +711,13 @@ unsigned
 iris_get_shader_num_ubos(const struct iris_context *ice, gl_shader_stage stage)
 {
    const struct iris_uncompiled_shader *ish = ice->shaders.uncompiled[stage];
+   const struct iris_compiled_shader *shader = ice->shaders.prog[stage];
 
    if (ish) {
       const nir_shader *nir = ish->nir;
       /* see assign_common_binding_table_offsets */
-      return nir->info.num_ubos + (nir->num_uniforms > 0 ? 1 : 0);
+      return nir->info.num_ubos +
+             ((nir->num_uniforms || shader->num_system_values) ? 1 : 0);
    }
    return 0;
 }
@@ -673,8 +748,8 @@ get_unified_tess_slots(const struct iris_context *ice,
    *per_patch_slots = tes->patch_inputs_read;
 
    if (tcs) {
-      *per_vertex_slots |= tcs->inputs_read;
-      *per_patch_slots |= tcs->patch_inputs_read;
+      *per_vertex_slots |= tcs->outputs_written;
+      *per_patch_slots |= tcs->patch_outputs_written;
    }
 }
 
@@ -704,9 +779,10 @@ iris_compile_tcs(struct iris_context *ice,
    if (ish) {
       nir = nir_shader_clone(mem_ctx, ish->nir);
 
-      assign_common_binding_table_offsets(devinfo, nir, prog_data, 0);
       iris_setup_uniforms(compiler, mem_ctx, nir, prog_data, &system_values,
                           &num_system_values);
+      assign_common_binding_table_offsets(devinfo, nir, prog_data, 0,
+                                          num_system_values);
    } else {
       nir = brw_nir_create_passthrough_tcs(mem_ctx, compiler, options, key);
 
@@ -782,11 +858,12 @@ iris_compile_tes(struct iris_context *ice,
 
    nir_shader *nir = nir_shader_clone(mem_ctx, ish->nir);
 
-   assign_common_binding_table_offsets(devinfo, nir, prog_data, 0);
-
    iris_setup_uniforms(compiler, mem_ctx, nir, prog_data, &system_values,
                        &num_system_values);
 
+   assign_common_binding_table_offsets(devinfo, nir, prog_data, 0,
+                                       num_system_values);
+
    struct brw_vue_map input_vue_map;
    brw_compute_tess_vue_map(&input_vue_map, key->inputs_read,
                             key->patch_inputs_read);
@@ -854,11 +931,12 @@ iris_compile_gs(struct iris_context *ice,
 
    nir_shader *nir = nir_shader_clone(mem_ctx, ish->nir);
 
-   assign_common_binding_table_offsets(devinfo, nir, prog_data, 0);
-
    iris_setup_uniforms(compiler, mem_ctx, nir, prog_data, &system_values,
                        &num_system_values);
 
+   assign_common_binding_table_offsets(devinfo, nir, prog_data, 0,
+                                       num_system_values);
+
    brw_compute_vue_map(devinfo,
                        &vue_prog_data->vue_map, nir->info.outputs_written,
                        nir->info.separate_shader);
@@ -931,12 +1009,13 @@ iris_compile_fs(struct iris_context *ice,
    nir_shader *nir = nir_shader_clone(mem_ctx, ish->nir);
 
    // XXX: alt mode
-   assign_common_binding_table_offsets(devinfo, nir, prog_data,
-                                       MAX2(key->nr_color_regions, 1));
 
    iris_setup_uniforms(compiler, mem_ctx, nir, prog_data, &system_values,
                        &num_system_values);
 
+   assign_common_binding_table_offsets(devinfo, nir, prog_data,
+                                       MAX2(key->nr_color_regions, 1),
+                                       num_system_values);
    char *error_str = NULL;
    const unsigned *program =
       brw_compile_fs(compiler, &ice->dbg, mem_ctx, key, fs_prog_data,
@@ -1122,11 +1201,15 @@ iris_compile_cs(struct iris_context *ice,
    nir_shader *nir = nir_shader_clone(mem_ctx, ish->nir);
 
    cs_prog_data->binding_table.work_groups_start = 0;
-   assign_common_binding_table_offsets(devinfo, nir, prog_data, 1);
+
+   prog_data->total_shared = nir->info.cs.shared_size;
 
    iris_setup_uniforms(compiler, mem_ctx, nir, prog_data, &system_values,
                        &num_system_values);
 
+   assign_common_binding_table_offsets(devinfo, nir, prog_data, 1,
+                                       num_system_values);
+
    char *error_str = NULL;
    const unsigned *program =
       brw_compile_cs(compiler, &ice->dbg, mem_ctx, key, cs_prog_data,
@@ -1225,11 +1308,11 @@ iris_get_scratch_space(struct iris_context *ice,
 void
 iris_init_program_functions(struct pipe_context *ctx)
 {
-   ctx->create_vs_state  = iris_create_shader_state;
-   ctx->create_tcs_state = iris_create_shader_state;
-   ctx->create_tes_state = iris_create_shader_state;
-   ctx->create_gs_state  = iris_create_shader_state;
-   ctx->create_fs_state  = iris_create_shader_state;
+   ctx->create_vs_state  = iris_create_vs_state;
+   ctx->create_tcs_state = iris_create_tcs_state;
+   ctx->create_tes_state = iris_create_tes_state;
+   ctx->create_gs_state  = iris_create_gs_state;
+   ctx->create_fs_state  = iris_create_fs_state;
    ctx->create_compute_state = iris_create_compute_state;
 
    ctx->delete_vs_state  = iris_delete_shader_state;