vtn/opencl: Hook up OpenCL async copy and group wait opcodes via libclc
Adds an additional hook for spirv_to_nir to handle a core opcode via the OpenCL libclc infrastructure, and adds handling for SpvOpGroupAsyncCopy and SpvOpGroupWaitEvents. Reviewed-by: Dave Airlie <airlied@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6035>
This commit is contained in:
@@ -5500,6 +5500,11 @@ vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode,
|
|||||||
case SpvOpLifetimeStop:
|
case SpvOpLifetimeStop:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SpvOpGroupAsyncCopy:
|
||||||
|
case SpvOpGroupWaitEvents:
|
||||||
|
vtn_handle_opencl_core_instruction(b, opcode, w, count);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
vtn_fail_with_opcode("Unhandled opcode", opcode);
|
vtn_fail_with_opcode("Unhandled opcode", opcode);
|
||||||
}
|
}
|
||||||
|
@@ -582,6 +582,49 @@ handle_special(struct vtn_builder *b, uint32_t opcode,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static nir_ssa_def *
|
||||||
|
handle_core(struct vtn_builder *b, uint32_t opcode,
|
||||||
|
unsigned num_srcs, nir_ssa_def **srcs, struct vtn_type **src_types,
|
||||||
|
const struct vtn_type *dest_type)
|
||||||
|
{
|
||||||
|
nir_deref_instr *ret_deref = NULL;
|
||||||
|
|
||||||
|
switch ((SpvOp)opcode) {
|
||||||
|
case SpvOpGroupAsyncCopy: {
|
||||||
|
/* Libclc doesn't include 3-component overloads of the async copy functions.
|
||||||
|
* However, the CLC spec says:
|
||||||
|
* async_work_group_copy and async_work_group_strided_copy for 3-component vector types
|
||||||
|
* behave as async_work_group_copy and async_work_group_strided_copy respectively for 4-component
|
||||||
|
* vector types
|
||||||
|
*/
|
||||||
|
for (unsigned i = 0; i < num_srcs; ++i) {
|
||||||
|
if (src_types[i]->base_type == vtn_base_type_pointer &&
|
||||||
|
src_types[i]->deref->base_type == vtn_base_type_vector &&
|
||||||
|
src_types[i]->deref->length == 3) {
|
||||||
|
src_types[i] =
|
||||||
|
get_pointer_type(b,
|
||||||
|
get_vtn_type_for_glsl_type(b, glsl_replace_vector_type(src_types[i]->deref->type, 4)),
|
||||||
|
src_types[i]->storage_class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!call_mangled_function(b, "async_work_group_strided_copy", (1 << 1), num_srcs, src_types, dest_type, srcs, &ret_deref))
|
||||||
|
return NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SpvOpGroupWaitEvents: {
|
||||||
|
src_types[0] = get_vtn_type_for_glsl_type(b, glsl_int_type());
|
||||||
|
if (!call_mangled_function(b, "wait_group_events", 0, num_srcs, src_types, dest_type, srcs, &ret_deref))
|
||||||
|
return NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret_deref ? nir_load_deref(&b->nb, ret_deref) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_handle_v_load_store(struct vtn_builder *b, enum OpenCLstd_Entrypoints opcode,
|
_handle_v_load_store(struct vtn_builder *b, enum OpenCLstd_Entrypoints opcode,
|
||||||
const uint32_t *w, unsigned count, bool load)
|
const uint32_t *w, unsigned count, bool load)
|
||||||
@@ -888,3 +931,20 @@ vtn_handle_opencl_instruction(struct vtn_builder *b, SpvOp ext_opcode,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
vtn_handle_opencl_core_instruction(struct vtn_builder *b, SpvOp opcode,
|
||||||
|
const uint32_t *w, unsigned count)
|
||||||
|
{
|
||||||
|
switch (opcode) {
|
||||||
|
case SpvOpGroupAsyncCopy:
|
||||||
|
handle_instr(b, opcode, w + 4, count - 4, w + 1, handle_core);
|
||||||
|
return true;
|
||||||
|
case SpvOpGroupWaitEvents:
|
||||||
|
handle_instr(b, opcode, w + 2, count - 2, NULL, handle_core);
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@@ -889,6 +889,8 @@ bool vtn_handle_glsl450_instruction(struct vtn_builder *b, SpvOp ext_opcode,
|
|||||||
|
|
||||||
bool vtn_handle_opencl_instruction(struct vtn_builder *b, SpvOp ext_opcode,
|
bool vtn_handle_opencl_instruction(struct vtn_builder *b, SpvOp ext_opcode,
|
||||||
const uint32_t *words, unsigned count);
|
const uint32_t *words, unsigned count);
|
||||||
|
bool vtn_handle_opencl_core_instruction(struct vtn_builder *b, SpvOp opcode,
|
||||||
|
const uint32_t *w, unsigned count);
|
||||||
|
|
||||||
struct vtn_builder* vtn_create_builder(const uint32_t *words, size_t word_count,
|
struct vtn_builder* vtn_create_builder(const uint32_t *words, size_t word_count,
|
||||||
gl_shader_stage stage, const char *entry_point_name,
|
gl_shader_stage stage, const char *entry_point_name,
|
||||||
|
Reference in New Issue
Block a user