From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/dxil.c | 83 ++++++++++++++++++++++++ libs/vkd3d-shader/vkd3d_shader_private.h | 1 + 2 files changed, 84 insertions(+)
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 030f70230..2147ef96e 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -246,6 +246,7 @@ enum dx_intrinsic_opcode { DX_LOAD_INPUT = 4, DX_STORE_OUTPUT = 5, + DX_CREATE_HANDLE = 57, };
struct sm6_pointer_info @@ -305,6 +306,7 @@ enum sm6_value_type { VALUE_TYPE_FUNCTION, VALUE_TYPE_REG, + VALUE_TYPE_HANDLE, };
struct sm6_function_data @@ -314,6 +316,12 @@ struct sm6_function_data unsigned int attribs_id; };
+struct sm6_handle_data +{ + const struct vkd3d_shader_descriptor_info1 *d; + struct vkd3d_shader_register reg; +}; + struct sm6_value { const struct sm6_type *type; @@ -323,6 +331,7 @@ struct sm6_value { struct sm6_function_data function; struct vkd3d_shader_register reg; + struct sm6_handle_data handle; } u; };
@@ -442,6 +451,7 @@ struct sm6_parser struct sm6_type *types; size_t type_count; struct sm6_type *metadata_type; + struct sm6_type *handle_type;
struct sm6_symbol *global_symbols; size_t global_symbol_count; @@ -1391,6 +1401,9 @@ static enum vkd3d_result sm6_parser_type_table_init(struct sm6_parser *sm6) break; }
+ if (!ascii_strcasecmp(struct_name, "dx.types.Handle")) + sm6->handle_type = type; + type->u.struc->name = struct_name; struct_name = NULL; break; @@ -1438,6 +1451,11 @@ static inline bool sm6_type_is_integer(const struct sm6_type *type) 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) { return type->class == TYPE_CLASS_INTEGER && type->u.width == 8; @@ -1782,6 +1800,8 @@ static enum vkd3d_data_type vkd3d_data_type_from_sm6_type(const struct sm6_type { switch (type->u.width) { + case 1: + return VKD3D_DATA_BOOL; case 8: return VKD3D_DATA_UINT8; case 32: @@ -2519,6 +2539,62 @@ static struct sm6_block *sm6_block_create() return block; }
+static const struct vkd3d_shader_descriptor_info1 *parser_get_descriptor(struct vkd3d_shader_parser *parser, + enum vkd3d_shader_descriptor_type type, unsigned int id) +{ + const struct vkd3d_shader_descriptor_info1 *d; + size_t i; + + for (i = 0; i < parser->shader_desc.descriptor_count; ++i) + { + d = &parser->shader_desc.descriptors[i]; + if (d->type == type && d->register_id == id) + 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) +{ + const struct vkd3d_shader_descriptor_info1 *d; + enum vkd3d_shader_descriptor_type type; + 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 = parser_get_descriptor(&sm6->p, type, id))) + { + 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; + vsir_register_init(reg, VKD3DSPR_CONSTBUFFER, VKD3D_DATA_FLOAT, 2); + reg->idx[0].offset = id; + register_address_init(reg, 1, operands[2], sm6); + if (!sm6_value_is_constant(operands[3])) + { + WARN("Non-uniform attribute is not constant.\n"); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Resource handle non-uniform attribute is not a constant."); + return; + } + 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, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct vkd3d_shader_instruction *ins) { @@ -2613,8 +2689,10 @@ struct sm6_dx_opcode_info };
/* + 1 -> int1 8 -> int8 i -> int32 + H -> handle v -> void o -> overloaded */ @@ -2622,6 +2700,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = { [DX_LOAD_INPUT ] = {'o', "ii8i", sm6_parser_emit_dx_load_input}, [DX_STORE_OUTPUT ] = {'v', "ii8o", sm6_parser_emit_dx_store_output}, + [DX_CREATE_HANDLE ] = {'H', "8ii1", sm6_parser_emit_dx_create_handle}, };
static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struct sm6_type *type, char info_type) @@ -2631,10 +2710,14 @@ static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struc case 0: FIXME("Invalid operand count.\n"); return false; + case '1': + return sm6_type_is_bool(type); case '8': return sm6_type_is_i8(type); case 'i': return sm6_type_is_i32(type); + case 'H': + return type == sm6->handle_type; case 'v': return !type; case 'o': diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 1305e4aff..71731b632 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -574,6 +574,7 @@ enum vkd3d_data_type VKD3D_DATA_UNUSED, VKD3D_DATA_UINT8, VKD3D_DATA_UINT64, + VKD3D_DATA_BOOL, };
static inline bool data_type_is_integer(enum vkd3d_data_type data_type)