spirv/libclc: Add generic versions of arithmetic functions

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15622>
This commit is contained in:
Jason Ekstrand 2022-03-28 17:08:17 -05:00 committed by Marge Bot
parent 688d478045
commit 4a08ee7ecf
1 changed files with 59 additions and 0 deletions

View File

@ -239,6 +239,63 @@ nir_can_find_libclc(unsigned ptr_bit_size)
}
}
/** Adds generic pointer variants of libclc functions
*
* Libclc currently doesn't contain generic variants for a bunch of functions
* like `frexp` but the OpenCL spec with generic pointers requires them. We
* really should fix libclc but, in the mean time, we can easily duplicate
* every function that works on global memory and make it also work on generic
* memory.
*/
static void
libclc_add_generic_variants(nir_shader *shader)
{
nir_foreach_function(func, shader) {
/* These don't need generic variants */
if (strstr(func->name, "async_work_group_strided_copy"))
continue;
char *U3AS1 = strstr(func->name, "U3AS1");
if (U3AS1 == NULL)
continue;
ptrdiff_t offset_1 = U3AS1 - func->name + 4;
assert(offset_1 < strlen(func->name) && func->name[offset_1] == '1');
char *generic_name = ralloc_strdup(shader, func->name);
assert(generic_name[offset_1] == '1');
generic_name[offset_1] = '4';
nir_function *gfunc = nir_function_create(shader, generic_name);
gfunc->num_params = func->num_params;
gfunc->params = ralloc_array(shader, nir_parameter, gfunc->num_params);
for (unsigned i = 0; i < gfunc->num_params; i++)
gfunc->params[i] = func->params[i];
gfunc->impl = nir_function_impl_clone(shader, func->impl);
gfunc->impl->function = gfunc;
/* Rewrite any global pointers to generic */
nir_foreach_block(block, gfunc->impl) {
nir_foreach_instr(instr, block) {
if (instr->type != nir_instr_type_deref)
continue;
nir_deref_instr *deref = nir_instr_as_deref(instr);
if (!nir_deref_mode_may_be(deref, nir_var_mem_global))
continue;
assert(deref->type != nir_deref_type_var);
assert(nir_deref_mode_is(deref, nir_var_mem_global));
deref->modes = nir_var_mem_generic;
}
}
nir_metadata_preserve(gfunc->impl, nir_metadata_none);
}
}
nir_shader *
nir_load_libclc_shader(unsigned ptr_bit_size,
struct disk_cache *disk_cache,
@ -293,6 +350,8 @@ nir_load_libclc_shader(unsigned ptr_bit_size,
NIR_PASS_V(nir, nir_lower_variable_initializers, nir_var_function_temp);
NIR_PASS_V(nir, nir_lower_returns);
NIR_PASS_V(nir, libclc_add_generic_variants);
/* TODO: One day, we may want to run some optimizations on the libclc
* shader once and cache them to save time in each shader call.
*/