-- v3: vkd3d-shader/dxil: Implement DX intrinsic RawBufferLoad. vkd3d-shader/dxil: Load raw/structured buffer SRV/UAV descriptors.
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/dxil.c | 48 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 2a0ff61cf..9e87ba5b2 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -5930,6 +5930,8 @@ static enum vkd3d_shader_resource_type shader_resource_type_from_dxil_resource_k switch (kind) { case RESOURCE_KIND_TYPEDBUFFER: + case RESOURCE_KIND_RAWBUFFER: + case RESOURCE_KIND_STRUCTUREDBUFFER: return VKD3D_SHADER_RESOURCE_BUFFER; default: return VKD3D_SHADER_RESOURCE_NONE; @@ -5994,6 +5996,13 @@ static struct vkd3d_shader_resource *sm6_parser_resources_load_common_info(struc } ins->resource_type = resource_type;
+ if (!m) + { + ins->handler_idx = is_uav ? VKD3DSIH_DCL_UAV_RAW : VKD3DSIH_DCL_RESOURCE_RAW; + ins->declaration.raw_resource.resource.reg.write_mask = 0; + return &ins->declaration.raw_resource.resource; + } + if (!sm6_metadata_value_is_node(m)) { WARN("Resource metadata list is not a node.\n"); @@ -6048,6 +6057,39 @@ static struct vkd3d_shader_resource *sm6_parser_resources_load_common_info(struc
return &ins->declaration.semantic.resource; } + else if (dxil_resource_type == RESOURCE_TYPE_RAW_STRUCTURED) + { + if (kind == RESOURCE_KIND_RAWBUFFER) + { + ins->handler_idx = is_uav ? VKD3DSIH_DCL_UAV_RAW : VKD3DSIH_DCL_RESOURCE_RAW; + ins->declaration.raw_resource.resource.reg.write_mask = 0; + + return &ins->declaration.raw_resource.resource; + } + + if (kind != RESOURCE_KIND_STRUCTUREDBUFFER) + { + WARN("Unhandled resource kind %u.\n", kind); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES, + "Resource kind %u for a raw or structured buffer is unhandled.", kind); + return NULL; + } + + ins->handler_idx = is_uav ? VKD3DSIH_DCL_UAV_STRUCTURED : VKD3DSIH_DCL_RESOURCE_STRUCTURED; + ins->declaration.structured_resource.byte_stride = values[1]; + ins->declaration.structured_resource.resource.reg.write_mask = 0; + + /* TODO: 16-bit resources. */ + if (ins->declaration.structured_resource.byte_stride % 4u) + { + WARN("Byte stride %u is not a multiple of 4.\n", ins->declaration.structured_resource.byte_stride); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES, + "Structured resource byte stride %u is not a multiple of 4.", + ins->declaration.structured_resource.byte_stride); + } + + return &ins->declaration.structured_resource.resource; + } else { FIXME("Unhandled resource type %u.\n", dxil_resource_type); @@ -6114,7 +6156,8 @@ static enum vkd3d_result sm6_parser_resources_load_srv(struct sm6_parser *sm6, d->kind = kind; d->reg_type = VKD3DSPR_RESOURCE; d->reg_data_type = (ins->resource_type == VKD3D_SHADER_RESOURCE_BUFFER) ? VKD3D_DATA_UINT : VKD3D_DATA_RESOURCE; - d->resource_data_type = ins->declaration.semantic.resource_data_type[0]; + d->resource_data_type = (ins->handler_idx == VKD3DSIH_DCL) + ? ins->declaration.semantic.resource_data_type[0] : VKD3D_DATA_UNUSED;
init_resource_declaration(resource, VKD3DSPR_RESOURCE, d->reg_data_type, d->id, &d->range);
@@ -6187,7 +6230,8 @@ static enum vkd3d_result sm6_parser_resources_load_uav(struct sm6_parser *sm6, d->kind = values[0]; d->reg_type = VKD3DSPR_UAV; d->reg_data_type = (ins->resource_type == VKD3D_SHADER_RESOURCE_BUFFER) ? VKD3D_DATA_UINT : VKD3D_DATA_UAV; - d->resource_data_type = ins->declaration.semantic.resource_data_type[0]; + d->resource_data_type = (ins->handler_idx == VKD3DSIH_DCL_UAV_TYPED) + ? ins->declaration.semantic.resource_data_type[0] : VKD3D_DATA_UNUSED;
init_resource_declaration(resource, VKD3DSPR_UAV, d->reg_data_type, d->id, &d->range);
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/dxil.c | 61 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+)
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 9e87ba5b2..1a0539254 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -357,6 +357,7 @@ enum dx_intrinsic_opcode DX_DERIV_FINEY = 86, DX_LEGACY_F32TOF16 = 130, DX_LEGACY_F16TOF32 = 131, + DX_RAW_BUFFER_LOAD = 139, };
enum dxil_cast_code @@ -2072,6 +2073,8 @@ static void instruction_init_with_resource(struct vkd3d_shader_instruction *ins, { vsir_instruction_init(ins, &sm6->p.location, handler_idx); ins->resource_type = resource->u.handle.d->resource_type; + ins->raw = resource->u.handle.d->kind == RESOURCE_KIND_RAWBUFFER; + ins->structured = resource->u.handle.d->kind == RESOURCE_KIND_STRUCTUREDBUFFER; }
static struct vkd3d_shader_src_param *instruction_src_params_alloc(struct vkd3d_shader_instruction *ins, @@ -3094,6 +3097,15 @@ static void dst_param_io_init(struct vkd3d_shader_dst_param *param, param->reg.dimension = VSIR_DIMENSION_VEC4; }
+static void src_params_init_from_operands(struct vkd3d_shader_src_param *src_params, + const struct sm6_value **operands, unsigned int count) +{ + unsigned int i; + + for (i = 0; i < count; ++i) + src_param_init_from_value(&src_params[i], operands[i]); +} + static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shader_signature *s, enum vkd3d_shader_register_type reg_type, struct vkd3d_shader_dst_param *params) { @@ -3708,6 +3720,48 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin instruction_dst_param_init_ssa_scalar(ins, sm6); }
+static void sm6_parser_emit_dx_raw_buffer_load(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, + const struct sm6_value **operands, struct function_emission_state *state) +{ + unsigned int operand_count, write_mask, component_count = VKD3D_VEC4_SIZE; + struct vkd3d_shader_instruction *ins = state->ins; + struct vkd3d_shader_src_param *src_params; + const struct sm6_value *resource; + bool raw; + + resource = operands[0]; + if (!sm6_value_validate_is_handle(resource, sm6)) + return; + raw = resource->u.handle.d->kind == RESOURCE_KIND_RAWBUFFER; + + if (op == DX_RAW_BUFFER_LOAD) + { + write_mask = sm6_value_get_constant_uint(operands[3]); + if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL) + { + WARN("Invalid write mask %#x.\n", write_mask); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Write mask %#x for a raw/structured buffer load operation is invalid.", write_mask); + return; + } + else if (write_mask & (write_mask + 1)) + { + FIXME("Unhandled write mask %#x.\n", write_mask); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Write mask %#x for a raw/structured buffer load operation is unhandled.", write_mask); + } + component_count = vsir_write_mask_component_count(write_mask); + } + + instruction_init_with_resource(ins, raw ? VKD3DSIH_LD_RAW : VKD3DSIH_LD_STRUCTURED, resource, sm6); + operand_count = 2 + !raw; + src_params = instruction_src_params_alloc(ins, operand_count, sm6); + src_params_init_from_operands(src_params, &operands[1], operand_count - 1); + src_param_init_vector_from_reg(&src_params[operand_count - 1], &resource->u.handle.reg); + + instruction_dst_param_init_ssa_vector(ins, component_count, sm6); +} + static void sm6_parser_emit_dx_buffer_load(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state) { @@ -3719,6 +3773,12 @@ static void sm6_parser_emit_dx_buffer_load(struct sm6_parser *sm6, enum dx_intri if (!sm6_value_validate_is_handle(resource, sm6)) return;
+ if (resource->u.handle.d->kind == RESOURCE_KIND_RAWBUFFER + || resource->u.handle.d->kind == RESOURCE_KIND_STRUCTUREDBUFFER) + { + return sm6_parser_emit_dx_raw_buffer_load(sm6, op, operands, state); + } + if (resource->u.handle.d->kind != RESOURCE_KIND_TYPEDBUFFER) { WARN("Resource is not a typed buffer.\n"); @@ -3843,6 +3903,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = [DX_LEGACY_F32TOF16 ] = {"i", "f", sm6_parser_emit_dx_unary}, [DX_LOAD_INPUT ] = {"o", "ii8i", sm6_parser_emit_dx_load_input}, [DX_LOG ] = {"g", "R", sm6_parser_emit_dx_unary}, + [DX_RAW_BUFFER_LOAD ] = {"o", "Hii8i", sm6_parser_emit_dx_raw_buffer_load}, [DX_ROUND_NE ] = {"g", "R", sm6_parser_emit_dx_unary}, [DX_ROUND_NI ] = {"g", "R", sm6_parser_emit_dx_unary}, [DX_ROUND_PI ] = {"g", "R", sm6_parser_emit_dx_unary},
Giovanni Mascellani (@giomasce) commented about libs/vkd3d-shader/dxil.c:
return;
}
else if (write_mask & (write_mask + 1))
{
FIXME("Unhandled write mask %#x.\n", write_mask);
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
"Write mask %#x for a raw/structured buffer load operation is unhandled.", write_mask);
}
component_count = vsir_write_mask_component_count(write_mask);
- }
- instruction_init_with_resource(ins, raw ? VKD3DSIH_LD_RAW : VKD3DSIH_LD_STRUCTURED, resource, sm6);
- operand_count = 2 + !raw;
- src_params = instruction_src_params_alloc(ins, operand_count, sm6);
- src_params_init_from_operands(src_params, &operands[1], operand_count - 1);
- src_param_init_vector_from_reg(&src_params[operand_count - 1], &resource->u.handle.reg);
Shouldn't we check for allocation success here?