diff options
Diffstat (limited to 'src/compiler/spirv')
-rw-r--r-- | src/compiler/spirv/nir_spirv.h | 5 | ||||
-rw-r--r-- | src/compiler/spirv/spirv_to_nir.c | 42 | ||||
-rw-r--r-- | src/compiler/spirv/vtn_private.h | 6 |
3 files changed, 47 insertions, 6 deletions
diff --git a/src/compiler/spirv/nir_spirv.h b/src/compiler/spirv/nir_spirv.h index e0112ef4ad4..116b0a374cd 100644 --- a/src/compiler/spirv/nir_spirv.h +++ b/src/compiler/spirv/nir_spirv.h @@ -38,7 +38,10 @@ extern "C" { struct nir_spirv_specialization { uint32_t id; - uint32_t data; + union { + uint32_t data32; + uint64_t data64; + }; }; struct nir_spirv_supported_extensions { diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c index f203ebc7ef7..b67189e07a6 100644 --- a/src/compiler/spirv/spirv_to_nir.c +++ b/src/compiler/spirv/spirv_to_nir.c @@ -31,6 +31,14 @@ #include "nir/nir_constant_expressions.h" #include "spirv_info.h" +struct spec_constant_value { + bool is_double; + union { + uint32_t data32; + uint64_t data64; + }; +}; + void _vtn_warn(const char *file, int line, const char *msg, ...) { @@ -942,11 +950,14 @@ spec_constant_decoration_cb(struct vtn_builder *b, struct vtn_value *v, if (dec->decoration != SpvDecorationSpecId) return; - uint32_t *const_value = data; + struct spec_constant_value *const_value = data; for (unsigned i = 0; i < b->num_specializations; i++) { if (b->specializations[i].id == dec->literals[0]) { - *const_value = b->specializations[i].data; + if (const_value->is_double) + const_value->data64 = b->specializations[i].data64; + else + const_value->data32 = b->specializations[i].data32; return; } } @@ -956,8 +967,22 @@ static uint32_t get_specialization(struct vtn_builder *b, struct vtn_value *val, uint32_t const_value) { - vtn_foreach_decoration(b, val, spec_constant_decoration_cb, &const_value); - return const_value; + struct spec_constant_value data; + data.is_double = false; + data.data32 = const_value; + vtn_foreach_decoration(b, val, spec_constant_decoration_cb, &data); + return data.data32; +} + +static uint64_t +get_specialization64(struct vtn_builder *b, struct vtn_value *val, + uint64_t const_value) +{ + struct spec_constant_value data; + data.is_double = true; + data.data64 = const_value; + vtn_foreach_decoration(b, val, spec_constant_decoration_cb, &data); + return data.data64; } static void @@ -1017,10 +1042,17 @@ vtn_handle_constant(struct vtn_builder *b, SpvOp opcode, } break; } - case SpvOpSpecConstant: + case SpvOpSpecConstant: { assert(glsl_type_is_scalar(val->const_type)); val->constant->values[0].u32[0] = get_specialization(b, val, w[3]); + int bit_size = glsl_get_bit_size(val->const_type); + if (bit_size == 64) + val->constant->values[0].u64[0] = + get_specialization64(b, val, vtn_u64_literal(&w[3])); + else + val->constant->values[0].u32[0] = get_specialization(b, val, w[3]); break; + } case SpvOpSpecConstantComposite: case SpvOpConstantComposite: { unsigned elem_count = count - 3; diff --git a/src/compiler/spirv/vtn_private.h b/src/compiler/spirv/vtn_private.h index ffa00d7f68a..7471ca1e21a 100644 --- a/src/compiler/spirv/vtn_private.h +++ b/src/compiler/spirv/vtn_private.h @@ -489,3 +489,9 @@ void vtn_handle_alu(struct vtn_builder *b, SpvOp opcode, bool vtn_handle_glsl450_instruction(struct vtn_builder *b, uint32_t ext_opcode, const uint32_t *words, unsigned count); + +static inline uint64_t +vtn_u64_literal(const uint32_t *w) +{ + return (uint64_t)w[1] << 32 | w[0]; +} |