From abb6d0797c8a0c32f45d38d7a41e96b2db47a47d Mon Sep 17 00:00:00 2001 From: Eduardo Lima Mitev Date: Fri, 13 Oct 2017 10:31:50 +0200 Subject: [PATCH] mesa/glspirv: Add a _mesa_spirv_to_nir() function This is basically a wrapper around spirv_to_nir() that includes arguments setup and post-conversion validation. v2: * Rebase update (SpirVCapabilities not a pointer anymore, spirv_to_nir_options added, and others). * Code-style improvements and remove debug hunk. (Timothy Arceri) Reviewed-by: Timothy Arceri --- src/mesa/main/glspirv.c | 58 +++++++++++++++++++++++++++++++++++++++++ src/mesa/main/glspirv.h | 7 +++++ 2 files changed, 65 insertions(+) diff --git a/src/mesa/main/glspirv.c b/src/mesa/main/glspirv.c index 7aa06f8e8c0..71dc9154ef2 100644 --- a/src/mesa/main/glspirv.c +++ b/src/mesa/main/glspirv.c @@ -174,6 +174,64 @@ _mesa_spirv_link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) } } +nir_shader * +_mesa_spirv_to_nir(struct gl_context *ctx, + const struct gl_shader_program *prog, + gl_shader_stage stage, + const nir_shader_compiler_options *options) +{ + nir_shader *nir = NULL; + + struct gl_linked_shader *linked_shader = prog->_LinkedShaders[stage]; + assert (linked_shader); + + struct gl_shader_spirv_data *spirv_data = linked_shader->spirv_data; + assert(spirv_data); + + struct gl_spirv_module *spirv_module = spirv_data->SpirVModule; + assert (spirv_module != NULL); + + const char *entry_point_name = spirv_data->SpirVEntryPoint; + assert(entry_point_name); + + struct nir_spirv_specialization *spec_entries = + calloc(sizeof(*spec_entries), + spirv_data->NumSpecializationConstants); + + for (unsigned i = 0; i < spirv_data->NumSpecializationConstants; ++i) { + spec_entries[i].id = spirv_data->SpecializationConstantsIndex[i]; + spec_entries[i].data32 = spirv_data->SpecializationConstantsValue[i]; + spec_entries[i].defined_on_module = false; + } + + const struct spirv_to_nir_options spirv_options = { + .caps = ctx->Const.SpirVCapabilities + }; + + nir_function *entry_point = + spirv_to_nir((const uint32_t *) &spirv_module->Binary[0], + spirv_module->Length / 4, + spec_entries, spirv_data->NumSpecializationConstants, + stage, entry_point_name, + &spirv_options, + options); + free(spec_entries); + + assert (entry_point); + nir = entry_point->shader; + assert(nir->info.stage == stage); + + nir->options = options; + + nir->info.name = + ralloc_asprintf(nir, "SPIRV:%s:%d", + _mesa_shader_stage_to_abbrev(nir->info.stage), + prog->Name); + nir_validate_shader(nir); + + return nir; +} + void GLAPIENTRY _mesa_SpecializeShaderARB(GLuint shader, const GLchar *pEntryPoint, diff --git a/src/mesa/main/glspirv.h b/src/mesa/main/glspirv.h index 0f03b75c111..81626ce75b5 100644 --- a/src/mesa/main/glspirv.h +++ b/src/mesa/main/glspirv.h @@ -24,6 +24,7 @@ #ifndef GLSPIRV_H #define GLSPIRV_H +#include "compiler/nir/nir.h" #include "mtypes.h" #ifdef __cplusplus @@ -80,6 +81,12 @@ void _mesa_spirv_link_shaders(struct gl_context *ctx, struct gl_shader_program *prog); +nir_shader * +_mesa_spirv_to_nir(struct gl_context *ctx, + const struct gl_shader_program *prog, + gl_shader_stage stage, + const nir_shader_compiler_options *options); + /** * \name API functions */ -- 2.30.2