diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 09895b201..b25655a5c 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -3179,6 +3179,7 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co struct vkd3d_shader_immediate_constant_buffer *icb; const struct sm6_type *elem_type; unsigned int i, size, count; + uint64_t *data64; elem_type = type->u.array.elem_type; /* Multidimensional arrays are emitted in flattened form. */ @@ -3230,16 +3231,37 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co return VKD3D_OK; count = type->u.array.count; - if (size > sizeof(icb->data[0])) + switch (icb->data_type) { - uint64_t *data = (uint64_t *)icb->data; - for (i = 0; i < count; ++i) - data[i] = operands[i]; - } - else - { - for (i = 0; i < count; ++i) - icb->data[i] = operands[i]; + case VKD3D_DATA_HALF: + for (i = 0; i < count; ++i) + icb->data[i] = half_to_float(operands[i]); + icb->data_type = VKD3D_DATA_FLOAT; + break; + + case VKD3D_DATA_UINT16: + for (i = 0; i < count; ++i) + icb->data[i] = (int16_t)operands[i]; + icb->data_type = VKD3D_DATA_UINT; + break; + + case VKD3D_DATA_FLOAT: + case VKD3D_DATA_UINT: + for (i = 0; i < count; ++i) + icb->data[i] = operands[i]; + break; + + case VKD3D_DATA_DOUBLE: + case VKD3D_DATA_UINT64: + data64 = (uint64_t *)icb->data; + for (i = 0; i < count; ++i) + data64[i] = operands[i]; + break; + + default: + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Invalid array of type %u.", icb->data_type); + return VKD3D_ERROR_INVALID_SHADER; } return VKD3D_OK; diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 92a31a989..4a576868c 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -4527,70 +4527,6 @@ static uint32_t spirv_compiler_emit_bool_to_double(struct spirv_compiler *compil return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); } -/* Based on the implementation in the OpenGL Mathematics library. */ -static uint32_t half_to_float(uint16_t value) -{ - uint32_t s = (value & 0x8000u) << 16; - uint32_t e = (value >> 10) & 0x1fu; - uint32_t m = value & 0x3ffu; - - if (!e) - { - if (!m) - { - /* Plus or minus zero */ - return s; - } - else - { - /* Denormalized number -- renormalize it */ - - while (!(m & 0x400u)) - { - m <<= 1; - --e; - } - - ++e; - m &= ~0x400u; - } - } - else if (e == 31u) - { - /* Positive or negative infinity for zero 'm'. - * Nan for non-zero 'm' -- preserve sign and significand bits */ - return s | 0x7f800000u | (m << 13); - } - - /* Normalized number */ - e += 127u - 15u; - m <<= 13; - - /* Assemble s, e and m. */ - return s | (e << 23) | m; -} - -static uint32_t convert_raw_constant32(enum vkd3d_data_type data_type, unsigned int uint_value) -{ - int16_t i; - - /* TODO: native 16-bit support. */ - if (data_type != VKD3D_DATA_UINT16 && data_type != VKD3D_DATA_HALF) - return uint_value; - - if (data_type == VKD3D_DATA_HALF) - return half_to_float(uint_value); - - /* Values in DXIL have no signedness, so it is ambiguous whether 16-bit constants should or - * should not be sign-extended when 16-bit execution is not supported. The AMD RX 580 Windows - * driver has no 16-bit support, and sign-extends all 16-bit constant ints to 32 bits. These - * results differ from SM 5. The RX 6750 XT supports 16-bit execution, so constants are not - * extended, and results match SM 5. It seems best to replicate the sign-extension, and if - * execution is 16-bit, the values will be truncated. */ - i = uint_value; - return (int32_t)i; -} - static uint32_t spirv_compiler_emit_load_constant(struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg, uint32_t swizzle, uint32_t write_mask) { @@ -4754,13 +4690,6 @@ static uint32_t spirv_compiler_emit_constant_array(struct spirv_compiler *compil switch (icb->data_type) { - case VKD3D_DATA_HALF: - case VKD3D_DATA_UINT16: - /* Scalar only. */ - for (i = 0; i < element_count; ++i) - elements[i] = vkd3d_spirv_get_op_constant(builder, elem_type_id, - convert_raw_constant32(icb->data_type, icb->data[i])); - break; case VKD3D_DATA_FLOAT: case VKD3D_DATA_INT: case VKD3D_DATA_UINT: