mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
vkd3d-shader/dxil: Implement DX instruction CreateHandle.
This commit is contained in:
parent
f57d65361a
commit
3b1bbe2b0a
Notes:
Alexandre Julliard
2023-11-01 22:39:52 +01: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/408
@ -246,6 +246,7 @@ enum dx_intrinsic_opcode
|
|||||||
{
|
{
|
||||||
DX_LOAD_INPUT = 4,
|
DX_LOAD_INPUT = 4,
|
||||||
DX_STORE_OUTPUT = 5,
|
DX_STORE_OUTPUT = 5,
|
||||||
|
DX_CREATE_HANDLE = 57,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sm6_pointer_info
|
struct sm6_pointer_info
|
||||||
@ -305,6 +306,7 @@ enum sm6_value_type
|
|||||||
{
|
{
|
||||||
VALUE_TYPE_FUNCTION,
|
VALUE_TYPE_FUNCTION,
|
||||||
VALUE_TYPE_REG,
|
VALUE_TYPE_REG,
|
||||||
|
VALUE_TYPE_HANDLE,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sm6_function_data
|
struct sm6_function_data
|
||||||
@ -314,6 +316,12 @@ struct sm6_function_data
|
|||||||
unsigned int attribs_id;
|
unsigned int attribs_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct sm6_handle_data
|
||||||
|
{
|
||||||
|
const struct sm6_descriptor_info *d;
|
||||||
|
struct vkd3d_shader_register reg;
|
||||||
|
};
|
||||||
|
|
||||||
struct sm6_value
|
struct sm6_value
|
||||||
{
|
{
|
||||||
const struct sm6_type *type;
|
const struct sm6_type *type;
|
||||||
@ -323,6 +331,7 @@ struct sm6_value
|
|||||||
{
|
{
|
||||||
struct sm6_function_data function;
|
struct sm6_function_data function;
|
||||||
struct vkd3d_shader_register reg;
|
struct vkd3d_shader_register reg;
|
||||||
|
struct sm6_handle_data handle;
|
||||||
} u;
|
} u;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -427,6 +436,13 @@ struct sm6_named_metadata
|
|||||||
struct sm6_metadata_value value;
|
struct sm6_metadata_value value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct sm6_descriptor_info
|
||||||
|
{
|
||||||
|
enum vkd3d_shader_descriptor_type type;
|
||||||
|
unsigned int id;
|
||||||
|
struct vkd3d_shader_register_range range;
|
||||||
|
};
|
||||||
|
|
||||||
struct sm6_parser
|
struct sm6_parser
|
||||||
{
|
{
|
||||||
const uint32_t *ptr, *start, *end;
|
const uint32_t *ptr, *start, *end;
|
||||||
@ -442,6 +458,7 @@ struct sm6_parser
|
|||||||
struct sm6_type *types;
|
struct sm6_type *types;
|
||||||
size_t type_count;
|
size_t type_count;
|
||||||
struct sm6_type *metadata_type;
|
struct sm6_type *metadata_type;
|
||||||
|
struct sm6_type *handle_type;
|
||||||
|
|
||||||
struct sm6_symbol *global_symbols;
|
struct sm6_symbol *global_symbols;
|
||||||
size_t global_symbol_count;
|
size_t global_symbol_count;
|
||||||
@ -458,6 +475,10 @@ struct sm6_parser
|
|||||||
struct sm6_named_metadata *named_metadata;
|
struct sm6_named_metadata *named_metadata;
|
||||||
unsigned int named_metadata_count;
|
unsigned int named_metadata_count;
|
||||||
|
|
||||||
|
struct sm6_descriptor_info *descriptors;
|
||||||
|
size_t descriptor_capacity;
|
||||||
|
size_t descriptor_count;
|
||||||
|
|
||||||
struct sm6_value *values;
|
struct sm6_value *values;
|
||||||
size_t value_count;
|
size_t value_count;
|
||||||
size_t value_capacity;
|
size_t value_capacity;
|
||||||
@ -1391,6 +1412,9 @@ static enum vkd3d_result sm6_parser_type_table_init(struct sm6_parser *sm6)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ascii_strcasecmp(struct_name, "dx.types.Handle"))
|
||||||
|
sm6->handle_type = type;
|
||||||
|
|
||||||
type->u.struc->name = struct_name;
|
type->u.struc->name = struct_name;
|
||||||
struct_name = NULL;
|
struct_name = NULL;
|
||||||
break;
|
break;
|
||||||
@ -1438,6 +1462,11 @@ static inline bool sm6_type_is_integer(const struct sm6_type *type)
|
|||||||
return type->class == TYPE_CLASS_INTEGER;
|
return type->class == TYPE_CLASS_INTEGER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool sm6_type_is_bool(const struct sm6_type *type)
|
||||||
|
{
|
||||||
|
return type->class == TYPE_CLASS_INTEGER && type->u.width == 1;
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool sm6_type_is_i8(const struct sm6_type *type)
|
static inline bool sm6_type_is_i8(const struct sm6_type *type)
|
||||||
{
|
{
|
||||||
return type->class == TYPE_CLASS_INTEGER && type->u.width == 8;
|
return type->class == TYPE_CLASS_INTEGER && type->u.width == 8;
|
||||||
@ -1710,6 +1739,11 @@ static inline bool sm6_value_is_register(const struct sm6_value *value)
|
|||||||
return value->value_type == VALUE_TYPE_REG;
|
return value->value_type == VALUE_TYPE_REG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool sm6_value_is_handle(const struct sm6_value *value)
|
||||||
|
{
|
||||||
|
return value->value_type == VALUE_TYPE_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool sm6_value_is_constant(const struct sm6_value *value)
|
static inline bool sm6_value_is_constant(const struct sm6_value *value)
|
||||||
{
|
{
|
||||||
return sm6_value_is_register(value) && register_is_constant(&value->u.reg);
|
return sm6_value_is_register(value) && register_is_constant(&value->u.reg);
|
||||||
@ -1782,6 +1816,8 @@ static enum vkd3d_data_type vkd3d_data_type_from_sm6_type(const struct sm6_type
|
|||||||
{
|
{
|
||||||
switch (type->u.width)
|
switch (type->u.width)
|
||||||
{
|
{
|
||||||
|
case 1:
|
||||||
|
return VKD3D_DATA_BOOL;
|
||||||
case 8:
|
case 8:
|
||||||
return VKD3D_DATA_UINT8;
|
return VKD3D_DATA_UINT8;
|
||||||
case 32:
|
case 32:
|
||||||
@ -2518,6 +2554,66 @@ static struct sm6_block *sm6_block_create()
|
|||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct sm6_descriptor_info *sm6_parser_get_descriptor(struct sm6_parser *sm6,
|
||||||
|
enum vkd3d_shader_descriptor_type type, unsigned int id, const struct sm6_value *address)
|
||||||
|
{
|
||||||
|
const struct sm6_descriptor_info *d;
|
||||||
|
unsigned int register_index;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < sm6->descriptor_count; ++i)
|
||||||
|
{
|
||||||
|
d = &sm6->descriptors[i];
|
||||||
|
|
||||||
|
if (d->type != type || d->id != id)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!sm6_value_is_constant(address))
|
||||||
|
return d;
|
||||||
|
|
||||||
|
register_index = sm6_value_get_constant_uint(address);
|
||||||
|
if (register_index >= d->range.first && register_index <= d->range.last)
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, struct sm6_block *code_block,
|
||||||
|
enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct vkd3d_shader_instruction *ins)
|
||||||
|
{
|
||||||
|
enum vkd3d_shader_descriptor_type type;
|
||||||
|
const struct sm6_descriptor_info *d;
|
||||||
|
struct vkd3d_shader_register *reg;
|
||||||
|
struct sm6_value *dst;
|
||||||
|
unsigned int id;
|
||||||
|
|
||||||
|
type = sm6_value_get_constant_uint(operands[0]);
|
||||||
|
id = sm6_value_get_constant_uint(operands[1]);
|
||||||
|
if (!(d = sm6_parser_get_descriptor(sm6, type, id, operands[2])))
|
||||||
|
{
|
||||||
|
WARN("Failed to find resource type %#x, id %#x.\n", type, id);
|
||||||
|
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
||||||
|
"Descriptor for resource type %#x, id %#x was not found.", type, id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst = sm6_parser_get_current_value(sm6);
|
||||||
|
dst->value_type = VALUE_TYPE_HANDLE;
|
||||||
|
dst->u.handle.d = d;
|
||||||
|
|
||||||
|
reg = &dst->u.handle.reg;
|
||||||
|
/* Set idx_count to 3 for use with load instructions.
|
||||||
|
* TODO: set register type from resource type when other types are supported. */
|
||||||
|
vsir_register_init(reg, VKD3DSPR_CONSTBUFFER, VKD3D_DATA_FLOAT, 3);
|
||||||
|
reg->idx[0].offset = id;
|
||||||
|
register_index_address_init(®->idx[1], operands[2], sm6);
|
||||||
|
reg->non_uniform = !!sm6_value_get_constant_uint(operands[3]);
|
||||||
|
|
||||||
|
/* NOP is used to flag no instruction emitted. */
|
||||||
|
ins->handler_idx = VKD3DSIH_NOP;
|
||||||
|
}
|
||||||
|
|
||||||
static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, struct sm6_block *code_block,
|
static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, struct sm6_block *code_block,
|
||||||
enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct vkd3d_shader_instruction *ins)
|
enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct vkd3d_shader_instruction *ins)
|
||||||
{
|
{
|
||||||
@ -2613,18 +2709,28 @@ struct sm6_dx_opcode_info
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
8 -> int8
|
8 -> int8
|
||||||
|
b -> constant int1
|
||||||
|
c -> constant int8/16/32
|
||||||
i -> int32
|
i -> int32
|
||||||
|
H -> handle
|
||||||
v -> void
|
v -> void
|
||||||
o -> overloaded
|
o -> overloaded
|
||||||
*/
|
*/
|
||||||
static const struct sm6_dx_opcode_info sm6_dx_op_table[] =
|
static const struct sm6_dx_opcode_info sm6_dx_op_table[] =
|
||||||
{
|
{
|
||||||
|
[DX_CREATE_HANDLE ] = {'H', "ccib", sm6_parser_emit_dx_create_handle},
|
||||||
[DX_LOAD_INPUT ] = {'o', "ii8i", sm6_parser_emit_dx_load_input},
|
[DX_LOAD_INPUT ] = {'o', "ii8i", sm6_parser_emit_dx_load_input},
|
||||||
[DX_STORE_OUTPUT ] = {'v', "ii8o", sm6_parser_emit_dx_store_output},
|
[DX_STORE_OUTPUT ] = {'v', "ii8o", sm6_parser_emit_dx_store_output},
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struct sm6_type *type, char info_type)
|
static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struct sm6_value *value, char info_type,
|
||||||
|
bool is_return)
|
||||||
{
|
{
|
||||||
|
const struct sm6_type *type = value->type;
|
||||||
|
|
||||||
|
if (info_type != 'H' && !sm6_value_is_register(value))
|
||||||
|
return false;
|
||||||
|
|
||||||
switch (info_type)
|
switch (info_type)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
@ -2632,8 +2738,15 @@ static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struc
|
|||||||
return false;
|
return false;
|
||||||
case '8':
|
case '8':
|
||||||
return sm6_type_is_i8(type);
|
return sm6_type_is_i8(type);
|
||||||
|
case 'b':
|
||||||
|
return sm6_value_is_constant(value) && sm6_type_is_bool(type);
|
||||||
|
case 'c':
|
||||||
|
return sm6_value_is_constant(value) && sm6_type_is_integer(type) && type->u.width >= 8
|
||||||
|
&& type->u.width <= 32;
|
||||||
case 'i':
|
case 'i':
|
||||||
return sm6_type_is_i32(type);
|
return sm6_type_is_i32(type);
|
||||||
|
case 'H':
|
||||||
|
return (is_return || sm6_value_is_handle(value)) && type == sm6->handle_type;
|
||||||
case 'v':
|
case 'v':
|
||||||
return !type;
|
return !type;
|
||||||
case 'o':
|
case 'o':
|
||||||
@ -2653,7 +2766,7 @@ static bool sm6_parser_validate_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_
|
|||||||
|
|
||||||
info = &sm6_dx_op_table[op];
|
info = &sm6_dx_op_table[op];
|
||||||
|
|
||||||
if (!sm6_parser_validate_operand_type(sm6, dst->type, info->ret_type))
|
if (!sm6_parser_validate_operand_type(sm6, dst, info->ret_type, true))
|
||||||
{
|
{
|
||||||
WARN("Failed to validate return type for dx intrinsic id %u, '%s'.\n", op, name);
|
WARN("Failed to validate return type for dx intrinsic id %u, '%s'.\n", op, name);
|
||||||
/* Return type validation failure is not so critical. We only need to set
|
/* Return type validation failure is not so critical. We only need to set
|
||||||
@ -2663,7 +2776,7 @@ static bool sm6_parser_validate_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_
|
|||||||
for (i = 0; i < operand_count; ++i)
|
for (i = 0; i < operand_count; ++i)
|
||||||
{
|
{
|
||||||
const struct sm6_value *value = operands[i];
|
const struct sm6_value *value = operands[i];
|
||||||
if (!sm6_value_is_register(value) || !sm6_parser_validate_operand_type(sm6, value->type, info->operand_info[i]))
|
if (!sm6_parser_validate_operand_type(sm6, value, info->operand_info[i], false))
|
||||||
{
|
{
|
||||||
WARN("Failed to validate operand %u for dx intrinsic id %u, '%s'.\n", i + 1, op, name);
|
WARN("Failed to validate operand %u for dx intrinsic id %u, '%s'.\n", i + 1, op, name);
|
||||||
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
|
||||||
@ -3422,8 +3535,7 @@ static bool sm6_parser_resources_load_register_range(struct sm6_parser *sm6,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static enum vkd3d_result sm6_parser_resources_load_cbv(struct sm6_parser *sm6,
|
static enum vkd3d_result sm6_parser_resources_load_cbv(struct sm6_parser *sm6,
|
||||||
const struct sm6_metadata_node *node, const struct vkd3d_shader_register_range *range,
|
const struct sm6_metadata_node *node, struct sm6_descriptor_info *d, struct vkd3d_shader_instruction *ins)
|
||||||
unsigned int register_id, struct vkd3d_shader_instruction *ins)
|
|
||||||
{
|
{
|
||||||
struct vkd3d_shader_register *reg;
|
struct vkd3d_shader_register *reg;
|
||||||
unsigned int buffer_size;
|
unsigned int buffer_size;
|
||||||
@ -3458,11 +3570,11 @@ static enum vkd3d_result sm6_parser_resources_load_cbv(struct sm6_parser *sm6,
|
|||||||
|
|
||||||
reg = &ins->declaration.cb.src.reg;
|
reg = &ins->declaration.cb.src.reg;
|
||||||
vsir_register_init(reg, VKD3DSPR_CONSTBUFFER, VKD3D_DATA_FLOAT, 3);
|
vsir_register_init(reg, VKD3DSPR_CONSTBUFFER, VKD3D_DATA_FLOAT, 3);
|
||||||
reg->idx[0].offset = register_id;
|
reg->idx[0].offset = d->id;
|
||||||
reg->idx[1].offset = range->first;
|
reg->idx[1].offset = d->range.first;
|
||||||
reg->idx[2].offset = range->last;
|
reg->idx[2].offset = d->range.last;
|
||||||
|
|
||||||
ins->declaration.cb.range = *range;
|
ins->declaration.cb.range = d->range;
|
||||||
|
|
||||||
return VKD3D_OK;
|
return VKD3D_OK;
|
||||||
}
|
}
|
||||||
@ -3470,12 +3582,12 @@ static enum vkd3d_result sm6_parser_resources_load_cbv(struct sm6_parser *sm6,
|
|||||||
static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6,
|
static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6,
|
||||||
enum vkd3d_shader_descriptor_type type, const struct sm6_metadata_node *descriptor_node)
|
enum vkd3d_shader_descriptor_type type, const struct sm6_metadata_node *descriptor_node)
|
||||||
{
|
{
|
||||||
struct vkd3d_shader_register_range range;
|
|
||||||
struct vkd3d_shader_instruction *ins;
|
struct vkd3d_shader_instruction *ins;
|
||||||
const struct sm6_metadata_node *node;
|
const struct sm6_metadata_node *node;
|
||||||
const struct sm6_metadata_value *m;
|
const struct sm6_metadata_value *m;
|
||||||
unsigned int i, register_id;
|
struct sm6_descriptor_info *d;
|
||||||
enum vkd3d_result ret;
|
enum vkd3d_result ret;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
for (i = 0; i < descriptor_node->operand_count; ++i)
|
for (i = 0; i < descriptor_node->operand_count; ++i)
|
||||||
{
|
{
|
||||||
@ -3497,7 +3609,18 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6,
|
|||||||
return VKD3D_ERROR_INVALID_SHADER;
|
return VKD3D_ERROR_INVALID_SHADER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sm6_metadata_get_uint_value(sm6, node->operands[0], ®ister_id))
|
if (!vkd3d_array_reserve((void **)&sm6->descriptors, &sm6->descriptor_capacity,
|
||||||
|
sm6->descriptor_count + 1, sizeof(*sm6->descriptors)))
|
||||||
|
{
|
||||||
|
ERR("Failed to allocate descriptor array.\n");
|
||||||
|
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
|
||||||
|
"Out of memory allocating the descriptor array.");
|
||||||
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
d = &sm6->descriptors[sm6->descriptor_count];
|
||||||
|
d->type = type;
|
||||||
|
|
||||||
|
if (!sm6_metadata_get_uint_value(sm6, node->operands[0], &d->id))
|
||||||
{
|
{
|
||||||
WARN("Failed to load resource id.\n");
|
WARN("Failed to load resource id.\n");
|
||||||
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES,
|
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES,
|
||||||
@ -3505,7 +3628,7 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6,
|
|||||||
return VKD3D_ERROR_INVALID_SHADER;
|
return VKD3D_ERROR_INVALID_SHADER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sm6_parser_resources_load_register_range(sm6, node, &range))
|
if (!sm6_parser_resources_load_register_range(sm6, node, &d->range))
|
||||||
{
|
{
|
||||||
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES,
|
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES,
|
||||||
"Resource register range is invalid.");
|
"Resource register range is invalid.");
|
||||||
@ -3521,7 +3644,7 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6,
|
|||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV:
|
case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV:
|
||||||
if ((ret = sm6_parser_resources_load_cbv(sm6, node, &range, register_id, ins)) < 0)
|
if ((ret = sm6_parser_resources_load_cbv(sm6, node, d, ins)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -3531,6 +3654,7 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6,
|
|||||||
return VKD3D_ERROR_INVALID_SHADER;
|
return VKD3D_ERROR_INVALID_SHADER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
++sm6->descriptor_count;
|
||||||
++sm6->p.instructions.count;
|
++sm6->p.instructions.count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4131,6 +4255,7 @@ static void sm6_parser_destroy(struct vkd3d_shader_parser *parser)
|
|||||||
sm6_symtab_cleanup(sm6->global_symbols, sm6->global_symbol_count);
|
sm6_symtab_cleanup(sm6->global_symbols, sm6->global_symbol_count);
|
||||||
sm6_functions_cleanup(sm6->functions, sm6->function_count);
|
sm6_functions_cleanup(sm6->functions, sm6->function_count);
|
||||||
sm6_parser_metadata_cleanup(sm6);
|
sm6_parser_metadata_cleanup(sm6);
|
||||||
|
vkd3d_free(sm6->descriptors);
|
||||||
vkd3d_free(sm6->values);
|
vkd3d_free(sm6->values);
|
||||||
free_shader_desc(&parser->shader_desc);
|
free_shader_desc(&parser->shader_desc);
|
||||||
vkd3d_free(sm6);
|
vkd3d_free(sm6);
|
||||||
|
@ -575,6 +575,7 @@ enum vkd3d_data_type
|
|||||||
VKD3D_DATA_UNUSED,
|
VKD3D_DATA_UNUSED,
|
||||||
VKD3D_DATA_UINT8,
|
VKD3D_DATA_UINT8,
|
||||||
VKD3D_DATA_UINT64,
|
VKD3D_DATA_UINT64,
|
||||||
|
VKD3D_DATA_BOOL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline bool data_type_is_integer(enum vkd3d_data_type data_type)
|
static inline bool data_type_is_integer(enum vkd3d_data_type data_type)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user