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:
Jason Ekstrand
2020-10-23 14:22:23 -05:00
committed by Marge Bot
parent 80a076382d
commit 4b2c78c08a
5 changed files with 47 additions and 3 deletions

View File

@@ -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;

View File

@@ -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:

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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 *