diff --git a/src/compiler/glsl/glsl_to_nir.cpp b/src/compiler/glsl/glsl_to_nir.cpp index 0b5b65f16f9..f1d6ee85105 100644 --- a/src/compiler/glsl/glsl_to_nir.cpp +++ b/src/compiler/glsl/glsl_to_nir.cpp @@ -55,7 +55,8 @@ namespace { class nir_visitor : public ir_visitor { public: - nir_visitor(const struct gl_constants *consts, nir_shader *shader); + nir_visitor(const struct gl_constants *consts, nir_shader *shader, + const uint8_t *src_blake3); nir_visitor(const nir_visitor &) = delete; ~nir_visitor(); nir_visitor & operator=(const nir_visitor &) = delete; @@ -100,6 +101,7 @@ private: nir_shader *shader; nir_function_impl *impl; + nir_function_impl *global_impl; nir_builder b; nir_def *result; /* result of the expression tree last visited */ @@ -153,13 +155,14 @@ private: nir_shader * glsl_to_nir(const struct gl_constants *consts, struct exec_list **ir, shader_info *si, gl_shader_stage stage, - const nir_shader_compiler_options *options) + const nir_shader_compiler_options *options, + const uint8_t *src_blake3) { MESA_TRACE_FUNC(); nir_shader *shader = nir_shader_create(NULL, stage, options, si); - nir_visitor v1(consts, shader); + nir_visitor v1(consts, shader, src_blake3); nir_function_visitor v2(&v1); v2.run(*ir); visit_exec_list(*ir, &v1); @@ -177,7 +180,8 @@ glsl_to_nir(const struct gl_constants *consts, return shader; } -nir_visitor::nir_visitor(const struct gl_constants *consts, nir_shader *shader) +nir_visitor::nir_visitor(const struct gl_constants *consts, nir_shader *shader, + const uint8_t *src_blake3) { this->consts = consts; this->supports_std430 = consts->UseSTD430AsDefaultPacking; @@ -190,7 +194,26 @@ nir_visitor::nir_visitor(const struct gl_constants *consts, nir_shader *shader) this->impl = NULL; this->deref = NULL; this->sig = NULL; + this->global_impl = NULL; memset(&this->b, 0, sizeof(this->b)); + + if (src_blake3) { + char blake_as_str[BLAKE3_OUT_LEN * 2 + 1];; + _mesa_blake3_format(blake_as_str, src_blake3); + + /* Create unique function name of function to temporarily hold global + * instructions. + */ + char gloabl_func_name[45]; + snprintf(gloabl_func_name, 45, "%s_%s", "gl_mesa_tmp", blake_as_str); + + nir_function *func = nir_function_create(shader, gloabl_func_name); + func->is_tmp_globals_wrapper = true; + this->global_impl = nir_function_impl_create(func); + + this->impl = this->global_impl; + b = nir_builder_at(nir_after_impl(this->impl)); + } } nir_visitor::~nir_visitor() @@ -690,9 +713,11 @@ nir_visitor::visit(ir_function_signature *ir) visit_exec_list(&ir->body, this); + this->impl = global_impl; + if (this->impl) + b = nir_builder_at(nir_after_impl(this->impl)); + this->is_global = true; - } else { - func->impl = NULL; } } @@ -2783,7 +2808,7 @@ glsl_float64_funcs_to_nir(struct gl_context *ctx, nir_shader *nir = nir_shader_create(NULL, MESA_SHADER_VERTEX, options, NULL); - nir_visitor v1(&ctx->Const, nir); + nir_visitor v1(&ctx->Const, nir, NULL); nir_function_visitor v2(&v1); v2.run(sh->ir); visit_exec_list(sh->ir, &v1); diff --git a/src/compiler/glsl/glsl_to_nir.h b/src/compiler/glsl/glsl_to_nir.h index 50f2ae79082..08165f3abb8 100644 --- a/src/compiler/glsl/glsl_to_nir.h +++ b/src/compiler/glsl/glsl_to_nir.h @@ -41,7 +41,8 @@ struct gl_shader_program; nir_shader *glsl_to_nir(const struct gl_constants *consts, struct exec_list **ir, shader_info *si, gl_shader_stage stage, - const nir_shader_compiler_options *options); + const nir_shader_compiler_options *options, + const uint8_t *src_blake3); nir_shader *glsl_float64_funcs_to_nir(struct gl_context *ctx, const nir_shader_compiler_options *options); diff --git a/src/compiler/glsl/tests/test_gl_lower_mediump.cpp b/src/compiler/glsl/tests/test_gl_lower_mediump.cpp index 5ad2387ac53..1ec2056404f 100644 --- a/src/compiler/glsl/tests/test_gl_lower_mediump.cpp +++ b/src/compiler/glsl/tests/test_gl_lower_mediump.cpp @@ -214,11 +214,13 @@ namespace struct gl_linked_shader *sh = whole_program->_LinkedShaders[MESA_SHADER_VERTEX]; sh->Program->nir = glsl_to_nir(&ctx->Const, &sh->ir, &sh->Program->info, - MESA_SHADER_VERTEX, &compiler_options); + MESA_SHADER_VERTEX, &compiler_options, + NULL); sh = whole_program->_LinkedShaders[MESA_SHADER_FRAGMENT]; sh->Program->nir = glsl_to_nir(&ctx->Const, &sh->ir, &sh->Program->info, - MESA_SHADER_FRAGMENT, &compiler_options); + MESA_SHADER_FRAGMENT, &compiler_options, + NULL); nir = sh->Program->nir; gl_nir_link_glsl(ctx, whole_program); diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c index 96309cf9a4b..a65c9b1ebab 100644 --- a/src/compiler/nir/nir.c +++ b/src/compiler/nir/nir.c @@ -503,6 +503,7 @@ nir_function_create(nir_shader *shader, const char *name) func->dont_inline = false; func->should_inline = false; func->is_subroutine = false; + func->is_tmp_globals_wrapper = false; func->subroutine_index = 0; func->num_subroutine_types = 0; func->subroutine_types = NULL; diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 2ef2b7dce26..9306104f22e 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -3646,6 +3646,11 @@ typedef struct nir_function { */ bool is_subroutine; + /* Temporary function created to wrap global instructions before they can + * be inlined into the main function. + */ + bool is_tmp_globals_wrapper; + /** * Is this function associated to a subroutine type * e.g. subroutine (type1, type2) function_name { function_body }; diff --git a/src/compiler/nir/nir_clone.c b/src/compiler/nir/nir_clone.c index c41318fab56..b684fe9e5a2 100644 --- a/src/compiler/nir/nir_clone.c +++ b/src/compiler/nir/nir_clone.c @@ -696,6 +696,7 @@ nir_function_clone(nir_shader *ns, const nir_function *fxn) nfxn->should_inline = fxn->should_inline; nfxn->dont_inline = fxn->dont_inline; nfxn->is_subroutine = fxn->is_subroutine; + nfxn->is_tmp_globals_wrapper = fxn->is_tmp_globals_wrapper; nfxn->num_subroutine_types = fxn->num_subroutine_types; nfxn->subroutine_index = fxn->subroutine_index; if (fxn->num_subroutine_types) { diff --git a/src/compiler/nir/nir_serialize.c b/src/compiler/nir/nir_serialize.c index 943c51944c0..2bb6a9ad7ac 100644 --- a/src/compiler/nir/nir_serialize.c +++ b/src/compiler/nir/nir_serialize.c @@ -1963,6 +1963,8 @@ write_function(write_ctx *ctx, const nir_function *fxn) flags |= 0x20; if (fxn->is_subroutine) flags |= 0x40; + if (fxn->is_tmp_globals_wrapper) + flags |= 0x80; blob_write_uint32(ctx->blob, flags); if (fxn->name) blob_write_string(ctx->blob, fxn->name); @@ -2023,6 +2025,7 @@ read_function(read_ctx *ctx) fxn->should_inline = flags & 0x10; fxn->dont_inline = flags & 0x20; fxn->is_subroutine = flags & 0x40; + fxn->is_tmp_globals_wrapper = flags & 0x80; } static void diff --git a/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c b/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c index ca2abd8960e..93fb1db713f 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_cmdline.c @@ -106,7 +106,7 @@ load_glsl(unsigned num_files, char *const *files, gl_shader_stage stage) nir_shader *nir = glsl_to_nir(&local_ctx.Const, &prog->_LinkedShaders[stage]->ir, &prog->_LinkedShaders[stage]->Program->info, - stage, nir_options); + stage, nir_options, NULL); if (nir->info.stage == MESA_SHADER_FRAGMENT) { nir->info.fs.pixel_center_integer = diff --git a/src/mesa/state_tracker/st_glsl_to_nir.cpp b/src/mesa/state_tracker/st_glsl_to_nir.cpp index 19944a2be48..91d602b5ac4 100644 --- a/src/mesa/state_tracker/st_glsl_to_nir.cpp +++ b/src/mesa/state_tracker/st_glsl_to_nir.cpp @@ -544,7 +544,8 @@ st_link_glsl_to_nir(struct gl_context *ctx, } prog->nir = glsl_to_nir(&st->ctx->Const, &shader->ir, - &shader->Program->info, shader->Stage, options); + &shader->Program->info, shader->Stage, + options, NULL); prog->nir->info.name = ralloc_asprintf(shader, "GLSL%d", shader_program->Name);