nir/spirv: Take an entrypoint stage as well as a name
authorJason Ekstrand <jason.ekstrand@intel.com>
Mon, 11 Jan 2016 18:31:25 +0000 (10:31 -0800)
committerJason Ekstrand <jason.ekstrand@intel.com>
Mon, 11 Jan 2016 19:06:06 +0000 (11:06 -0800)
src/glsl/nir/spirv/nir_spirv.h
src/glsl/nir/spirv/spirv_to_nir.c
src/glsl/nir/spirv/vtn_private.h
src/glsl/nir/spirv2nir.c
src/vulkan/anv_pipeline.c

index 506bd98..354c0a9 100644 (file)
@@ -37,7 +37,7 @@ extern "C" {
 #endif
 
 nir_function *spirv_to_nir(const uint32_t *words, size_t word_count,
-                           const char *entry_point_name,
+                           gl_shader_stage stage, const char *entry_point_name,
                            const nir_shader_compiler_options *options);
 
 #ifdef __cplusplus
index 49b9a65..d72846f 100644 (file)
@@ -176,9 +176,15 @@ vtn_ssa_value(struct vtn_builder *b, uint32_t value_id)
 
 static char *
 vtn_string_literal(struct vtn_builder *b, const uint32_t *words,
-                   unsigned word_count)
+                   unsigned word_count, unsigned *words_used)
 {
-   return ralloc_strndup(b, (char *)words, word_count * sizeof(*words));
+   char *dup = ralloc_strndup(b, (char *)words, word_count * sizeof(*words));
+   if (words_used) {
+      /* Ammount of space taken by the string (including the null) */
+      unsigned len = strlen(dup) + 1;
+      *words_used = DIV_ROUND_UP(len, sizeof(*words));
+   }
+   return dup;
 }
 
 const uint32_t *
@@ -2988,6 +2994,27 @@ vertices_in_from_spv_execution_mode(SpvExecutionMode mode)
    }
 }
 
+static gl_shader_stage
+stage_for_execution_model(SpvExecutionModel model)
+{
+   switch (model) {
+   case SpvExecutionModelVertex:
+      return MESA_SHADER_VERTEX;
+   case SpvExecutionModelTessellationControl:
+      return MESA_SHADER_TESS_CTRL;
+   case SpvExecutionModelTessellationEvaluation:
+      return MESA_SHADER_TESS_EVAL;
+   case SpvExecutionModelGeometry:
+      return MESA_SHADER_GEOMETRY;
+   case SpvExecutionModelFragment:
+      return MESA_SHADER_FRAGMENT;
+   case SpvExecutionModelGLCompute:
+      return MESA_SHADER_COMPUTE;
+   default:
+      unreachable("Unsupported execution model");
+   }
+}
+
 static bool
 vtn_handle_preamble_instruction(struct vtn_builder *b, SpvOp opcode,
                                 const uint32_t *w, unsigned count)
@@ -3019,25 +3046,28 @@ vtn_handle_preamble_instruction(struct vtn_builder *b, SpvOp opcode,
       assert(w[2] == SpvMemoryModelGLSL450);
       break;
 
-   case SpvOpEntryPoint:
+   case SpvOpEntryPoint: {
+      struct vtn_value *entry_point = &b->values[w[2]];
       /* Let this be a name label regardless */
-      b->values[w[2]].name = vtn_string_literal(b, &w[3], count - 3);
+      unsigned name_words;
+      entry_point->name = vtn_string_literal(b, &w[3], count - 3, &name_words);
 
-      if (strcmp(b->values[w[2]].name, b->entry_point_name) != 0)
+      if (strcmp(entry_point->name, b->entry_point_name) != 0 ||
+          stage_for_execution_model(w[1]) != b->entry_point_stage)
          break;
 
       assert(b->entry_point == NULL);
-      b->entry_point = &b->values[w[2]];
-      b->execution_model = w[1];
+      b->entry_point = entry_point;
       break;
+   }
 
    case SpvOpString:
       vtn_push_value(b, w[1], vtn_value_type_string)->str =
-         vtn_string_literal(b, &w[2], count - 2);
+         vtn_string_literal(b, &w[2], count - 2, NULL);
       break;
 
    case SpvOpName:
-      b->values[w[1]].name = vtn_string_literal(b, &w[2], count - 2);
+      b->values[w[1]].name = vtn_string_literal(b, &w[2], count - 2, NULL);
       break;
 
    case SpvOpMemberName:
@@ -3453,30 +3483,9 @@ vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode,
    return true;
 }
 
-static gl_shader_stage
-stage_for_execution_model(SpvExecutionModel model)
-{
-   switch (model) {
-   case SpvExecutionModelVertex:
-      return MESA_SHADER_VERTEX;
-   case SpvExecutionModelTessellationControl:
-      return MESA_SHADER_TESS_CTRL;
-   case SpvExecutionModelTessellationEvaluation:
-      return MESA_SHADER_TESS_EVAL;
-   case SpvExecutionModelGeometry:
-      return MESA_SHADER_GEOMETRY;
-   case SpvExecutionModelFragment:
-      return MESA_SHADER_FRAGMENT;
-   case SpvExecutionModelGLCompute:
-      return MESA_SHADER_COMPUTE;
-   default:
-      unreachable("Unsupported execution model");
-   }
-}
-
 nir_function *
 spirv_to_nir(const uint32_t *words, size_t word_count,
-             const char *entry_point_name,
+             gl_shader_stage stage, const char *entry_point_name,
              const nir_shader_compiler_options *options)
 {
    const uint32_t *word_end = words + word_count;
@@ -3497,6 +3506,7 @@ spirv_to_nir(const uint32_t *words, size_t word_count,
    b->value_id_bound = value_id_bound;
    b->values = rzalloc_array(b, struct vtn_value, value_id_bound);
    exec_list_make_empty(&b->functions);
+   b->entry_point_stage = stage;
    b->entry_point_name = entry_point_name;
 
    /* Handle all the preamble instructions */
@@ -3509,7 +3519,6 @@ spirv_to_nir(const uint32_t *words, size_t word_count,
       return NULL;
    }
 
-   gl_shader_stage stage = stage_for_execution_model(b->execution_model);
    b->shader = nir_shader_create(NULL, stage, options);
 
    /* Parse execution modes */
index 14355c9..7ab3c9f 100644 (file)
@@ -321,9 +321,9 @@ struct vtn_builder {
    unsigned value_id_bound;
    struct vtn_value *values;
 
+   gl_shader_stage entry_point_stage;
    const char *entry_point_name;
    struct vtn_value *entry_point;
-   SpvExecutionModel execution_model;
    bool origin_upper_left;
 
    struct vtn_function *func;
index db56d09..4cb484c 100644 (file)
@@ -49,6 +49,7 @@ int main(int argc, char **argv)
    const void *map = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
    assert(map != NULL);
 
-   nir_function *func = spirv_to_nir(map, word_count, "main", NULL);
+   nir_function *func = spirv_to_nir(map, word_count, MESA_SHADER_FRAGMENT,
+                                     "main", NULL);
    nir_print_shader(func->shader, stderr);
 }
index 769afe8..53c7d1f 100644 (file)
@@ -113,8 +113,8 @@ anv_shader_compile_to_nir(struct anv_device *device,
       assert(spirv[0] == SPIR_V_MAGIC_NUMBER);
       assert(module->size % 4 == 0);
 
-      entry_point = spirv_to_nir(spirv, module->size / 4, entrypoint_name,
-                                 nir_options);
+      entry_point = spirv_to_nir(spirv, module->size / 4, stage,
+                                 entrypoint_name, nir_options);
       nir = entry_point->shader;
       assert(nir->stage == stage);
       nir_validate_shader(nir);