mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-09-12 18:50:22 -07:00
vkd3d-shader/dxil: Emit 16-bit CONSTANT values as minimum precision registers.
This commit is contained in:
committed by
Henri Verbeet
parent
14477b1066
commit
1d780e1a6b
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
@@ -2499,6 +2499,79 @@ static enum vkd3d_data_type vkd3d_data_type_from_sm6_type(const struct sm6_type
|
|||||||
return VKD3D_DATA_UINT;
|
return VKD3D_DATA_UINT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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 void register_convert_to_minimum_precision(struct vkd3d_shader_register *reg)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
switch (reg->data_type)
|
||||||
|
{
|
||||||
|
case VKD3D_DATA_HALF:
|
||||||
|
reg->data_type = VKD3D_DATA_FLOAT;
|
||||||
|
reg->precision = VKD3D_SHADER_REGISTER_PRECISION_MIN_FLOAT_16;
|
||||||
|
if (reg->type == VKD3DSPR_IMMCONST)
|
||||||
|
{
|
||||||
|
for (i = 0; i < VSIR_DIMENSION_VEC4; ++i)
|
||||||
|
reg->u.immconst_u32[i] = half_to_float(reg->u.immconst_u32[i]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VKD3D_DATA_UINT16:
|
||||||
|
reg->data_type = VKD3D_DATA_UINT;
|
||||||
|
reg->precision = VKD3D_SHADER_REGISTER_PRECISION_MIN_UINT_16;
|
||||||
|
if (reg->type == VKD3DSPR_IMMCONST)
|
||||||
|
{
|
||||||
|
for (i = 0; i < VSIR_DIMENSION_VEC4; ++i)
|
||||||
|
reg->u.immconst_u32[i] = (int16_t)reg->u.immconst_u32[i];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void register_index_address_init(struct vkd3d_shader_register_index *idx, const struct sm6_value *address,
|
static void register_index_address_init(struct vkd3d_shader_register_index *idx, const struct sm6_value *address,
|
||||||
struct sm6_parser *sm6);
|
struct sm6_parser *sm6);
|
||||||
|
|
||||||
@@ -2543,6 +2616,7 @@ static void sm6_register_from_value(struct vkd3d_shader_register *reg, const str
|
|||||||
vsir_register_init(reg, scalar_type->u.width == 64 ? VKD3DSPR_IMMCONST64 : VKD3DSPR_IMMCONST,
|
vsir_register_init(reg, scalar_type->u.width == 64 ? VKD3DSPR_IMMCONST64 : VKD3DSPR_IMMCONST,
|
||||||
data_type, 0);
|
data_type, 0);
|
||||||
reg->u = value->u.constant.immconst;
|
reg->u = value->u.constant.immconst;
|
||||||
|
register_convert_to_minimum_precision(reg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VALUE_TYPE_UNDEFINED:
|
case VALUE_TYPE_UNDEFINED:
|
||||||
|
|||||||
@@ -4603,15 +4603,14 @@ static uint32_t spirv_compiler_emit_load_constant(struct spirv_compiler *compile
|
|||||||
if (reg->dimension == VSIR_DIMENSION_SCALAR)
|
if (reg->dimension == VSIR_DIMENSION_SCALAR)
|
||||||
{
|
{
|
||||||
for (i = 0; i < component_count; ++i)
|
for (i = 0; i < component_count; ++i)
|
||||||
values[i] = convert_raw_constant32(reg->data_type, reg->u.immconst_u32[0]);
|
values[i] = reg->u.immconst_u32[0];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (i = 0, j = 0; i < VKD3D_VEC4_SIZE; ++i)
|
for (i = 0, j = 0; i < VKD3D_VEC4_SIZE; ++i)
|
||||||
{
|
{
|
||||||
if (write_mask & (VKD3DSP_WRITEMASK_0 << i))
|
if (write_mask & (VKD3DSP_WRITEMASK_0 << i))
|
||||||
values[j++] = convert_raw_constant32(reg->data_type,
|
values[j++] = reg->u.immconst_u32[vsir_swizzle_get_component(swizzle, i)];
|
||||||
reg->u.immconst_u32[vsir_swizzle_get_component(swizzle, i)]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user