[PATCH vkd3d 01/12] libs/vkd3d: Validate miplevel count while creating resources.

classic Classic list List threaded Threaded
26 messages Options
12
Reply | Threaded
Open this post in threaded view
|

[PATCH vkd3d 01/12] libs/vkd3d: Validate miplevel count while creating resources.

Józef Kucia
From: Józef Kucia <[hidden email]>

vkd3d_log2i() is imported from wined3d.

Signed-off-by: Józef Kucia <[hidden email]>
---
 configure.ac                   |  1 +
 include/private/vkd3d_common.h | 32 ++++++++++++++++++++++++++++++++
 libs/vkd3d/resource.c          | 40 +++++++++++++++++++++++++++++++++++-----
 m4/check-builtin-functions.m4  | 10 ++++++++++
 tests/d3d12.c                  | 25 +++++++++++++++++++++++++
 5 files changed, 103 insertions(+), 5 deletions(-)

diff --git a/configure.ac b/configure.ac
index 27c03a6c9400..d13b440755cd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -79,6 +79,7 @@ AS_IF([test "x$with_spirv_tools" = "xyes"],
 PKG_CHECK_MODULES([XCB], [xcb xcb-keysyms])
 
 dnl Check for functions
+VKD3D_CHECK_BUILTIN_CLZ
 VKD3D_CHECK_BUILTIN_POPCOUNT
 VKD3D_CHECK_SYNC_ADD_AND_FETCH_FUNC
 VKD3D_CHECK_SYNC_SUB_AND_FETCH_FUNC
diff --git a/include/private/vkd3d_common.h b/include/private/vkd3d_common.h
index ce8f32e1b1aa..2e3873b82440 100644
--- a/include/private/vkd3d_common.h
+++ b/include/private/vkd3d_common.h
@@ -50,6 +50,38 @@ static inline unsigned int vkd3d_popcount(unsigned int v)
 #endif
 }
 
+/* Undefined for x == 0. */
+static inline unsigned int vkd3d_log2i(unsigned int x)
+{
+#ifdef HAVE_BUILTIN_CLZ
+    return __builtin_clz(x) ^ 0x1f;
+#else
+    static const unsigned int l[] =
+    {
+        ~0u, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
+          4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+          6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+          6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+          6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+          6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    };
+    unsigned int i;
+
+    return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24
+            : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
+#endif
+}
+
 #ifndef _WIN32
 # if HAVE_SYNC_ADD_AND_FETCH
 static inline LONG InterlockedIncrement(LONG volatile *x)
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c
index 72848a4457b7..264578bd31a8 100644
--- a/libs/vkd3d/resource.c
+++ b/libs/vkd3d/resource.c
@@ -103,14 +103,16 @@ HRESULT vkd3d_create_buffer(struct d3d12_device *device,
 }
 
 static HRESULT vkd3d_create_image(struct d3d12_resource *resource, struct d3d12_device *device,
-        const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags,
-        const D3D12_RESOURCE_DESC *desc)
+        const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags)
 {
     const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
     const struct vkd3d_format *format;
+    const D3D12_RESOURCE_DESC *desc;
     VkImageCreateInfo image_info;
     VkResult vr;
 
+    desc = &resource->desc;
+
     if (!(format = vkd3d_format_from_d3d12_resource_desc(desc, 0)))
     {
         WARN("Invalid DXGI format %#x.\n", desc->Format);
@@ -606,6 +608,30 @@ struct d3d12_resource *unsafe_impl_from_ID3D12Resource(ID3D12Resource *iface)
     return impl_from_ID3D12Resource(iface);
 }
 
+static HRESULT validate_buffer_desc(const D3D12_RESOURCE_DESC *desc)
+{
+    if (desc->MipLevels != 1)
+    {
+        WARN("Invalid miplevel count %u for buffer.\n", desc->MipLevels);
+        return E_INVALIDARG;
+    }
+
+    return S_OK;
+}
+
+static HRESULT validate_texture_desc(D3D12_RESOURCE_DESC *desc)
+{
+    if (!desc->MipLevels)
+    {
+        unsigned int size = max(desc->Width, desc->Height);
+        if (desc->Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D)
+            size = max(size, desc->DepthOrArraySize);
+        desc->MipLevels = vkd3d_log2i(size) + 1;
+    }
+
+    return S_OK;
+}
+
 static HRESULT d3d12_committed_resource_init(struct d3d12_resource *resource, struct d3d12_device *device,
         const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags,
         const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state,
@@ -658,8 +684,10 @@ static HRESULT d3d12_committed_resource_init(struct d3d12_resource *resource, st
     switch (desc->Dimension)
     {
         case D3D12_RESOURCE_DIMENSION_BUFFER:
-            if (FAILED(hr = vkd3d_create_buffer(device, heap_properties, heap_flags, desc,
-                    &resource->u.vk_buffer)))
+            if (FAILED(hr = validate_buffer_desc(&resource->desc)))
+                return hr;
+            if (FAILED(hr = vkd3d_create_buffer(device, heap_properties, heap_flags,
+                    &resource->desc, &resource->u.vk_buffer)))
                 return hr;
             if (!(resource->gpu_address = vkd3d_gpu_va_allocator_allocate(&device->gpu_va_allocator,
                     desc->Width, resource)))
@@ -679,8 +707,10 @@ static HRESULT d3d12_committed_resource_init(struct d3d12_resource *resource, st
         case D3D12_RESOURCE_DIMENSION_TEXTURE1D:
         case D3D12_RESOURCE_DIMENSION_TEXTURE2D:
         case D3D12_RESOURCE_DIMENSION_TEXTURE3D:
+            if (FAILED(hr = validate_texture_desc(&resource->desc)))
+                return hr;
             resource->flags |= VKD3D_RESOURCE_INITIAL_STATE_TRANSITION;
-            if (FAILED(hr = vkd3d_create_image(resource, device, heap_properties, heap_flags, desc)))
+            if (FAILED(hr = vkd3d_create_image(resource, device, heap_properties, heap_flags)))
                 return hr;
             if (FAILED(hr = vkd3d_allocate_image_memory(resource, device, heap_properties, heap_flags)))
             {
diff --git a/m4/check-builtin-functions.m4 b/m4/check-builtin-functions.m4
index c09eb4748a3a..2b24a802a3e3 100644
--- a/m4/check-builtin-functions.m4
+++ b/m4/check-builtin-functions.m4
@@ -18,6 +18,16 @@ AC_LINK_IFELSE([AC_LANG_SOURCE([int main(void) { return __sync_sub_and_fetch((in
                          [Define to 1 if you have __sync_sub_and_fetch.])],
                [AC_MSG_RESULT([no])])])
 
+dnl VKD3D_CHECK_BUILTIN_CLZ
+AC_DEFUN([VKD3D_CHECK_BUILTIN_CLZ],
+[AC_MSG_CHECKING([for __builtin_clz])
+AC_LINK_IFELSE([AC_LANG_SOURCE([int main(void) { return __builtin_clz(0); }])],
+               [AC_MSG_RESULT([yes])
+               AC_DEFINE([HAVE_BUILTIN_CLZ],
+                         [1],
+                         [Define to 1 if you have __builtin_clz.])],
+               [AC_MSG_RESULT([no])])])
+
 dnl VKD3D_CHECK_BUILTIN_POPCOUNT
 AC_DEFUN([VKD3D_CHECK_BUILTIN_POPCOUNT],
 [AC_MSG_CHECKING([for __builtin_popcount])
diff --git a/tests/d3d12.c b/tests/d3d12.c
index dfc9257bff61..55116204a209 100644
--- a/tests/d3d12.c
+++ b/tests/d3d12.c
@@ -2213,6 +2213,24 @@ static void test_create_committed_resource(void)
     refcount = ID3D12Resource_Release(resource);
     ok(!refcount, "ID3D12Resource has %u references left.\n", (unsigned int)refcount);
 
+    resource_desc.MipLevels = 0;
+    hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
+            &resource_desc, D3D12_RESOURCE_STATE_RENDER_TARGET, &clear_value,
+            &IID_ID3D12Resource, (void **)&resource);
+    ok(SUCCEEDED(hr), "Failed to create committed resource, hr %#x.\n", hr);
+    resource_desc = ID3D12Resource_GetDesc(resource);
+    ok(resource_desc.MipLevels == 6, "Got unexpected miplevels %u.\n", resource_desc.MipLevels);
+    ID3D12Resource_Release(resource);
+    resource_desc.MipLevels = 10;
+    hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
+            &resource_desc, D3D12_RESOURCE_STATE_RENDER_TARGET, &clear_value,
+            &IID_ID3D12Resource, (void **)&resource);
+    ok(SUCCEEDED(hr), "Failed to create committed resource, hr %#x.\n", hr);
+    resource_desc = ID3D12Resource_GetDesc(resource);
+    ok(resource_desc.MipLevels == 10, "Got unexpected miplevels %u.\n", resource_desc.MipLevels);
+    ID3D12Resource_Release(resource);
+    resource_desc.MipLevels = 1;
+
     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
             &resource_desc, D3D12_RESOURCE_STATE_RENDER_TARGET | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
             &clear_value, &IID_ID3D12Resource, (void **)&resource);
@@ -2291,6 +2309,13 @@ static void test_create_committed_resource(void)
     refcount = ID3D12Resource_Release(resource);
     ok(!refcount, "ID3D12Resource has %u references left.\n", (unsigned int)refcount);
 
+    resource_desc.MipLevels = 0;
+    hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
+            &resource_desc, D3D12_RESOURCE_STATE_GENERIC_READ, &clear_value,
+            &IID_ID3D12Resource, (void **)&resource);
+    ok(hr == E_INVALIDARG, "Failed to create committed resource, hr %#x.\n", hr);
+    resource_desc.MipLevels = 1;
+
     /* The clear value must be NULL for buffers. */
     hr = ID3D12Device_CreateCommittedResource(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
             &resource_desc, D3D12_RESOURCE_STATE_GENERIC_READ, &clear_value,
--
2.13.6



Reply | Threaded
Open this post in threaded view
|

[PATCH vkd3d 02/12] build: Add VKD3D_CHECK_FUNC() macro.

Józef Kucia
From: Józef Kucia <[hidden email]>

Signed-off-by: Józef Kucia <[hidden email]>
---
 configure.ac                  |  8 ++++----
 m4/check-builtin-functions.m4 | 39 ---------------------------------------
 m4/check-functions.m4         |  9 +++++++++
 3 files changed, 13 insertions(+), 43 deletions(-)
 delete mode 100644 m4/check-builtin-functions.m4
 create mode 100644 m4/check-functions.m4

diff --git a/configure.ac b/configure.ac
index d13b440755cd..5614f791fe64 100644
--- a/configure.ac
+++ b/configure.ac
@@ -79,10 +79,10 @@ AS_IF([test "x$with_spirv_tools" = "xyes"],
 PKG_CHECK_MODULES([XCB], [xcb xcb-keysyms])
 
 dnl Check for functions
-VKD3D_CHECK_BUILTIN_CLZ
-VKD3D_CHECK_BUILTIN_POPCOUNT
-VKD3D_CHECK_SYNC_ADD_AND_FETCH_FUNC
-VKD3D_CHECK_SYNC_SUB_AND_FETCH_FUNC
+VKD3D_CHECK_FUNC([HAVE_BUILTIN_CLZ], [__builtin_clz], [__builtin_clz(0)])
+VKD3D_CHECK_FUNC([HAVE_BUILTIN_POPCOUNT], [__builtin_popcount], [__builtin_popcount(0)])
+VKD3D_CHECK_FUNC([HAVE_SYNC_ADD_AND_FETCH], [__sync_add_and_fetch], [__sync_add_and_fetch((int *)0, 0)])
+VKD3D_CHECK_FUNC([HAVE_SYNC_SUB_AND_FETCH], [__sync_sub_and_fetch], [__sync_sub_and_fetch((int *)0, 0)])
 
 AM_CONDITIONAL([HAS_CROSSTARGET32], [test "x$CROSSTARGET32" != "xno"])
 AM_CONDITIONAL([HAS_CROSSTARGET64], [test "x$CROSSTARGET64" != "xno"])
diff --git a/m4/check-builtin-functions.m4 b/m4/check-builtin-functions.m4
deleted file mode 100644
index 2b24a802a3e3..000000000000
--- a/m4/check-builtin-functions.m4
+++ /dev/null
@@ -1,39 +0,0 @@
-dnl VKD3D_CHECK_SYNC_ADD_AND_FETCH_FUNC
-AC_DEFUN([VKD3D_CHECK_SYNC_ADD_AND_FETCH_FUNC],
-[AC_MSG_CHECKING([for __sync_add_and_fetch])
-AC_LINK_IFELSE([AC_LANG_SOURCE([int main(void) { return __sync_add_and_fetch((int *)0, 0); }])],
-               [AC_MSG_RESULT([yes])
-               AC_DEFINE([HAVE_SYNC_ADD_AND_FETCH],
-                         [1],
-                         [Define to 1 if you have __sync_add_and_fetch.])],
-               [AC_MSG_RESULT([no])])])
-
-dnl VKD3D_CHECK_SYNC_SUB_AND_FETCH_FUNC
-AC_DEFUN([VKD3D_CHECK_SYNC_SUB_AND_FETCH_FUNC],
-[AC_MSG_CHECKING([for __sync_sub_and_fetch])
-AC_LINK_IFELSE([AC_LANG_SOURCE([int main(void) { return __sync_sub_and_fetch((int *)0, 0); }])],
-               [AC_MSG_RESULT([yes])
-               AC_DEFINE([HAVE_SYNC_SUB_AND_FETCH],
-                         [1],
-                         [Define to 1 if you have __sync_sub_and_fetch.])],
-               [AC_MSG_RESULT([no])])])
-
-dnl VKD3D_CHECK_BUILTIN_CLZ
-AC_DEFUN([VKD3D_CHECK_BUILTIN_CLZ],
-[AC_MSG_CHECKING([for __builtin_clz])
-AC_LINK_IFELSE([AC_LANG_SOURCE([int main(void) { return __builtin_clz(0); }])],
-               [AC_MSG_RESULT([yes])
-               AC_DEFINE([HAVE_BUILTIN_CLZ],
-                         [1],
-                         [Define to 1 if you have __builtin_clz.])],
-               [AC_MSG_RESULT([no])])])
-
-dnl VKD3D_CHECK_BUILTIN_POPCOUNT
-AC_DEFUN([VKD3D_CHECK_BUILTIN_POPCOUNT],
-[AC_MSG_CHECKING([for __builtin_popcount])
-AC_LINK_IFELSE([AC_LANG_SOURCE([int main(void) { return __builtin_popcount(0); }])],
-               [AC_MSG_RESULT([yes])
-               AC_DEFINE([HAVE_BUILTIN_POPCOUNT],
-                         [1],
-                         [Define to 1 if you have __builtin_popcount.])],
-               [AC_MSG_RESULT([no])])])
diff --git a/m4/check-functions.m4 b/m4/check-functions.m4
new file mode 100644
index 000000000000..8bb8213153af
--- /dev/null
+++ b/m4/check-functions.m4
@@ -0,0 +1,9 @@
+dnl VKD3D_CHECK_FUNC
+AC_DEFUN([VKD3D_CHECK_FUNC],
+[AC_MSG_CHECKING([for $2])
+AC_LINK_IFELSE([AC_LANG_SOURCE([int main(void) { return [$3]; }])],
+               [AC_MSG_RESULT([yes])
+               AC_DEFINE([$1],
+                         [1],
+                         [Define to 1 if you have $2.])],
+               [AC_MSG_RESULT([no])])])
--
2.13.6



Reply | Threaded
Open this post in threaded view
|

[PATCH vkd3d 03/12] libs/vkd3d: Allow library user to create internal threads.

Józef Kucia
In reply to this post by Józef Kucia
From: Józef Kucia <[hidden email]>

We want to create Win32 threads when running under Wine.

Signed-off-by: Józef Kucia <[hidden email]>
---
 include/vkd3d.h                     |  7 +++++++
 libs/vkd3d-utils/vkd3d_utils_main.c |  2 ++
 libs/vkd3d/command.c                | 35 ++++++++++++++++++++++++++++++-----
 libs/vkd3d/device.c                 | 10 +++++++++-
 libs/vkd3d/vkd3d_private.h          | 12 ++++++++++--
 5 files changed, 58 insertions(+), 8 deletions(-)

diff --git a/include/vkd3d.h b/include/vkd3d.h
index f6872c3b6d6f..c4d1a2ade034 100644
--- a/include/vkd3d.h
+++ b/include/vkd3d.h
@@ -33,10 +33,17 @@ extern "C" {
 
 typedef bool (*vkd3d_signal_event_pfn)(HANDLE event);
 
+typedef void * (*vkd3d_thread_pfn)(void *data);
+
+typedef void * (*vkd3d_create_thread_pfn)(vkd3d_thread_pfn thread_main, void *data);
+typedef bool (*vkd3d_join_thread_pfn)(void *thread);
+
 struct vkd3d_device_create_info
 {
     D3D_FEATURE_LEVEL minimum_feature_level;
     vkd3d_signal_event_pfn signal_event_pfn;
+    vkd3d_create_thread_pfn create_thread_pfn;
+    vkd3d_join_thread_pfn join_thread_pfn;
     size_t wchar_size;
 };
 
diff --git a/libs/vkd3d-utils/vkd3d_utils_main.c b/libs/vkd3d-utils/vkd3d_utils_main.c
index 1d0bde1dd882..1964df15efb1 100644
--- a/libs/vkd3d-utils/vkd3d_utils_main.c
+++ b/libs/vkd3d-utils/vkd3d_utils_main.c
@@ -38,6 +38,8 @@ HRESULT WINAPI D3D12CreateDevice(IUnknown *adapter,
 
     create_info.minimum_feature_level = minimum_feature_level;
     create_info.signal_event_pfn = vkd3d_signal_event;
+    create_info.create_thread_pfn = NULL;
+    create_info.join_thread_pfn = NULL;
     create_info.wchar_size = sizeof(WCHAR);
 
     return vkd3d_create_device(&create_info, riid, device);
diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c
index cda3c1ffb8bf..f7d1699e3958 100644
--- a/libs/vkd3d/command.c
+++ b/libs/vkd3d/command.c
@@ -204,7 +204,20 @@ HRESULT vkd3d_fence_worker_start(struct vkd3d_fence_worker *worker,
         return E_FAIL;
     }
 
-    if ((rc = pthread_create(&worker->thread, NULL, vkd3d_fence_worker_main, worker)))
+    if (device->create_thread)
+    {
+        if (!(worker->u.handle = device->create_thread(vkd3d_fence_worker_main, worker)))
+        {
+            ERR("Failed to create fence worker thread.\n");
+            pthread_mutex_destroy(&worker->mutex);
+            pthread_cond_destroy(&worker->cond);
+            return E_FAIL;
+        }
+
+        return S_OK;
+    }
+
+    if ((rc = pthread_create(&worker->u.thread, NULL, vkd3d_fence_worker_main, worker)))
     {
         ERR("Failed to create fence worker thread, error %d.\n", rc);
         pthread_mutex_destroy(&worker->mutex);
@@ -215,7 +228,8 @@ HRESULT vkd3d_fence_worker_start(struct vkd3d_fence_worker *worker,
     return S_OK;
 }
 
-HRESULT vkd3d_fence_worker_stop(struct vkd3d_fence_worker *worker)
+HRESULT vkd3d_fence_worker_stop(struct vkd3d_fence_worker *worker,
+        struct d3d12_device *device)
 {
     int rc;
 
@@ -232,10 +246,21 @@ HRESULT vkd3d_fence_worker_stop(struct vkd3d_fence_worker *worker)
 
     pthread_mutex_unlock(&worker->mutex);
 
-    if ((rc = pthread_join(worker->thread, NULL)))
+    if (device->join_thread)
     {
-        ERR("Failed to join fence worker thread, error %d.\n", rc);
-        return E_FAIL;
+        if (!device->join_thread(worker->u.handle))
+        {
+            ERR("Failed to join fence worker thread.\n");
+            return E_FAIL;
+        }
+    }
+    else
+    {
+        if ((rc = pthread_join(worker->u.thread, NULL)))
+        {
+            ERR("Failed to join fence worker thread, error %d.\n", rc);
+            return E_FAIL;
+        }
     }
 
     pthread_mutex_destroy(&worker->mutex);
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index bbc87bac259b..51edd3660fb7 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -919,7 +919,7 @@ static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device *iface)
         const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
 
         vkd3d_gpu_va_allocator_cleanup(&device->gpu_va_allocator);
-        vkd3d_fence_worker_stop(&device->fence_worker);
+        vkd3d_fence_worker_stop(&device->fence_worker, device);
         VK_CALL(vkDestroySampler(device->vk_device, device->vk_default_sampler, NULL));
         if (device->vk_pipeline_cache)
             VK_CALL(vkDestroyPipelineCache(device->vk_device, device->vk_pipeline_cache, NULL));
@@ -1813,6 +1813,12 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
 {
     HRESULT hr;
 
+    if (!create_info->create_thread_pfn != !create_info->join_thread_pfn)
+    {
+        ERR("Invalid create/join thread function pointers.\n");
+        return E_INVALIDARG;
+    }
+
     device->ID3D12Device_iface.lpVtbl = &d3d12_device_vtbl;
     device->refcount = 1;
 
@@ -1828,6 +1834,8 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
     }
 
     device->signal_event = create_info->signal_event_pfn;
+    device->create_thread = create_info->create_thread_pfn;
+    device->join_thread = create_info->join_thread_pfn;
     device->wchar_size = create_info->wchar_size;
 
     if (FAILED(hr = d3d12_device_create_default_sampler(device)))
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index 9e0d6ae0eba4..ed636b562445 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -73,7 +73,11 @@ struct vkd3d_instance
 
 struct vkd3d_fence_worker
 {
-    pthread_t thread;
+    union
+    {
+        pthread_t thread;
+        void *handle;
+    } u;
     pthread_mutex_t mutex;
     pthread_cond_t cond;
     bool should_exit;
@@ -93,7 +97,8 @@ struct vkd3d_fence_worker
 
 HRESULT vkd3d_fence_worker_start(struct vkd3d_fence_worker *worker,
         struct d3d12_device *device) DECLSPEC_HIDDEN;
-HRESULT vkd3d_fence_worker_stop(struct vkd3d_fence_worker *worker) DECLSPEC_HIDDEN;
+HRESULT vkd3d_fence_worker_stop(struct vkd3d_fence_worker *worker,
+        struct d3d12_device *device) DECLSPEC_HIDDEN;
 
 struct vkd3d_gpu_va_allocator
 {
@@ -628,6 +633,9 @@ struct d3d12_device
     struct vkd3d_vulkan_info vk_info;
 
     struct vkd3d_instance vkd3d_instance;
+
+    vkd3d_create_thread_pfn create_thread;
+    vkd3d_join_thread_pfn join_thread;
 };
 
 HRESULT d3d12_device_create(const struct vkd3d_device_create_info *create_info,
--
2.13.6



Reply | Threaded
Open this post in threaded view
|

[PATCH vkd3d 04/12] libs/vkd3d: Add API for creating vkd3d instances.

Józef Kucia
In reply to this post by Józef Kucia
From: Józef Kucia <[hidden email]>

Makes possible to share a Vulkan instance between multiple devices.

Signed-off-by: Józef Kucia <[hidden email]>
---
 include/vkd3d.h                     |  22 ++++++-
 libs/vkd3d-utils/vkd3d_utils_main.c |  18 +++---
 libs/vkd3d/device.c                 | 114 +++++++++++++++++++++++++-----------
 libs/vkd3d/vkd3d_main.c             |  28 ++++++++-
 libs/vkd3d/vkd3d_private.h          |  34 +++++++----
 5 files changed, 158 insertions(+), 58 deletions(-)

diff --git a/include/vkd3d.h b/include/vkd3d.h
index c4d1a2ade034..8a04dbd97cfa 100644
--- a/include/vkd3d.h
+++ b/include/vkd3d.h
@@ -38,27 +38,41 @@ typedef void * (*vkd3d_thread_pfn)(void *data);
 typedef void * (*vkd3d_create_thread_pfn)(vkd3d_thread_pfn thread_main, void *data);
 typedef bool (*vkd3d_join_thread_pfn)(void *thread);
 
-struct vkd3d_device_create_info
+struct vkd3d_instance;
+
+struct vkd3d_instance_create_info
 {
-    D3D_FEATURE_LEVEL minimum_feature_level;
     vkd3d_signal_event_pfn signal_event_pfn;
     vkd3d_create_thread_pfn create_thread_pfn;
     vkd3d_join_thread_pfn join_thread_pfn;
     size_t wchar_size;
 };
 
+struct vkd3d_device_create_info
+{
+    D3D_FEATURE_LEVEL minimum_feature_level;
+
+    struct vkd3d_instance *instance;
+    const struct vkd3d_instance_create_info *instance_create_info;
+};
+
 /* resource flags */
 #define VKD3D_RESOURCE_INITIAL_STATE_TRANSITION 0x00000001
 #define VKD3D_RESOURCE_SWAPCHAIN_IMAGE          0x00000002
 
+HRESULT vkd3d_create_instance(const struct vkd3d_instance_create_info *create_info,
+        struct vkd3d_instance **instance);
+ULONG vkd3d_instance_decref(struct vkd3d_instance *instance);
+ULONG vkd3d_instance_incref(struct vkd3d_instance *instance);
+
 HRESULT vkd3d_create_device(const struct vkd3d_device_create_info *create_info,
         REFIID riid, void **device);
 HRESULT vkd3d_create_image_resource(ID3D12Device *device, const D3D12_RESOURCE_DESC *desc,
         VkImage vk_image, unsigned int resource_flags, ID3D12Resource **resource);
 VkDevice vkd3d_get_vk_device(ID3D12Device *device);
-VkFormat vkd3d_get_vk_format(DXGI_FORMAT format);
 VkInstance vkd3d_get_vk_instance(ID3D12Device *device);
 VkPhysicalDevice vkd3d_get_vk_physical_device(ID3D12Device *device);
+
 VkQueue vkd3d_get_vk_queue(ID3D12CommandQueue *queue);
 uint32_t vkd3d_get_vk_queue_family_index(ID3D12CommandQueue *queue);
 
@@ -68,6 +82,8 @@ HRESULT vkd3d_serialize_root_signature(const D3D12_ROOT_SIGNATURE_DESC *root_sig
 HRESULT vkd3d_create_root_signature_deserializer(const void *data, SIZE_T data_size,
         REFIID iid, void **deserializer);
 
+VkFormat vkd3d_get_vk_format(DXGI_FORMAT format);
+
 #ifdef __cplusplus
 }
 #endif  /* __cplusplus */
diff --git a/libs/vkd3d-utils/vkd3d_utils_main.c b/libs/vkd3d-utils/vkd3d_utils_main.c
index 1964df15efb1..38283bf23585 100644
--- a/libs/vkd3d-utils/vkd3d_utils_main.c
+++ b/libs/vkd3d-utils/vkd3d_utils_main.c
@@ -28,7 +28,8 @@ HRESULT WINAPI D3D12GetDebugInterface(REFIID riid, void **debug)
 HRESULT WINAPI D3D12CreateDevice(IUnknown *adapter,
         D3D_FEATURE_LEVEL minimum_feature_level, REFIID riid, void **device)
 {
-    struct vkd3d_device_create_info create_info;
+    struct vkd3d_instance_create_info instance_create_info;
+    struct vkd3d_device_create_info device_create_info;
 
     TRACE("adapter %p, minimum_feature_level %#x, riid %s, device %p.\n",
             adapter, minimum_feature_level, debugstr_guid(riid), device);
@@ -36,13 +37,16 @@ HRESULT WINAPI D3D12CreateDevice(IUnknown *adapter,
     if (adapter)
         FIXME("Ignoring adapter %p.\n", adapter);
 
-    create_info.minimum_feature_level = minimum_feature_level;
-    create_info.signal_event_pfn = vkd3d_signal_event;
-    create_info.create_thread_pfn = NULL;
-    create_info.join_thread_pfn = NULL;
-    create_info.wchar_size = sizeof(WCHAR);
+    instance_create_info.signal_event_pfn = vkd3d_signal_event;
+    instance_create_info.create_thread_pfn = NULL;
+    instance_create_info.join_thread_pfn = NULL;
+    instance_create_info.wchar_size = sizeof(WCHAR);
 
-    return vkd3d_create_device(&create_info, riid, device);
+    device_create_info.minimum_feature_level = minimum_feature_level;
+    device_create_info.instance = NULL;
+    device_create_info.instance_create_info = &instance_create_info;
+
+    return vkd3d_create_device(&device_create_info, riid, device);
 }
 
 HRESULT WINAPI D3D12CreateRootSignatureDeserializer(const void *data, SIZE_T data_size,
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index 51edd3660fb7..9819ea0df56b 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -170,7 +170,7 @@ static void vkd3d_init_instance_caps(struct vkd3d_vulkan_info *vulkan_info)
 }
 
 static HRESULT vkd3d_instance_init(struct vkd3d_instance *instance,
-        struct vkd3d_vulkan_info *vk_info)
+        const struct vkd3d_instance_create_info *create_info)
 {
     const char *extensions[MAX_INSTANCE_EXTENSION_COUNT];
     VkApplicationInfo application_info;
@@ -179,7 +179,19 @@ static HRESULT vkd3d_instance_init(struct vkd3d_instance *instance,
     VkResult vr;
     HRESULT hr;
 
-    TRACE("instance %p.\n", instance);
+    if (!create_info->create_thread_pfn != !create_info->join_thread_pfn)
+    {
+        ERR("Invalid create/join thread function pointers.\n");
+        return E_INVALIDARG;
+    }
+
+    instance->signal_event = create_info->signal_event_pfn;
+    instance->create_thread = create_info->create_thread_pfn;
+    instance->join_thread = create_info->join_thread_pfn;
+    instance->wchar_size = create_info->wchar_size;
+
+    memset(&instance->vk_info, 0, sizeof(instance->vk_info));
+    vkd3d_init_instance_caps(&instance->vk_info);
 
     application_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
     application_info.pNext = NULL;
@@ -198,7 +210,7 @@ static HRESULT vkd3d_instance_init(struct vkd3d_instance *instance,
     instance_info.enabledExtensionCount = vkd3d_enable_extensions(extensions,
             required_instance_extensions, ARRAY_SIZE(required_instance_extensions),
             optional_instance_extensions, ARRAY_SIZE(optional_instance_extensions),
-            vk_info);
+            &instance->vk_info);
     instance_info.ppEnabledExtensionNames = extensions;
 
     if ((vr = vkCreateInstance(&instance_info, NULL, &vk_instance)))
@@ -218,16 +230,58 @@ static HRESULT vkd3d_instance_init(struct vkd3d_instance *instance,
 
     TRACE("Created Vulkan instance %p.\n", vk_instance);
 
+    instance->refcount = 1;
+
     return S_OK;
 }
 
-static void vkd3d_instance_destroy(struct vkd3d_instance *instance)
+HRESULT vkd3d_create_instance(const struct vkd3d_instance_create_info *create_info,
+        struct vkd3d_instance **instance)
 {
-    const struct vkd3d_vk_instance_procs *vk_procs = &instance->vk_procs;
+    struct vkd3d_instance *object;
+    HRESULT hr;
 
-    TRACE("instance %p.\n", instance);
+    TRACE("create_info %p.\n", create_info);
 
-    VK_CALL(vkDestroyInstance(instance->vk_instance, NULL));
+    if (!(object = vkd3d_malloc(sizeof(*object))))
+        return E_OUTOFMEMORY;
+
+    if (FAILED(hr = vkd3d_instance_init(object, create_info)))
+    {
+        vkd3d_free(object);
+        return hr;
+    }
+
+    TRACE("Created instance %p.\n", object);
+
+    *instance = object;
+
+    return S_OK;
+}
+
+ULONG vkd3d_instance_incref(struct vkd3d_instance *instance)
+{
+    ULONG refcount = InterlockedIncrement(&instance->refcount);
+
+    TRACE("%p increasing refcount to %u.\n", instance, refcount);
+
+    return refcount;
+}
+
+ULONG vkd3d_instance_decref(struct vkd3d_instance *instance)
+{
+    ULONG refcount = InterlockedDecrement(&instance->refcount);
+
+    TRACE("%p decreasing refcount to %u.\n", instance, refcount);
+
+    if (!refcount)
+    {
+        const struct vkd3d_vk_instance_procs *vk_procs = &instance->vk_procs;
+        VK_CALL(vkDestroyInstance(instance->vk_instance, NULL));
+        vkd3d_free(instance);
+    }
+
+    return refcount;
 }
 
 static void vkd3d_trace_physical_device(VkPhysicalDevice device,
@@ -502,7 +556,7 @@ static void vkd3d_check_feature_level_11_requirements(const VkPhysicalDeviceLimi
 static void vkd3d_init_device_caps(struct d3d12_device *device,
         const VkPhysicalDeviceFeatures *features)
 {
-    const struct vkd3d_vk_instance_procs *vk_procs = &device->vkd3d_instance.vk_procs;
+    const struct vkd3d_vk_instance_procs *vk_procs = &device->vkd3d_instance->vk_procs;
     VkPhysicalDevice physical_device = device->vk_physical_device;
     struct vkd3d_vulkan_info *vulkan_info = &device->vk_info;
     VkPhysicalDeviceProperties device_properties;
@@ -629,7 +683,7 @@ static HRESULT vkd3d_create_vk_device(struct d3d12_device *device)
 {
     unsigned int direct_queue_family_index, copy_queue_family_index, compute_queue_family_index;
     uint32_t direct_queue_timestamp_bits, copy_queue_timestamp_bits, compute_queue_timestamp_bits;
-    const struct vkd3d_vk_instance_procs *vk_procs = &device->vkd3d_instance.vk_procs;
+    const struct vkd3d_vk_instance_procs *vk_procs = &device->vkd3d_instance->vk_procs;
     const char *extensions[MAX_DEVICE_EXTENSION_COUNT];
     VkQueueFamilyProperties *queue_properties;
     VkPhysicalDeviceFeatures device_features;
@@ -645,7 +699,7 @@ static HRESULT vkd3d_create_vk_device(struct d3d12_device *device)
     TRACE("device %p.\n", device);
 
     physical_device = VK_NULL_HANDLE;
-    if (FAILED(hr = vkd3d_select_physical_device(&device->vkd3d_instance, &physical_device)))
+    if (FAILED(hr = vkd3d_select_physical_device(device->vkd3d_instance, &physical_device)))
         return hr;
 
     /* Create command queues */
@@ -924,7 +978,7 @@ static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device *iface)
         if (device->vk_pipeline_cache)
             VK_CALL(vkDestroyPipelineCache(device->vk_device, device->vk_pipeline_cache, NULL));
         VK_CALL(vkDestroyDevice(device->vk_device, NULL));
-        vkd3d_instance_destroy(&device->vkd3d_instance);
+        vkd3d_instance_decref(device->vkd3d_instance);
 
         vkd3d_free(device);
     }
@@ -1808,42 +1862,32 @@ struct d3d12_device *unsafe_impl_from_ID3D12Device(ID3D12Device *iface)
     return impl_from_ID3D12Device(iface);
 }
 
-static HRESULT d3d12_device_init(struct d3d12_device *device,
-        const struct vkd3d_device_create_info *create_info)
+static HRESULT d3d12_device_init(struct d3d12_device *device, struct vkd3d_instance *instance)
 {
     HRESULT hr;
 
-    if (!create_info->create_thread_pfn != !create_info->join_thread_pfn)
-    {
-        ERR("Invalid create/join thread function pointers.\n");
-        return E_INVALIDARG;
-    }
-
     device->ID3D12Device_iface.lpVtbl = &d3d12_device_vtbl;
     device->refcount = 1;
 
-    memset(&device->vk_info, 0, sizeof(device->vk_info));
-    vkd3d_init_instance_caps(&device->vk_info);
-    if (FAILED(hr = vkd3d_instance_init(&device->vkd3d_instance, &device->vk_info)))
-        return hr;
+    vkd3d_instance_incref(device->vkd3d_instance = instance);
+    device->vk_info = instance->vk_info;
+    device->signal_event = instance->signal_event;
+    device->create_thread = instance->create_thread;
+    device->join_thread = instance->join_thread;
+    device->wchar_size = instance->wchar_size;
 
     if (FAILED(hr = vkd3d_create_vk_device(device)))
     {
-        vkd3d_instance_destroy(&device->vkd3d_instance);
+        vkd3d_instance_decref(device->vkd3d_instance);
         return hr;
     }
 
-    device->signal_event = create_info->signal_event_pfn;
-    device->create_thread = create_info->create_thread_pfn;
-    device->join_thread = create_info->join_thread_pfn;
-    device->wchar_size = create_info->wchar_size;
-
     if (FAILED(hr = d3d12_device_create_default_sampler(device)))
     {
         const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
         ERR("Failed to create default sampler, hr %#x.\n", hr);
         VK_CALL(vkDestroyDevice(device->vk_device, NULL));
-        vkd3d_instance_destroy(&device->vkd3d_instance);
+        vkd3d_instance_decref(device->vkd3d_instance);
         return hr;
     }
 
@@ -1852,7 +1896,7 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
         const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
         VK_CALL(vkDestroySampler(device->vk_device, device->vk_default_sampler, NULL));
         VK_CALL(vkDestroyDevice(device->vk_device, NULL));
-        vkd3d_instance_destroy(&device->vkd3d_instance);
+        vkd3d_instance_decref(device->vkd3d_instance);
         return hr;
     }
 
@@ -1863,8 +1907,7 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
     return S_OK;
 }
 
-HRESULT d3d12_device_create(const struct vkd3d_device_create_info *create_info,
-        struct d3d12_device **device)
+HRESULT d3d12_device_create(struct vkd3d_instance *instance, struct d3d12_device **device)
 {
     struct d3d12_device *object;
     HRESULT hr;
@@ -1872,7 +1915,7 @@ HRESULT d3d12_device_create(const struct vkd3d_device_create_info *create_info,
     if (!(object = vkd3d_malloc(sizeof(*object))))
         return E_OUTOFMEMORY;
 
-    if (FAILED(hr = d3d12_device_init(object, create_info)))
+    if (FAILED(hr = d3d12_device_init(object, instance)))
     {
         vkd3d_free(object);
         return hr;
@@ -1895,8 +1938,9 @@ VkDevice vkd3d_get_vk_device(ID3D12Device *device)
 VkInstance vkd3d_get_vk_instance(ID3D12Device *device)
 {
     struct d3d12_device *d3d12_device = impl_from_ID3D12Device(device);
+    struct vkd3d_instance *instance = d3d12_device->vkd3d_instance;
 
-    return d3d12_device->vkd3d_instance.vk_instance;
+    return instance->vk_instance;
 }
 
 VkPhysicalDevice vkd3d_get_vk_physical_device(ID3D12Device *device)
diff --git a/libs/vkd3d/vkd3d_main.c b/libs/vkd3d/vkd3d_main.c
index d1cb87bebd22..005e6bf240cc 100644
--- a/libs/vkd3d/vkd3d_main.c
+++ b/libs/vkd3d/vkd3d_main.c
@@ -22,11 +22,25 @@
 HRESULT vkd3d_create_device(const struct vkd3d_device_create_info *create_info,
         REFIID riid, void **device)
 {
+    struct vkd3d_instance *instance;
     struct d3d12_device *object;
     HRESULT hr;
 
     TRACE("create_info %p, riid %s, device %p.\n", create_info, debugstr_guid(riid), device);
 
+    if (!create_info || !device)
+        return E_INVALIDARG;
+    if (!create_info->instance && !create_info->instance_create_info)
+    {
+        ERR("Instance or instance create info is required.\n");
+        return E_INVALIDARG;
+    }
+    if (create_info->instance && create_info->instance_create_info)
+    {
+        ERR("Instance and instance create info are mutually exclusive parameters.\n");
+        return E_INVALIDARG;
+    }
+
     if (create_info->minimum_feature_level < D3D_FEATURE_LEVEL_11_0
             || !is_valid_feature_level(create_info->minimum_feature_level))
     {
@@ -40,7 +54,19 @@ HRESULT vkd3d_create_device(const struct vkd3d_device_create_info *create_info,
         return E_INVALIDARG;
     }
 
-    if (FAILED(hr = d3d12_device_create(create_info, &object)))
+    if ((instance = create_info->instance))
+    {
+        vkd3d_instance_incref(instance);
+    }
+    else if (FAILED(hr = vkd3d_create_instance(create_info->instance_create_info, &instance)))
+    {
+        WARN("Failed to create instance, hr %#x.\n", hr);
+        return E_FAIL;
+    }
+
+    hr = d3d12_device_create(instance, &object);
+    vkd3d_instance_decref(instance);
+    if (FAILED(hr))
         return hr;
 
     return return_interface((IUnknown *)&object->ID3D12Device_iface, &IID_ID3D12Device,
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index ed636b562445..d09cb53eef8b 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -65,10 +65,30 @@ struct vkd3d_vk_device_procs
 };
 #undef DECLARE_VK_PFN
 
+struct vkd3d_vulkan_info
+{
+    /* instance extensions */
+    bool KHR_get_physical_device_properties2;
+    /* device extensions */
+    bool KHR_push_descriptor;
+
+    VkPhysicalDeviceLimits device_limits;
+    VkPhysicalDeviceSparseProperties sparse_properties;
+};
+
 struct vkd3d_instance
 {
     VkInstance vk_instance;
     struct vkd3d_vk_instance_procs vk_procs;
+
+    vkd3d_signal_event_pfn signal_event;
+    vkd3d_create_thread_pfn create_thread;
+    vkd3d_join_thread_pfn join_thread;
+    size_t wchar_size;
+
+    struct vkd3d_vulkan_info vk_info;
+
+    LONG refcount;
 };
 
 struct vkd3d_fence_worker
@@ -591,15 +611,6 @@ HRESULT d3d12_command_signature_create(struct d3d12_device *device, const D3D12_
         struct d3d12_command_signature **signature) DECLSPEC_HIDDEN;
 struct d3d12_command_signature *unsafe_impl_from_ID3D12CommandSignature(ID3D12CommandSignature *iface) DECLSPEC_HIDDEN;
 
-struct vkd3d_vulkan_info
-{
-    bool KHR_get_physical_device_properties2;
-    bool KHR_push_descriptor;
-
-    VkPhysicalDeviceLimits device_limits;
-    VkPhysicalDeviceSparseProperties sparse_properties;
-};
-
 /* ID3D12Device */
 struct d3d12_device
 {
@@ -632,14 +643,13 @@ struct d3d12_device
 
     struct vkd3d_vulkan_info vk_info;
 
-    struct vkd3d_instance vkd3d_instance;
+    struct vkd3d_instance *vkd3d_instance;
 
     vkd3d_create_thread_pfn create_thread;
     vkd3d_join_thread_pfn join_thread;
 };
 
-HRESULT d3d12_device_create(const struct vkd3d_device_create_info *create_info,
-        struct d3d12_device **device) DECLSPEC_HIDDEN;
+HRESULT d3d12_device_create(struct vkd3d_instance *instance, struct d3d12_device **device) DECLSPEC_HIDDEN;
 struct d3d12_device *unsafe_impl_from_ID3D12Device(ID3D12Device *iface) DECLSPEC_HIDDEN;
 
 HRESULT vkd3d_create_buffer(struct d3d12_device *device,
--
2.13.6



Reply | Threaded
Open this post in threaded view
|

[PATCH vkd3d 05/12] tests: Add test for creating vkd3d instances.

Józef Kucia
In reply to this post by Józef Kucia
From: Józef Kucia <[hidden email]>

Signed-off-by: Józef Kucia <[hidden email]>
---
 Makefile.am       | 11 +++++---
 tests/vkd3d_api.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 91 insertions(+), 4 deletions(-)
 create mode 100644 tests/vkd3d_api.c

diff --git a/Makefile.am b/Makefile.am
index 4d32b2fde1f0..2876f6486df4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -33,6 +33,9 @@ vkd3d_demos_shaders = \
  demos/triangle_vs.h
 
 vkd3d_tests = \
+ tests/vkd3d_api
+
+vkd3d_cross_tests = \
  tests/d3d12
 
 vkd3d_demos = \
@@ -101,9 +104,9 @@ vkd3d_compiler_SOURCES = programs/vkd3d-compiler/main.c
 vkd3d_compiler_LDADD = libvkd3d-shader.la
 
 LDADD = libvkd3d.la libvkd3d-utils.la
-check_PROGRAMS = $(vkd3d_tests)
+check_PROGRAMS = $(vkd3d_tests) $(vkd3d_cross_tests)
 AM_DEFAULT_SOURCE_EXT = .c
-TESTS = $(vkd3d_tests)
+TESTS = $(vkd3d_tests) $(vkd3d_cross_tests)
 tests_d3d12_LDADD = $(LDADD) @PTHREAD_LIBS@
 
 DEMOS_LDADD = $(LDADD) libvkd3d-shader.la @XCB_LIBS@ @VULKAN_LIBS@
@@ -154,7 +157,7 @@ if HAS_CROSSTARGET32
 CROSS32_CC = @CROSSCC32@
 CROSS32_DLLTOOL = @CROSSTARGET32@-dlltool
 CROSS32_IMPLIBS = $(cross_implibs:=.cross32.a)
-CROSS32_EXEFILES = $(vkd3d_tests:=.cross32.exe) $(vkd3d_demos:=.cross32.exe)
+CROSS32_EXEFILES = $(vkd3d_cross_tests:=.cross32.exe) $(vkd3d_demos:=.cross32.exe)
 CROSS32_FILES = $(CROSS32_IMPLIBS) $(CROSS32_EXEFILES)
 
 CLEANFILES += $(CROSS32_FILES)
@@ -179,7 +182,7 @@ if HAS_CROSSTARGET64
 CROSS64_CC = @CROSSCC64@
 CROSS64_DLLTOOL = @CROSSTARGET64@-dlltool
 CROSS64_IMPLIBS = $(cross_implibs:=.cross64.a)
-CROSS64_EXEFILES = $(vkd3d_tests:=.cross64.exe) $(vkd3d_demos:=.cross64.exe)
+CROSS64_EXEFILES = $(vkd3d_cross_tests:=.cross64.exe) $(vkd3d_demos:=.cross64.exe)
 CROSS64_FILES = $(CROSS64_IMPLIBS) $(CROSS64_EXEFILES)
 
 CLEANFILES += $(CROSS64_FILES)
diff --git a/tests/vkd3d_api.c b/tests/vkd3d_api.c
new file mode 100644
index 000000000000..871dbe29349d
--- /dev/null
+++ b/tests/vkd3d_api.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright 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
+ */
+
+#define COBJMACROS
+#define INITGUID
+#define WIDL_C_INLINE_WRAPPERS
+#include "vkd3d_test.h"
+#include <vkd3d.h>
+
+static bool signal_event(HANDLE event)
+{
+    trace("Signal event %p.\n", event);
+    return true;
+}
+
+static void test_create_instance(void)
+{
+    struct vkd3d_instance_create_info create_info;
+    struct vkd3d_instance *instance;
+    ULONG refcount;
+    HRESULT hr;
+
+    memset(&create_info, 0, sizeof(create_info));
+    create_info.wchar_size = sizeof(WCHAR);
+
+    hr = vkd3d_create_instance(&create_info, &instance);
+    ok(hr == S_OK, "Failed to create instance, hr %#x.\n", hr);
+    refcount = vkd3d_instance_incref(instance);
+    ok(refcount == 2, "Got unexpected refcount %u.\n", refcount);
+    vkd3d_instance_decref(instance);
+    refcount = vkd3d_instance_decref(instance);
+    ok(!refcount, "Instance has %u references left.\n", refcount);
+
+    create_info.signal_event_pfn = signal_event;
+    hr = vkd3d_create_instance(&create_info, &instance);
+    ok(hr == S_OK, "Failed to create instance, hr %#x.\n", hr);
+    refcount = vkd3d_instance_decref(instance);
+    ok(!refcount, "Instance has %u references left.\n", refcount);
+}
+
+static bool have_d3d12_device(void)
+{
+    struct vkd3d_instance_create_info instance_create_info =
+    {
+        .wchar_size = sizeof(WCHAR),
+    };
+    struct vkd3d_device_create_info device_create_info =
+    {
+        .minimum_feature_level = D3D_FEATURE_LEVEL_11_0,
+        .instance_create_info = &instance_create_info,
+    };
+    ID3D12Device *device;
+    HRESULT hr;
+
+    if (SUCCEEDED(hr = vkd3d_create_device(&device_create_info, &IID_ID3D12Device, (void **)&device)))
+        ID3D12Device_Release(device);
+    return hr == S_OK;
+}
+
+START_TEST(vkd3d_api)
+{
+    if (!have_d3d12_device())
+    {
+        skip("D3D12 device cannot be created.\n");
+        return;
+    }
+
+    run_test(test_create_instance);
+}
--
2.13.6



Reply | Threaded
Open this post in threaded view
|

[PATCH vkd3d 06/12] tests: Add test for vkd3d_create_device().

Józef Kucia
In reply to this post by Józef Kucia
From: Józef Kucia <[hidden email]>

Signed-off-by: Józef Kucia <[hidden email]>
---
 tests/vkd3d_api.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 60 insertions(+), 10 deletions(-)

diff --git a/tests/vkd3d_api.c b/tests/vkd3d_api.c
index 871dbe29349d..79d51ccd36aa 100644
--- a/tests/vkd3d_api.c
+++ b/tests/vkd3d_api.c
@@ -28,6 +28,18 @@ static bool signal_event(HANDLE event)
     return true;
 }
 
+static const struct vkd3d_instance_create_info instance_default_create_info =
+{
+    .wchar_size = sizeof(WCHAR),
+    .signal_event_pfn = signal_event,
+};
+
+static const struct vkd3d_device_create_info device_default_create_info =
+{
+    .minimum_feature_level = D3D_FEATURE_LEVEL_11_0,
+    .instance_create_info = &instance_default_create_info,
+};
+
 static void test_create_instance(void)
 {
     struct vkd3d_instance_create_info create_info;
@@ -53,21 +65,58 @@ static void test_create_instance(void)
     ok(!refcount, "Instance has %u references left.\n", refcount);
 }
 
+static void test_create_device(void)
+{
+    struct vkd3d_device_create_info create_info;
+    struct vkd3d_instance *instance;
+    ID3D12Device *device;
+    ULONG refcount;
+    HRESULT hr;
+
+    hr = vkd3d_create_device(NULL, &IID_ID3D12Device, (void **)&device);
+    ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
+
+    create_info = device_default_create_info;
+    create_info.instance = NULL;
+    create_info.instance_create_info = NULL;
+    hr = vkd3d_create_device(&create_info, &IID_ID3D12Device, (void **)&device);
+    ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
+
+    create_info.instance_create_info = &instance_default_create_info;
+    hr = vkd3d_create_device(&create_info, &IID_ID3D12Device, (void **)&device);
+    ok(hr == S_OK, "Failed to create device, hr %#x.\n", hr);
+    refcount = ID3D12Device_Release(device);
+    ok(!refcount, "Device has %u references left.\n", refcount);
+
+    hr = vkd3d_create_instance(&instance_default_create_info, &instance);
+    ok(hr == S_OK, "Failed to create instance, hr %#x.\n", hr);
+
+    create_info.instance = instance;
+    create_info.instance_create_info = NULL;
+    hr = vkd3d_create_device(&create_info, &IID_ID3D12Device, (void **)&device);
+    ok(hr == S_OK, "Failed to create device, hr %#x.\n", hr);
+    refcount = vkd3d_instance_incref(instance);
+    ok(refcount >= 3, "Got unexpected refcount %u.\n", refcount);
+    vkd3d_instance_decref(instance);
+    refcount = ID3D12Device_Release(device);
+    ok(!refcount, "Device has %u references left.\n", refcount);
+
+    create_info.instance = instance;
+    create_info.instance_create_info = &instance_default_create_info;
+    hr = vkd3d_create_device(&create_info, &IID_ID3D12Device, (void **)&device);
+    ok(hr == E_INVALIDARG, "Got unexpected hr %#x.\n", hr);
+
+    refcount = vkd3d_instance_decref(instance);
+    ok(!refcount, "Instance has %u references left.\n", refcount);
+}
+
 static bool have_d3d12_device(void)
 {
-    struct vkd3d_instance_create_info instance_create_info =
-    {
-        .wchar_size = sizeof(WCHAR),
-    };
-    struct vkd3d_device_create_info device_create_info =
-    {
-        .minimum_feature_level = D3D_FEATURE_LEVEL_11_0,
-        .instance_create_info = &instance_create_info,
-    };
     ID3D12Device *device;
     HRESULT hr;
 
-    if (SUCCEEDED(hr = vkd3d_create_device(&device_create_info, &IID_ID3D12Device, (void **)&device)))
+    if (SUCCEEDED(hr = vkd3d_create_device(&device_default_create_info,
+            &IID_ID3D12Device, (void **)&device)))
         ID3D12Device_Release(device);
     return hr == S_OK;
 }
@@ -81,4 +130,5 @@ START_TEST(vkd3d_api)
     }
 
     run_test(test_create_instance);
+    run_test(test_create_device);
 }
--
2.13.6



Reply | Threaded
Open this post in threaded view
|

[PATCH vkd3d 07/12] libs/vkd3d: Validate WCHAR size.

Józef Kucia
In reply to this post by Józef Kucia
From: Józef Kucia <[hidden email]>

Signed-off-by: Józef Kucia <[hidden email]>
---
 libs/vkd3d/device.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index 9819ea0df56b..198971aca8b9 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -184,6 +184,11 @@ static HRESULT vkd3d_instance_init(struct vkd3d_instance *instance,
         ERR("Invalid create/join thread function pointers.\n");
         return E_INVALIDARG;
     }
+    if (create_info->wchar_size != 2 && create_info->wchar_size != 4)
+    {
+        ERR("Unexpected WCHAR size %zu.\n", create_info->wchar_size);
+        return E_INVALIDARG;
+    }
 
     instance->signal_event = create_info->signal_event_pfn;
     instance->create_thread = create_info->create_thread_pfn;
--
2.13.6



Reply | Threaded
Open this post in threaded view
|

[PATCH vkd3d 08/12] libs/vkd3d-shader: Translate dcl_maxout instructions.

Józef Kucia
In reply to this post by Józef Kucia
From: Józef Kucia <[hidden email]>

Signed-off-by: Józef Kucia <[hidden email]>
---
 libs/vkd3d-shader/spirv.c | 36 ++++++++++++++++++++++++++++++++++--
 1 file changed, 34 insertions(+), 2 deletions(-)

diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 79127c527201..b31e9f1de035 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -228,6 +228,10 @@ struct vkd3d_spirv_builder
         } compute;
         struct
         {
+            uint32_t output_vertices;
+        } geometry;
+        struct
+        {
             bool depth_replacing;
         } fragment;
     } u;
@@ -318,6 +322,15 @@ static void vkd3d_spirv_set_local_size(struct vkd3d_spirv_builder *builder,
     builder->u.compute.local_size[2] = z;
 }
 
+static void vkd3d_spirv_set_output_vertices(struct vkd3d_spirv_builder *builder,
+        unsigned int output_vertex_count)
+{
+    assert(builder->execution_model == SpvExecutionModelGeometry);
+
+    assert(output_vertex_count > 0);
+    builder->u.geometry.output_vertices = output_vertex_count;
+}
+
 static void vkd3d_spirv_enable_depth_replacing(struct vkd3d_spirv_builder *builder)
 {
     assert(builder->execution_model == SpvExecutionModelFragment);
@@ -1513,16 +1526,24 @@ static void vkd3d_spirv_builder_free(struct vkd3d_spirv_builder *builder)
 static void vkd3d_spirv_build_execution_mode_declarations(struct vkd3d_spirv_builder *builder,
         struct vkd3d_spirv_stream *stream)
 {
+    const uint32_t function_id = builder->main_function_id;
+
     switch (builder->execution_model)
     {
+        case SpvExecutionModelGeometry:
+            if (builder->u.geometry.output_vertices)
+                vkd3d_spirv_build_op_execution_mode(stream, function_id,
+                    SpvExecutionModeOutputVertices, &builder->u.geometry.output_vertices, 1);
+            break;
+
         case SpvExecutionModelFragment:
             if (builder->u.fragment.depth_replacing)
-                vkd3d_spirv_build_op_execution_mode(stream, builder->main_function_id,
+                vkd3d_spirv_build_op_execution_mode(stream, function_id,
                         SpvExecutionModeDepthReplacing, NULL, 0);
             break;
 
         case SpvExecutionModelGLCompute:
-            vkd3d_spirv_build_op_execution_mode(stream, builder->main_function_id,
+            vkd3d_spirv_build_op_execution_mode(stream, function_id,
                     SpvExecutionModeLocalSize, builder->u.compute.local_size,
                     ARRAY_SIZE(builder->u.compute.local_size));
             break;
@@ -3548,6 +3569,14 @@ static void vkd3d_dxbc_compiler_emit_dcl_output_siv(struct vkd3d_dxbc_compiler *
             instruction->declaration.register_semantic.sysval_semantic);
 }
 
+static void vkd3d_dxbc_compiler_emit_dcl_vertices_out(struct vkd3d_dxbc_compiler *compiler,
+        const struct vkd3d_shader_instruction *instruction)
+{
+    struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
+
+    vkd3d_spirv_set_output_vertices(builder, instruction->declaration.count);
+}
+
 static void vkd3d_dxbc_compiler_emit_dcl_thread_group(struct vkd3d_dxbc_compiler *compiler,
         const struct vkd3d_shader_instruction *instruction)
 {
@@ -5426,6 +5455,9 @@ void vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler
         case VKD3DSIH_DCL_OUTPUT_SIV:
             vkd3d_dxbc_compiler_emit_dcl_output_siv(compiler, instruction);
             break;
+        case VKD3DSIH_DCL_VERTICES_OUT:
+            vkd3d_dxbc_compiler_emit_dcl_vertices_out(compiler, instruction);
+            break;
         case VKD3DSIH_DCL_THREAD_GROUP:
             vkd3d_dxbc_compiler_emit_dcl_thread_group(compiler, instruction);
             break;
--
2.13.6



Reply | Threaded
Open this post in threaded view
|

[PATCH vkd3d 09/12] libs/vkd3d-shader: Introduce separate stream for execution mode declarations.

Józef Kucia
In reply to this post by Józef Kucia
From: Józef Kucia <[hidden email]>

Tessellation and geometry shaders generate a lot of execution mode
declarations.

Signed-off-by: Józef Kucia <[hidden email]>
---
 libs/vkd3d-shader/spirv.c | 79 +++++++++++++++++++----------------------------
 1 file changed, 32 insertions(+), 47 deletions(-)

diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index b31e9f1de035..d0d0373b3519 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -220,18 +220,12 @@ struct vkd3d_spirv_builder
     struct vkd3d_spirv_stream global_stream; /* types, constants, global variables */
     struct vkd3d_spirv_stream function_stream; /* function definitions */
 
+    struct vkd3d_spirv_stream execution_mode_stream; /* execution mode instructions */
+
     union
     {
         struct
         {
-            uint32_t local_size[3];
-        } compute;
-        struct
-        {
-            uint32_t output_vertices;
-        } geometry;
-        struct
-        {
             bool depth_replacing;
         } fragment;
     } u;
@@ -312,25 +306,6 @@ static void vkd3d_spirv_set_execution_model(struct vkd3d_spirv_builder *builder,
     }
 }
 
-static void vkd3d_spirv_set_local_size(struct vkd3d_spirv_builder *builder,
-        unsigned int x, unsigned int y, unsigned int z)
-{
-    assert(builder->execution_model == SpvExecutionModelGLCompute);
-
-    builder->u.compute.local_size[0] = x;
-    builder->u.compute.local_size[1] = y;
-    builder->u.compute.local_size[2] = z;
-}
-
-static void vkd3d_spirv_set_output_vertices(struct vkd3d_spirv_builder *builder,
-        unsigned int output_vertex_count)
-{
-    assert(builder->execution_model == SpvExecutionModelGeometry);
-
-    assert(output_vertex_count > 0);
-    builder->u.geometry.output_vertices = output_vertex_count;
-}
-
 static void vkd3d_spirv_enable_depth_replacing(struct vkd3d_spirv_builder *builder)
 {
     assert(builder->execution_model == SpvExecutionModelFragment);
@@ -783,7 +758,7 @@ static void vkd3d_spirv_build_op_entry_point(struct vkd3d_spirv_stream *stream,
 }
 
 static void vkd3d_spirv_build_op_execution_mode(struct vkd3d_spirv_stream *stream,
-        uint32_t entry_point, SpvExecutionMode mode, uint32_t *literals, unsigned int literal_count)
+        uint32_t entry_point, SpvExecutionMode mode, const uint32_t *literals, unsigned int literal_count)
 {
     vkd3d_spirv_build_op2v(stream, SpvOpExecutionMode, entry_point, mode, literals, literal_count);
 }
@@ -1491,6 +1466,7 @@ static void vkd3d_spirv_builder_init(struct vkd3d_spirv_builder *builder)
     vkd3d_spirv_stream_init(&builder->annotation_stream);
     vkd3d_spirv_stream_init(&builder->global_stream);
     vkd3d_spirv_stream_init(&builder->function_stream);
+    vkd3d_spirv_stream_init(&builder->execution_mode_stream);
 
     vkd3d_spirv_stream_init(&builder->insertion_stream);
     builder->insertion_location = ~(size_t)0;
@@ -1515,6 +1491,7 @@ static void vkd3d_spirv_builder_free(struct vkd3d_spirv_builder *builder)
     vkd3d_spirv_stream_free(&builder->annotation_stream);
     vkd3d_spirv_stream_free(&builder->global_stream);
     vkd3d_spirv_stream_free(&builder->function_stream);
+    vkd3d_spirv_stream_free(&builder->execution_mode_stream);
 
     vkd3d_spirv_stream_free(&builder->insertion_stream);
 
@@ -1523,31 +1500,19 @@ static void vkd3d_spirv_builder_free(struct vkd3d_spirv_builder *builder)
     vkd3d_free(builder->iface);
 }
 
-static void vkd3d_spirv_build_execution_mode_declarations(struct vkd3d_spirv_builder *builder,
+static void vkd3d_spirv_build_additional_execution_modes(struct vkd3d_spirv_builder *builder,
         struct vkd3d_spirv_stream *stream)
 {
     const uint32_t function_id = builder->main_function_id;
 
     switch (builder->execution_model)
     {
-        case SpvExecutionModelGeometry:
-            if (builder->u.geometry.output_vertices)
-                vkd3d_spirv_build_op_execution_mode(stream, function_id,
-                    SpvExecutionModeOutputVertices, &builder->u.geometry.output_vertices, 1);
-            break;
-
         case SpvExecutionModelFragment:
             if (builder->u.fragment.depth_replacing)
                 vkd3d_spirv_build_op_execution_mode(stream, function_id,
                         SpvExecutionModeDepthReplacing, NULL, 0);
             break;
 
-        case SpvExecutionModelGLCompute:
-            vkd3d_spirv_build_op_execution_mode(stream, function_id,
-                    SpvExecutionModeLocalSize, builder->u.compute.local_size,
-                    ARRAY_SIZE(builder->u.compute.local_size));
-            break;
-
         default:
             break;
     }
@@ -1570,6 +1535,7 @@ static bool vkd3d_spirv_compile_module(struct vkd3d_spirv_builder *builder,
     vkd3d_spirv_build_word(&stream, builder->current_id); /* bound */
     vkd3d_spirv_build_word(&stream, 0); /* schema, reserved */
 
+    /* capabilities */
     for (i = 0; capability_mask; ++i)
     {
         if (capability_mask & 1)
@@ -1579,17 +1545,21 @@ static bool vkd3d_spirv_compile_module(struct vkd3d_spirv_builder *builder,
     if (builder->capability_draw_parameters)
         vkd3d_spirv_build_op_capability(&stream, SpvCapabilityDrawParameters);
 
+    /* extensions */
     if (builder->capability_draw_parameters)
         vkd3d_spirv_build_op_extension(&stream, "SPV_KHR_shader_draw_parameters");
 
     if (builder->ext_instr_set_glsl_450)
         vkd3d_spirv_build_op_ext_inst_import(&stream, builder->ext_instr_set_glsl_450, "GLSL.std.450");
 
+    /* entry point declarations */
     vkd3d_spirv_build_op_memory_model(&stream, SpvAddressingModelLogical, SpvMemoryModelGLSL450);
     vkd3d_spirv_build_op_entry_point(&stream, builder->execution_model, builder->main_function_id,
             "main", builder->iface, builder->iface_element_count);
 
-    vkd3d_spirv_build_execution_mode_declarations(builder, &stream);
+    /* execution mode declarations */
+    vkd3d_spirv_stream_append(&stream, &builder->execution_mode_stream);
+    vkd3d_spirv_build_additional_execution_modes(builder, &stream);
 
     vkd3d_spirv_stream_append(&stream, &builder->debug_stream);
     vkd3d_spirv_stream_append(&stream, &builder->annotation_stream);
@@ -2438,6 +2408,21 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_reg(struct vkd3d_dxbc_compiler *co
     return val_id;
 }
 
+static void vkd3d_dxbc_compiler_emit_execution_mode(struct vkd3d_dxbc_compiler *compiler,
+        SpvExecutionMode mode, const uint32_t *literals, unsigned int literal_count)
+{
+    struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
+
+    vkd3d_spirv_build_op_execution_mode(&builder->execution_mode_stream,
+            builder->main_function_id, mode, literals, literal_count);
+}
+
+static void vkd3d_dxbc_compiler_emit_execution_mode1(struct vkd3d_dxbc_compiler *compiler,
+        SpvExecutionMode mode, const uint32_t literal)
+{
+    vkd3d_dxbc_compiler_emit_execution_mode(compiler, mode, &literal, 1);
+}
+
 static uint32_t vkd3d_dxbc_compiler_emit_abs(struct vkd3d_dxbc_compiler *compiler,
         const struct vkd3d_shader_register *reg, DWORD write_mask, uint32_t val_id)
 {
@@ -3572,18 +3557,18 @@ static void vkd3d_dxbc_compiler_emit_dcl_output_siv(struct vkd3d_dxbc_compiler *
 static void vkd3d_dxbc_compiler_emit_dcl_vertices_out(struct vkd3d_dxbc_compiler *compiler,
         const struct vkd3d_shader_instruction *instruction)
 {
-    struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
-
-    vkd3d_spirv_set_output_vertices(builder, instruction->declaration.count);
+    vkd3d_dxbc_compiler_emit_execution_mode1(compiler,
+            SpvExecutionModeOutputVertices, instruction->declaration.count);
 }
 
 static void vkd3d_dxbc_compiler_emit_dcl_thread_group(struct vkd3d_dxbc_compiler *compiler,
         const struct vkd3d_shader_instruction *instruction)
 {
     const struct vkd3d_shader_thread_group_size *group_size = &instruction->declaration.thread_group_size;
-    struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
+    const uint32_t local_size[] = {group_size->x, group_size->y, group_size->z};
 
-    vkd3d_spirv_set_local_size(builder, group_size->x, group_size->y, group_size->z);
+    vkd3d_dxbc_compiler_emit_execution_mode(compiler,
+            SpvExecutionModeLocalSize, local_size, ARRAY_SIZE(local_size));
 }
 
 static SpvOp vkd3d_dxbc_compiler_map_alu_instruction(const struct vkd3d_shader_instruction *instruction)
--
2.13.6



Reply | Threaded
Open this post in threaded view
|

[PATCH vkd3d 10/12] libs/vkd3d-shader: Translate geometry shader emit instructions.

Józef Kucia
In reply to this post by Józef Kucia
From: Józef Kucia <[hidden email]>

Signed-off-by: Józef Kucia <[hidden email]>
---
 libs/vkd3d-shader/spirv.c | 52 +++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 50 insertions(+), 2 deletions(-)

diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index d0d0373b3519..6a56ede95040 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -1391,6 +1391,11 @@ static uint32_t vkd3d_spirv_build_op_image_query_levels(struct vkd3d_spirv_build
             SpvOpImageQueryLevels, result_type, image_id);
 }
 
+static void vkd3d_spirv_build_op_emit_vertex(struct vkd3d_spirv_builder *builder)
+{
+    return vkd3d_spirv_build_op(&builder->function_stream, SpvOpEmitVertex);
+}
+
 static void vkd3d_spirv_build_op_control_barrier(struct vkd3d_spirv_builder *builder,
         uint32_t execution_id, uint32_t memory_id, uint32_t memory_semantics_id)
 {
@@ -3554,6 +3559,15 @@ static void vkd3d_dxbc_compiler_emit_dcl_output_siv(struct vkd3d_dxbc_compiler *
             instruction->declaration.register_semantic.sysval_semantic);
 }
 
+static void vkd3d_dxbc_compiler_emit_dcl_stream(struct vkd3d_dxbc_compiler *compiler,
+        const struct vkd3d_shader_instruction *instruction)
+{
+    unsigned int stream_idx = instruction->src[0].reg.idx[0].offset;
+
+    if (stream_idx)
+        FIXME("Multiple streams are not supported yet.\n");
+}
+
 static void vkd3d_dxbc_compiler_emit_dcl_vertices_out(struct vkd3d_dxbc_compiler *compiler,
         const struct vkd3d_shader_instruction *instruction)
 {
@@ -4146,8 +4160,7 @@ static void vkd3d_dxbc_compiler_emit_breakc(struct vkd3d_dxbc_compiler *compiler
     vkd3d_spirv_build_op_label(builder, merge_block_id);
 }
 
-static void vkd3d_dxbc_compiler_emit_return(struct vkd3d_dxbc_compiler *compiler,
-        const struct vkd3d_shader_instruction *instruction)
+static void vkd3d_dxbc_compiler_emit_output_setup_invocation(struct vkd3d_dxbc_compiler *compiler)
 {
     struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
     uint32_t void_id, function_id, arguments[MAX_REG_OUTPUT];
@@ -4164,7 +4177,14 @@ static void vkd3d_dxbc_compiler_emit_return(struct vkd3d_dxbc_compiler *compiler
 
         vkd3d_spirv_build_op_function_call(builder, void_id, function_id, arguments, count);
     }
+}
+
+static void vkd3d_dxbc_compiler_emit_return(struct vkd3d_dxbc_compiler *compiler,
+        const struct vkd3d_shader_instruction *instruction)
+{
+    struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
 
+    vkd3d_dxbc_compiler_emit_output_setup_invocation(compiler);
     vkd3d_spirv_build_op_return(builder);
 }
 
@@ -5360,6 +5380,27 @@ static void vkd3d_dxbc_compiler_emit_sync(struct vkd3d_dxbc_compiler *compiler,
     }
 }
 
+static void vkd3d_dxbc_compiler_emit_emit_stream(struct vkd3d_dxbc_compiler *compiler,
+        const struct vkd3d_shader_instruction *instruction)
+{
+    struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
+    unsigned int stream_idx;
+
+    if (instruction->handler_idx == VKD3DSIH_EMIT_STREAM)
+        stream_idx = instruction->src[0].reg.idx[0].offset;
+    else
+        stream_idx = 0;
+
+    if (stream_idx)
+    {
+        FIXME("Multiple streams are not supported yet.\n");
+        return;
+    }
+
+    vkd3d_dxbc_compiler_emit_output_setup_invocation(compiler);
+    vkd3d_spirv_build_op_emit_vertex(builder);
+}
+
 /* This function is called after declarations are processed. */
 static void vkd3d_dxbc_compiler_emit_main_prolog(struct vkd3d_dxbc_compiler *compiler)
 {
@@ -5440,6 +5481,9 @@ void vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler
         case VKD3DSIH_DCL_OUTPUT_SIV:
             vkd3d_dxbc_compiler_emit_dcl_output_siv(compiler, instruction);
             break;
+        case VKD3DSIH_DCL_STREAM:
+            vkd3d_dxbc_compiler_emit_dcl_stream(compiler, instruction);
+            break;
         case VKD3DSIH_DCL_VERTICES_OUT:
             vkd3d_dxbc_compiler_emit_dcl_vertices_out(compiler, instruction);
             break;
@@ -5608,6 +5652,10 @@ void vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler
         case VKD3DSIH_SYNC:
             vkd3d_dxbc_compiler_emit_sync(compiler, instruction);
             break;
+        case VKD3DSIH_EMIT:
+        case VKD3DSIH_EMIT_STREAM:
+            vkd3d_dxbc_compiler_emit_emit_stream(compiler, instruction);
+            break;
         case VKD3DSIH_NOP:
             break;
         default:
--
2.13.6



Reply | Threaded
Open this post in threaded view
|

[PATCH vkd3d 11/12] libs/vkd3d-shader: Translate dcl_output_topology instructions.

Józef Kucia
In reply to this post by Józef Kucia
From: Józef Kucia <[hidden email]>

Signed-off-by: Józef Kucia <[hidden email]>
---
 libs/vkd3d-shader/dxbc.c  |  4 ++--
 libs/vkd3d-shader/spirv.c | 28 ++++++++++++++++++++++++++++
 2 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c
index 9be0e79c83db..6aa2ffad84b5 100644
--- a/libs/vkd3d-shader/dxbc.c
+++ b/libs/vkd3d-shader/dxbc.c
@@ -333,7 +333,7 @@ enum vkd3d_sm4_register_type
 enum vkd3d_sm4_output_primitive_type
 {
     VKD3D_SM4_OUTPUT_PT_POINTLIST     = 0x1,
-    VKD3D_SM4_OUTPUT_PT_LINELIST      = 0x3,
+    VKD3D_SM4_OUTPUT_PT_LINESTRIP     = 0x3,
     VKD3D_SM4_OUTPUT_PT_TRIANGLESTRIP = 0x5,
 };
 
@@ -462,7 +462,7 @@ static const enum vkd3d_primitive_type output_primitive_type_table[] =
     /* UNKNOWN */                             VKD3D_PT_UNDEFINED,
     /* VKD3D_SM4_OUTPUT_PT_POINTLIST */       VKD3D_PT_POINTLIST,
     /* UNKNOWN */                             VKD3D_PT_UNDEFINED,
-    /* VKD3D_SM4_OUTPUT_PT_LINELIST */        VKD3D_PT_LINELIST,
+    /* VKD3D_SM4_OUTPUT_PT_LINESTRIP */       VKD3D_PT_LINESTRIP,
     /* UNKNOWN */                             VKD3D_PT_UNDEFINED,
     /* VKD3D_SM4_OUTPUT_PT_TRIANGLESTRIP */   VKD3D_PT_TRIANGLESTRIP,
 };
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 6a56ede95040..87121898abdb 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -3575,6 +3575,31 @@ static void vkd3d_dxbc_compiler_emit_dcl_vertices_out(struct vkd3d_dxbc_compiler
             SpvExecutionModeOutputVertices, instruction->declaration.count);
 }
 
+static void vkd3d_dxbc_compiler_emit_dcl_output_topology(struct vkd3d_dxbc_compiler *compiler,
+        const struct vkd3d_shader_instruction *instruction)
+{
+    enum vkd3d_primitive_type primitive_type = instruction->declaration.primitive_type.type;
+    SpvExecutionMode mode;
+
+    switch (primitive_type)
+    {
+        case VKD3D_PT_POINTLIST:
+            mode = SpvExecutionModeOutputPoints;
+            break;
+        case VKD3D_PT_LINESTRIP:
+            mode = SpvExecutionModeOutputLineStrip;
+            break;
+        case VKD3D_PT_TRIANGLESTRIP:
+            mode = SpvExecutionModeOutputTriangleStrip;
+            break;
+        default:
+            ERR("Unexpected primitive type %#x.\n", primitive_type);
+            return;
+    }
+
+    vkd3d_dxbc_compiler_emit_execution_mode(compiler, mode, NULL, 0);
+}
+
 static void vkd3d_dxbc_compiler_emit_dcl_thread_group(struct vkd3d_dxbc_compiler *compiler,
         const struct vkd3d_shader_instruction *instruction)
 {
@@ -5487,6 +5512,9 @@ void vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler
         case VKD3DSIH_DCL_VERTICES_OUT:
             vkd3d_dxbc_compiler_emit_dcl_vertices_out(compiler, instruction);
             break;
+        case VKD3DSIH_DCL_OUTPUT_TOPOLOGY:
+            vkd3d_dxbc_compiler_emit_dcl_output_topology(compiler, instruction);
+            break;
         case VKD3DSIH_DCL_THREAD_GROUP:
             vkd3d_dxbc_compiler_emit_dcl_thread_group(compiler, instruction);
             break;
--
2.13.6



Reply | Threaded
Open this post in threaded view
|

[PATCH vkd3d 12/12] libs/vkd3d-shader: Translate dcl_input_primitive instructions.

Józef Kucia
In reply to this post by Józef Kucia
From: Józef Kucia <[hidden email]>

Signed-off-by: Józef Kucia <[hidden email]>
---
 libs/vkd3d-shader/spirv.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 87121898abdb..202c18d61924 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -3575,6 +3575,37 @@ static void vkd3d_dxbc_compiler_emit_dcl_vertices_out(struct vkd3d_dxbc_compiler
             SpvExecutionModeOutputVertices, instruction->declaration.count);
 }
 
+static void vkd3d_dxbc_compiler_emit_dcl_input_primitive(struct vkd3d_dxbc_compiler *compiler,
+        const struct vkd3d_shader_instruction *instruction)
+{
+    enum vkd3d_primitive_type primitive_type = instruction->declaration.primitive_type.type;
+    SpvExecutionMode mode;
+
+    switch (primitive_type)
+    {
+        case VKD3D_PT_POINTLIST:
+            mode = SpvExecutionModeInputPoints;
+            break;
+        case VKD3D_PT_LINELIST:
+            mode = SpvExecutionModeInputLines;
+            break;
+        case VKD3D_PT_LINELIST_ADJ:
+            mode = SpvExecutionModeInputLinesAdjacency;
+            break;
+        case VKD3D_PT_TRIANGLELIST:
+            mode = SpvExecutionModeTriangles;
+            break;
+        case VKD3D_PT_TRIANGLELIST_ADJ:
+            mode = SpvExecutionModeInputTrianglesAdjacency;
+            break;
+        default:
+            FIXME("Unhandled primitive type %#x.\n", primitive_type);
+            return;
+    }
+
+    vkd3d_dxbc_compiler_emit_execution_mode(compiler, mode, NULL, 0);
+}
+
 static void vkd3d_dxbc_compiler_emit_dcl_output_topology(struct vkd3d_dxbc_compiler *compiler,
         const struct vkd3d_shader_instruction *instruction)
 {
@@ -5512,6 +5543,9 @@ void vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler
         case VKD3DSIH_DCL_VERTICES_OUT:
             vkd3d_dxbc_compiler_emit_dcl_vertices_out(compiler, instruction);
             break;
+        case VKD3DSIH_DCL_INPUT_PRIMITIVE:
+            vkd3d_dxbc_compiler_emit_dcl_input_primitive(compiler, instruction);
+            break;
         case VKD3DSIH_DCL_OUTPUT_TOPOLOGY:
             vkd3d_dxbc_compiler_emit_dcl_output_topology(compiler, instruction);
             break;
--
2.13.6



Reply | Threaded
Open this post in threaded view
|

Re: [PATCH vkd3d 03/12] libs/vkd3d: Allow library user to create internal threads.

Henri Verbeet
In reply to this post by Józef Kucia
On 11 January 2018 at 17:03, Józef Kucia <[hidden email]> wrote:
>  struct vkd3d_device_create_info
>  {
>      D3D_FEATURE_LEVEL minimum_feature_level;
>      vkd3d_signal_event_pfn signal_event_pfn;
> +    vkd3d_create_thread_pfn create_thread_pfn;
> +    vkd3d_join_thread_pfn join_thread_pfn;
>      size_t wchar_size;
>  };
This breaks ABI. That's still kind of ok since we haven't made an
actual public release yet, but I think we should add a version or size
field to this structure to handle this kind of thing in the future.
Alternatively, we could version the vkd3d_create_device() symbol; not
sure whether that would be preferred. It's probably not a bad idea to
review the API for those kinds of issues before we make a release
either.


Reply | Threaded
Open this post in threaded view
|

Re: [PATCH vkd3d 01/12] libs/vkd3d: Validate miplevel count while creating resources.

Henri Verbeet-2
In reply to this post by Józef Kucia
Signed-off-by: Henri Verbeet <[hidden email]>


Reply | Threaded
Open this post in threaded view
|

Re: [PATCH vkd3d 02/12] build: Add VKD3D_CHECK_FUNC() macro.

Henri Verbeet-2
In reply to this post by Józef Kucia
Signed-off-by: Henri Verbeet <[hidden email]>


Reply | Threaded
Open this post in threaded view
|

Re: [PATCH vkd3d 10/12] libs/vkd3d-shader: Translate geometry shader emit instructions.

Henri Verbeet-2
In reply to this post by Józef Kucia
Signed-off-by: Henri Verbeet <[hidden email]>


Reply | Threaded
Open this post in threaded view
|

Re: [PATCH vkd3d 12/12] libs/vkd3d-shader: Translate dcl_input_primitive instructions.

Henri Verbeet-2
In reply to this post by Józef Kucia
Signed-off-by: Henri Verbeet <[hidden email]>


Reply | Threaded
Open this post in threaded view
|

Re: [PATCH vkd3d 11/12] libs/vkd3d-shader: Translate dcl_output_topology instructions.

Henri Verbeet-2
In reply to this post by Józef Kucia
Signed-off-by: Henri Verbeet <[hidden email]>


Reply | Threaded
Open this post in threaded view
|

Re: [PATCH vkd3d 08/12] libs/vkd3d-shader: Translate dcl_maxout instructions.

Henri Verbeet-2
In reply to this post by Józef Kucia
Signed-off-by: Henri Verbeet <[hidden email]>


Reply | Threaded
Open this post in threaded view
|

Re: [PATCH vkd3d 09/12] libs/vkd3d-shader: Introduce separate stream for execution mode declarations.

Henri Verbeet-2
In reply to this post by Józef Kucia
Signed-off-by: Henri Verbeet <[hidden email]>


12