From: Józef Kucia jkucia@codeweavers.com
vkd3d_log2i() is imported from wined3d.
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- 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,
From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- 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])])])
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Józef Kucia jkucia@codeweavers.com
We want to create Win32 threads when running under Wine.
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- 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,
On 11 January 2018 at 17:03, Józef Kucia joseph.kucia@gmail.com 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.
On Thu, Jan 11, 2018 at 7:32 PM, Henri Verbeet hverbeet@gmail.com wrote:
On 11 January 2018 at 17:03, Józef Kucia joseph.kucia@gmail.com 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.
Yes, I think we need to change and extend the API before the first release. My intent was to eventually introduce a version field or a similar mechanism. However, I have more incompatible changes, and it makes more sense to introduce structure or a similar mechanism after these changes.
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Józef Kucia jkucia@codeweavers.com
Makes possible to share a Vulkan instance between multiple devices.
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- 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,
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- 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); +}
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- 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); }
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- 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;
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- 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;
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Józef Kucia jkucia@codeweavers.com
Tessellation and geometry shaders generate a lot of execution mode declarations.
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- 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)
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- 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:
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- 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;
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- 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;
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com