mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-21 20:10:14 +01:00
glsl: add support for converting global instructions to NIR
NIR doesn't really support global instructions such as global val initilisation. So here we add functionality to glsl_to_nir() to put these instructions into a temporary function that will be later inlined into main. We give the function a name starting with gl_mesa_tmp_ as functions starting with gl_ are reserved and will not have any clashes with user functions, we finish the name with the blake3 of the shader source to avoid conflicts with multiple shaders attached to a single stage. Acked-by: Marek Olšák <marek.olsak@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31137>
This commit is contained in:
parent
1fc9d5223e
commit
7c5b21c032
9 changed files with 51 additions and 12 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 };
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue