-- v6: vkd3d-shader/dxil: Implement DX intrinsic SplitDouble. tests/shader-runner: Add an asuint() test to the 64-bit cast tests. tests/shader-runner: Support testing for integer pixel data.
From: Evan Tang etang@codeweavers.com
Modified by Conor McCarthy to use read_uint() and read_uint4(). --- tests/d3d12.c | 5 --- tests/d3d12_test_utils.h | 48 ----------------------- tests/shader_runner.c | 62 ++++++++++++++++++++++++------ tests/utils.h | 82 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 133 insertions(+), 64 deletions(-)
diff --git a/tests/d3d12.c b/tests/d3d12.c index 9a8532965..5172dd719 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -249,11 +249,6 @@ static uint64_t get_readback_uint64(struct resource_readback *rb, unsigned int x return *(uint64_t *)get_readback_data(rb, x, y, 0, sizeof(uint64_t)); }
-static const struct uvec4 *get_readback_uvec4(struct resource_readback *rb, unsigned int x, unsigned int y) -{ - return get_readback_data(rb, x, y, 0, sizeof(struct uvec4)); -} - #define check_sub_resource_float(a, b, c, d, e, f) check_sub_resource_float_(__LINE__, a, b, c, d, e, f) static void check_sub_resource_float_(unsigned int line, ID3D12Resource *resource, unsigned int sub_resource_idx, ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list, diff --git a/tests/d3d12_test_utils.h b/tests/d3d12_test_utils.h index 6de828d17..cf27b40f5 100644 --- a/tests/d3d12_test_utils.h +++ b/tests/d3d12_test_utils.h @@ -74,14 +74,6 @@ static void set_viewport(D3D12_VIEWPORT *vp, float x, float y, vp->MaxDepth = max_depth; }
-static bool compare_color(DWORD c1, DWORD c2, BYTE max_diff) -{ - return compare_uint(c1 & 0xff, c2 & 0xff, max_diff) - && compare_uint((c1 >> 8) & 0xff, (c2 >> 8) & 0xff, max_diff) - && compare_uint((c1 >> 16) & 0xff, (c2 >> 16) & 0xff, max_diff) - && compare_uint((c1 >> 24) & 0xff, (c2 >> 24) & 0xff, max_diff); -} - static D3D12_SHADER_BYTECODE shader_bytecode(const DWORD *code, size_t size) { D3D12_SHADER_BYTECODE shader_bytecode = { code, size }; @@ -526,12 +518,6 @@ static void get_resource_readback_with_command_list(ID3D12Resource *resource, un RESOURCE_STATE_DO_NOT_CHANGE, RESOURCE_STATE_DO_NOT_CHANGE); }
-static unsigned int get_readback_uint(struct resource_readback *rb, - unsigned int x, unsigned int y, unsigned int z) -{ - return *(unsigned int *)get_readback_data(rb, x, y, z, sizeof(unsigned int)); -} - static void release_resource_readback(struct d3d12_resource_readback *rb) { D3D12_RANGE range = {0, 0}; @@ -539,40 +525,6 @@ static void release_resource_readback(struct d3d12_resource_readback *rb) ID3D12Resource_Release(rb->resource); }
-#define check_readback_data_uint(a, b, c, d) check_readback_data_uint_(__LINE__, a, b, c, d) -static void check_readback_data_uint_(unsigned int line, struct resource_readback *rb, - const D3D12_BOX *box, unsigned int expected, unsigned int max_diff) -{ - D3D12_BOX b = {0, 0, 0, rb->width, rb->height, rb->depth}; - unsigned int x = 0, y = 0, z; - bool all_match = true; - unsigned int got = 0; - - if (box) - b = *box; - - for (z = b.front; z < b.back; ++z) - { - for (y = b.top; y < b.bottom; ++y) - { - for (x = b.left; x < b.right; ++x) - { - got = get_readback_uint(rb, x, y, z); - if (!compare_color(got, expected, max_diff)) - { - all_match = false; - break; - } - } - if (!all_match) - break; - } - if (!all_match) - break; - } - ok_(line)(all_match, "Got 0x%08x, expected 0x%08x at (%u, %u, %u).\n", got, expected, x, y, z); -} - #define check_sub_resource_uint(a, b, c, d, e, f) check_sub_resource_uint_(__LINE__, a, b, c, d, e, f) static inline void check_sub_resource_uint_(unsigned int line, ID3D12Resource *texture, unsigned int sub_resource_idx, ID3D12CommandQueue *queue, ID3D12GraphicsCommandList *command_list, diff --git a/tests/shader_runner.c b/tests/shader_runner.c index 6c5c1dba3..fe5ee5972 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -229,6 +229,17 @@ static bool match_directive_substring(const char *line, const char *token, const return match_string_generic(line, token, rest, true, false, 0); }
+static const char *close_parentheses(const char *line) +{ + while (isspace(*line)) + ++line; + + if (*line != ')') + fatal_error("Malformed probe arguments '%s'.\n", line); + + return line; +} + static void parse_require_directive(struct shader_runner *runner, const char *line) { bool less_than = false; @@ -564,7 +575,7 @@ static void read_int(const char **line, int *i) *line = rest; }
-static void read_uint(const char **line, unsigned int *u) +static void read_uint(const char **line, unsigned int *u, bool is_uniform) { char *rest; unsigned long val; @@ -572,14 +583,14 @@ static void read_uint(const char **line, unsigned int *u) errno = 0; val = strtoul(*line, &rest, 0);
- if (errno != 0 || (*rest != '\0' && !isspace((unsigned char)*rest))) + if (errno != 0 || (is_uniform && *rest != '\0' && !isspace((unsigned char)*rest))) fatal_error("Malformed uint constant '%s'.\n", *line);
*u = val; if (*u != val) fatal_error("Out of range uint constant '%.*s'.\n", (int)(rest - *line), *line);
- *line = rest; + *line = rest + (!is_uniform && *rest == ','); }
static void read_int4(const char **line, struct ivec4 *v) @@ -590,12 +601,12 @@ static void read_int4(const char **line, struct ivec4 *v) read_int(line, &v->w); }
-static void read_uint4(const char **line, struct uvec4 *v) +static void read_uint4(const char **line, struct uvec4 *v, bool is_uniform) { - read_uint(line, &v->x); - read_uint(line, &v->y); - read_uint(line, &v->z); - read_uint(line, &v->w); + read_uint(line, &v->x, is_uniform); + read_uint(line, &v->y, is_uniform); + read_uint(line, &v->z, is_uniform); + read_uint(line, &v->w, is_uniform); }
static void read_int64(const char **line, int64_t *i) @@ -825,7 +836,18 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) fatal_error("Malformed probe arguments '%s'.\n", line); }
- if (match_string(line, "rgba", &line)) + if (match_string(line, "rgbaui", &line)) + { + struct uvec4 v; + + if (*line != '(') + fatal_error("Malformed probe arguments '%s'.\n", line); + ++line; + read_uint4(&line, &v, false); + line = close_parentheses(line); + todo_if(runner->is_todo) check_readback_data_uvec4(rb, &rect, &v); + } + else if (match_string(line, "rgba", &line)) { struct vec4 v;
@@ -836,6 +858,24 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) ulps = 0; todo_if(runner->is_todo) check_readback_data_vec4(rb, &rect, &v, ulps); } + else if (match_string(line, "rui", &line)) + { + unsigned int expect; + D3D12_BOX box; + + box.left = rect.left; + box.right = rect.right; + box.top = rect.top; + box.bottom = rect.bottom; + box.front = 0; + box.back = 1; + if (*line != '(') + fatal_error("Malformed probe arguments '%s'.\n", line); + ++line; + read_uint(&line, &expect, false); + line = close_parentheses(line); + todo_if(runner->is_todo) check_readback_data_uint(rb, &box, expect, 0); + } else if (match_string(line, "r", &line)) { float expect; @@ -897,7 +937,7 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) { struct uvec4 v;
- read_uint4(&line, &v); + read_uint4(&line, &v, true); set_uniforms(runner, offset, 4, &v); } else if (match_string(line, "int", &line)) @@ -911,7 +951,7 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) { unsigned int u;
- read_uint(&line, &u); + read_uint(&line, &u, true); set_uniforms(runner, offset, 1, &u); } else if (match_string(line, "int64_t2", &line)) diff --git a/tests/utils.h b/tests/utils.h index e8bbacc37..98dceba84 100644 --- a/tests/utils.h +++ b/tests/utils.h @@ -104,6 +104,14 @@ static bool compare_uint(unsigned int x, unsigned int y, unsigned int max_diff) return diff <= max_diff; }
+static bool compare_color(DWORD c1, DWORD c2, BYTE max_diff) +{ + return compare_uint(c1 & 0xff, c2 & 0xff, max_diff) + && compare_uint((c1 >> 8) & 0xff, (c2 >> 8) & 0xff, max_diff) + && compare_uint((c1 >> 16) & 0xff, (c2 >> 16) & 0xff, max_diff) + && compare_uint((c1 >> 24) & 0xff, (c2 >> 24) & 0xff, max_diff); +} + static bool compare_float(float f, float g, unsigned int ulps) { int x, y; @@ -159,11 +167,21 @@ static float get_readback_float(const struct resource_readback *rb, unsigned int return *(float *)get_readback_data(rb, x, y, 0, sizeof(float)); }
+static unsigned int get_readback_uint(const struct resource_readback *rb, unsigned int x, unsigned int y, unsigned int z) +{ + return *(unsigned int*)get_readback_data(rb, x, y, z, sizeof(unsigned int)); +} + static const struct vec4 *get_readback_vec4(const struct resource_readback *rb, unsigned int x, unsigned int y) { return get_readback_data(rb, x, y, 0, sizeof(struct vec4)); }
+static const struct uvec4 *get_readback_uvec4(const struct resource_readback *rb, unsigned int x, unsigned int y) +{ + return get_readback_data(rb, x, y, 0, sizeof(struct uvec4)); +} + #define check_readback_data_float(a, b, c, d) check_readback_data_float_(__LINE__, a, b, c, d) static inline void check_readback_data_float_(unsigned int line, const struct resource_readback *rb, const RECT *rect, float expected, unsigned int max_diff) @@ -193,6 +211,40 @@ static inline void check_readback_data_float_(unsigned int line, const struct re ok_(line)(all_match, "Got %.8e, expected %.8e at (%u, %u).\n", got, expected, x, y); }
+#define check_readback_data_uint(a, b, c, d) check_readback_data_uint_(__LINE__, a, b, c, d) +static inline void check_readback_data_uint_(unsigned int line, struct resource_readback *rb, + const D3D12_BOX *box, unsigned int expected, unsigned int max_diff) +{ + D3D12_BOX b = {0, 0, 0, rb->width, rb->height, rb->depth}; + unsigned int x = 0, y = 0, z; + bool all_match = true; + unsigned int got = 0; + + if (box) + b = *box; + + for (z = b.front; z < b.back; ++z) + { + for (y = b.top; y < b.bottom; ++y) + { + for (x = b.left; x < b.right; ++x) + { + got = get_readback_uint(rb, x, y, z); + if (!compare_color(got, expected, max_diff)) + { + all_match = false; + break; + } + } + if (!all_match) + break; + } + if (!all_match) + break; + } + ok_(line)(all_match, "Got 0x%08x, expected 0x%08x at (%u, %u, %u).\n", got, expected, x, y, z); +} + #define check_readback_data_vec4(a, b, c, d) check_readback_data_vec4_(__LINE__, a, b, c, d) static inline void check_readback_data_vec4_(unsigned int line, const struct resource_readback *rb, const RECT *rect, const struct vec4 *expected, unsigned int max_diff) @@ -223,6 +275,36 @@ static inline void check_readback_data_vec4_(unsigned int line, const struct res got.x, got.y, got.z, got.w, expected->x, expected->y, expected->z, expected->w, x, y); }
+#define check_readback_data_uvec4(a, b, c) check_readback_data_uvec4_(__LINE__, a, b, c) +static inline void check_readback_data_uvec4_(unsigned int line, const struct resource_readback *rb, + const RECT *rect, const struct uvec4 *expected) +{ + RECT r = {0, 0, rb->width, rb->height}; + unsigned int x = 0, y = 0; + struct uvec4 got = {0}; + bool all_match = true; + + if (rect) + r = *rect; + + for (y = r.top; y < r.bottom; ++y) + { + for (x = r.left; x < r.right; ++x) + { + got = *get_readback_uvec4(rb, x, y); + if (!compare_uvec4(&got, expected)) + { + all_match = false; + break; + } + } + if (!all_match) + break; + } + ok_(line)(all_match, "Got {0x%08x, 0x%08x, 0x%08x, 0x%08x}, expected {0x%08x, 0x%08x, 0x%08x, 0x%08x} at (%u, %u).\n", + got.x, got.y, got.z, got.w, expected->x, expected->y, expected->z, expected->w, x, y); +} + struct test_options { bool use_warp_device;
From: Conor McCarthy cmccarthy@codeweavers.com
--- tests/hlsl/cast-64-bit.shader_test | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
diff --git a/tests/hlsl/cast-64-bit.shader_test b/tests/hlsl/cast-64-bit.shader_test index aa558ec9e..efdf92632 100644 --- a/tests/hlsl/cast-64-bit.shader_test +++ b/tests/hlsl/cast-64-bit.shader_test @@ -19,6 +19,23 @@ todo(sm<6) draw quad probe all rgba (-4.5, 8.5, 2.0, 2.0)
+[pixel shader todo] +uniform double2 d; + +uint4 main() : sv_target +{ + uint4 result; + asuint(d.x, result.x, result.y); + asuint(d.y, result.z, result.w); + return result; +} + +[test] +uniform 0 double2 -4.5 8.500003814697266 +todo draw quad +probe all rgbaui (0, 0xc0120000, 0x80000000, 0x40210000) + + [require] shader model >= 6.0 int64
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/dxil.c | 26 ++++++++++++++++++++++++++ tests/hlsl/cast-64-bit.shader_test | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 0358dbb6e..e315eabf2 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -367,6 +367,7 @@ enum dx_intrinsic_opcode DX_DERIV_COARSEY = 84, DX_DERIV_FINEX = 85, DX_DERIV_FINEY = 86, + DX_SPLIT_DOUBLE = 102, DX_LEGACY_F32TOF16 = 130, DX_LEGACY_F16TOF32 = 131, DX_RAW_BUFFER_LOAD = 139, @@ -1732,6 +1733,11 @@ static bool sm6_type_is_f16_f32(const struct sm6_type *type) return type->class == TYPE_CLASS_FLOAT && (type->u.width == 16 || type->u.width == 32); }
+static bool sm6_type_is_double(const struct sm6_type *type) +{ + return type->class == TYPE_CLASS_FLOAT && type->u.width == 64; +} + static inline bool sm6_type_is_floating_point(const struct sm6_type *type) { return type->class == TYPE_CLASS_FLOAT; @@ -3880,6 +3886,19 @@ static void sm6_parser_emit_dx_sincos(struct sm6_parser *sm6, enum dx_intrinsic_ dst->u.reg = dst_params[index].reg; }
+static void sm6_parser_emit_dx_split_double(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_param; + + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); + src_param = instruction_src_params_alloc(ins, 1, sm6); + src_param_init_from_value(src_param, operands[0]); + + instruction_dst_param_init_ssa_vector(ins, 2, sm6); +} + static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state) { @@ -3950,9 +3969,11 @@ struct sm6_dx_opcode_info i -> int32 m -> int16/32/64 f -> float + d -> double e -> half/float g -> half/float/double H -> handle + S -> splitdouble v -> void o -> overloaded R -> matches the return type @@ -3993,6 +4014,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = [DX_ROUND_Z ] = {"g", "R", sm6_parser_emit_dx_unary}, [DX_RSQRT ] = {"g", "R", sm6_parser_emit_dx_unary}, [DX_SIN ] = {"g", "R", sm6_parser_emit_dx_sincos}, + [DX_SPLIT_DOUBLE ] = {"S", "d", sm6_parser_emit_dx_split_double}, [DX_SQRT ] = {"g", "R", sm6_parser_emit_dx_unary}, [DX_STORE_OUTPUT ] = {"v", "ii8o", sm6_parser_emit_dx_store_output}, [DX_TAN ] = {"g", "R", sm6_parser_emit_dx_unary}, @@ -4029,12 +4051,16 @@ static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struc return sm6_type_is_i16_i32_i64(type); case 'f': return sm6_type_is_float(type); + case 'd': + return sm6_type_is_double(type); case 'e': return sm6_type_is_f16_f32(type); case 'g': return sm6_type_is_floating_point(type); case 'H': return (is_return || sm6_value_is_handle(value)) && type == sm6->handle_type; + case 'S': + return sm6_type_is_struct(type) && !strcmp(type->u.struc->name, "dx.types.splitdouble"); case 'v': return !type; case 'o': diff --git a/tests/hlsl/cast-64-bit.shader_test b/tests/hlsl/cast-64-bit.shader_test index efdf92632..1e33d8112 100644 --- a/tests/hlsl/cast-64-bit.shader_test +++ b/tests/hlsl/cast-64-bit.shader_test @@ -32,7 +32,7 @@ uint4 main() : sv_target
[test] uniform 0 double2 -4.5 8.500003814697266 -todo draw quad +todo(sm<6) draw quad probe all rgbaui (0, 0xc0120000, 0x80000000, 0x40210000)
This merge request was approved by Henri Verbeet.