mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-09-12 18:50:22 -07:00
vkd3d-shader/dxil: Emit 16-bit arrays as minimum precision types.
The type is not explicitly annotated as minimum precision, because no backend currently cares about that bit anyway. We're still relying on the fact that in SM 6.0 16-bit types are always understood as minimum precision.
This commit is contained in:
committed by
Henri Verbeet
parent
1d780e1a6b
commit
5e86d5c21b
Notes:
Henri Verbeet
2025-06-11 20:36:59 +02:00
Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1558
@@ -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;
|
||||
|
@@ -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:
|
||||
|
Reference in New Issue
Block a user