From 1bb3b13c0a330fa1e2cec1a052477bb6045a31e0 Mon Sep 17 00:00:00 2001 From: Conor McCarthy Date: Fri, 19 Apr 2024 13:30:45 +1000 Subject: [PATCH] vkd3d-shader/dxil: Implement DX intrinsic EvalSampleIndex. --- libs/vkd3d-shader/dxil.c | 47 ++++++++++++++++++++++++++++++ tests/hlsl/eval-attrib.shader_test | 2 +- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 4493602d..bdfcb7c1 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -430,6 +430,7 @@ enum dx_intrinsic_opcode DX_DERIV_COARSEY = 84, DX_DERIV_FINEX = 85, DX_DERIV_FINEY = 86, + DX_EVAL_SAMPLE_INDEX = 88, DX_SAMPLE_INDEX = 90, DX_COVERAGE = 91, DX_THREAD_ID = 93, @@ -5098,6 +5099,51 @@ static void sm6_parser_emit_dx_dot(struct sm6_parser *sm6, enum dx_intrinsic_opc instruction_dst_param_init_ssa_scalar(ins, sm6); } +static void sm6_parser_emit_dx_eval_attrib(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; + const struct shader_signature *signature; + unsigned int row_index, column_index; + const struct signature_element *e; + + row_index = sm6_value_get_constant_uint(operands[0]); + column_index = sm6_value_get_constant_uint(operands[2]); + + signature = &sm6->p.program->input_signature; + if (row_index >= signature->element_count) + { + WARN("Invalid row index %u.\n", row_index); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Invalid input row index %u for an attribute evaluation.", row_index); + return; + } + + e = &signature->elements[row_index]; + if (column_index >= VKD3D_VEC4_SIZE || !(e->mask & (1 << column_index))) + { + WARN("Invalid column index %u.\n", column_index); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Invalid input column index %u for an attribute evaluation.", column_index); + return; + } + + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_EVAL_SAMPLE_INDEX); + + if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) + return; + + src_params[0].reg = sm6->input_params[row_index].reg; + src_param_init_scalar(&src_params[0], column_index); + if (e->register_count > 1) + register_index_address_init(&src_params[0].reg.idx[0], operands[1], sm6); + + src_param_init_from_value(&src_params[1], operands[3]); + + instruction_dst_param_init_ssa_scalar(ins, sm6); +} + static void sm6_parser_emit_dx_fabs(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state) { @@ -6288,6 +6334,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = [DX_DOT4 ] = {"g", "RRRRRRRR", sm6_parser_emit_dx_dot}, [DX_EMIT_STREAM ] = {"v", "c", sm6_parser_emit_dx_stream}, [DX_EMIT_THEN_CUT_STREAM ] = {"v", "c", sm6_parser_emit_dx_stream}, + [DX_EVAL_SAMPLE_INDEX ] = {"o", "cici", sm6_parser_emit_dx_eval_attrib}, [DX_EXP ] = {"g", "R", sm6_parser_emit_dx_unary}, [DX_FABS ] = {"g", "R", sm6_parser_emit_dx_fabs}, [DX_FIRST_BIT_HI ] = {"i", "m", sm6_parser_emit_dx_unary}, diff --git a/tests/hlsl/eval-attrib.shader_test b/tests/hlsl/eval-attrib.shader_test index ded4727a..460f6026 100644 --- a/tests/hlsl/eval-attrib.shader_test +++ b/tests/hlsl/eval-attrib.shader_test @@ -252,7 +252,7 @@ float4 main(float4 pos : SV_Position, float2 attr : ATTR, [test] clear rtv 0 1.0 1.0 1.0 1.0 -todo draw triangle list 3 +todo(sm<6) draw triangle list 3 probe ( 0, 0) rgba(0.25, 0.25, 0.25, 0.25) probe (639, 0) rgba(0.0, 0.0, 0.0, 0.0) probe ( 0, 479) rgba(0.25, 0.25, 0.25, 0.25)