Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
January 2022
- 86 participants
- 2418 messages
[PATCH 1/5] secur32: Add support for setting DTLS timeouts.
by Connor McAdams
Add support for setting the DTLS timeout values, and set the
retransmission timeout value to 0 to allow for retransmission on each
call to schan_InitializeSecurityContext.
Signed-off-by: Connor McAdams <cmcadams(a)codeweavers.com>
---
dlls/secur32/schannel.c | 6 ++++++
dlls/secur32/schannel_gnutls.c | 22 ++++++++++++++++++++++
dlls/secur32/secur32_priv.h | 8 ++++++++
3 files changed, 36 insertions(+)
diff --git a/dlls/secur32/schannel.c b/dlls/secur32/schannel.c
index 141a191c7c6..f1b47a78d21 100644
--- a/dlls/secur32/schannel.c
+++ b/dlls/secur32/schannel.c
@@ -808,6 +808,12 @@ static SECURITY_STATUS SEC_ENTRY schan_InitializeSecurityContextW(
else WARN("invalid buffer size %u\n", buffer->cbBuffer);
}
+ if (is_dtls_context(ctx))
+ {
+ struct set_dtls_timeouts_params params = { ctx->transport.session, 0, 60000 };
+ GNUTLS_CALL( set_dtls_timeouts, ¶ms );
+ }
+
phNewContext->dwLower = handle;
phNewContext->dwUpper = 0;
}
diff --git a/dlls/secur32/schannel_gnutls.c b/dlls/secur32/schannel_gnutls.c
index 31fdb769677..ac51cbb5d9f 100644
--- a/dlls/secur32/schannel_gnutls.c
+++ b/dlls/secur32/schannel_gnutls.c
@@ -60,6 +60,7 @@ static int (*pgnutls_cipher_get_block_size)(gnutls_cipher_algorithm_t);
static void (*pgnutls_transport_set_pull_timeout_function)(gnutls_session_t,
int (*)(gnutls_transport_ptr_t, unsigned int));
static void (*pgnutls_dtls_set_mtu)(gnutls_session_t, unsigned int);
+static void (*pgnutls_dtls_set_timeouts)(gnutls_session_t, unsigned int, unsigned int);
/* Not present in gnutls version < 3.2.0. */
static int (*pgnutls_alpn_get_selected_protocol)(gnutls_session_t, gnutls_datum_t *);
@@ -198,6 +199,12 @@ static void compat_gnutls_dtls_set_mtu(gnutls_session_t session, unsigned int mt
FIXME("\n");
}
+static void compat_gnutls_dtls_set_timeouts(gnutls_session_t session, unsigned int retrans_timeout,
+ unsigned int total_timeout)
+{
+ FIXME("\n");
+}
+
static void init_schan_buffers(struct schan_buffers *s, const PSecBufferDesc desc,
int (*get_next_buffer)(const struct schan_transport *, struct schan_buffers *))
{
@@ -989,6 +996,15 @@ static NTSTATUS schan_set_dtls_mtu( void *args )
return SEC_E_OK;
}
+static NTSTATUS schan_set_dtls_timeouts( void *args )
+{
+ const struct set_dtls_timeouts_params *params = args;
+ gnutls_session_t s = (gnutls_session_t)params->session;
+
+ pgnutls_dtls_set_timeouts(s, params->retrans_timeout, params->total_timeout);
+ return SEC_E_OK;
+}
+
static inline void reverse_bytes(BYTE *buf, ULONG len)
{
BYTE tmp;
@@ -1245,6 +1261,11 @@ static NTSTATUS process_attach( void *args )
WARN("gnutls_dtls_set_mtu not found\n");
pgnutls_dtls_set_mtu = compat_gnutls_dtls_set_mtu;
}
+ if (!(pgnutls_dtls_set_timeouts = dlsym(libgnutls_handle, "gnutls_dtls_set_timeouts")))
+ {
+ WARN("gnutls_dtls_set_timeouts not found\n");
+ pgnutls_dtls_set_timeouts = compat_gnutls_dtls_set_timeouts;
+ }
if (!(pgnutls_privkey_export_x509 = dlsym(libgnutls_handle, "gnutls_privkey_export_x509")))
{
WARN("gnutls_privkey_export_x509 not found\n");
@@ -1308,6 +1329,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
schan_set_application_protocols,
schan_set_dtls_mtu,
schan_set_session_target,
+ schan_set_dtls_timeouts,
};
#endif /* SONAME_LIBGNUTLS */
diff --git a/dlls/secur32/secur32_priv.h b/dlls/secur32/secur32_priv.h
index c17adc96dc6..64edc0581d6 100644
--- a/dlls/secur32/secur32_priv.h
+++ b/dlls/secur32/secur32_priv.h
@@ -203,6 +203,13 @@ struct set_session_target_params
const char *target;
};
+struct set_dtls_timeouts_params
+{
+ schan_session session;
+ unsigned int retrans_timeout;
+ unsigned int total_timeout;
+};
+
enum schan_funcs
{
unix_process_attach,
@@ -225,6 +232,7 @@ enum schan_funcs
unix_set_application_protocols,
unix_set_dtls_mtu,
unix_set_session_target,
+ unix_set_dtls_timeouts,
};
#endif /* __SECUR32_PRIV_H__ */
--
2.25.1
Jan. 27, 2022
[PATCH vkd3d v3 8/8] tests: Add a D3D11 shader runner backend.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
Makefile.am | 1 +
tests/d3d12.c | 5 -
tests/d3d12_test_utils.h | 33 --
tests/shader_runner.c | 7 +-
tests/shader_runner.h | 4 +
tests/shader_runner_d3d11.c | 639 ++++++++++++++++++++++++++++++++++++
tests/utils.h | 39 +++
7 files changed, 689 insertions(+), 39 deletions(-)
create mode 100644 tests/shader_runner_d3d11.c
diff --git a/Makefile.am b/Makefile.am
index 5d996560f..82807a428 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -395,6 +395,7 @@ EXTRA_DIST += $(cross_implibs:=.cross32.def) $(cross_implibs:=.cross64.def)
shader_runner_cross_sources = \
$(srcdir)/tests/shader_runner.c \
+ $(srcdir)/tests/shader_runner_d3d11.c \
$(srcdir)/tests/shader_runner_d3d12.c
if HAVE_CROSSTARGET32
diff --git a/tests/d3d12.c b/tests/d3d12.c
index 82f353a72..eb6217bc9 100644
--- a/tests/d3d12.c
+++ b/tests/d3d12.c
@@ -26,11 +26,6 @@
static PFN_D3D12_CREATE_VERSIONED_ROOT_SIGNATURE_DESERIALIZER pfn_D3D12CreateVersionedRootSignatureDeserializer;
static PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE pfn_D3D12SerializeVersionedRootSignature;
-struct vec2
-{
- float x, y;
-};
-
struct uvec4
{
unsigned int x, y, z, w;
diff --git a/tests/d3d12_test_utils.h b/tests/d3d12_test_utils.h
index bab0c9ce2..7186a73e7 100644
--- a/tests/d3d12_test_utils.h
+++ b/tests/d3d12_test_utils.h
@@ -82,31 +82,6 @@ static void set_viewport(D3D12_VIEWPORT *vp, float x, float y,
vp->MaxDepth = max_depth;
}
-static bool compare_float(float f, float g, unsigned int ulps)
-{
- int x, y;
- union
- {
- float f;
- int i;
- } u;
-
- u.f = f;
- x = u.i;
- u.f = g;
- y = u.i;
-
- if (x < 0)
- x = INT_MIN - x;
- if (y < 0)
- y = INT_MIN - y;
-
- if (abs(x - y) > ulps)
- return false;
-
- return true;
-}
-
static bool compare_uint(unsigned int x, unsigned int y, unsigned int max_diff)
{
unsigned int diff = x > y ? x - y : y - x;
@@ -122,14 +97,6 @@ static bool compare_color(DWORD c1, DWORD c2, BYTE max_diff)
&& compare_uint((c1 >> 24) & 0xff, (c2 >> 24) & 0xff, max_diff);
}
-static bool compare_vec4(const struct vec4 *v1, const struct vec4 *v2, unsigned int ulps)
-{
- return compare_float(v1->x, v2->x, ulps)
- && compare_float(v1->y, v2->y, ulps)
- && compare_float(v1->z, v2->z, ulps)
- && compare_float(v1->w, v2->w, ulps);
-}
-
static D3D12_SHADER_BYTECODE shader_bytecode(const DWORD *code, size_t size)
{
D3D12_SHADER_BYTECODE shader_bytecode = { code, size };
diff --git a/tests/shader_runner.c b/tests/shader_runner.c
index ae5daa70b..5af4628eb 100644
--- a/tests/shader_runner.c
+++ b/tests/shader_runner.c
@@ -278,7 +278,7 @@ static void parse_texture_directive(struct texture_params *texture, const char *
static void set_uniforms(struct shader_context *context, size_t offset, size_t count, const void *uniforms)
{
- context->uniform_count = max(context->uniform_count, offset + count);
+ context->uniform_count = align(max(context->uniform_count, offset + count), 4);
vkd3d_array_reserve((void **)&context->uniforms, &context->uniform_capacity,
context->uniform_count, sizeof(*context->uniforms));
memcpy(context->uniforms + offset, uniforms, count * sizeof(*context->uniforms));
@@ -680,9 +680,14 @@ void run_shader_tests(struct shader_context *context, int argc, char **argv, con
free(context->textures);
fclose(f);
+
+ vkd3d_test_set_context(NULL);
}
START_TEST(shader_runner)
{
+#ifdef _WIN32
+ run_shader_tests_d3d11(argc, argv);
+#endif
run_shader_tests_d3d12(argc, argv);
}
diff --git a/tests/shader_runner.h b/tests/shader_runner.h
index 9a687edbc..245ef358f 100644
--- a/tests/shader_runner.h
+++ b/tests/shader_runner.h
@@ -16,6 +16,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include <stdint.h>
#include "vkd3d_windows.h"
#include "vkd3d_d3dcommon.h"
#include "vkd3d_d3d12.h"
@@ -89,4 +90,7 @@ struct shader_runner_ops
void run_shader_tests(struct shader_context *context, int argc, char **argv, const struct shader_runner_ops *ops);
+#ifdef _WIN32
+void run_shader_tests_d3d11(int argc, char **argv);
+#endif
void run_shader_tests_d3d12(int argc, char **argv);
diff --git a/tests/shader_runner_d3d11.c b/tests/shader_runner_d3d11.c
new file mode 100644
index 000000000..d77a4b246
--- /dev/null
+++ b/tests/shader_runner_d3d11.c
@@ -0,0 +1,639 @@
+/*
+ * Copyright 2008 Henri Verbeet for CodeWeavers
+ * Copyright 2015 Józef Kucia for CodeWeavers
+ * Copyright 2021 Zebediah Figura for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define COBJMACROS
+#define CONST_VTABLE
+#define VKD3D_TEST_NO_DEFS
+#include <d3d11_4.h>
+#define __vkd3d_d3dcommon_h__
+#define __vkd3d_dxgibase_h__
+#define __vkd3d_dxgiformat_h__
+#include "vkd3d_d3dcompiler.h"
+#include "shader_runner.h"
+#include "vkd3d_test.h"
+
+const GUID IID_IDXGIDevice = {0x54ec77fa, 0x1377, 0x44e6, {0x8c, 0x32, 0x88, 0xfd, 0x5f, 0x44, 0xc8, 0x4c}};
+
+static HRESULT (WINAPI *pCreateDXGIFactory1)(REFIID iid, void **factory);
+
+static HRESULT (WINAPI *pD3D11CreateDevice)(IDXGIAdapter *adapter, D3D_DRIVER_TYPE driver_type,
+ HMODULE swrast, UINT flags, const D3D_FEATURE_LEVEL *feature_levels, UINT levels,
+ UINT sdk_version, ID3D11Device **device_out, D3D_FEATURE_LEVEL *obtained_feature_level,
+ ID3D11DeviceContext **immediate_context);
+
+struct d3d11_texture
+{
+ struct texture t;
+
+ ID3D11Texture2D *texture;
+ ID3D11ShaderResourceView *srv;
+};
+
+static struct d3d11_texture *d3d11_texture(struct texture *t)
+{
+ return CONTAINING_RECORD(t, struct d3d11_texture, t);
+}
+
+struct d3d11_shader_context
+{
+ struct shader_context c;
+
+ ID3D11Device *device;
+ HWND window;
+ IDXGISwapChain *swapchain;
+ ID3D11Texture2D *rt;
+ ID3D11RenderTargetView *rtv;
+ ID3D11DeviceContext *immediate_context;
+
+ ID3D11InputLayout *input_layout;
+ ID3D11VertexShader *vs;
+ ID3D11Buffer *vb;
+};
+
+static struct d3d11_shader_context *d3d11_shader_context(struct shader_context *c)
+{
+ return CONTAINING_RECORD(c, struct d3d11_shader_context, c);
+}
+
+static bool enable_debug_layer;
+static bool use_warp_adapter;
+static unsigned int use_adapter_idx;
+
+static ID3D10Blob *compile_shader(const char *source, const char *profile)
+{
+ ID3D10Blob *blob = NULL, *errors = NULL;
+ HRESULT hr;
+
+ hr = D3DCompile(source, strlen(source), NULL, NULL, NULL, "main", profile, 0, 0, &blob, &errors);
+ ok(hr == S_OK, "Failed to compile shader, hr %#lx.\n", hr);
+ if (errors)
+ {
+ if (vkd3d_test_state.debug_level)
+ trace("%s\n", (char *)ID3D10Blob_GetBufferPointer(errors));
+ ID3D10Blob_Release(errors);
+ }
+ return blob;
+}
+
+static void parse_args(int argc, char **argv)
+{
+ unsigned int i;
+
+ for (i = 1; i < argc; ++i)
+ {
+ if (!strcmp(argv[i], "--warp"))
+ use_warp_adapter = true;
+ else if (!strcmp(argv[i], "--adapter") && i + 1 < argc)
+ use_adapter_idx = atoi(argv[++i]);
+ }
+}
+
+static void enable_d3d11_debug_layer(int argc, char **argv)
+{
+ unsigned int i;
+
+ for (i = 1; i < argc; ++i)
+ {
+ if (!strcmp(argv[i], "--validate"))
+ enable_debug_layer = true;
+ }
+}
+
+static IDXGIAdapter *create_adapter(void)
+{
+ IDXGIFactory4 *factory4;
+ IDXGIFactory *factory;
+ IDXGIAdapter *adapter;
+ HRESULT hr;
+
+ if (!pCreateDXGIFactory1)
+ {
+ trace("CreateDXGIFactory1() is not available.\n");
+ return NULL;
+ }
+
+ if (FAILED(hr = pCreateDXGIFactory1(&IID_IDXGIFactory, (void **)&factory)))
+ {
+ trace("Failed to create IDXGIFactory, hr %#lx.\n", hr);
+ return NULL;
+ }
+
+ adapter = NULL;
+ if (use_warp_adapter)
+ {
+ if (SUCCEEDED(hr = IDXGIFactory_QueryInterface(factory, &IID_IDXGIFactory4, (void **)&factory4)))
+ {
+ hr = IDXGIFactory4_EnumWarpAdapter(factory4, &IID_IDXGIAdapter, (void **)&adapter);
+ IDXGIFactory4_Release(factory4);
+ }
+ else
+ {
+ trace("Failed to get IDXGIFactory4, hr %#lx.\n", hr);
+ }
+ }
+ else
+ {
+ hr = IDXGIFactory_EnumAdapters(factory, use_adapter_idx, &adapter);
+ }
+ IDXGIFactory_Release(factory);
+ if (FAILED(hr))
+ trace("Failed to get adapter, hr %#lx.\n", hr);
+ return adapter;
+}
+
+static void init_adapter_info(void)
+{
+ char name[MEMBER_SIZE(DXGI_ADAPTER_DESC, Description)];
+ IDXGIAdapter *adapter;
+ DXGI_ADAPTER_DESC desc;
+ unsigned int i;
+ HRESULT hr;
+
+ if (!(adapter = create_adapter()))
+ return;
+
+ hr = IDXGIAdapter_GetDesc(adapter, &desc);
+ ok(hr == S_OK, "Failed to get adapter desc, hr %#lx.\n", hr);
+
+ /* FIXME: Use debugstr_w(). */
+ for (i = 0; i < ARRAY_SIZE(desc.Description) && isprint(desc.Description[i]); ++i)
+ name[i] = desc.Description[i];
+ name[min(i, ARRAY_SIZE(name) - 1)] = '\0';
+
+ trace("Adapter: %s, %04x:%04x.\n", name, desc.VendorId, desc.DeviceId);
+
+ if (desc.VendorId == 0x1414 && desc.DeviceId == 0x008c)
+ {
+ trace("Using WARP device.\n");
+ use_warp_adapter = true;
+ }
+
+ IDXGIAdapter_Release(adapter);
+}
+
+static ID3D11Device *create_device(void)
+{
+ static const D3D_FEATURE_LEVEL feature_level[] =
+ {
+ D3D_FEATURE_LEVEL_11_0,
+ D3D_FEATURE_LEVEL_10_1,
+ D3D_FEATURE_LEVEL_10_0,
+ };
+ IDXGIAdapter *adapter;
+ ID3D11Device *device;
+ UINT flags = 0;
+ HRESULT hr;
+
+ if (enable_debug_layer)
+ flags |= D3D11_CREATE_DEVICE_DEBUG;
+
+ if ((adapter = create_adapter()))
+ {
+ hr = pD3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, flags,
+ feature_level, ARRAY_SIZE(feature_level), D3D11_SDK_VERSION, &device, NULL, NULL);
+ IDXGIAdapter_Release(adapter);
+ return SUCCEEDED(hr) ? device : NULL;
+ }
+
+ if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, flags,
+ feature_level, ARRAY_SIZE(feature_level), D3D11_SDK_VERSION, &device, NULL, NULL)))
+ return device;
+ if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_WARP, NULL, flags,
+ feature_level, ARRAY_SIZE(feature_level), D3D11_SDK_VERSION, &device, NULL, NULL)))
+ return device;
+ if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, flags,
+ feature_level, ARRAY_SIZE(feature_level), D3D11_SDK_VERSION, &device, NULL, NULL)))
+ return device;
+
+ return NULL;
+}
+
+static IDXGISwapChain *create_swapchain(ID3D11Device *device, HWND window)
+{
+ DXGI_SWAP_CHAIN_DESC dxgi_desc;
+ IDXGISwapChain *swapchain;
+ IDXGIDevice *dxgi_device;
+ IDXGIAdapter *adapter;
+ IDXGIFactory *factory;
+ HRESULT hr;
+
+ hr = ID3D11Device_QueryInterface(device, &IID_IDXGIDevice, (void **)&dxgi_device);
+ ok(hr == S_OK, "Failed to get DXGI device, hr %#lx.\n", hr);
+ hr = IDXGIDevice_GetAdapter(dxgi_device, &adapter);
+ ok(hr == S_OK, "Failed to get adapter, hr %#lx.\n", hr);
+ IDXGIDevice_Release(dxgi_device);
+ hr = IDXGIAdapter_GetParent(adapter, &IID_IDXGIFactory, (void **)&factory);
+ ok(hr == S_OK, "Failed to get factory, hr %#lx.\n", hr);
+ IDXGIAdapter_Release(adapter);
+
+ dxgi_desc.BufferDesc.Width = 640;
+ dxgi_desc.BufferDesc.Height = 480;
+ dxgi_desc.BufferDesc.RefreshRate.Numerator = 60;
+ dxgi_desc.BufferDesc.RefreshRate.Denominator = 1;
+ dxgi_desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+ dxgi_desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
+ dxgi_desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
+ dxgi_desc.SampleDesc.Count = 1;
+ dxgi_desc.SampleDesc.Quality = 0;
+ dxgi_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+ dxgi_desc.BufferCount = 1;
+ dxgi_desc.OutputWindow = window;
+ dxgi_desc.Windowed = TRUE;
+ dxgi_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
+ dxgi_desc.Flags = 0;
+
+ hr = IDXGIFactory_CreateSwapChain(factory, (IUnknown *)device, &dxgi_desc, &swapchain);
+ ok(hr == S_OK, "Failed to create swapchain, hr %#lx.\n", hr);
+ IDXGIFactory_Release(factory);
+
+ return swapchain;
+}
+
+static BOOL init_test_context(struct d3d11_shader_context *context)
+{
+ const D3D11_TEXTURE2D_DESC texture_desc =
+ {
+ .Width = 640,
+ .Height = 480,
+ .MipLevels = 1,
+ .ArraySize = 1,
+ .Format = DXGI_FORMAT_R32G32B32A32_FLOAT,
+ .SampleDesc.Count = 1,
+ .Usage = D3D11_USAGE_DEFAULT,
+ .BindFlags = D3D11_BIND_RENDER_TARGET,
+ };
+ unsigned int rt_width, rt_height;
+ D3D11_VIEWPORT vp;
+ HRESULT hr;
+ RECT rect;
+
+ memset(context, 0, sizeof(*context));
+
+ if (!(context->device = create_device()))
+ {
+ skip("Failed to create device.\n");
+ return FALSE;
+ }
+
+ rt_width = 640;
+ rt_height = 480;
+ SetRect(&rect, 0, 0, rt_width, rt_height);
+ AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
+ context->window = CreateWindowA("static", "d3dcompiler_test", WS_OVERLAPPEDWINDOW,
+ 0, 0, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, NULL, NULL);
+ context->swapchain = create_swapchain(context->device, context->window);
+
+ hr = ID3D11Device_CreateTexture2D(context->device, &texture_desc, NULL, &context->rt);
+ ok(hr == S_OK, "Failed to create texture, hr %#lx.\n", hr);
+
+ hr = ID3D11Device_CreateRenderTargetView(context->device, (ID3D11Resource *)context->rt, NULL, &context->rtv);
+ ok(hr == S_OK, "Failed to create rendertarget view, hr %#lx.\n", hr);
+
+ ID3D11Device_GetImmediateContext(context->device, &context->immediate_context);
+
+ ID3D11DeviceContext_OMSetRenderTargets(context->immediate_context, 1, &context->rtv, NULL);
+
+ vp.TopLeftX = 0.0f;
+ vp.TopLeftY = 0.0f;
+ vp.Width = rt_width;
+ vp.Height = rt_height;
+ vp.MinDepth = 0.0f;
+ vp.MaxDepth = 1.0f;
+ ID3D11DeviceContext_RSSetViewports(context->immediate_context, 1, &vp);
+
+ return TRUE;
+}
+
+static void destroy_test_context(struct d3d11_shader_context *context)
+{
+ ULONG ref;
+
+ if (context->input_layout)
+ ID3D11InputLayout_Release(context->input_layout);
+ if (context->vs)
+ ID3D11VertexShader_Release(context->vs);
+ if (context->vb)
+ ID3D11Buffer_Release(context->vb);
+
+ ID3D11DeviceContext_Release(context->immediate_context);
+ ID3D11RenderTargetView_Release(context->rtv);
+ ID3D11Texture2D_Release(context->rt);
+ IDXGISwapChain_Release(context->swapchain);
+ DestroyWindow(context->window);
+
+ ref = ID3D11Device_Release(context->device);
+ ok(!ref, "Device has %lu references left.\n", ref);
+}
+
+static ID3D11Buffer *create_buffer(ID3D11Device *device, unsigned int bind_flags, unsigned int size, const void *data)
+{
+ D3D11_SUBRESOURCE_DATA resource_data;
+ D3D11_BUFFER_DESC buffer_desc;
+ ID3D11Buffer *buffer;
+ HRESULT hr;
+
+ buffer_desc.ByteWidth = size;
+ buffer_desc.Usage = D3D11_USAGE_DEFAULT;
+ buffer_desc.BindFlags = bind_flags;
+ buffer_desc.CPUAccessFlags = 0;
+ buffer_desc.MiscFlags = 0;
+ buffer_desc.StructureByteStride = 0;
+
+ resource_data.pSysMem = data;
+ resource_data.SysMemPitch = 0;
+ resource_data.SysMemSlicePitch = 0;
+
+ hr = ID3D11Device_CreateBuffer(device, &buffer_desc, data ? &resource_data : NULL, &buffer);
+ ok(hr == S_OK, "Failed to create buffer, hr %#lx.\n", hr);
+ return buffer;
+}
+
+static struct texture *d3d11_runner_create_texture(struct shader_context *c, const struct texture_params *params)
+{
+ struct d3d11_shader_context *context = d3d11_shader_context(c);
+ ID3D11Device *device = context->device;
+ D3D11_SUBRESOURCE_DATA resource_data;
+ D3D11_TEXTURE2D_DESC desc = {0};
+ struct d3d11_texture *texture;
+ HRESULT hr;
+
+ texture = calloc(1, sizeof(*texture));
+
+ texture->t.slot = params->slot;
+
+ desc.Width = params->width;
+ desc.Height = params->height;
+ desc.MipLevels = 1;
+ desc.ArraySize = 1;
+ desc.Format = params->format;
+ desc.SampleDesc.Count = 1;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
+
+ resource_data.pSysMem = params->data;
+ resource_data.SysMemPitch = params->width * params->texel_size;
+ resource_data.SysMemSlicePitch = params->height * resource_data.SysMemPitch;
+
+ hr = ID3D11Device_CreateTexture2D(device, &desc, &resource_data, &texture->texture);
+ ok(hr == S_OK, "Failed to create texture, hr %#lx.\n", hr);
+ hr = ID3D11Device_CreateShaderResourceView(device,
+ (ID3D11Resource *)texture->texture, NULL, &texture->srv);
+ ok(hr == S_OK, "Failed to create shader resource view, hr %#lx.\n", hr);
+
+ return &texture->t;
+}
+
+static void d3d11_runner_destroy_texture(struct shader_context *c, struct texture *t)
+{
+ struct d3d11_texture *texture = d3d11_texture(t);
+
+ ID3D11Texture2D_Release(texture->texture);
+ ID3D11ShaderResourceView_Release(texture->srv);
+ free(texture);
+}
+
+static void d3d11_runner_draw_quad(struct shader_context *c)
+{
+ static const D3D11_INPUT_ELEMENT_DESC default_layout_desc[] =
+ {
+ {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
+ };
+
+ static const char vs_source[] =
+ "float4 main(float4 position : POSITION) : sv_position\n"
+ "{\n"
+ " return position;\n"
+ "}";
+
+ static const struct vec2 quad[] =
+ {
+ {-1.0f, -1.0f},
+ {-1.0f, 1.0f},
+ { 1.0f, -1.0f},
+ { 1.0f, 1.0f},
+ };
+
+ struct d3d11_shader_context *context = d3d11_shader_context(c);
+ ID3D11Device *device = context->device;
+ unsigned int stride, offset;
+ ID3D11Buffer *cb = NULL;
+ ID3D11PixelShader *ps;
+ ID3D10Blob *ps_code;
+ unsigned int i;
+ HRESULT hr;
+
+ static const char *const ps_profiles[] =
+ {
+ [SHADER_MODEL_4_0] = "ps_4_0",
+ [SHADER_MODEL_4_1] = "ps_4_1",
+ [SHADER_MODEL_5_0] = "ps_5_0",
+ [SHADER_MODEL_5_1] = "ps_5_1",
+ };
+
+ if (!(ps_code = compile_shader(context->c.ps_source, ps_profiles[context->c.minimum_shader_model])))
+ return;
+
+ if (!context->input_layout || !context->vs)
+ {
+ ID3D10Blob *vs_code = compile_shader(vs_source, "vs_4_0");
+
+ if (!context->input_layout)
+ {
+ hr = ID3D11Device_CreateInputLayout(device, default_layout_desc, ARRAY_SIZE(default_layout_desc),
+ ID3D10Blob_GetBufferPointer(vs_code), ID3D10Blob_GetBufferSize(vs_code), &context->input_layout);
+ ok(hr == S_OK, "Failed to create input layout, hr %#lx.\n", hr);
+ }
+
+ if (!context->vs)
+ {
+ hr = ID3D11Device_CreateVertexShader(device, ID3D10Blob_GetBufferPointer(vs_code),
+ ID3D10Blob_GetBufferSize(vs_code), NULL, &context->vs);
+ ok(hr == S_OK, "Failed to create vertex shader, hr %#lx.\n", hr);
+ }
+
+ ID3D10Blob_Release(vs_code);
+ }
+
+ if (!context->vb)
+ context->vb = create_buffer(device, D3D11_BIND_VERTEX_BUFFER, sizeof(quad), quad);
+
+ hr = ID3D11Device_CreatePixelShader(device, ID3D10Blob_GetBufferPointer(ps_code),
+ ID3D10Blob_GetBufferSize(ps_code), NULL, &ps);
+ ok(hr == S_OK, "Failed to create pixel shader, hr %#lx.\n", hr);
+
+ if (context->c.uniform_count)
+ {
+ cb = create_buffer(device, D3D11_BIND_CONSTANT_BUFFER,
+ context->c.uniform_count * sizeof(*context->c.uniforms), context->c.uniforms);
+ ID3D11DeviceContext_PSSetConstantBuffers(context->immediate_context, 0, 1, &cb);
+ }
+
+ for (i = 0; i < context->c.texture_count; ++i)
+ {
+ struct d3d11_texture *texture = d3d11_texture(context->c.textures[i]);
+
+ ID3D11DeviceContext_PSSetShaderResources(context->immediate_context, texture->t.slot, 1, &texture->srv);
+ }
+
+ for (i = 0; i < context->c.sampler_count; ++i)
+ {
+ struct sampler *sampler = &context->c.samplers[i];
+ ID3D11SamplerState *d3d11_sampler;
+ D3D11_SAMPLER_DESC desc = {0};
+
+ /* Members of D3D11_FILTER are compatible with D3D12_FILTER. */
+ desc.Filter = (D3D11_FILTER)sampler->filter;
+ /* Members of D3D11_TEXTURE_ADDRESS_MODE are compatible with D3D12_TEXTURE_ADDRESS_MODE. */
+ desc.AddressU = (D3D11_TEXTURE_ADDRESS_MODE)sampler->u_address;
+ desc.AddressV = (D3D11_TEXTURE_ADDRESS_MODE)sampler->v_address;
+ desc.AddressW = (D3D11_TEXTURE_ADDRESS_MODE)sampler->w_address;
+ desc.ComparisonFunc = D3D11_COMPARISON_NEVER;
+ desc.MaxLOD = D3D11_FLOAT32_MAX;
+
+ hr = ID3D11Device_CreateSamplerState(device, &desc, &d3d11_sampler);
+ ok(hr == S_OK, "Failed to create sampler state, hr %#lx.\n", hr);
+ ID3D11DeviceContext_PSSetSamplers(context->immediate_context, sampler->slot, 1, &d3d11_sampler);
+ ID3D11SamplerState_Release(d3d11_sampler);
+ }
+
+ ID3D11DeviceContext_IASetInputLayout(context->immediate_context, context->input_layout);
+ ID3D11DeviceContext_IASetPrimitiveTopology(context->immediate_context, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
+ stride = sizeof(*quad);
+ offset = 0;
+ ID3D11DeviceContext_IASetVertexBuffers(context->immediate_context, 0, 1, &context->vb, &stride, &offset);
+ ID3D11DeviceContext_VSSetShader(context->immediate_context, context->vs, NULL, 0);
+ ID3D11DeviceContext_PSSetShader(context->immediate_context, ps, NULL, 0);
+
+ ID3D11DeviceContext_Draw(context->immediate_context, 4, 0);
+
+ ID3D11PixelShader_Release(ps);
+ if (cb)
+ ID3D11Buffer_Release(cb);
+}
+
+struct resource_readback
+{
+ uint64_t width;
+ unsigned int height;
+ ID3D11Resource *resource;
+ D3D11_MAPPED_SUBRESOURCE map_desc;
+};
+
+static void init_readback(struct d3d11_shader_context *context, struct resource_readback *rb)
+{
+ D3D11_TEXTURE2D_DESC texture_desc;
+ HRESULT hr;
+
+ ID3D11Texture2D_GetDesc(context->rt, &texture_desc);
+ texture_desc.Usage = D3D11_USAGE_STAGING;
+ texture_desc.BindFlags = 0;
+ texture_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+ texture_desc.MiscFlags = 0;
+ hr = ID3D11Device_CreateTexture2D(context->device, &texture_desc, NULL, (ID3D11Texture2D **)&rb->resource);
+ ok(hr == S_OK, "Failed to create texture, hr %#lx.\n", hr);
+
+ ID3D11DeviceContext_CopyResource(context->immediate_context, rb->resource, (ID3D11Resource *)context->rt);
+ hr = ID3D11DeviceContext_Map(context->immediate_context, rb->resource, 0, D3D11_MAP_READ, 0, &rb->map_desc);
+ ok(hr == S_OK, "Failed to map texture, hr %#lx.\n", hr);
+
+ rb->width = texture_desc.Width;
+ rb->height = texture_desc.Height;
+}
+
+static void release_readback(struct d3d11_shader_context *context, struct resource_readback *rb)
+{
+ ID3D11DeviceContext_Unmap(context->immediate_context, rb->resource, 0);
+ ID3D11Resource_Release(rb->resource);
+}
+
+static const struct vec4 *get_readback_vec4(struct resource_readback *rb, unsigned int x, unsigned int y)
+{
+ return (struct vec4 *)((BYTE *)rb->map_desc.pData + y * rb->map_desc.RowPitch) + x;
+}
+
+static void check_readback_data_vec4(struct resource_readback *rb,
+ const RECT *rect, const struct vec4 *expected, unsigned int max_diff)
+{
+ RECT r = {0, 0, rb->width, rb->height};
+ unsigned int x = 0, y = 0;
+ struct vec4 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_vec4(rb, x, y);
+ if (!compare_vec4(&got, expected, max_diff))
+ {
+ all_match = false;
+ break;
+ }
+ }
+ if (!all_match)
+ break;
+ }
+ ok(all_match, "Got {%.8e, %.8e, %.8e, %.8e}, expected {%.8e, %.8e, %.8e, %.8e} at (%u, %u).\n",
+ got.x, got.y, got.z, got.w, expected->x, expected->y, expected->z, expected->w, x, y);
+}
+
+static void d3d11_runner_probe_vec4(struct shader_context *c, const RECT *rect, const struct vec4 *v, unsigned int ulps)
+{
+ struct d3d11_shader_context *context = d3d11_shader_context(c);
+ struct resource_readback rb;
+
+ init_readback(context, &rb);
+ check_readback_data_vec4(&rb, rect, v, ulps);
+ release_readback(context, &rb);
+}
+
+static const struct shader_runner_ops d3d11_runner_ops =
+{
+ .create_texture = d3d11_runner_create_texture,
+ .destroy_texture = d3d11_runner_destroy_texture,
+ .draw_quad = d3d11_runner_draw_quad,
+ .probe_vec4 = d3d11_runner_probe_vec4,
+};
+
+void run_shader_tests_d3d11(int argc, char **argv)
+{
+ HMODULE dxgi_module, d3d11_module;
+ struct d3d11_shader_context context;
+
+ d3d11_module = LoadLibraryA("d3d11.dll");
+ dxgi_module = LoadLibraryA("dxgi.dll");
+ if (d3d11_module && dxgi_module)
+ {
+ pCreateDXGIFactory1 = (void *)GetProcAddress(dxgi_module, "CreateDXGIFactory1");
+ pD3D11CreateDevice = (void *)GetProcAddress(d3d11_module, "D3D11CreateDevice");
+
+ parse_args(argc, argv);
+ enable_d3d11_debug_layer(argc, argv);
+ init_adapter_info();
+ init_test_context(&context);
+ run_shader_tests(&context.c, argc, argv, &d3d11_runner_ops);
+ destroy_test_context(&context);
+ }
+ FreeLibrary(d3d11_module);
+ FreeLibrary(dxgi_module);
+}
diff --git a/tests/utils.h b/tests/utils.h
index 825520c27..530a3cee7 100644
--- a/tests/utils.h
+++ b/tests/utils.h
@@ -19,9 +19,15 @@
#ifndef __VKD3D_TEST_UTILS_H
#define __VKD3D_TEST_UTILS_H
+#include <limits.h>
#include <stdbool.h>
#include <stdlib.h>
+struct vec2
+{
+ float x, y;
+};
+
struct vec4
{
float x, y, z, w;
@@ -55,4 +61,37 @@ static inline bool vkd3d_array_reserve(void **elements, size_t *capacity, size_t
return true;
}
+static bool compare_float(float f, float g, unsigned int ulps)
+{
+ int x, y;
+ union
+ {
+ float f;
+ int i;
+ } u;
+
+ u.f = f;
+ x = u.i;
+ u.f = g;
+ y = u.i;
+
+ if (x < 0)
+ x = INT_MIN - x;
+ if (y < 0)
+ y = INT_MIN - y;
+
+ if (abs(x - y) > ulps)
+ return false;
+
+ return true;
+}
+
+static inline bool compare_vec4(const struct vec4 *v1, const struct vec4 *v2, unsigned int ulps)
+{
+ return compare_float(v1->x, v2->x, ulps)
+ && compare_float(v1->y, v2->y, ulps)
+ && compare_float(v1->z, v2->z, ulps)
+ && compare_float(v1->w, v2->w, ulps);
+}
+
#endif
--
2.34.1
Jan. 27, 2022
[PATCH vkd3d v3 7/8] tests: Add a helper to set uniforms.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
tests/shader_runner.c | 36 ++++++++++++------------------------
tests/shader_runner.h | 2 +-
2 files changed, 13 insertions(+), 25 deletions(-)
diff --git a/tests/shader_runner.c b/tests/shader_runner.c
index 12fdad308..ae5daa70b 100644
--- a/tests/shader_runner.c
+++ b/tests/shader_runner.c
@@ -276,6 +276,14 @@ static void parse_texture_directive(struct texture_params *texture, const char *
}
}
+static void set_uniforms(struct shader_context *context, size_t offset, size_t count, const void *uniforms)
+{
+ context->uniform_count = max(context->uniform_count, offset + count);
+ vkd3d_array_reserve((void **)&context->uniforms, &context->uniform_capacity,
+ context->uniform_count, sizeof(*context->uniforms));
+ memcpy(context->uniforms + offset, uniforms, count * sizeof(*context->uniforms));
+}
+
static void parse_test_directive(struct shader_context *context, const char *line)
{
if (match_string(line, "draw quad", &line))
@@ -350,12 +358,7 @@ static void parse_test_directive(struct shader_context *context, const char *lin
if (sscanf(line, "%f %f %f %f", &v.x, &v.y, &v.z, &v.w) < 4)
fatal_error("Malformed float4 constant '%s'.\n", line);
- if (offset + 4 > context->uniform_count)
- {
- context->uniform_count = offset + 4;
- context->uniforms = realloc(context->uniforms, context->uniform_count * sizeof(*context->uniforms));
- }
- memcpy(context->uniforms + offset, &v, sizeof(v));
+ set_uniforms(context, offset, 4, &v);
}
else if (match_string(line, "float", &line))
{
@@ -363,12 +366,7 @@ static void parse_test_directive(struct shader_context *context, const char *lin
if (sscanf(line, "%f", &f) < 1)
fatal_error("Malformed float constant '%s'.\n", line);
- if (offset + 1 > context->uniform_count)
- {
- context->uniform_count = offset + 1;
- context->uniforms = realloc(context->uniforms, context->uniform_count * sizeof(*context->uniforms));
- }
- memcpy(context->uniforms + offset, &f, sizeof(f));
+ set_uniforms(context, offset, 1, &f);
}
else if (match_string(line, "int", &line))
{
@@ -376,12 +374,7 @@ static void parse_test_directive(struct shader_context *context, const char *lin
if (sscanf(line, "%i", &i) < 1)
fatal_error("Malformed int constant '%s'.\n", line);
- if (offset + 1 > context->uniform_count)
- {
- context->uniform_count = offset + 1;
- context->uniforms = realloc(context->uniforms, context->uniform_count * sizeof(*context->uniforms));
- }
- memcpy(context->uniforms + offset, &i, sizeof(i));
+ set_uniforms(context, offset, 1, &i);
}
else if (match_string(line, "uint", &line))
{
@@ -389,12 +382,7 @@ static void parse_test_directive(struct shader_context *context, const char *lin
if (sscanf(line, "%u", &u) < 1)
fatal_error("Malformed uint constant '%s'.\n", line);
- if (offset + 1 > context->uniform_count)
- {
- context->uniform_count = offset + 1;
- context->uniforms = realloc(context->uniforms, context->uniform_count * sizeof(*context->uniforms));
- }
- memcpy(context->uniforms + offset, &u, sizeof(u));
+ set_uniforms(context, offset, 1, &u);
}
}
else
diff --git a/tests/shader_runner.h b/tests/shader_runner.h
index 6865d4d05..9a687edbc 100644
--- a/tests/shader_runner.h
+++ b/tests/shader_runner.h
@@ -70,7 +70,7 @@ struct shader_context
enum shader_model minimum_shader_model;
uint32_t *uniforms;
- size_t uniform_count;
+ size_t uniform_count, uniform_capacity;
struct texture **textures;
size_t texture_count;
--
2.34.1
Jan. 27, 2022
[PATCH vkd3d v3 6/8] tests: Pass HLSL source to the draw_quad() function.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
tests/shader_runner.c | 14 +++++---------
tests/shader_runner.h | 3 +--
tests/shader_runner_d3d12.c | 14 +++++++++-----
3 files changed, 15 insertions(+), 16 deletions(-)
diff --git a/tests/shader_runner.c b/tests/shader_runner.c
index aabae5ae0..12fdad308 100644
--- a/tests/shader_runner.c
+++ b/tests/shader_runner.c
@@ -495,10 +495,11 @@ void run_shader_tests(struct shader_context *context, int argc, char **argv, con
break;
case STATE_SHADER_PIXEL:
- if (!(context->ps_code = context->ops->compile_shader(context,
- shader_source, context->minimum_shader_model)))
- return;
+ free(context->ps_source);
+ context->ps_source = shader_source;
+ shader_source = NULL;
shader_source_len = 0;
+ shader_source_size = 0;
break;
case STATE_SHADER_INVALID_PIXEL:
@@ -590,10 +591,6 @@ void run_shader_tests(struct shader_context *context, int argc, char **argv, con
else if (!strcmp(line, "[pixel shader]\n"))
{
state = STATE_SHADER_PIXEL;
-
- if (context->ps_code)
- ID3D10Blob_Release(context->ps_code);
- context->ps_code = NULL;
}
else if (!strcmp(line, "[pixel shader fail]\n"))
{
@@ -686,8 +683,7 @@ void run_shader_tests(struct shader_context *context, int argc, char **argv, con
}
}
- if (context->ps_code)
- ID3D10Blob_Release(context->ps_code);
+ free(context->ps_source);
for (i = 0; i < context->texture_count; ++i)
{
if (context->textures[i])
diff --git a/tests/shader_runner.h b/tests/shader_runner.h
index 2e6d3606f..6865d4d05 100644
--- a/tests/shader_runner.h
+++ b/tests/shader_runner.h
@@ -66,7 +66,7 @@ struct shader_context
{
const struct shader_runner_ops *ops;
- ID3D10Blob *ps_code;
+ char *ps_source;
enum shader_model minimum_shader_model;
uint32_t *uniforms;
@@ -81,7 +81,6 @@ struct shader_context
struct shader_runner_ops
{
- ID3D10Blob *(*compile_shader)(struct shader_context *context, const char *source, enum shader_model minimum_shader_model);
struct texture *(*create_texture)(struct shader_context *context, const struct texture_params *params);
void (*destroy_texture)(struct shader_context *context, struct texture *texture);
void (*draw_quad)(struct shader_context *context);
diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c
index f79c53be4..3b415ec76 100644
--- a/tests/shader_runner_d3d12.c
+++ b/tests/shader_runner_d3d12.c
@@ -51,8 +51,7 @@ static struct d3d12_shader_context *d3d12_shader_context(struct shader_context *
return CONTAINING_RECORD(c, struct d3d12_shader_context, c);
}
-static ID3D10Blob *d3d12_runner_compile_shader(struct shader_context *c,
- const char *source, enum shader_model shader_model)
+static ID3D10Blob *compile_shader(const char *source, enum shader_model shader_model)
{
ID3D10Blob *blob = NULL, *errors = NULL;
HRESULT hr;
@@ -118,8 +117,6 @@ static void d3d12_runner_draw_quad(struct shader_context *c)
struct d3d12_shader_context *context = d3d12_shader_context(c);
struct test_context *test_context = &context->test_context;
- D3D12_SHADER_BYTECODE ps
- = {ID3D10Blob_GetBufferPointer(context->c.ps_code), ID3D10Blob_GetBufferSize(context->c.ps_code)};
ID3D12GraphicsCommandList *command_list = test_context->list;
D3D12_ROOT_SIGNATURE_DESC root_signature_desc = {0};
D3D12_ROOT_PARAMETER root_params[3], *root_param;
@@ -128,10 +125,15 @@ static void d3d12_runner_draw_quad(struct shader_context *c)
ID3D12Device *device = test_context->device;
static const float clear_color[4];
unsigned int uniform_index;
+ D3D12_SHADER_BYTECODE ps;
ID3D12PipelineState *pso;
+ ID3D10Blob *ps_code;
HRESULT hr;
size_t i;
+ if (!(ps_code = compile_shader(context->c.ps_source, context->c.minimum_shader_model)))
+ return;
+
root_signature_desc.NumParameters = 0;
root_signature_desc.pParameters = root_params;
root_signature_desc.NumStaticSamplers = 0;
@@ -191,8 +193,11 @@ static void d3d12_runner_draw_quad(struct shader_context *c)
hr = create_root_signature(device, &root_signature_desc, &test_context->root_signature);
ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
+ ps.pShaderBytecode = ID3D10Blob_GetBufferPointer(ps_code);
+ ps.BytecodeLength = ID3D10Blob_GetBufferSize(ps_code);
pso = create_pipeline_state(device, test_context->root_signature,
test_context->render_target_desc.Format, NULL, &ps, NULL);
+ ID3D10Blob_Release(ps_code);
if (!pso)
return;
vkd3d_array_reserve((void **)&test_context->pso, &test_context->pso_capacity,
@@ -245,7 +250,6 @@ static void d3d12_runner_probe_vec4(struct shader_context *c,
static const struct shader_runner_ops d3d12_runner_ops =
{
- .compile_shader = d3d12_runner_compile_shader,
.create_texture = d3d12_runner_create_texture,
.destroy_texture = d3d12_runner_destroy_texture,
.draw_quad = d3d12_runner_draw_quad,
--
2.34.1
Jan. 27, 2022
[PATCH vkd3d v3 5/8] tests: Move d3d12-specific members of struct texture to a new d3d12_texture structure.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
tests/shader_runner.h | 5 -----
tests/shader_runner_d3d12.c | 31 ++++++++++++++++++++++++-------
2 files changed, 24 insertions(+), 12 deletions(-)
diff --git a/tests/shader_runner.h b/tests/shader_runner.h
index c541b56e8..2e6d3606f 100644
--- a/tests/shader_runner.h
+++ b/tests/shader_runner.h
@@ -60,11 +60,6 @@ struct texture_params
struct texture
{
unsigned int slot;
-
- D3D12_DESCRIPTOR_RANGE descriptor_range;
- ID3D12DescriptorHeap *heap;
- ID3D12Resource *resource;
- unsigned int root_index;
};
struct shader_context
diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c
index 94399aea6..f79c53be4 100644
--- a/tests/shader_runner_d3d12.c
+++ b/tests/shader_runner_d3d12.c
@@ -24,6 +24,21 @@
#include "d3d12_crosstest.h"
#include "shader_runner.h"
+struct d3d12_texture
+{
+ struct texture t;
+
+ D3D12_DESCRIPTOR_RANGE descriptor_range;
+ ID3D12DescriptorHeap *heap;
+ ID3D12Resource *resource;
+ unsigned int root_index;
+};
+
+static struct d3d12_texture *d3d12_texture(struct texture *t)
+{
+ return CONTAINING_RECORD(t, struct d3d12_texture, t);
+}
+
struct d3d12_shader_context
{
struct shader_context c;
@@ -68,11 +83,11 @@ static struct texture *d3d12_runner_create_texture(struct shader_context *c, con
struct test_context *test_context = &context->test_context;
ID3D12Device *device = test_context->device;
D3D12_SUBRESOURCE_DATA resource_data;
- struct texture *texture;
+ struct d3d12_texture *texture;
texture = calloc(1, sizeof(*texture));
- texture->slot = params->slot;
+ texture->t.slot = params->slot;
texture->heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
texture->resource = create_default_texture(device, params->width, params->height,
@@ -86,11 +101,13 @@ static struct texture *d3d12_runner_create_texture(struct shader_context *c, con
ID3D12Device_CreateShaderResourceView(device, texture->resource,
NULL, get_cpu_descriptor_handle(test_context, texture->heap, 0));
- return texture;
+ return &texture->t;
}
-static void d3d12_runner_destroy_texture(struct shader_context *c, struct texture *texture)
+static void d3d12_runner_destroy_texture(struct shader_context *c, struct texture *t)
{
+ struct d3d12_texture *texture = d3d12_texture(t);
+
ID3D12DescriptorHeap_Release(texture->heap);
ID3D12Resource_Release(texture->resource);
free(texture);
@@ -133,7 +150,7 @@ static void d3d12_runner_draw_quad(struct shader_context *c)
for (i = 0; i < context->c.texture_count; ++i)
{
- struct texture *texture = context->c.textures[i];
+ struct d3d12_texture *texture = d3d12_texture(context->c.textures[i]);
D3D12_DESCRIPTOR_RANGE *range;
range = &texture->descriptor_range;
@@ -147,7 +164,7 @@ static void d3d12_runner_draw_quad(struct shader_context *c)
range->RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
range->NumDescriptors = 1;
- range->BaseShaderRegister = texture->slot;
+ range->BaseShaderRegister = texture->t.slot;
range->RegisterSpace = 0;
range->OffsetInDescriptorsFromTableStart = 0;
}
@@ -188,7 +205,7 @@ static void d3d12_runner_draw_quad(struct shader_context *c)
context->c.uniform_count, context->c.uniforms, 0);
for (i = 0; i < context->c.texture_count; ++i)
{
- struct texture *texture = context->c.textures[i];
+ struct d3d12_texture *texture = d3d12_texture(context->c.textures[i]);
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, texture->root_index,
get_gpu_descriptor_handle(test_context, texture->heap, 0));
--
2.34.1
Jan. 27, 2022
[PATCH vkd3d v3 4/8] tests: Make texture allocation and destruction into separate shader_runner ops.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
tests/shader_runner.c | 60 ++++++++++++++++------------------
tests/shader_runner.h | 11 +++++--
tests/shader_runner_d3d12.c | 65 ++++++++++++++++++++++---------------
3 files changed, 75 insertions(+), 61 deletions(-)
diff --git a/tests/shader_runner.c b/tests/shader_runner.c
index 74b70890f..aabae5ae0 100644
--- a/tests/shader_runner.c
+++ b/tests/shader_runner.c
@@ -71,12 +71,6 @@ static void VKD3D_NORETURN VKD3D_PRINTF_FUNC(1, 2) fatal_error(const char *forma
exit(1);
}
-static void free_texture(struct texture *texture)
-{
- free(texture->data);
- memset(texture, 0, sizeof(*texture));
-}
-
enum parse_state
{
STATE_NONE,
@@ -135,7 +129,7 @@ static void parse_require_directive(struct shader_context *context, const char *
}
}
-static void parse_texture_format(struct texture *texture, const char *line)
+static void parse_texture_format(struct texture_params *texture, const char *line)
{
static const struct
{
@@ -228,7 +222,7 @@ static void parse_sampler_directive(struct sampler *sampler, const char *line)
}
}
-static void parse_texture_directive(struct texture *texture, const char *line)
+static void parse_texture_directive(struct texture_params *texture, const char *line)
{
int ret;
@@ -425,26 +419,29 @@ static struct sampler *get_sampler(struct shader_context *context, unsigned int
return NULL;
}
-static struct texture *get_texture(struct shader_context *context, unsigned int slot)
+static void set_texture(struct shader_context *context, struct texture *texture)
{
- struct texture *texture;
size_t i;
for (i = 0; i < context->texture_count; ++i)
{
- texture = &context->textures[i];
- if (texture->slot == slot)
- return texture;
+ if (context->textures[i]->slot == texture->slot)
+ {
+ context->ops->destroy_texture(context, context->textures[i]);
+ context->textures[i] = texture;
+ return;
+ }
}
- return NULL;
+ context->textures = realloc(context->textures, (context->texture_count + 1) * sizeof(*context->textures));
+ context->textures[context->texture_count++] = texture;
}
void run_shader_tests(struct shader_context *context, int argc, char **argv, const struct shader_runner_ops *ops)
{
size_t shader_source_size = 0, shader_source_len = 0;
struct sampler *current_sampler = NULL;
- struct texture *current_texture = NULL;
+ struct texture_params current_texture;
enum parse_state state = STATE_NONE;
unsigned int i, line_number = 0;
const char *filename = NULL;
@@ -490,7 +487,11 @@ void run_shader_tests(struct shader_context *context, int argc, char **argv, con
case STATE_REQUIRE:
case STATE_SAMPLER:
case STATE_TEST:
+ break;
+
case STATE_TEXTURE:
+ set_texture(context, context->ops->create_texture(context, ¤t_texture));
+ free(current_texture.data);
break;
case STATE_SHADER_PIXEL:
@@ -623,21 +624,12 @@ void run_shader_tests(struct shader_context *context, int argc, char **argv, con
{
state = STATE_TEXTURE;
- if ((current_texture = get_texture(context, index)))
- {
- free_texture(current_texture);
- }
- else
- {
- context->textures = realloc(context->textures,
- ++context->texture_count * sizeof(*context->textures));
- current_texture = &context->textures[context->texture_count - 1];
- memset(current_texture, 0, sizeof(*current_texture));
- }
- current_texture->slot = index;
- current_texture->format = DXGI_FORMAT_R32G32B32A32_FLOAT;
- current_texture->data_type = TEXTURE_DATA_FLOAT;
- current_texture->texel_size = 16;
+ memset(¤t_texture, 0, sizeof(current_texture));
+
+ current_texture.slot = index;
+ current_texture.format = DXGI_FORMAT_R32G32B32A32_FLOAT;
+ current_texture.data_type = TEXTURE_DATA_FLOAT;
+ current_texture.texel_size = 16;
}
else if (!strcmp(line, "[test]\n"))
{
@@ -684,7 +676,7 @@ void run_shader_tests(struct shader_context *context, int argc, char **argv, con
break;
case STATE_TEXTURE:
- parse_texture_directive(current_texture, line);
+ parse_texture_directive(¤t_texture, line);
break;
case STATE_TEST:
@@ -697,7 +689,11 @@ void run_shader_tests(struct shader_context *context, int argc, char **argv, con
if (context->ps_code)
ID3D10Blob_Release(context->ps_code);
for (i = 0; i < context->texture_count; ++i)
- free_texture(&context->textures[i]);
+ {
+ if (context->textures[i])
+ context->ops->destroy_texture(context, context->textures[i]);
+ }
+ free(context->textures);
fclose(f);
}
diff --git a/tests/shader_runner.h b/tests/shader_runner.h
index e9001eeda..c541b56e8 100644
--- a/tests/shader_runner.h
+++ b/tests/shader_runner.h
@@ -45,7 +45,7 @@ struct sampler
D3D12_TEXTURE_ADDRESS_MODE u_address, v_address, w_address;
};
-struct texture
+struct texture_params
{
unsigned int slot;
@@ -55,6 +55,11 @@ struct texture
unsigned int width, height;
uint8_t *data;
size_t data_size, data_capacity;
+};
+
+struct texture
+{
+ unsigned int slot;
D3D12_DESCRIPTOR_RANGE descriptor_range;
ID3D12DescriptorHeap *heap;
@@ -72,7 +77,7 @@ struct shader_context
uint32_t *uniforms;
size_t uniform_count;
- struct texture *textures;
+ struct texture **textures;
size_t texture_count;
struct sampler *samplers;
@@ -82,6 +87,8 @@ struct shader_context
struct shader_runner_ops
{
ID3D10Blob *(*compile_shader)(struct shader_context *context, const char *source, enum shader_model minimum_shader_model);
+ struct texture *(*create_texture)(struct shader_context *context, const struct texture_params *params);
+ void (*destroy_texture)(struct shader_context *context, struct texture *texture);
void (*draw_quad)(struct shader_context *context);
void (*probe_vec4)(struct shader_context *context, const RECT *rect, const struct vec4 *v, unsigned int ulps);
};
diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c
index bb0288e83..94399aea6 100644
--- a/tests/shader_runner_d3d12.c
+++ b/tests/shader_runner_d3d12.c
@@ -62,6 +62,40 @@ static ID3D10Blob *d3d12_runner_compile_shader(struct shader_context *c,
return blob;
}
+static struct texture *d3d12_runner_create_texture(struct shader_context *c, const struct texture_params *params)
+{
+ struct d3d12_shader_context *context = d3d12_shader_context(c);
+ struct test_context *test_context = &context->test_context;
+ ID3D12Device *device = test_context->device;
+ D3D12_SUBRESOURCE_DATA resource_data;
+ struct texture *texture;
+
+ texture = calloc(1, sizeof(*texture));
+
+ texture->slot = params->slot;
+
+ texture->heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
+ texture->resource = create_default_texture(device, params->width, params->height,
+ params->format, 0, D3D12_RESOURCE_STATE_COPY_DEST);
+ resource_data.pData = params->data;
+ resource_data.SlicePitch = resource_data.RowPitch = params->width * params->texel_size;
+ upload_texture_data(texture->resource, &resource_data, 1, test_context->queue, test_context->list);
+ reset_command_list(test_context->list, test_context->allocator);
+ transition_resource_state(test_context->list, texture->resource, D3D12_RESOURCE_STATE_COPY_DEST,
+ D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
+ ID3D12Device_CreateShaderResourceView(device, texture->resource,
+ NULL, get_cpu_descriptor_handle(test_context, texture->heap, 0));
+
+ return texture;
+}
+
+static void d3d12_runner_destroy_texture(struct shader_context *c, struct texture *texture)
+{
+ ID3D12DescriptorHeap_Release(texture->heap);
+ ID3D12Resource_Release(texture->resource);
+ free(texture);
+}
+
static void d3d12_runner_draw_quad(struct shader_context *c)
{
struct d3d12_shader_context *context = d3d12_shader_context(c);
@@ -99,10 +133,8 @@ static void d3d12_runner_draw_quad(struct shader_context *c)
for (i = 0; i < context->c.texture_count; ++i)
{
- struct texture *texture = &context->c.textures[i];
- D3D12_SUBRESOURCE_DATA resource_data;
+ struct texture *texture = context->c.textures[i];
D3D12_DESCRIPTOR_RANGE *range;
- ID3D12Resource *resource;
range = &texture->descriptor_range;
@@ -118,20 +150,6 @@ static void d3d12_runner_draw_quad(struct shader_context *c)
range->BaseShaderRegister = texture->slot;
range->RegisterSpace = 0;
range->OffsetInDescriptorsFromTableStart = 0;
-
- texture->heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
- resource = create_default_texture(device, texture->width, texture->height,
- texture->format, 0, D3D12_RESOURCE_STATE_COPY_DEST);
- resource_data.pData = texture->data;
- resource_data.SlicePitch = resource_data.RowPitch = texture->width * texture->texel_size;
- upload_texture_data(resource, &resource_data, 1, queue, command_list);
- reset_command_list(command_list, test_context->allocator);
- transition_resource_state(command_list, resource, D3D12_RESOURCE_STATE_COPY_DEST,
- D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
- ID3D12Device_CreateShaderResourceView(device, resource,
- NULL, get_cpu_descriptor_handle(test_context, texture->heap, 0));
-
- texture->resource = resource;
}
assert(root_signature_desc.NumParameters <= ARRAY_SIZE(root_params));
@@ -170,7 +188,7 @@ static void d3d12_runner_draw_quad(struct shader_context *c)
context->c.uniform_count, context->c.uniforms, 0);
for (i = 0; i < context->c.texture_count; ++i)
{
- struct texture *texture = &context->c.textures[i];
+ struct texture *texture = context->c.textures[i];
ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, texture->root_index,
get_gpu_descriptor_handle(test_context, texture->heap, 0));
@@ -192,15 +210,6 @@ static void d3d12_runner_draw_quad(struct shader_context *c)
exec_command_list(queue, command_list);
wait_queue_idle(device, queue);
reset_command_list(command_list, test_context->allocator);
-
- for (i = 0; i < context->c.texture_count; ++i)
- {
- struct texture *texture = &context->c.textures[i];
-
- ID3D12DescriptorHeap_Release(texture->heap);
- ID3D12Resource_Release(texture->resource);
- free(texture);
- }
}
static void d3d12_runner_probe_vec4(struct shader_context *c,
@@ -220,6 +229,8 @@ static void d3d12_runner_probe_vec4(struct shader_context *c,
static const struct shader_runner_ops d3d12_runner_ops =
{
.compile_shader = d3d12_runner_compile_shader,
+ .create_texture = d3d12_runner_create_texture,
+ .destroy_texture = d3d12_runner_destroy_texture,
.draw_quad = d3d12_runner_draw_quad,
.probe_vec4 = d3d12_runner_probe_vec4,
};
--
2.34.1
Jan. 27, 2022
[PATCH vkd3d v3 3/8] tests: Move the drawing and readback implementation to the d3d12 shader runner.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
Makefile.am | 3 +-
tests/d3d12_test_utils.h | 5 +-
tests/shader_runner.c | 285 ++++++------------------------------
tests/shader_runner.h | 58 +++++++-
tests/shader_runner_d3d12.c | 200 +++++++++++++++++++++++--
tests/utils.h | 58 ++++++++
6 files changed, 351 insertions(+), 258 deletions(-)
create mode 100644 tests/utils.h
diff --git a/Makefile.am b/Makefile.am
index 51fa6719e..5d996560f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -115,7 +115,8 @@ vkd3d_shader_tests = \
vkd3d_test_headers = \
tests/d3d12_crosstest.h \
tests/d3d12_test_utils.h \
- tests/shader_runner.h
+ tests/shader_runner.h \
+ tests/utils.h
vkd3d_demos = \
demos/vkd3d-gears \
diff --git a/tests/d3d12_test_utils.h b/tests/d3d12_test_utils.h
index b8227282e..bab0c9ce2 100644
--- a/tests/d3d12_test_utils.h
+++ b/tests/d3d12_test_utils.h
@@ -19,10 +19,7 @@
#ifndef __VKD3D_D3D12_TEST_UTILS_H
#define __VKD3D_D3D12_TEST_UTILS_H
-struct vec4
-{
- float x, y, z, w;
-};
+#include "utils.h"
#define wait_queue_idle(a, b) wait_queue_idle_(__LINE__, a, b)
static void wait_queue_idle_(unsigned int line, ID3D12Device *device, ID3D12CommandQueue *queue);
diff --git a/tests/shader_runner.c b/tests/shader_runner.c
index ef0b81d1b..74b70890f 100644
--- a/tests/shader_runner.c
+++ b/tests/shader_runner.c
@@ -42,9 +42,24 @@
* DEALINGS IN THE SOFTWARE.
*/
-#include "d3d12_crosstest.h"
-#include "shader_runner.h"
+#ifdef __MINGW32__
+# define _HRESULT_DEFINED
+typedef int HRESULT;
+#endif
+
+#define COBJMACROS
+#define CONST_VTABLE
+#include "config.h"
+#include <ctype.h>
#include <errno.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include "vkd3d_windows.h"
+#include "vkd3d_d3dcommon.h"
+#include "vkd3d_d3dcompiler.h"
+#include "vkd3d_common.h"
+#include "vkd3d_test.h"
+#include "shader_runner.h"
static void VKD3D_NORETURN VKD3D_PRINTF_FUNC(1, 2) fatal_error(const char *format, ...)
{
@@ -56,89 +71,8 @@ static void VKD3D_NORETURN VKD3D_PRINTF_FUNC(1, 2) fatal_error(const char *forma
exit(1);
}
-static bool vkd3d_array_reserve(void **elements, size_t *capacity, size_t element_count, size_t element_size)
-{
- size_t new_capacity, max_capacity;
- void *new_elements;
-
- if (element_count <= *capacity)
- return true;
-
- max_capacity = ~(size_t)0 / element_size;
- if (max_capacity < element_count)
- return false;
-
- new_capacity = max(*capacity, 4);
- while (new_capacity < element_count && new_capacity <= max_capacity / 2)
- new_capacity *= 2;
-
- if (new_capacity < element_count)
- new_capacity = element_count;
-
- if (!(new_elements = realloc(*elements, new_capacity * element_size)))
- return false;
-
- *elements = new_elements;
- *capacity = new_capacity;
-
- return true;
-}
-
-enum texture_data_type
-{
- TEXTURE_DATA_FLOAT,
- TEXTURE_DATA_SINT,
- TEXTURE_DATA_UINT,
-};
-
-struct sampler
-{
- unsigned int slot;
-
- D3D12_FILTER filter;
- D3D12_TEXTURE_ADDRESS_MODE u_address, v_address, w_address;
-};
-
-struct texture
-{
- unsigned int slot;
-
- DXGI_FORMAT format;
- enum texture_data_type data_type;
- unsigned int texel_size;
- unsigned int width, height;
- uint8_t *data;
- size_t data_size, data_capacity;
-
- D3D12_DESCRIPTOR_RANGE descriptor_range;
- ID3D12DescriptorHeap *heap;
- ID3D12Resource *resource;
- unsigned int root_index;
-};
-
-struct shader_context
-{
- const struct shader_runner_ops *ops;
-
- struct test_context c;
- enum shader_model minimum_shader_model;
-
- ID3D10Blob *ps_code;
-
- uint32_t *uniforms;
- size_t uniform_count;
-
- struct texture *textures;
- size_t texture_count;
-
- struct sampler *samplers;
- size_t sampler_count;
-};
-
static void free_texture(struct texture *texture)
{
- ID3D12DescriptorHeap_Release(texture->heap);
- ID3D12Resource_Release(texture->resource);
free(texture->data);
memset(texture, 0, sizeof(*texture));
}
@@ -352,119 +286,11 @@ static void parse_test_directive(struct shader_context *context, const char *lin
{
if (match_string(line, "draw quad", &line))
{
- D3D12_SHADER_BYTECODE ps
- = {ID3D10Blob_GetBufferPointer(context->ps_code), ID3D10Blob_GetBufferSize(context->ps_code)};
- ID3D12GraphicsCommandList *command_list = context->c.list;
- D3D12_ROOT_SIGNATURE_DESC root_signature_desc = {0};
- D3D12_ROOT_PARAMETER root_params[3], *root_param;
- D3D12_STATIC_SAMPLER_DESC static_samplers[1];
- static const float clear_color[4];
- unsigned int uniform_index;
- ID3D12PipelineState *pso;
- HRESULT hr;
- size_t i;
-
- root_signature_desc.NumParameters = 0;
- root_signature_desc.pParameters = root_params;
- root_signature_desc.NumStaticSamplers = 0;
- root_signature_desc.pStaticSamplers = static_samplers;
-
- if (context->uniform_count)
- {
- uniform_index = root_signature_desc.NumParameters++;
- root_param = &root_params[uniform_index];
- root_param->ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
- root_param->Constants.ShaderRegister = 0;
- root_param->Constants.RegisterSpace = 0;
- root_param->Constants.Num32BitValues = context->uniform_count;
- root_param->ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
- }
-
- for (i = 0; i < context->texture_count; ++i)
- {
- struct texture *texture = &context->textures[i];
- D3D12_DESCRIPTOR_RANGE *range = &texture->descriptor_range;
- D3D12_SUBRESOURCE_DATA resource_data;
-
- texture->root_index = root_signature_desc.NumParameters++;
- root_param = &root_params[texture->root_index];
- root_param->ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
- root_param->DescriptorTable.NumDescriptorRanges = 1;
- root_param->DescriptorTable.pDescriptorRanges = range;
- root_param->ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
-
- range->RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
- range->NumDescriptors = 1;
- range->BaseShaderRegister = texture->slot;
- range->RegisterSpace = 0;
- range->OffsetInDescriptorsFromTableStart = 0;
-
- if (!texture->resource)
- {
- texture->heap = create_gpu_descriptor_heap(context->c.device,
- D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
- texture->resource = create_default_texture(context->c.device, texture->width, texture->height,
- texture->format, 0, D3D12_RESOURCE_STATE_COPY_DEST);
- resource_data.pData = texture->data;
- resource_data.SlicePitch = resource_data.RowPitch = texture->width * texture->texel_size;
- upload_texture_data(texture->resource, &resource_data, 1, context->c.queue, command_list);
- reset_command_list(command_list, context->c.allocator);
- transition_resource_state(command_list, texture->resource, D3D12_RESOURCE_STATE_COPY_DEST,
- D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
- ID3D12Device_CreateShaderResourceView(context->c.device, texture->resource,
- NULL, get_cpu_descriptor_handle(&context->c, texture->heap, 0));
- }
- }
-
- assert(root_signature_desc.NumParameters <= ARRAY_SIZE(root_params));
-
- for (i = 0; i < context->sampler_count; ++i)
- {
- D3D12_STATIC_SAMPLER_DESC *sampler_desc = &static_samplers[root_signature_desc.NumStaticSamplers++];
- const struct sampler *sampler = &context->samplers[i];
-
- memset(sampler_desc, 0, sizeof(*sampler_desc));
- sampler_desc->Filter = sampler->filter;
- sampler_desc->AddressU = sampler->u_address;
- sampler_desc->AddressV = sampler->v_address;
- sampler_desc->AddressW = sampler->w_address;
- sampler_desc->ShaderRegister = sampler->slot;
- sampler_desc->RegisterSpace = 0;
- sampler_desc->ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
- }
-
- if (context->c.root_signature)
- ID3D12RootSignature_Release(context->c.root_signature);
- hr = create_root_signature(context->c.device, &root_signature_desc, &context->c.root_signature);
- ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
-
- pso = create_pipeline_state(context->c.device, context->c.root_signature, context->c.render_target_desc.Format,
- NULL, &ps, NULL);
- if (!pso)
- return;
- vkd3d_array_reserve((void **)&context->c.pso, &context->c.pso_capacity, context->c.pso_count + 1, sizeof(*context->c.pso));
- context->c.pso[context->c.pso_count++] = pso;
-
- ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context->c.root_signature);
- if (context->uniform_count)
- ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, uniform_index,
- context->uniform_count, context->uniforms, 0);
- for (i = 0; i < context->texture_count; ++i)
- ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, context->textures[i].root_index,
- get_gpu_descriptor_handle(&context->c, context->textures[i].heap, 0));
-
- ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context->c.rtv, false, NULL);
- ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context->c.scissor_rect);
- ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context->c.viewport);
- ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
- ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context->c.rtv, clear_color, 0, NULL);
- ID3D12GraphicsCommandList_SetPipelineState(command_list, pso);
- ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
- transition_resource_state(command_list, context->c.render_target,
- D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
+ context->ops->draw_quad(context);
}
else if (match_string(line, "probe all rgba", &line))
{
+ static const RECT rect = {0, 0, 640, 480};
unsigned int ulps;
struct vec4 v;
int ret;
@@ -474,13 +300,12 @@ static void parse_test_directive(struct shader_context *context, const char *lin
fatal_error("Malformed probe arguments '%s'.\n", line);
if (ret < 5)
ulps = 0;
- check_sub_resource_vec4(context->c.render_target, 0, context->c.queue, context->c.list, &v, ulps);
- reset_command_list(context->c.list, context->c.allocator);
+
+ context->ops->probe_vec4(context, &rect, &v, ulps);
}
else if (match_string(line, "probe rect rgba", &line))
{
unsigned int x, y, w, h, ulps;
- struct resource_readback rb;
struct vec4 v;
RECT rect;
int ret;
@@ -492,18 +317,14 @@ static void parse_test_directive(struct shader_context *context, const char *lin
if (ret < 9)
ulps = 0;
- get_texture_readback_with_command_list(context->c.render_target, 0, &rb, context->c.queue, context->c.list);
rect.left = x;
rect.right = x + w;
rect.top = y;
rect.bottom = y + h;
- check_readback_data_vec4(&rb, &rect, &v, ulps);
- release_resource_readback(&rb);
- reset_command_list(context->c.list, context->c.allocator);
+ context->ops->probe_vec4(context, &rect, &v, ulps);
}
else if (match_string(line, "probe rgba", &line))
{
- struct resource_readback rb;
unsigned int x, y, ulps;
struct vec4 v;
RECT rect;
@@ -515,14 +336,11 @@ static void parse_test_directive(struct shader_context *context, const char *lin
if (ret < 7)
ulps = 0;
- get_texture_readback_with_command_list(context->c.render_target, 0, &rb, context->c.queue, context->c.list);
rect.left = x;
rect.right = x + 1;
rect.top = y;
rect.bottom = y + 1;
- check_readback_data_vec4(&rb, &rect, &v, ulps);
- release_resource_readback(&rb);
- reset_command_list(context->c.list, context->c.allocator);
+ context->ops->probe_vec4(context, &rect, &v, ulps);
}
else if (match_string(line, "uniform", &line))
{
@@ -622,30 +440,18 @@ static struct texture *get_texture(struct shader_context *context, unsigned int
return NULL;
}
-void run_shader_tests(int argc, char **argv, const struct shader_runner_ops *ops)
+void run_shader_tests(struct shader_context *context, int argc, char **argv, const struct shader_runner_ops *ops)
{
- static const struct test_context_desc desc =
- {
- .rt_width = 640,
- .rt_height = 480,
- .no_root_signature = true,
- .rt_format = DXGI_FORMAT_R32G32B32A32_FLOAT,
- };
size_t shader_source_size = 0, shader_source_len = 0;
struct sampler *current_sampler = NULL;
struct texture *current_texture = NULL;
enum parse_state state = STATE_NONE;
unsigned int i, line_number = 0;
- struct shader_context context;
const char *filename = NULL;
char *shader_source = NULL;
char line[256];
FILE *f;
- parse_args(argc, argv);
- enable_d3d12_debug_layer(argc, argv);
- init_adapter_info();
-
for (i = 1; i < argc; ++i)
{
if (argv[i][0] != '-')
@@ -667,9 +473,8 @@ void run_shader_tests(int argc, char **argv, const struct shader_runner_ops *ops
return;
}
- memset(&context, 0, sizeof(context));
- context.ops = ops;
- init_test_context(&context.c, &desc);
+ memset(context, 0, sizeof(*context));
+ context->ops = ops;
for (;;)
{
@@ -689,7 +494,8 @@ void run_shader_tests(int argc, char **argv, const struct shader_runner_ops *ops
break;
case STATE_SHADER_PIXEL:
- if (!(context.ps_code = context.ops->compile_shader(shader_source, context.minimum_shader_model)))
+ if (!(context->ps_code = context->ops->compile_shader(context,
+ shader_source, context->minimum_shader_model)))
return;
shader_source_len = 0;
break;
@@ -784,9 +590,9 @@ void run_shader_tests(int argc, char **argv, const struct shader_runner_ops *ops
{
state = STATE_SHADER_PIXEL;
- if (context.ps_code)
- ID3D10Blob_Release(context.ps_code);
- context.ps_code = NULL;
+ if (context->ps_code)
+ ID3D10Blob_Release(context->ps_code);
+ context->ps_code = NULL;
}
else if (!strcmp(line, "[pixel shader fail]\n"))
{
@@ -796,15 +602,15 @@ void run_shader_tests(int argc, char **argv, const struct shader_runner_ops *ops
{
state = STATE_SAMPLER;
- if ((current_sampler = get_sampler(&context, index)))
+ if ((current_sampler = get_sampler(context, index)))
{
memset(current_sampler, 0, sizeof(*current_sampler));
}
else
{
- context.samplers = realloc(context.samplers,
- ++context.sampler_count * sizeof(*context.samplers));
- current_sampler = &context.samplers[context.sampler_count - 1];
+ context->samplers = realloc(context->samplers,
+ ++context->sampler_count * sizeof(*context->samplers));
+ current_sampler = &context->samplers[context->sampler_count - 1];
memset(current_sampler, 0, sizeof(*current_sampler));
}
current_sampler->slot = index;
@@ -817,15 +623,15 @@ void run_shader_tests(int argc, char **argv, const struct shader_runner_ops *ops
{
state = STATE_TEXTURE;
- if ((current_texture = get_texture(&context, index)))
+ if ((current_texture = get_texture(context, index)))
{
free_texture(current_texture);
}
else
{
- context.textures = realloc(context.textures,
- ++context.texture_count * sizeof(*context.textures));
- current_texture = &context.textures[context.texture_count - 1];
+ context->textures = realloc(context->textures,
+ ++context->texture_count * sizeof(*context->textures));
+ current_texture = &context->textures[context->texture_count - 1];
memset(current_texture, 0, sizeof(*current_texture));
}
current_texture->slot = index;
@@ -870,7 +676,7 @@ void run_shader_tests(int argc, char **argv, const struct shader_runner_ops *ops
}
case STATE_REQUIRE:
- parse_require_directive(&context, line);
+ parse_require_directive(context, line);
break;
case STATE_SAMPLER:
@@ -882,17 +688,16 @@ void run_shader_tests(int argc, char **argv, const struct shader_runner_ops *ops
break;
case STATE_TEST:
- parse_test_directive(&context, line);
+ parse_test_directive(context, line);
break;
}
}
}
- if (context.ps_code)
- ID3D10Blob_Release(context.ps_code);
- for (i = 0; i < context.texture_count; ++i)
- free_texture(&context.textures[i]);
- destroy_test_context(&context.c);
+ if (context->ps_code)
+ ID3D10Blob_Release(context->ps_code);
+ for (i = 0; i < context->texture_count; ++i)
+ free_texture(&context->textures[i]);
fclose(f);
}
diff --git a/tests/shader_runner.h b/tests/shader_runner.h
index b00803cff..e9001eeda 100644
--- a/tests/shader_runner.h
+++ b/tests/shader_runner.h
@@ -18,6 +18,9 @@
#include "vkd3d_windows.h"
#include "vkd3d_d3dcommon.h"
+#include "vkd3d_d3d12.h"
+#include "vkd3d_dxgiformat.h"
+#include "utils.h"
enum shader_model
{
@@ -27,11 +30,62 @@ enum shader_model
SHADER_MODEL_5_1,
};
+enum texture_data_type
+{
+ TEXTURE_DATA_FLOAT,
+ TEXTURE_DATA_SINT,
+ TEXTURE_DATA_UINT,
+};
+
+struct sampler
+{
+ unsigned int slot;
+
+ D3D12_FILTER filter;
+ D3D12_TEXTURE_ADDRESS_MODE u_address, v_address, w_address;
+};
+
+struct texture
+{
+ unsigned int slot;
+
+ DXGI_FORMAT format;
+ enum texture_data_type data_type;
+ unsigned int texel_size;
+ unsigned int width, height;
+ uint8_t *data;
+ size_t data_size, data_capacity;
+
+ D3D12_DESCRIPTOR_RANGE descriptor_range;
+ ID3D12DescriptorHeap *heap;
+ ID3D12Resource *resource;
+ unsigned int root_index;
+};
+
+struct shader_context
+{
+ const struct shader_runner_ops *ops;
+
+ ID3D10Blob *ps_code;
+ enum shader_model minimum_shader_model;
+
+ uint32_t *uniforms;
+ size_t uniform_count;
+
+ struct texture *textures;
+ size_t texture_count;
+
+ struct sampler *samplers;
+ size_t sampler_count;
+};
+
struct shader_runner_ops
{
- ID3D10Blob *(*compile_shader)(const char *source, enum shader_model minimum_shader_model);
+ ID3D10Blob *(*compile_shader)(struct shader_context *context, const char *source, enum shader_model minimum_shader_model);
+ void (*draw_quad)(struct shader_context *context);
+ void (*probe_vec4)(struct shader_context *context, const RECT *rect, const struct vec4 *v, unsigned int ulps);
};
-void run_shader_tests(int argc, char **argv, const struct shader_runner_ops *ops);
+void run_shader_tests(struct shader_context *context, int argc, char **argv, const struct shader_runner_ops *ops);
void run_shader_tests_d3d12(int argc, char **argv);
diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c
index 6343f78e9..bb0288e83 100644
--- a/tests/shader_runner_d3d12.c
+++ b/tests/shader_runner_d3d12.c
@@ -16,21 +16,28 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#ifdef __MINGW32__
-# define _HRESULT_DEFINED
-typedef int HRESULT;
-#endif
-
+#include "config.h"
+#include <assert.h>
#define COBJMACROS
#define CONST_VTABLE
#define VKD3D_TEST_NO_DEFS
-#include "vkd3d_windows.h"
-#include "vkd3d_d3dcommon.h"
-#include "vkd3d_d3dcompiler.h"
-#include "vkd3d_test.h"
+#include "d3d12_crosstest.h"
#include "shader_runner.h"
-static ID3D10Blob *d3d12_runner_compile_shader(const char *source, enum shader_model shader_model)
+struct d3d12_shader_context
+{
+ struct shader_context c;
+
+ struct test_context test_context;
+};
+
+static struct d3d12_shader_context *d3d12_shader_context(struct shader_context *c)
+{
+ return CONTAINING_RECORD(c, struct d3d12_shader_context, c);
+}
+
+static ID3D10Blob *d3d12_runner_compile_shader(struct shader_context *c,
+ const char *source, enum shader_model shader_model)
{
ID3D10Blob *blob = NULL, *errors = NULL;
HRESULT hr;
@@ -55,12 +62,183 @@ static ID3D10Blob *d3d12_runner_compile_shader(const char *source, enum shader_m
return blob;
}
+static void d3d12_runner_draw_quad(struct shader_context *c)
+{
+ struct d3d12_shader_context *context = d3d12_shader_context(c);
+ struct test_context *test_context = &context->test_context;
+
+ D3D12_SHADER_BYTECODE ps
+ = {ID3D10Blob_GetBufferPointer(context->c.ps_code), ID3D10Blob_GetBufferSize(context->c.ps_code)};
+ ID3D12GraphicsCommandList *command_list = test_context->list;
+ D3D12_ROOT_SIGNATURE_DESC root_signature_desc = {0};
+ D3D12_ROOT_PARAMETER root_params[3], *root_param;
+ ID3D12CommandQueue *queue = test_context->queue;
+ D3D12_STATIC_SAMPLER_DESC static_samplers[1];
+ ID3D12Device *device = test_context->device;
+ static const float clear_color[4];
+ unsigned int uniform_index;
+ ID3D12PipelineState *pso;
+ HRESULT hr;
+ size_t i;
+
+ root_signature_desc.NumParameters = 0;
+ root_signature_desc.pParameters = root_params;
+ root_signature_desc.NumStaticSamplers = 0;
+ root_signature_desc.pStaticSamplers = static_samplers;
+
+ if (context->c.uniform_count)
+ {
+ uniform_index = root_signature_desc.NumParameters++;
+ root_param = &root_params[uniform_index];
+ root_param->ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS;
+ root_param->Constants.ShaderRegister = 0;
+ root_param->Constants.RegisterSpace = 0;
+ root_param->Constants.Num32BitValues = context->c.uniform_count;
+ root_param->ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
+ }
+
+ for (i = 0; i < context->c.texture_count; ++i)
+ {
+ struct texture *texture = &context->c.textures[i];
+ D3D12_SUBRESOURCE_DATA resource_data;
+ D3D12_DESCRIPTOR_RANGE *range;
+ ID3D12Resource *resource;
+
+ range = &texture->descriptor_range;
+
+ texture->root_index = root_signature_desc.NumParameters++;
+ root_param = &root_params[texture->root_index];
+ root_param->ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE;
+ root_param->DescriptorTable.NumDescriptorRanges = 1;
+ root_param->DescriptorTable.pDescriptorRanges = range;
+ root_param->ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
+
+ range->RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
+ range->NumDescriptors = 1;
+ range->BaseShaderRegister = texture->slot;
+ range->RegisterSpace = 0;
+ range->OffsetInDescriptorsFromTableStart = 0;
+
+ texture->heap = create_gpu_descriptor_heap(device, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1);
+ resource = create_default_texture(device, texture->width, texture->height,
+ texture->format, 0, D3D12_RESOURCE_STATE_COPY_DEST);
+ resource_data.pData = texture->data;
+ resource_data.SlicePitch = resource_data.RowPitch = texture->width * texture->texel_size;
+ upload_texture_data(resource, &resource_data, 1, queue, command_list);
+ reset_command_list(command_list, test_context->allocator);
+ transition_resource_state(command_list, resource, D3D12_RESOURCE_STATE_COPY_DEST,
+ D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
+ ID3D12Device_CreateShaderResourceView(device, resource,
+ NULL, get_cpu_descriptor_handle(test_context, texture->heap, 0));
+
+ texture->resource = resource;
+ }
+
+ assert(root_signature_desc.NumParameters <= ARRAY_SIZE(root_params));
+
+ for (i = 0; i < context->c.sampler_count; ++i)
+ {
+ D3D12_STATIC_SAMPLER_DESC *sampler_desc = &static_samplers[root_signature_desc.NumStaticSamplers++];
+ const struct sampler *sampler = &context->c.samplers[i];
+
+ memset(sampler_desc, 0, sizeof(*sampler_desc));
+ sampler_desc->Filter = sampler->filter;
+ sampler_desc->AddressU = sampler->u_address;
+ sampler_desc->AddressV = sampler->v_address;
+ sampler_desc->AddressW = sampler->w_address;
+ sampler_desc->ShaderRegister = sampler->slot;
+ sampler_desc->RegisterSpace = 0;
+ sampler_desc->ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
+ }
+
+ if (test_context->root_signature)
+ ID3D12RootSignature_Release(test_context->root_signature);
+ hr = create_root_signature(device, &root_signature_desc, &test_context->root_signature);
+ ok(hr == S_OK, "Failed to create root signature, hr %#x.\n", hr);
+
+ pso = create_pipeline_state(device, test_context->root_signature,
+ test_context->render_target_desc.Format, NULL, &ps, NULL);
+ if (!pso)
+ return;
+ vkd3d_array_reserve((void **)&test_context->pso, &test_context->pso_capacity,
+ test_context->pso_count + 1, sizeof(*test_context->pso));
+ test_context->pso[test_context->pso_count++] = pso;
+
+ ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, test_context->root_signature);
+ if (context->c.uniform_count)
+ ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, uniform_index,
+ context->c.uniform_count, context->c.uniforms, 0);
+ for (i = 0; i < context->c.texture_count; ++i)
+ {
+ struct texture *texture = &context->c.textures[i];
+
+ ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(command_list, texture->root_index,
+ get_gpu_descriptor_handle(test_context, texture->heap, 0));
+ }
+
+ ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &test_context->rtv, false, NULL);
+ ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &test_context->scissor_rect);
+ ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &test_context->viewport);
+ ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+ ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, test_context->rtv, clear_color, 0, NULL);
+ ID3D12GraphicsCommandList_SetPipelineState(command_list, pso);
+ ID3D12GraphicsCommandList_DrawInstanced(command_list, 3, 1, 0, 0);
+ transition_resource_state(command_list, test_context->render_target,
+ D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
+
+ /* Finish the command list so that we can destroy objects. */
+ hr = ID3D12GraphicsCommandList_Close(command_list);
+ ok(hr == S_OK, "Failed to close command list, hr %#x.\n", hr);
+ exec_command_list(queue, command_list);
+ wait_queue_idle(device, queue);
+ reset_command_list(command_list, test_context->allocator);
+
+ for (i = 0; i < context->c.texture_count; ++i)
+ {
+ struct texture *texture = &context->c.textures[i];
+
+ ID3D12DescriptorHeap_Release(texture->heap);
+ ID3D12Resource_Release(texture->resource);
+ free(texture);
+ }
+}
+
+static void d3d12_runner_probe_vec4(struct shader_context *c,
+ const RECT *rect, const struct vec4 *v, unsigned int ulps)
+{
+ struct d3d12_shader_context *context = d3d12_shader_context(c);
+ struct test_context *test_context = &context->test_context;
+ struct resource_readback rb;
+
+ get_texture_readback_with_command_list(test_context->render_target, 0, &rb,
+ test_context->queue, test_context->list);
+ check_readback_data_vec4(&rb, rect, v, ulps);
+ release_resource_readback(&rb);
+ reset_command_list(test_context->list, test_context->allocator);
+}
+
static const struct shader_runner_ops d3d12_runner_ops =
{
.compile_shader = d3d12_runner_compile_shader,
+ .draw_quad = d3d12_runner_draw_quad,
+ .probe_vec4 = d3d12_runner_probe_vec4,
};
void run_shader_tests_d3d12(int argc, char **argv)
{
- run_shader_tests(argc, argv, &d3d12_runner_ops);
+ static const struct test_context_desc desc =
+ {
+ .rt_width = 640,
+ .rt_height = 480,
+ .no_root_signature = true,
+ .rt_format = DXGI_FORMAT_R32G32B32A32_FLOAT,
+ };
+ struct d3d12_shader_context context;
+
+ parse_args(argc, argv);
+ enable_d3d12_debug_layer(argc, argv);
+ init_adapter_info();
+ init_test_context(&context.test_context, &desc);
+ run_shader_tests(&context.c, argc, argv, &d3d12_runner_ops);
+ destroy_test_context(&context.test_context);
}
diff --git a/tests/utils.h b/tests/utils.h
new file mode 100644
index 000000000..825520c27
--- /dev/null
+++ b/tests/utils.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2016-2018 Józef Kucia for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __VKD3D_TEST_UTILS_H
+#define __VKD3D_TEST_UTILS_H
+
+#include <stdbool.h>
+#include <stdlib.h>
+
+struct vec4
+{
+ float x, y, z, w;
+};
+
+static inline bool vkd3d_array_reserve(void **elements, size_t *capacity, size_t element_count, size_t element_size)
+{
+ size_t new_capacity, max_capacity;
+ void *new_elements;
+
+ if (element_count <= *capacity)
+ return true;
+
+ max_capacity = ~(size_t)0 / element_size;
+ if (max_capacity < element_count)
+ return false;
+
+ new_capacity = max(*capacity, 4);
+ while (new_capacity < element_count && new_capacity <= max_capacity / 2)
+ new_capacity *= 2;
+
+ if (new_capacity < element_count)
+ new_capacity = element_count;
+
+ if (!(new_elements = realloc(*elements, new_capacity * element_size)))
+ return false;
+
+ *elements = new_elements;
+ *capacity = new_capacity;
+
+ return true;
+}
+
+#endif
--
2.34.1
Jan. 27, 2022
[PATCH vkd3d v3 2/8] tests: Move HLSL shader compilation to a new d3d12 shader runner backend.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
Makefile.am | 37 ++++++++++++++------
include/private/vkd3d_test.h | 19 +++++++----
tests/shader_runner.c | 49 +++++++-------------------
tests/shader_runner.h | 37 ++++++++++++++++++++
tests/shader_runner_d3d12.c | 66 ++++++++++++++++++++++++++++++++++++
5 files changed, 154 insertions(+), 54 deletions(-)
create mode 100644 tests/shader_runner.h
create mode 100644 tests/shader_runner_d3d12.c
diff --git a/Makefile.am b/Makefile.am
index 17fcae32f..51fa6719e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -50,9 +50,6 @@ vkd3d_cross_tests = \
tests/d3d12_invalid_usage \
tests/hlsl_d3d12
-vkd3d_shader_runners = \
- tests/shader_runner
-
vkd3d_shader_tests = \
tests/abs.shader_test \
tests/cast-to-float.shader_test \
@@ -117,7 +114,8 @@ vkd3d_shader_tests = \
vkd3d_test_headers = \
tests/d3d12_crosstest.h \
- tests/d3d12_test_utils.h
+ tests/d3d12_test_utils.h \
+ tests/shader_runner.h
vkd3d_demos = \
demos/vkd3d-gears \
@@ -277,12 +275,15 @@ AM_DEFAULT_SOURCE_EXT = .c
TEST_EXTENSIONS = .shader_test
if BUILD_TESTS
-check_PROGRAMS = $(vkd3d_tests) $(vkd3d_cross_tests) $(vkd3d_shader_runners)
+check_PROGRAMS = $(vkd3d_tests) $(vkd3d_cross_tests) tests/shader_runner
TESTS = $(vkd3d_tests) $(vkd3d_cross_tests) $(vkd3d_shader_tests)
tests_d3d12_LDADD = $(LDADD) @PTHREAD_LIBS@ @VULKAN_LIBS@
tests_d3d12_invalid_usage_LDADD = $(LDADD) @VULKAN_LIBS@
tests_hlsl_d3d12_LDADD = $(LDADD) @VULKAN_LIBS@
tests_shader_runner_LDADD = $(LDADD) @VULKAN_LIBS@
+tests_shader_runner_SOURCES = \
+ tests/shader_runner.c \
+ tests/shader_runner_d3d12.c
tests_vkd3d_api_LDADD = libvkd3d.la @VULKAN_LIBS@
tests_vkd3d_shader_api_LDADD = libvkd3d-shader.la
SHADER_TEST_LOG_COMPILER = tests/shader_runner
@@ -391,14 +392,17 @@ CROSS_CPPFLAGS = -I$(srcdir)/include -I$(srcdir)/include/private -I$(builddir)/i
CROSS_CFLAGS = -g -O2 -Wall -municode ${CROSS_CPPFLAGS} -D__USE_MINGW_ANSI_STDIO=0
EXTRA_DIST += $(cross_implibs:=.cross32.def) $(cross_implibs:=.cross64.def)
+shader_runner_cross_sources = \
+ $(srcdir)/tests/shader_runner.c \
+ $(srcdir)/tests/shader_runner_d3d12.c
+
if HAVE_CROSSTARGET32
CROSS32_CC = @CROSSCC32@
CROSS32_DLLTOOL = @CROSSTARGET32(a)-dlltool
CROSS32_IMPLIBS = $(cross_implibs:=.cross32.a)
CROSS32_EXEFILES = $(vkd3d_cross_tests:=.cross32.exe) \
- $(vkd3d_demos:demos/vkd3d-%=demos/%.cross32.exe) \
- $(vkd3d_shader_runners:=.cross32.exe)
-CROSS32_FILES = $(CROSS32_IMPLIBS) $(CROSS32_EXEFILES)
+ $(vkd3d_demos:demos/vkd3d-%=demos/%.cross32.exe)
+CROSS32_FILES = $(CROSS32_IMPLIBS) $(CROSS32_EXEFILES) tests/shader_runner.cross32.exe
CLEANFILES += $(CROSS32_FILES)
crosstest32: $(CROSS32_FILES)
@@ -414,6 +418,12 @@ $(CROSS32_EXEFILES): %.cross32.exe: %.c $(CROSS32_IMPLIBS) $(widl_headers)
$(AM_V_CCLD)depbase=`echo $@ | $(SED) 's![^/]*$$!$(DEPDIR)/&!;s!\.exe$$!!'`; \
$(CROSS32_CC) $(CROSS_CFLAGS) -MT $@ -MD -MP -MF $$depbase.Tpo -o $@ $< $(CROSS32_IMPLIBS) -ldxgi -lgdi32 -ld3dcompiler_47 && \
$(am__mv) $$depbase.Tpo $$depbase.Po
+
+tests/shader_runner.cross32.exe: $(shader_runner_cross_sources) $(CROSS32_IMPLIBS) $(widl_headers)
+ $(AM_V_CCLD)depbase=`echo $@ | sed 's![^/]*$$!$(DEPDIR)/&!;s!\.exe$$!!'`; \
+ $(CROSS32_CC) $(CROSS_CFLAGS) -MT $@ -MD -MP -MF $$depbase.Tpo -o $@ $(shader_runner_cross_sources) $(CROSS32_IMPLIBS) -ldxgi -lgdi32 -ld3dcompiler_47 && \
+ $(am__mv) $$depbase.Tpo $$depbase.Po
+
else
crosstest32:
endif
@@ -423,9 +433,8 @@ CROSS64_CC = @CROSSCC64@
CROSS64_DLLTOOL = @CROSSTARGET64(a)-dlltool
CROSS64_IMPLIBS = $(cross_implibs:=.cross64.a)
CROSS64_EXEFILES = $(vkd3d_cross_tests:=.cross64.exe) \
- $(vkd3d_demos:demos/vkd3d-%=demos/%.cross64.exe) \
- $(vkd3d_shader_runners:=.cross64.exe)
-CROSS64_FILES = $(CROSS64_IMPLIBS) $(CROSS64_EXEFILES)
+ $(vkd3d_demos:demos/vkd3d-%=demos/%.cross64.exe)
+CROSS64_FILES = $(CROSS64_IMPLIBS) $(CROSS64_EXEFILES) tests/shader_runner.cross64.exe
CLEANFILES += $(CROSS64_FILES)
crosstest64: $(CROSS64_FILES)
@@ -441,6 +450,12 @@ $(CROSS64_EXEFILES): %.cross64.exe: %.c $(CROSS64_IMPLIBS) $(widl_headers)
$(AM_V_CCLD)depbase=`echo $@ | sed 's![^/]*$$!$(DEPDIR)/&!;s!\.exe$$!!'`; \
$(CROSS64_CC) $(CROSS_CFLAGS) -MT $@ -MD -MP -MF $$depbase.Tpo -o $@ $< $(CROSS64_IMPLIBS) -ldxgi -lgdi32 -ld3dcompiler_47 && \
$(am__mv) $$depbase.Tpo $$depbase.Po
+
+tests/shader_runner.cross64.exe: $(shader_runner_cross_sources) $(CROSS64_IMPLIBS) $(widl_headers)
+ $(AM_V_CCLD)depbase=`echo $@ | sed 's![^/]*$$!$(DEPDIR)/&!;s!\.exe$$!!'`; \
+ $(CROSS64_CC) $(CROSS_CFLAGS) -MT $@ -MD -MP -MF $$depbase.Tpo -o $@ $(shader_runner_cross_sources) $(CROSS64_IMPLIBS) -ldxgi -lgdi32 -ld3dcompiler_47 && \
+ $(am__mv) $$depbase.Tpo $$depbase.Po
+
else
crosstest64:
endif
diff --git a/include/private/vkd3d_test.h b/include/private/vkd3d_test.h
index 6b8763dde..0cc7fe4f3 100644
--- a/include/private/vkd3d_test.h
+++ b/include/private/vkd3d_test.h
@@ -28,16 +28,15 @@
#include <stdlib.h>
#include <string.h>
-static void vkd3d_test_main(int argc, char **argv);
-static const char *vkd3d_test_name;
-static const char *vkd3d_test_platform = "other";
+extern const char *vkd3d_test_name;
+extern const char *vkd3d_test_platform;
static void vkd3d_test_start_todo(bool is_todo);
static int vkd3d_test_loop_todo(void);
static void vkd3d_test_end_todo(void);
#define START_TEST(name) \
- static const char *vkd3d_test_name = #name; \
+ const char *vkd3d_test_name = #name; \
static void vkd3d_test_main(int argc, char **argv)
/*
@@ -100,7 +99,7 @@ static void vkd3d_test_end_todo(void);
#define todo todo_if(true)
-static struct
+struct vkd3d_test_state
{
LONG success_count;
LONG failure_count;
@@ -120,7 +119,8 @@ static struct
const char *test_name_filter;
char context[1024];
-} vkd3d_test_state;
+};
+extern struct vkd3d_test_state vkd3d_test_state;
static bool
vkd3d_test_platform_is_windows(void)
@@ -253,6 +253,12 @@ vkd3d_test_debug(const char *fmt, ...)
printf("%s\n", buffer);
}
+#ifndef VKD3D_TEST_NO_DEFS
+const char *vkd3d_test_platform = "other";
+struct vkd3d_test_state vkd3d_test_state;
+
+static void vkd3d_test_main(int argc, char **argv);
+
int main(int argc, char **argv)
{
const char *test_filter = getenv("VKD3D_TEST_FILTER");
@@ -339,6 +345,7 @@ int wmain(int argc, WCHAR **wargv)
return ret;
}
#endif /* _WIN32 */
+#endif /* VKD3D_TEST_NO_DEFS */
typedef void (*vkd3d_test_pfn)(void);
diff --git a/tests/shader_runner.c b/tests/shader_runner.c
index 5db963f51..ef0b81d1b 100644
--- a/tests/shader_runner.c
+++ b/tests/shader_runner.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 Zebediah Figura for CodeWeavers
+ * Copyright 2020-2021 Zebediah Figura for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -43,6 +43,7 @@
*/
#include "d3d12_crosstest.h"
+#include "shader_runner.h"
#include <errno.h>
static void VKD3D_NORETURN VKD3D_PRINTF_FUNC(1, 2) fatal_error(const char *format, ...)
@@ -115,16 +116,10 @@ struct texture
unsigned int root_index;
};
-enum shader_model
-{
- SHADER_MODEL_4_0 = 0,
- SHADER_MODEL_4_1,
- SHADER_MODEL_5_0,
- SHADER_MODEL_5_1,
-};
-
struct shader_context
{
+ const struct shader_runner_ops *ops;
+
struct test_context c;
enum shader_model minimum_shader_model;
@@ -140,22 +135,6 @@ struct shader_context
size_t sampler_count;
};
-static ID3D10Blob *compile_shader(const char *source, const char *target)
-{
- ID3D10Blob *blob = NULL, *errors = NULL;
- HRESULT hr;
-
- hr = D3DCompile(source, strlen(source), NULL, NULL, NULL, "main", target, 0, 0, &blob, &errors);
- ok(hr == S_OK, "Failed to compile shader, hr %#x.\n", hr);
- if (errors)
- {
- if (vkd3d_test_state.debug_level)
- trace("%s\n", (char *)ID3D10Blob_GetBufferPointer(errors));
- ID3D10Blob_Release(errors);
- }
- return blob;
-}
-
static void free_texture(struct texture *texture)
{
ID3D12DescriptorHeap_Release(texture->heap);
@@ -643,7 +622,7 @@ static struct texture *get_texture(struct shader_context *context, unsigned int
return NULL;
}
-START_TEST(shader_runner)
+void run_shader_tests(int argc, char **argv, const struct shader_runner_ops *ops)
{
static const struct test_context_desc desc =
{
@@ -689,6 +668,7 @@ START_TEST(shader_runner)
}
memset(&context, 0, sizeof(context));
+ context.ops = ops;
init_test_context(&context.c, &desc);
for (;;)
@@ -709,20 +689,10 @@ START_TEST(shader_runner)
break;
case STATE_SHADER_PIXEL:
- {
- static const char *const shader_models[] =
- {
- [SHADER_MODEL_4_0] = "ps_4_0",
- [SHADER_MODEL_4_1] = "ps_4_1",
- [SHADER_MODEL_5_0] = "ps_5_0",
- [SHADER_MODEL_5_1] = "ps_5_1",
- };
-
- if (!(context.ps_code = compile_shader(shader_source, shader_models[context.minimum_shader_model])))
+ if (!(context.ps_code = context.ops->compile_shader(shader_source, context.minimum_shader_model)))
return;
shader_source_len = 0;
break;
- }
case STATE_SHADER_INVALID_PIXEL:
{
@@ -926,3 +896,8 @@ START_TEST(shader_runner)
fclose(f);
}
+
+START_TEST(shader_runner)
+{
+ run_shader_tests_d3d12(argc, argv);
+}
diff --git a/tests/shader_runner.h b/tests/shader_runner.h
new file mode 100644
index 000000000..b00803cff
--- /dev/null
+++ b/tests/shader_runner.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2021 Zebediah Figura for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "vkd3d_windows.h"
+#include "vkd3d_d3dcommon.h"
+
+enum shader_model
+{
+ SHADER_MODEL_4_0 = 0,
+ SHADER_MODEL_4_1,
+ SHADER_MODEL_5_0,
+ SHADER_MODEL_5_1,
+};
+
+struct shader_runner_ops
+{
+ ID3D10Blob *(*compile_shader)(const char *source, enum shader_model minimum_shader_model);
+};
+
+void run_shader_tests(int argc, char **argv, const struct shader_runner_ops *ops);
+
+void run_shader_tests_d3d12(int argc, char **argv);
diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c
new file mode 100644
index 000000000..6343f78e9
--- /dev/null
+++ b/tests/shader_runner_d3d12.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2020-2021 Zebediah Figura for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef __MINGW32__
+# define _HRESULT_DEFINED
+typedef int HRESULT;
+#endif
+
+#define COBJMACROS
+#define CONST_VTABLE
+#define VKD3D_TEST_NO_DEFS
+#include "vkd3d_windows.h"
+#include "vkd3d_d3dcommon.h"
+#include "vkd3d_d3dcompiler.h"
+#include "vkd3d_test.h"
+#include "shader_runner.h"
+
+static ID3D10Blob *d3d12_runner_compile_shader(const char *source, enum shader_model shader_model)
+{
+ ID3D10Blob *blob = NULL, *errors = NULL;
+ HRESULT hr;
+
+ static const char *const shader_models[] =
+ {
+ [SHADER_MODEL_4_0] = "ps_4_0",
+ [SHADER_MODEL_4_1] = "ps_4_1",
+ [SHADER_MODEL_5_0] = "ps_5_0",
+ [SHADER_MODEL_5_1] = "ps_5_1",
+ };
+
+ hr = D3DCompile(source, strlen(source), NULL, NULL, NULL, "main",
+ shader_models[shader_model], 0, 0, &blob, &errors);
+ ok(hr == S_OK, "Failed to compile shader, hr %#x.\n", hr);
+ if (errors)
+ {
+ if (vkd3d_test_state.debug_level)
+ trace("%s\n", (char *)ID3D10Blob_GetBufferPointer(errors));
+ ID3D10Blob_Release(errors);
+ }
+ return blob;
+}
+
+static const struct shader_runner_ops d3d12_runner_ops =
+{
+ .compile_shader = d3d12_runner_compile_shader,
+};
+
+void run_shader_tests_d3d12(int argc, char **argv)
+{
+ run_shader_tests(argc, argv, &d3d12_runner_ops);
+}
--
2.34.1
Jan. 27, 2022
[PATCH vkd3d v3 1/8] tests: Rename shader_runner_d3d12 to shader_runner.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
I don't know why I didn't think of this in the first place...
Makefile.am | 6 +++---
tests/{shader_runner_d3d12.c => shader_runner.c} | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
rename tests/{shader_runner_d3d12.c => shader_runner.c} (99%)
diff --git a/Makefile.am b/Makefile.am
index db0a6f680..17fcae32f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -51,7 +51,7 @@ vkd3d_cross_tests = \
tests/hlsl_d3d12
vkd3d_shader_runners = \
- tests/shader_runner_d3d12
+ tests/shader_runner
vkd3d_shader_tests = \
tests/abs.shader_test \
@@ -282,10 +282,10 @@ TESTS = $(vkd3d_tests) $(vkd3d_cross_tests) $(vkd3d_shader_tests)
tests_d3d12_LDADD = $(LDADD) @PTHREAD_LIBS@ @VULKAN_LIBS@
tests_d3d12_invalid_usage_LDADD = $(LDADD) @VULKAN_LIBS@
tests_hlsl_d3d12_LDADD = $(LDADD) @VULKAN_LIBS@
-tests_shader_runner_d3d12_LDADD = $(LDADD) @VULKAN_LIBS@
+tests_shader_runner_LDADD = $(LDADD) @VULKAN_LIBS@
tests_vkd3d_api_LDADD = libvkd3d.la @VULKAN_LIBS@
tests_vkd3d_shader_api_LDADD = libvkd3d-shader.la
-SHADER_TEST_LOG_COMPILER = tests/shader_runner_d3d12
+SHADER_TEST_LOG_COMPILER = tests/shader_runner
XFAIL_TESTS = \
tests/cast-to-float.shader_test \
tests/cast-to-half.shader_test \
diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner.c
similarity index 99%
rename from tests/shader_runner_d3d12.c
rename to tests/shader_runner.c
index 4a8d1f18e..5db963f51 100644
--- a/tests/shader_runner_d3d12.c
+++ b/tests/shader_runner.c
@@ -643,7 +643,7 @@ static struct texture *get_texture(struct shader_context *context, unsigned int
return NULL;
}
-START_TEST(shader_runner_d3d12)
+START_TEST(shader_runner)
{
static const struct test_context_desc desc =
{
--
2.34.1
Jan. 27, 2022
Re: [PATCH 2/5] winhttp: Attemp sync websocket send even if data doesn't fit SSL buffer.
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=106124
Your paranoid android.
=== w8adm (32 bit report) ===
winhttp:
notification.c:256: Test failed: failed to send request 12007
notification.c:258: Test failed: unexpected function 3, expected 4. probably some notifications were missing
notification.c:260: Test failed: failed to receive response 12019
notification.c:264: Test failed: failed unexpectedly 12019
notification.c:265: Test failed: request failed unexpectedly 0
notification.c:268: Test failed: unexpected function 3, expected 13. probably some notifications were missing
notification.c:116: Test failed: 268: expected status 0x00000002 got 0x00000800
notification.c:117: Test failed: 268: expected function 3 got 13
notification: Timeout
Jan. 27, 2022