[PATCH v2 0/2] MR587: vkd3d-shader/dxil: Implement DX intrinsic Tertiary.
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. https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/587
From: Conor McCarthy <cmccarthy(a)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}, }; -- GitLab https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/587
From: Conor McCarthy <cmccarthy(a)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) { -- GitLab https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/587
The code looks fine, but isn't the word we should use here "ternary" rather than "tertiary"? -- https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/587#note_58787
This merge request was approved by Giovanni Mascellani. -- https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/587
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`.
-- https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/587#note_58840
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.
-- https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/587#note_58841
This doesn't apply cleanly. -- https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/587#note_58995
participants (4)
-
Conor McCarthy -
Conor McCarthy (@cmccarthy) -
Giovanni Mascellani (@giomasce) -
Henri Verbeet (@hverbeet)