diff --git a/src/compiler/glsl/glsl_to_nir.cpp b/src/compiler/glsl/glsl_to_nir.cpp index 938bf30b2a9..5660a2a7821 100644 --- a/src/compiler/glsl/glsl_to_nir.cpp +++ b/src/compiler/glsl/glsl_to_nir.cpp @@ -672,6 +672,14 @@ nir_visitor::create_function(ir_function_signature *ir) } assert(np == func->num_params); + func->is_subroutine = ir->function()->is_subroutine; + func->num_subroutine_types = ir->function()->num_subroutine_types; + func->subroutine_index = ir->function()->subroutine_index; + func->subroutine_types = + ralloc_array(func, const struct glsl_type *, func->num_subroutine_types); + for (int i = 0; i < func->num_subroutine_types; i++) + func->subroutine_types[i] = ir->function()->subroutine_types[i]; + _mesa_hash_table_insert(this->overload_table, ir, func); } diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c index 579f9b5a125..ee594af44fa 100644 --- a/src/compiler/nir/nir.c +++ b/src/compiler/nir/nir.c @@ -502,6 +502,10 @@ nir_function_create(nir_shader *shader, const char *name) func->is_preamble = false; func->dont_inline = false; func->should_inline = false; + func->is_subroutine = false; + func->subroutine_index = 0; + func->num_subroutine_types = 0; + func->subroutine_types = NULL; /* Only meaningful for shader libraries, so don't export by default. */ func->is_exported = false; diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 02c40d79fa1..4ea6ee3d6cc 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -3525,6 +3525,23 @@ typedef struct nir_function { /* from SPIR-V function control */ bool should_inline; bool dont_inline; /* from SPIR-V */ + + /** + * Is this function a subroutine type declaration + * e.g. subroutine void type1(float arg1); + */ + bool is_subroutine; + + /** + * Is this function associated to a subroutine type + * e.g. subroutine (type1, type2) function_name { function_body }; + * would have num_subroutine_types 2, + * and pointers to the type1 and type2 types. + */ + int num_subroutine_types; + const struct glsl_type **subroutine_types; + + int subroutine_index; } nir_function; typedef enum { diff --git a/src/compiler/nir/nir_clone.c b/src/compiler/nir/nir_clone.c index 62ab9588dfe..c8e48e531df 100644 --- a/src/compiler/nir/nir_clone.c +++ b/src/compiler/nir/nir_clone.c @@ -667,6 +667,16 @@ nir_function_clone(nir_shader *ns, const nir_function *fxn) nfxn->is_preamble = fxn->is_preamble; nfxn->should_inline = fxn->should_inline; nfxn->dont_inline = fxn->dont_inline; + nfxn->is_subroutine = fxn->is_subroutine; + nfxn->num_subroutine_types = fxn->num_subroutine_types; + nfxn->subroutine_index = fxn->subroutine_index; + if (fxn->num_subroutine_types) { + nfxn->subroutine_types = ralloc_array(ns, const struct glsl_type *, + fxn->num_subroutine_types); + for (unsigned i = 0; i < fxn->num_subroutine_types; i++) { + nfxn->subroutine_types[i] = fxn->subroutine_types[i]; + } + } /* At first glance, it looks like we should clone the function_impl here. * However, call instructions need to be able to reference at least the diff --git a/src/compiler/nir/nir_serialize.c b/src/compiler/nir/nir_serialize.c index 709dc4b1b63..0f92961fa98 100644 --- a/src/compiler/nir/nir_serialize.c +++ b/src/compiler/nir/nir_serialize.c @@ -1897,10 +1897,18 @@ write_function(write_ctx *ctx, const nir_function *fxn) flags |= 0x10; if (fxn->dont_inline) flags |= 0x20; + if (fxn->is_subroutine) + flags |= 0x40; blob_write_uint32(ctx->blob, flags); if (fxn->name) blob_write_string(ctx->blob, fxn->name); + blob_write_uint32(ctx->blob, fxn->subroutine_index); + blob_write_uint32(ctx->blob, fxn->num_subroutine_types); + for (unsigned i = 0; i < fxn->num_subroutine_types; i++) { + encode_type_to_blob(ctx->blob, fxn->subroutine_types[i]); + } + write_add_object(ctx, fxn); blob_write_uint32(ctx->blob, fxn->num_params); @@ -1922,11 +1930,18 @@ static void read_function(read_ctx *ctx) { uint32_t flags = blob_read_uint32(ctx->blob); + bool has_name = flags & 0x4; char *name = has_name ? blob_read_string(ctx->blob) : NULL; nir_function *fxn = nir_function_create(ctx->nir, name); + fxn->subroutine_index = blob_read_uint32(ctx->blob); + fxn->num_subroutine_types = blob_read_uint32(ctx->blob); + for (unsigned i = 0; i < fxn->num_subroutine_types; i++) { + fxn->subroutine_types[i] = decode_type_from_blob(ctx->blob); + } + read_add_object(ctx, fxn); fxn->num_params = blob_read_uint32(ctx->blob); @@ -1943,6 +1958,7 @@ read_function(read_ctx *ctx) fxn->impl = NIR_SERIALIZE_FUNC_HAS_IMPL; fxn->should_inline = flags & 0x10; fxn->dont_inline = flags & 0x20; + fxn->is_subroutine = flags & 0x40; } static void