I'll revise the operand codes once !572 is upstream.
-- v2: vkd3d-shader/spirv: Support 64-bit source value for bitfield instructions. vkd3d-shader/dxil: Implement DX intrinsic Tertiary.
From: Conor McCarthy cmccarthy@codeweavers.com
IBFE and UBFE are not emitted for HLSL sources which perform bitfield extractions, e.g. loading a value from a struct containing bitfields, or the equivalent done with bit shifts. These instructions are probably only emitted by the TPF -> DXIL converter, which makes them hard to test. --- libs/vkd3d-shader/dxil.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 2a0ff61cf..609f1ec08 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -348,6 +348,8 @@ enum dx_intrinsic_opcode DX_IMIN = 38, DX_UMAX = 39, DX_UMIN = 40, + DX_IBFE = 51, + DX_UBFE = 52, DX_CREATE_HANDLE = 57, DX_CBUFFER_LOAD_LEGACY = 59, DX_BUFFER_LOAD = 68, @@ -3675,6 +3677,34 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_int ins->handler_idx = VKD3DSIH_NOP; }
+static enum vkd3d_shader_opcode sm6_dx_map_tertiary_op(enum dx_intrinsic_opcode op) +{ + switch (op) + { + case DX_IBFE: + return VKD3DSIH_IBFE; + case DX_UBFE: + return VKD3DSIH_UBFE; + default: + vkd3d_unreachable(); + } +} + +static void sm6_parser_emit_dx_tertiary(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, + const struct sm6_value **operands, struct function_emission_state *state) +{ + struct vkd3d_shader_instruction *ins = state->ins; + struct vkd3d_shader_src_param *src_params; + unsigned int i; + + vsir_instruction_init(ins, &sm6->p.location, sm6_dx_map_tertiary_op(op)); + src_params = instruction_src_params_alloc(ins, 3, sm6); + for (i = 0; i < 3; ++i) + src_param_init_from_value(&src_params[i], operands[i]); + + instruction_dst_param_init_ssa_scalar(ins, sm6); +} + static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state) { @@ -3837,6 +3867,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = [DX_FMAX ] = {"g", "RR", sm6_parser_emit_dx_binary}, [DX_FMIN ] = {"g", "RR", sm6_parser_emit_dx_binary}, [DX_FRC ] = {"g", "R", sm6_parser_emit_dx_unary}, + [DX_IBFE ] = {"m", "iiR", sm6_parser_emit_dx_tertiary}, [DX_IMAX ] = {"m", "RR", sm6_parser_emit_dx_binary}, [DX_IMIN ] = {"m", "RR", sm6_parser_emit_dx_binary}, [DX_LEGACY_F16TOF32 ] = {"f", "i", sm6_parser_emit_dx_unary}, @@ -3850,6 +3881,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = [DX_RSQRT ] = {"g", "R", sm6_parser_emit_dx_unary}, [DX_SQRT ] = {"g", "R", sm6_parser_emit_dx_unary}, [DX_STORE_OUTPUT ] = {"v", "ii8o", sm6_parser_emit_dx_store_output}, + [DX_UBFE ] = {"m", "iiR", sm6_parser_emit_dx_tertiary}, [DX_UMAX ] = {"m", "RR", sm6_parser_emit_dx_binary}, [DX_UMIN ] = {"m", "RR", sm6_parser_emit_dx_binary}, };
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/spirv.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 2acf3b27b..9f0680f24 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -7415,7 +7415,7 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp const struct vkd3d_shader_dst_param *dst = instruction->dst; const struct vkd3d_shader_src_param *src = instruction->src; enum vkd3d_shader_component_type component_type; - unsigned int i, j, k, src_count; + unsigned int i, j, k, src_count, size; uint32_t write_mask; SpvOp op;
@@ -7424,8 +7424,9 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp
component_type = vkd3d_component_type_from_data_type(dst->reg.data_type); type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); - mask_id = spirv_compiler_get_constant_uint(compiler, 0x1f); - size_id = spirv_compiler_get_constant_uint(compiler, 0x20); + size = (src[src_count - 1].reg.data_type == VKD3D_DATA_UINT64) ? 0x40 : 0x20; + mask_id = spirv_compiler_get_constant_uint(compiler, size - 1); + size_id = spirv_compiler_get_constant_uint(compiler, size);
switch (instruction->handler_idx) {
The code looks fine, but isn't the word we should use here "ternary" rather than "tertiary"?
This merge request was approved by Giovanni Mascellani.
On Wed Jan 24 13:57:50 2024 +0000, Giovanni Mascellani wrote:
The code looks fine, but isn't the word we should use here "ternary" rather than "tertiary"?
Depends on whether we want to stick with DXC's function names. It emits them as `dx.op.tertiary`.
On Wed Jan 24 13:57:50 2024 +0000, Conor McCarthy wrote:
Depends on whether we want to stick with DXC's function names. It emits them as `dx.op.tertiary`.
Ah, funny. Well, it's not a big problem.
This doesn't apply cleanly.