nir/spirv: Get the shader stage from the SPIR-V

Previously, we depended on it being passed in.
This commit is contained in:
Jason Ekstrand
2015-12-30 17:00:16 -08:00
parent db3a64fcea
commit e993e45eb1
5 changed files with 31 additions and 14 deletions

View File

@@ -37,7 +37,6 @@ extern "C" {
#endif
nir_shader *spirv_to_nir(const uint32_t *words, size_t word_count,
gl_shader_stage stage,
const nir_shader_compiler_options *options);
#ifdef __cplusplus

View File

@@ -3207,10 +3207,7 @@ vtn_handle_preamble_instruction(struct vtn_builder *b, SpvOp opcode,
switch ((SpvCapability)w[1]) {
case SpvCapabilityMatrix:
case SpvCapabilityShader:
/* All shaders support these */
break;
case SpvCapabilityGeometry:
assert(b->shader->stage == MESA_SHADER_GEOMETRY);
break;
default:
assert(!"Unsupported capability");
@@ -3647,9 +3644,29 @@ 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_shader *
spirv_to_nir(const uint32_t *words, size_t word_count,
gl_shader_stage stage,
const nir_shader_compiler_options *options)
{
const uint32_t *word_end = words + word_count;
@@ -3665,11 +3682,8 @@ spirv_to_nir(const uint32_t *words, size_t word_count,
words+= 5;
nir_shader *shader = nir_shader_create(NULL, stage, options);
/* Initialize the stn_builder object */
struct vtn_builder *b = rzalloc(NULL, struct vtn_builder);
b->shader = shader;
b->value_id_bound = value_id_bound;
b->values = rzalloc_array(b, struct vtn_value, value_id_bound);
exec_list_make_empty(&b->functions);
@@ -3678,6 +3692,10 @@ spirv_to_nir(const uint32_t *words, size_t word_count,
words = vtn_foreach_instruction(b, words, word_end,
vtn_handle_preamble_instruction);
gl_shader_stage stage = stage_for_execution_model(b->execution_model);
nir_shader *shader = nir_shader_create(NULL, stage, options);
b->shader = shader;
/* Parse execution modes */
vtn_foreach_execution_mode(b, b->entry_point,
vtn_handle_execution_mode, NULL);
@@ -3699,12 +3717,12 @@ spirv_to_nir(const uint32_t *words, size_t word_count,
vtn_handle_phi_second_pass);
}
ralloc_free(b);
/* Because we can still have output reads in NIR, we need to lower
* outputs to temporaries before we are truely finished.
*/
nir_lower_outputs_to_temporaries(shader);
ralloc_free(b);
return shader;
}

View File

@@ -317,9 +317,9 @@ struct vtn_builder {
unsigned value_id_bound;
struct vtn_value *values;
struct vtn_value *entry_point;
SpvExecutionModel execution_model;
bool origin_upper_left;
struct vtn_value *entry_point;
struct vtn_function *func;
struct exec_list functions;

View File

@@ -49,7 +49,6 @@ int main(int argc, char **argv)
const void *map = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
assert(map != NULL);
nir_shader *shader = spirv_to_nir(map, MESA_SHADER_FRAGMENT,
word_count, NULL);
nir_shader *shader = spirv_to_nir(map, word_count, NULL);
nir_print_shader(shader, stderr);
}

View File

@@ -108,7 +108,8 @@ anv_shader_compile_to_nir(struct anv_device *device,
assert(spirv[0] == SPIR_V_MAGIC_NUMBER);
assert(module->size % 4 == 0);
nir = spirv_to_nir(spirv, module->size / 4, stage, nir_options);
nir = spirv_to_nir(spirv, module->size / 4, nir_options);
assert(nir->stage == stage);
nir_validate_shader(nir);
nir_lower_returns(nir);