spirv: Implement the function portion of the Linkage capability
Acked-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15486>
This commit is contained in:

committed by
Marge Bot

parent
80a076382d
commit
4b2c78c08a
@@ -72,6 +72,7 @@ struct spirv_supported_capabilities {
|
||||
bool kernel;
|
||||
bool kernel_image;
|
||||
bool kernel_image_read_write;
|
||||
bool linkage;
|
||||
bool literal_sampler;
|
||||
bool mesh_shading_nv;
|
||||
bool min_lod;
|
||||
|
@@ -433,7 +433,7 @@ vtn_get_sampled_image(struct vtn_builder *b, uint32_t value_id)
|
||||
return si;
|
||||
}
|
||||
|
||||
static const char *
|
||||
const char *
|
||||
vtn_string_literal(struct vtn_builder *b, const uint32_t *words,
|
||||
unsigned word_count, unsigned *words_used)
|
||||
{
|
||||
@@ -681,6 +681,7 @@ vtn_handle_decoration(struct vtn_builder *b, SpvOp opcode,
|
||||
unreachable("Invalid decoration opcode");
|
||||
}
|
||||
dec->decoration = *(w++);
|
||||
dec->num_operands = w_end - w;
|
||||
dec->operands = w;
|
||||
|
||||
/* Link into the list */
|
||||
@@ -4482,6 +4483,8 @@ vtn_handle_preamble_instruction(struct vtn_builder *b, SpvOp opcode,
|
||||
if (!b->options->create_library)
|
||||
vtn_warn("Unsupported SPIR-V capability: %s",
|
||||
spirv_capability_to_string(cap));
|
||||
spv_check_supported(linkage, cap);
|
||||
vtn_warn("The SPIR-V Linkage capability is not fully supported");
|
||||
break;
|
||||
|
||||
case SpvCapabilitySparseResidency:
|
||||
|
@@ -148,6 +148,29 @@ vtn_handle_function_call(struct vtn_builder *b, SpvOp opcode,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
function_decoration_cb(struct vtn_builder *b, struct vtn_value *val, int member,
|
||||
const struct vtn_decoration *dec, void *void_func)
|
||||
{
|
||||
struct vtn_function *func = void_func;
|
||||
|
||||
switch (dec->decoration) {
|
||||
case SpvDecorationLinkageAttributes: {
|
||||
unsigned name_words;
|
||||
const char *name =
|
||||
vtn_string_literal(b, dec->operands, dec->num_operands, &name_words);
|
||||
vtn_fail_if(name_words >= dec->num_operands,
|
||||
"Malformed LinkageAttributes decoration");
|
||||
(void)name; /* TODO: What is this? */
|
||||
func->linkage = dec->operands[name_words];
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
vtn_cfg_handle_prepass_instruction(struct vtn_builder *b, SpvOp opcode,
|
||||
const uint32_t *w, unsigned count)
|
||||
@@ -160,12 +183,15 @@ vtn_cfg_handle_prepass_instruction(struct vtn_builder *b, SpvOp opcode,
|
||||
b->func->node.type = vtn_cf_node_type_function;
|
||||
b->func->node.parent = NULL;
|
||||
list_inithead(&b->func->body);
|
||||
b->func->linkage = SpvLinkageTypeMax;
|
||||
b->func->control = w[3];
|
||||
|
||||
UNUSED const struct glsl_type *result_type = vtn_get_type(b, w[1])->type;
|
||||
struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_function);
|
||||
val->func = b->func;
|
||||
|
||||
vtn_foreach_decoration(b, val, function_decoration_cb, b->func);
|
||||
|
||||
b->func->type = vtn_get_type(b, w[4]);
|
||||
const struct vtn_type *func_type = b->func->type;
|
||||
|
||||
@@ -221,10 +247,19 @@ vtn_cfg_handle_prepass_instruction(struct vtn_builder *b, SpvOp opcode,
|
||||
case SpvOpFunctionEnd:
|
||||
b->func->end = w;
|
||||
if (b->func->start_block == NULL) {
|
||||
vtn_fail_if(b->func->linkage != SpvLinkageTypeImport,
|
||||
"A function declaration (an OpFunction with no basic "
|
||||
"blocks), must have a Linkage Attributes Decoration "
|
||||
"with the Import Linkage Type.");
|
||||
|
||||
/* In this case, the function didn't have any actual blocks. It's
|
||||
* just a prototype so delete the function_impl.
|
||||
*/
|
||||
b->func->nir_func->impl = NULL;
|
||||
} else {
|
||||
vtn_fail_if(b->func->linkage == SpvLinkageTypeImport,
|
||||
"A function definition (an OpFunction with basic blocks) "
|
||||
"cannot be decorated with the Import Linkage Type.");
|
||||
}
|
||||
b->func = NULL;
|
||||
break;
|
||||
|
@@ -812,8 +812,7 @@ handle_printf(struct vtn_builder *b, uint32_t opcode,
|
||||
glsl_struct_type(fields, num_srcs - 1, "printf", true);
|
||||
|
||||
/* Step 3, create a variable of that type and populate its fields */
|
||||
nir_variable *var = nir_local_variable_create(b->func->nir_func->impl,
|
||||
struct_type, NULL);
|
||||
nir_variable *var = nir_local_variable_create(b->nb.impl, struct_type, NULL);
|
||||
nir_deref_instr *deref_var = nir_build_deref_var(&b->nb, var);
|
||||
size_t fmt_pos = 0;
|
||||
for (unsigned i = 1; i < num_srcs; ++i) {
|
||||
|
@@ -274,6 +274,7 @@ struct vtn_function {
|
||||
|
||||
const uint32_t *end;
|
||||
|
||||
SpvLinkageType linkage;
|
||||
SpvFunctionControlMask control;
|
||||
};
|
||||
|
||||
@@ -646,6 +647,7 @@ struct vtn_decoration {
|
||||
*/
|
||||
int scope;
|
||||
|
||||
uint32_t num_operands;
|
||||
const uint32_t *operands;
|
||||
struct vtn_value *group;
|
||||
|
||||
@@ -743,6 +745,10 @@ struct vtn_builder {
|
||||
unsigned mem_model;
|
||||
};
|
||||
|
||||
const char *
|
||||
vtn_string_literal(struct vtn_builder *b, const uint32_t *words,
|
||||
unsigned word_count, unsigned *words_used);
|
||||
|
||||
nir_ssa_def *
|
||||
vtn_pointer_to_ssa(struct vtn_builder *b, struct vtn_pointer *ptr);
|
||||
struct vtn_pointer *
|
||||
|
Reference in New Issue
Block a user