From: Conor McCarthy cmccarthy@codeweavers.com
--- Makefile.am | 1 + tests/d3d12.c | 7 --- .../hlsl/uav-rwbyteaddressbuffer.shader_test | 25 ++++++++ tests/shader_runner.c | 11 ++++ tests/utils.h | 63 +++++++++++++++++++ 5 files changed, 100 insertions(+), 7 deletions(-) create mode 100644 tests/hlsl/uav-rwbyteaddressbuffer.shader_test
diff --git a/Makefile.am b/Makefile.am index cfb225f9c..bc7616fb2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -202,6 +202,7 @@ vkd3d_shader_tests = \ tests/hlsl/uav-load.shader_test \ tests/hlsl/uav-out-param.shader_test \ tests/hlsl/uav-rwbuffer.shader_test \ + tests/hlsl/uav-rwbyteaddressbuffer.shader_test \ tests/hlsl/uav-rwstructuredbuffer.shader_test \ tests/hlsl/uav-rwtexture.shader_test \ tests/hlsl/uniform-parameters.shader_test \ diff --git a/tests/d3d12.c b/tests/d3d12.c index d7933ed63..611edf1d3 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -52,13 +52,6 @@ static bool compare_uint16(uint16_t a, uint16_t b, unsigned int max_diff) return abs(a - b) <= max_diff; }
-static bool compare_uint64(uint64_t a, uint64_t b, unsigned int max_diff) -{ - uint64_t diff = a > b ? a - b : b - a; - - return diff <= max_diff; -} - static ULONG get_refcount(void *iface) { IUnknown *unk = iface; diff --git a/tests/hlsl/uav-rwbyteaddressbuffer.shader_test b/tests/hlsl/uav-rwbyteaddressbuffer.shader_test new file mode 100644 index 000000000..723c0eb54 --- /dev/null +++ b/tests/hlsl/uav-rwbyteaddressbuffer.shader_test @@ -0,0 +1,25 @@ +[require] +shader model >= 5.0 + +[uav 1] +format r32 float +size (buffer, 4) + +0.1 0.2 0.3 0.4 + +[pixel shader todo] +RWByteAddressBuffer u : register(u1); + +float4 main() : sv_target +{ + u.Store(0, 11); + u.Store(4, 11.1); + u.Store<double>(8, 12.2); + return 0; +} + +[test] +todo draw quad +probe uav 1 (0) ri (11) +probe uav 1 (1) r (11.1) +probe uav 1 (1) rd (12.2) diff --git a/tests/shader_runner.c b/tests/shader_runner.c index d0d806508..3a1174868 100644 --- a/tests/shader_runner.c +++ b/tests/shader_runner.c @@ -951,6 +951,17 @@ static void parse_test_directive(struct shader_runner *runner, const char *line) line = close_parentheses(line); todo_if(runner->is_todo) check_readback_data_uint(rb, &box, expect, 0); } + else if (match_string(line, "rd", &line)) + { + double expect; + + ret = sscanf(line, "( %lf ) %u", &expect, &ulps); + if (ret < 1) + fatal_error("Malformed probe arguments '%s'.\n", line); + if (ret < 2) + ulps = 0; + todo_if(runner->is_todo) check_readback_data_double(rb, &rect, expect, ulps); + } else if (match_string(line, "r", &line)) { float expect; diff --git a/tests/utils.h b/tests/utils.h index cd5215fe5..ab7c8b53b 100644 --- a/tests/utils.h +++ b/tests/utils.h @@ -104,6 +104,13 @@ static bool compare_uint(unsigned int x, unsigned int y, unsigned int max_diff) return diff <= max_diff; }
+static bool compare_uint64(uint64_t x, uint64_t y, uint64_t max_diff) +{ + uint64_t diff = x > y ? x - y : y - x; + + return diff <= max_diff; +} + static bool compare_color(DWORD c1, DWORD c2, BYTE max_diff) { return compare_uint(c1 & 0xff, c2 & 0xff, max_diff) @@ -134,6 +141,28 @@ static bool compare_float(float f, float g, unsigned int ulps) return compare_uint(x, y, ulps); }
+static bool compare_double(double f, double g, unsigned int ulps) +{ + int64_t x, y; + union + { + double f; + int64_t i; + } u; + + u.f = f; + x = u.i; + u.f = g; + y = u.i; + + if (x < 0) + x = INT64_MIN - x; + if (y < 0) + y = INT64_MIN - y; + + return compare_uint64(x, y, ulps); +} + static inline bool compare_uvec4(const struct uvec4 *v1, const struct uvec4 *v2) { return v1->x == v2->x && v1->y == v2->y && v1->z == v2->z && v1->w == v2->w; @@ -167,6 +196,11 @@ static float get_readback_float(const struct resource_readback *rb, unsigned int return *(float *)get_readback_data(rb, x, y, 0, sizeof(float)); }
+static double get_readback_double(const struct resource_readback *rb, unsigned int x, unsigned int y) +{ + return *(double *)get_readback_data(rb, x, y, 0, sizeof(double)); +} + 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)); @@ -211,6 +245,35 @@ 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_double(a, b, c, d) check_readback_data_double_(__LINE__, a, b, c, d) +static inline void check_readback_data_double_(unsigned int line, const struct resource_readback *rb, + const RECT *rect, double expected, unsigned int max_diff) +{ + RECT r = {0, 0, rb->width, rb->height}; + unsigned int x = 0, y; + bool all_match = true; + double got = 0; + + if (rect) + r = *rect; + + for (y = r.top; y < r.bottom; ++y) + { + for (x = r.left; x < r.right; ++x) + { + got = get_readback_double(rb, x, y); + if (!compare_double(got, expected, max_diff)) + { + all_match = false; + break; + } + } + if (!all_match) + break; + } + ok_(line)(all_match, "Got %.15le, expected %.15le 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)
From: Conor McCarthy cmccarthy@codeweavers.com
There is no way to tell in spirv_compiler_emit_load_reg() if the write mask is 64-bit. All loads are 32-bit except for IMMCONST64 and SSA, and the latter ignores the mask, so the only issue lies in spirv_compiler_emit_load_constant64(). This is only a DXIL workaround and needs a more general solution. --- libs/vkd3d-shader/spirv.c | 8 ++++---- tests/hlsl/uav-rwbyteaddressbuffer.shader_test | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index a3baeea75..b60bb9ce6 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -3766,16 +3766,15 @@ static uint32_t spirv_compiler_emit_load_constant(struct spirv_compiler *compile static uint32_t spirv_compiler_emit_load_constant64(struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg, uint32_t swizzle, uint32_t write_mask) { - unsigned int component_count = vsir_write_mask_component_count(write_mask); uint64_t values[VKD3D_DVEC2_SIZE] = {0}; - unsigned int i, j; + unsigned int i, j, component_count;
assert(reg->type == VKD3DSPR_IMMCONST64);
if (reg->dimension == VSIR_DIMENSION_SCALAR) { - for (i = 0; i < component_count; ++i) - values[i] = *reg->u.immconst_u64; + values[0] = reg->u.immconst_u64[0]; + component_count = 1; } else { @@ -3784,6 +3783,7 @@ static uint32_t spirv_compiler_emit_load_constant64(struct spirv_compiler *compi if (write_mask & (VKD3DSP_WRITEMASK_0 << i)) values[j++] = reg->u.immconst_u64[vsir_swizzle_get_component(swizzle, i)]; } + component_count = vsir_write_mask_component_count(write_mask); }
return spirv_compiler_get_constant64(compiler, diff --git a/tests/hlsl/uav-rwbyteaddressbuffer.shader_test b/tests/hlsl/uav-rwbyteaddressbuffer.shader_test index 723c0eb54..8b103fe98 100644 --- a/tests/hlsl/uav-rwbyteaddressbuffer.shader_test +++ b/tests/hlsl/uav-rwbyteaddressbuffer.shader_test @@ -19,7 +19,7 @@ float4 main() : sv_target }
[test] -todo draw quad +todo(sm<6) draw quad probe uav 1 (0) ri (11) probe uav 1 (1) r (11.1) probe uav 1 (1) rd (12.2)