mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
vkd3d-shader/dxil: Handle constexpr pointer cast.
This commit is contained in:
parent
2fc32c3d1d
commit
fb730b11cf
Notes:
Alexandre Julliard
2024-04-30 23:14:34 +02:00
Approved-by: Giovanni Mascellani (@giomasce) Approved-by: Henri Verbeet (@hverbeet) Approved-by: Alexandre Julliard (@julliard) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/836
@ -103,6 +103,7 @@ enum bitcode_constant_code
|
|||||||
CST_CODE_INTEGER = 4,
|
CST_CODE_INTEGER = 4,
|
||||||
CST_CODE_FLOAT = 6,
|
CST_CODE_FLOAT = 6,
|
||||||
CST_CODE_STRING = 8,
|
CST_CODE_STRING = 8,
|
||||||
|
CST_CODE_CE_CAST = 11,
|
||||||
CST_CODE_CE_GEP = 12,
|
CST_CODE_CE_GEP = 12,
|
||||||
CST_CODE_CE_INBOUNDS_GEP = 20,
|
CST_CODE_CE_INBOUNDS_GEP = 20,
|
||||||
CST_CODE_DATA = 22,
|
CST_CODE_DATA = 22,
|
||||||
@ -2217,6 +2218,11 @@ static bool sm6_value_is_ssa(const struct sm6_value *value)
|
|||||||
return sm6_value_is_register(value) && register_is_ssa(&value->u.reg);
|
return sm6_value_is_register(value) && register_is_ssa(&value->u.reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool sm6_value_is_numeric_array(const struct sm6_value *value)
|
||||||
|
{
|
||||||
|
return sm6_value_is_register(value) && register_is_numeric_array(&value->u.reg);
|
||||||
|
}
|
||||||
|
|
||||||
static inline unsigned int sm6_value_get_constant_uint(const struct sm6_value *value)
|
static inline unsigned int sm6_value_get_constant_uint(const struct sm6_value *value)
|
||||||
{
|
{
|
||||||
if (!sm6_value_is_constant(value))
|
if (!sm6_value_is_constant(value))
|
||||||
@ -3099,15 +3105,16 @@ static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, c
|
|||||||
static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const struct dxil_block *block)
|
static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const struct dxil_block *block)
|
||||||
{
|
{
|
||||||
enum vkd3d_shader_register_type reg_type = VKD3DSPR_INVALID;
|
enum vkd3d_shader_register_type reg_type = VKD3DSPR_INVALID;
|
||||||
const struct sm6_type *type, *elem_type;
|
const struct sm6_type *type, *elem_type, *ptr_type;
|
||||||
|
size_t i, base_value_idx, value_idx;
|
||||||
enum vkd3d_data_type reg_data_type;
|
enum vkd3d_data_type reg_data_type;
|
||||||
const struct dxil_record *record;
|
const struct dxil_record *record;
|
||||||
|
const struct sm6_value *src;
|
||||||
enum vkd3d_result ret;
|
enum vkd3d_result ret;
|
||||||
struct sm6_value *dst;
|
struct sm6_value *dst;
|
||||||
size_t i, value_idx;
|
|
||||||
uint64_t value;
|
uint64_t value;
|
||||||
|
|
||||||
for (i = 0, type = NULL; i < block->record_count; ++i)
|
for (i = 0, type = NULL, base_value_idx = sm6->value_count; i < block->record_count; ++i)
|
||||||
{
|
{
|
||||||
sm6->p.location.column = i;
|
sm6->p.location.column = i;
|
||||||
record = block->records[i];
|
record = block->records[i];
|
||||||
@ -3223,6 +3230,48 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const
|
|||||||
return ret;
|
return ret;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CST_CODE_CE_CAST:
|
||||||
|
if (!dxil_record_validate_operand_count(record, 3, 3, sm6))
|
||||||
|
return VKD3D_ERROR_INVALID_SHADER;
|
||||||
|
|
||||||
|
if ((value = record->operands[0]) != CAST_BITCAST)
|
||||||
|
{
|
||||||
|
WARN("Unhandled constexpr cast op %"PRIu64".\n", value);
|
||||||
|
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
||||||
|
"Constexpr cast op %"PRIu64" is unhandled.", value);
|
||||||
|
return VKD3D_ERROR_INVALID_SHADER;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr_type = sm6_parser_get_type(sm6, record->operands[1]);
|
||||||
|
if (!sm6_type_is_pointer(ptr_type))
|
||||||
|
{
|
||||||
|
WARN("Constexpr cast at constant idx %zu is not a pointer.\n", value_idx);
|
||||||
|
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
||||||
|
"Constexpr cast source operand is not a pointer.");
|
||||||
|
return VKD3D_ERROR_INVALID_SHADER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((value = record->operands[2]) >= sm6->cur_max_value)
|
||||||
|
{
|
||||||
|
WARN("Invalid value index %"PRIu64".\n", value);
|
||||||
|
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
||||||
|
"Invalid value index %"PRIu64".", value);
|
||||||
|
return VKD3D_ERROR_INVALID_SHADER;
|
||||||
|
}
|
||||||
|
else if (value == value_idx)
|
||||||
|
{
|
||||||
|
WARN("Invalid value self-reference at %"PRIu64".\n", value);
|
||||||
|
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
||||||
|
"Invalid value self-reference for a constexpr cast.");
|
||||||
|
return VKD3D_ERROR_INVALID_SHADER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Resolve later in case forward refs exist. */
|
||||||
|
dst->type = type;
|
||||||
|
dst->u.reg.type = VKD3DSPR_COUNT;
|
||||||
|
dst->u.reg.idx[0].offset = value;
|
||||||
|
break;
|
||||||
|
|
||||||
case CST_CODE_UNDEF:
|
case CST_CODE_UNDEF:
|
||||||
dxil_record_validate_operand_max_count(record, 0, sm6);
|
dxil_record_validate_operand_max_count(record, 0, sm6);
|
||||||
dst->u.reg.type = VKD3DSPR_UNDEF;
|
dst->u.reg.type = VKD3DSPR_UNDEF;
|
||||||
@ -3248,6 +3297,29 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const
|
|||||||
++sm6->value_count;
|
++sm6->value_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Resolve cast forward refs. */
|
||||||
|
for (i = base_value_idx; i < sm6->value_count; ++i)
|
||||||
|
{
|
||||||
|
dst = &sm6->values[i];
|
||||||
|
if (dst->u.reg.type != VKD3DSPR_COUNT)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
type = dst->type;
|
||||||
|
|
||||||
|
src = &sm6->values[dst->u.reg.idx[0].offset];
|
||||||
|
if (!sm6_value_is_numeric_array(src))
|
||||||
|
{
|
||||||
|
WARN("Value is not an array.\n");
|
||||||
|
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
||||||
|
"Constexpr cast source value is not a global array element.");
|
||||||
|
return VKD3D_ERROR_INVALID_SHADER;
|
||||||
|
}
|
||||||
|
|
||||||
|
*dst = *src;
|
||||||
|
dst->type = type;
|
||||||
|
dst->u.reg.data_type = vkd3d_data_type_from_sm6_type(type->u.pointer.type);
|
||||||
|
}
|
||||||
|
|
||||||
return VKD3D_OK;
|
return VKD3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1241,6 +1241,12 @@ static inline bool register_is_scalar_constant_zero(const struct vkd3d_shader_re
|
|||||||
&& (data_type_is_64_bit(reg->data_type) ? !reg->u.immconst_u64[0] : !reg->u.immconst_u32[0]);
|
&& (data_type_is_64_bit(reg->data_type) ? !reg->u.immconst_u64[0] : !reg->u.immconst_u32[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool register_is_numeric_array(const struct vkd3d_shader_register *reg)
|
||||||
|
{
|
||||||
|
return (reg->type == VKD3DSPR_IMMCONSTBUFFER || reg->type == VKD3DSPR_IDXTEMP
|
||||||
|
|| reg->type == VKD3DSPR_GROUPSHAREDMEM);
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool vsir_register_is_label(const struct vkd3d_shader_register *reg)
|
static inline bool vsir_register_is_label(const struct vkd3d_shader_register *reg)
|
||||||
{
|
{
|
||||||
return reg->type == VKD3DSPR_LABEL;
|
return reg->type == VKD3DSPR_LABEL;
|
||||||
|
@ -16,8 +16,8 @@ float4 main(float4 pos : SV_Position) : SV_Target
|
|||||||
|
|
||||||
[test]
|
[test]
|
||||||
uniform 0 uint4 0 1 0x3e000000 0
|
uniform 0 uint4 0 1 0x3e000000 0
|
||||||
todo draw quad
|
draw quad
|
||||||
probe all rgba (0.25, 0.125, 0.0, 1.0)
|
probe all rgba (0.25, 0.125, 0.0, 1.0)
|
||||||
uniform 0 uint4 1 0 0x3e000000 0
|
uniform 0 uint4 1 0 0x3e000000 0
|
||||||
todo draw quad
|
draw quad
|
||||||
probe all rgba (0.5, 0.75, 0.0, 1.0)
|
probe all rgba (0.5, 0.75, 0.0, 1.0)
|
||||||
|
Loading…
Reference in New Issue
Block a user