mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-23 06:50:11 +01:00
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:
parent
688d478045
commit
4a08ee7ecf
1 changed files with 59 additions and 0 deletions
|
|
@ -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_shader *
|
||||||
nir_load_libclc_shader(unsigned ptr_bit_size,
|
nir_load_libclc_shader(unsigned ptr_bit_size,
|
||||||
struct disk_cache *disk_cache,
|
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_variable_initializers, nir_var_function_temp);
|
||||||
NIR_PASS_V(nir, nir_lower_returns);
|
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
|
/* 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.
|
* shader once and cache them to save time in each shader call.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue