mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-06 05:08:08 +02:00
spirv: Add support for OpBitcast in OpSpecConstantOp
This is required for OpenCL but not Vulkan. This fixes a bunch of OpenCL CTS fails using the SPIR-V back-end in LLVM as opposed to SPIRV-LLVM-Translator. Reviewed-by: Karol Herbst <kherbst@redhat.com> Cc: mesa-stable Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37555>
This commit is contained in:
parent
7df6431bf7
commit
8ef811b02a
1 changed files with 48 additions and 0 deletions
|
|
@ -2652,6 +2652,54 @@ vtn_handle_constant(struct vtn_builder *b, SpvOp opcode,
|
|||
vtn_foreach_decoration(b, val, spec_constant_decoration_cb, &u32op);
|
||||
SpvOp opcode = u32op.u32;
|
||||
switch (opcode) {
|
||||
case SpvOpBitcast: {
|
||||
struct vtn_value *src = &b->values[w[4]];
|
||||
|
||||
vtn_assert(src->value_type == vtn_value_type_constant ||
|
||||
src->value_type == vtn_value_type_undef);
|
||||
|
||||
unsigned src_len = glsl_get_vector_elements(src->type->type);
|
||||
unsigned dst_len = glsl_get_vector_elements(val->type->type);
|
||||
|
||||
unsigned src_bit_size = glsl_get_bit_size(src->type->type);
|
||||
unsigned dst_bit_size = glsl_get_bit_size(val->type->type);
|
||||
|
||||
vtn_assert(src_len * src_bit_size == dst_len * dst_bit_size);
|
||||
|
||||
/* This will end up being zero */
|
||||
if (src->value_type == vtn_value_type_undef)
|
||||
break;
|
||||
|
||||
if (src_bit_size == dst_bit_size) {
|
||||
/* This is just a copy */
|
||||
for (unsigned i = 0; i < src_len; i++)
|
||||
val->constant->values[i] = src->constant->values[i];
|
||||
} else {
|
||||
/* You can't non-trivially bitcast booleans */
|
||||
vtn_assert(src_bit_size >= 8 && dst_bit_size >= 8);
|
||||
const unsigned src_byte_size = src_bit_size / 8;
|
||||
const unsigned dst_byte_size = dst_bit_size / 8;
|
||||
|
||||
vtn_assert(src_len <= NIR_MAX_VEC_COMPONENTS &&
|
||||
dst_len <= NIR_MAX_VEC_COMPONENTS);
|
||||
|
||||
uint8_t bits[NIR_MAX_VEC_COMPONENTS * sizeof(nir_const_value)];
|
||||
|
||||
for (unsigned i = 0; i < src_len; i++) {
|
||||
uint64_t v = nir_const_value_as_int(src->constant->values[i],
|
||||
src_bit_size);
|
||||
memcpy(bits + i * src_byte_size, &v, src_byte_size);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < dst_len; i++) {
|
||||
uint64_t v = 0;
|
||||
memcpy(&v, bits + i * dst_byte_size, dst_byte_size);
|
||||
val->constant->values[i] =
|
||||
nir_const_value_for_uint(v, dst_bit_size);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SpvOpVectorShuffle: {
|
||||
struct vtn_value *v0 = &b->values[w[4]];
|
||||
struct vtn_value *v1 = &b->values[w[5]];
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue