Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
May 2018
- 74 participants
- 1336 messages
[PATCH resend 2/8] dxgi: Implement d3d12_swapchain_GetBuffer().
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/dxgi/swapchain.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c
index 23731e0dd07b..e20e973a7185 100644
--- a/dlls/dxgi/swapchain.c
+++ b/dlls/dxgi/swapchain.c
@@ -1012,10 +1012,18 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_Present(IDXGISwapChain3 *iface,
static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetBuffer(IDXGISwapChain3 *iface,
UINT buffer_idx, REFIID iid, void **surface)
{
- FIXME("iface %p, buffer_idx %u, iid %s, surface %p stub!\n",
+ struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface);
+
+ TRACE("iface %p, buffer_idx %u, iid %s, surface %p.\n",
iface, buffer_idx, debugstr_guid(iid), surface);
- return E_NOTIMPL;
+ if (buffer_idx >= swapchain->buffer_count)
+ {
+ WARN("Invalid buffer index %u.\n", buffer_idx);
+ return DXGI_ERROR_INVALID_CALL;
+ }
+
+ return ID3D12Resource_QueryInterface(swapchain->buffers[buffer_idx], iid, surface);
}
static HRESULT STDMETHODCALLTYPE DECLSPEC_HOTPATCH d3d12_swapchain_SetFullscreenState(IDXGISwapChain3 *iface,
--
2.16.1
May 31, 2018
[PATCH v2 1/8] dxgi: Create Vulkan swapchains for D3D12.
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
Version 2: Load libvkd3d just before creating a Direct3D 12 swapchain.
---
dlls/d3d12/d3d12_main.c | 16 ++
dlls/dxgi/Makefile.in | 3 +-
dlls/dxgi/swapchain.c | 502 +++++++++++++++++++++++++++++++++++++++++++++---
3 files changed, 498 insertions(+), 23 deletions(-)
diff --git a/dlls/d3d12/d3d12_main.c b/dlls/d3d12/d3d12_main.c
index 71eb1f97a73e..91525b49a790 100644
--- a/dlls/d3d12/d3d12_main.c
+++ b/dlls/d3d12/d3d12_main.c
@@ -34,6 +34,8 @@
#include <vkd3d.h>
+#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
+
WINE_DEFAULT_DEBUG_CHANNEL(d3d12);
WINE_DECLARE_DEBUG_CHANNEL(winediag);
@@ -113,6 +115,16 @@ HRESULT WINAPI D3D12CreateDevice(IUnknown *adapter, D3D_FEATURE_LEVEL minimum_fe
struct vkd3d_device_create_info device_create_info;
const struct vulkan_funcs *vk_funcs;
+ static const char * const instance_extensions[] =
+ {
+ VK_KHR_SURFACE_EXTENSION_NAME,
+ VK_KHR_WIN32_SURFACE_EXTENSION_NAME,
+ };
+ static const char * const device_extensions[] =
+ {
+ VK_KHR_SWAPCHAIN_EXTENSION_NAME,
+ };
+
TRACE("adapter %p, minimum_feature_level %#x, iid %s, device %p.\n",
adapter, minimum_feature_level, debugstr_guid(iid), device);
@@ -132,11 +144,15 @@ HRESULT WINAPI D3D12CreateDevice(IUnknown *adapter, D3D_FEATURE_LEVEL minimum_fe
instance_create_info.wchar_size = sizeof(WCHAR);
instance_create_info.pfn_vkGetInstanceProcAddr
= (PFN_vkGetInstanceProcAddr)vk_funcs->p_vkGetInstanceProcAddr;
+ instance_create_info.instance_extensions = instance_extensions;
+ instance_create_info.instance_extension_count = ARRAY_SIZE(instance_extensions);
memset(&device_create_info, 0, sizeof(device_create_info));
device_create_info.type = VKD3D_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
device_create_info.minimum_feature_level = minimum_feature_level;
device_create_info.instance_create_info = &instance_create_info;
+ device_create_info.device_extensions = device_extensions;
+ device_create_info.device_extension_count = ARRAY_SIZE(device_extensions);
return vkd3d_create_device(&device_create_info, iid, device);
}
diff --git a/dlls/dxgi/Makefile.in b/dlls/dxgi/Makefile.in
index ce76b8eecc61..c21cb18d8ffc 100644
--- a/dlls/dxgi/Makefile.in
+++ b/dlls/dxgi/Makefile.in
@@ -1,6 +1,7 @@
MODULE = dxgi.dll
IMPORTLIB = dxgi
-IMPORTS = dxguid uuid wined3d user32
+IMPORTS = gdi32 dxguid uuid wined3d user32
+EXTRAINCL = $(VKD3D_CFLAGS)
C_SRCS = \
adapter.c \
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c
index ca4e59004ef2..23731e0dd07b 100644
--- a/dlls/dxgi/swapchain.c
+++ b/dlls/dxgi/swapchain.c
@@ -22,7 +22,21 @@
#include "dxgi_private.h"
+#ifdef SONAME_LIBVKD3D
+#define VK_NO_PROTOTYPES
+#define VKAPI_CALL
+#define VKD3D_NO_PROTOTYPES
+#define VKD3D_NO_VULKAN_H
+#define VKD3D_NO_WIN32_TYPES
+#define WINE_VK_ALIGN(x)
+#include "wine/library.h"
+#include "wine/vulkan.h"
+#include "wine/vulkan_driver.h"
+#include <vkd3d.h>
+#endif
+
WINE_DEFAULT_DEBUG_CHANNEL(dxgi);
+WINE_DECLARE_DEBUG_CHANNEL(winediag);
static inline struct d3d11_swapchain *d3d11_swapchain_from_IDXGISwapChain1(IDXGISwapChain1 *iface)
{
@@ -797,12 +811,59 @@ HRESULT d3d11_swapchain_create(IWineDXGIDevice *device, HWND window, const DXGI_
return S_OK;
}
+#ifdef SONAME_LIBVKD3D
+
+static PFN_vkd3d_acquire_vk_queue vkd3d_acquire_vk_queue;
+static PFN_vkd3d_create_image_resource vkd3d_create_image_resource;
+static PFN_vkd3d_get_vk_device vkd3d_get_vk_device;
+static PFN_vkd3d_get_vk_format vkd3d_get_vk_format;
+static PFN_vkd3d_get_vk_physical_device vkd3d_get_vk_physical_device;
+static PFN_vkd3d_get_vk_queue_family_index vkd3d_get_vk_queue_family_index;
+static PFN_vkd3d_instance_from_device vkd3d_instance_from_device;
+static PFN_vkd3d_instance_get_vk_instance vkd3d_instance_get_vk_instance;
+static PFN_vkd3d_release_vk_queue vkd3d_release_vk_queue;
+static PFN_vkd3d_resource_decref vkd3d_resource_decref;
+static PFN_vkd3d_resource_incref vkd3d_resource_incref;
+
+struct dxgi_vk_funcs
+{
+ PFN_vkAcquireNextImageKHR p_vkAcquireNextImageKHR;
+ PFN_vkCreateSwapchainKHR p_vkCreateSwapchainKHR;
+ PFN_vkCreateWin32SurfaceKHR p_vkCreateWin32SurfaceKHR;
+ PFN_vkDestroySurfaceKHR p_vkDestroySurfaceKHR;
+ PFN_vkDestroySwapchainKHR p_vkDestroySwapchainKHR;
+ PFN_vkGetDeviceProcAddr p_vkGetDeviceProcAddr;
+ PFN_vkGetInstanceProcAddr p_vkGetInstanceProcAddr;
+ PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR;
+ PFN_vkGetPhysicalDeviceSurfaceFormatsKHR p_vkGetPhysicalDeviceSurfaceFormatsKHR;
+ PFN_vkGetPhysicalDeviceSurfacePresentModesKHR p_vkGetPhysicalDeviceSurfacePresentModesKHR;
+ PFN_vkGetPhysicalDeviceSurfaceSupportKHR p_vkGetPhysicalDeviceSurfaceSupportKHR;
+ PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR p_vkGetPhysicalDeviceWin32PresentationSupportKHR;
+ PFN_vkGetSwapchainImagesKHR p_vkGetSwapchainImagesKHR;
+ PFN_vkQueuePresentKHR p_vkQueuePresentKHR;
+ PFN_vkCreateFence p_vkCreateFence;
+ PFN_vkWaitForFences p_vkWaitForFences;
+ PFN_vkResetFences p_vkResetFences;
+ PFN_vkDestroyFence p_vkDestroyFence;
+};
+
struct d3d12_swapchain
{
IDXGISwapChain3 IDXGISwapChain3_iface;
LONG refcount;
struct wined3d_private_store private_store;
+ VkSwapchainKHR vk_swapchain;
+ VkSurfaceKHR vk_surface;
+ VkFence vk_fence;
+ VkInstance vk_instance;
+ VkDevice vk_device;
+ ID3D12Resource *buffers[DXGI_MAX_SWAP_CHAIN_BUFFERS];
+ unsigned int buffer_count;
+
+ uint32_t current_buffer_index;
+ struct dxgi_vk_funcs vk_funcs;
+
ID3D12CommandQueue *command_queue;
ID3D12Device *device;
IWineDXGIFactory *factory;
@@ -855,7 +916,9 @@ static ULONG STDMETHODCALLTYPE d3d12_swapchain_AddRef(IDXGISwapChain3 *iface)
static ULONG STDMETHODCALLTYPE d3d12_swapchain_Release(IDXGISwapChain3 *iface)
{
struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain3(iface);
+ const struct dxgi_vk_funcs *vk_funcs = &swapchain->vk_funcs;
ULONG refcount = InterlockedDecrement(&swapchain->refcount);
+ unsigned int i;
TRACE("%p decreasing refcount to %u.\n", swapchain, refcount);
@@ -866,6 +929,15 @@ static ULONG STDMETHODCALLTYPE d3d12_swapchain_Release(IDXGISwapChain3 *iface)
wined3d_private_store_cleanup(&swapchain->private_store);
+ for (i = 0; i < swapchain->buffer_count; ++i)
+ {
+ vkd3d_resource_decref(swapchain->buffers[i]);
+ }
+
+ vk_funcs->p_vkDestroyFence(swapchain->vk_device, swapchain->vk_fence, NULL);
+ vk_funcs->p_vkDestroySwapchainKHR(swapchain->vk_device, swapchain->vk_swapchain, NULL);
+ vk_funcs->p_vkDestroySurfaceKHR(swapchain->vk_instance, swapchain->vk_surface, NULL);
+
ID3D12Device_Release(swapchain->device);
heap_free(swapchain);
@@ -1295,45 +1367,419 @@ static const struct IDXGISwapChain3Vtbl d3d12_swapchain_vtbl =
d3d12_swapchain_ResizeBuffers1,
};
+static const struct vulkan_funcs *get_vk_funcs(void)
+{
+ const struct vulkan_funcs *vk_funcs;
+ HDC hdc;
+
+ hdc = GetDC(0);
+ vk_funcs = __wine_get_vulkan_driver(hdc, WINE_VULKAN_DRIVER_VERSION);
+ ReleaseDC(0, hdc);
+ return vk_funcs;
+}
+
+static BOOL load_vkd3d_functions(void *vkd3d_handle)
+{
+#define LOAD_FUNCPTR(f) if (!(f = wine_dlsym(vkd3d_handle, #f, NULL, 0))) return FALSE;
+ LOAD_FUNCPTR(vkd3d_acquire_vk_queue)
+ LOAD_FUNCPTR(vkd3d_create_image_resource)
+ LOAD_FUNCPTR(vkd3d_get_vk_device)
+ LOAD_FUNCPTR(vkd3d_get_vk_format)
+ LOAD_FUNCPTR(vkd3d_get_vk_physical_device)
+ LOAD_FUNCPTR(vkd3d_get_vk_queue_family_index)
+ LOAD_FUNCPTR(vkd3d_instance_from_device)
+ LOAD_FUNCPTR(vkd3d_instance_get_vk_instance)
+ LOAD_FUNCPTR(vkd3d_release_vk_queue)
+ LOAD_FUNCPTR(vkd3d_resource_decref)
+ LOAD_FUNCPTR(vkd3d_resource_incref)
+#undef LOAD_FUNCPTR
+
+ return TRUE;
+}
+
+static BOOL init_vkd3d(void)
+{
+ static void *vkd3d_handle;
+
+ if (vkd3d_handle)
+ return TRUE;
+
+ TRACE("Loading vkd3d %s.\n", SONAME_LIBVKD3D);
+
+ if (!(vkd3d_handle = wine_dlopen(SONAME_LIBVKD3D, RTLD_NOW, NULL, 0)))
+ return FALSE;
+
+ if (!load_vkd3d_functions(vkd3d_handle))
+ {
+ ERR("Failed to load vkd3d functions.\n");
+ wine_dlclose(vkd3d_handle, NULL, 0);
+ vkd3d_handle = NULL;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static BOOL init_vk_funcs(struct dxgi_vk_funcs *dxgi, VkDevice vk_device)
+{
+ const struct vulkan_funcs *vk;
+
+ if (!(vk = get_vk_funcs()))
+ {
+ ERR_(winediag)("Failed to load Wine Vulkan driver.\n");
+ return FALSE;
+ }
+
+ dxgi->p_vkAcquireNextImageKHR = vk->p_vkAcquireNextImageKHR;
+ dxgi->p_vkCreateSwapchainKHR = vk->p_vkCreateSwapchainKHR;
+ dxgi->p_vkCreateWin32SurfaceKHR = vk->p_vkCreateWin32SurfaceKHR;
+ dxgi->p_vkDestroySurfaceKHR = vk->p_vkDestroySurfaceKHR;
+ dxgi->p_vkDestroySwapchainKHR = vk->p_vkDestroySwapchainKHR;
+ dxgi->p_vkGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr)vk->p_vkGetDeviceProcAddr;
+ dxgi->p_vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)vk->p_vkGetInstanceProcAddr;
+ dxgi->p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR = vk->p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR;
+ dxgi->p_vkGetPhysicalDeviceSurfaceFormatsKHR = vk->p_vkGetPhysicalDeviceSurfaceFormatsKHR;
+ dxgi->p_vkGetPhysicalDeviceSurfacePresentModesKHR = vk->p_vkGetPhysicalDeviceSurfacePresentModesKHR;
+ dxgi->p_vkGetPhysicalDeviceSurfaceSupportKHR = vk->p_vkGetPhysicalDeviceSurfaceSupportKHR;
+ dxgi->p_vkGetPhysicalDeviceWin32PresentationSupportKHR = vk->p_vkGetPhysicalDeviceWin32PresentationSupportKHR;
+ dxgi->p_vkGetSwapchainImagesKHR = vk->p_vkGetSwapchainImagesKHR;
+ dxgi->p_vkQueuePresentKHR = vk->p_vkQueuePresentKHR;
+
+#define LOAD_DEVICE_PFN(name) \
+ if (!(dxgi->p_##name = vk->p_vkGetDeviceProcAddr(vk_device, #name))) \
+ { \
+ ERR("Failed to get device proc "#name".\n"); \
+ return FALSE; \
+ }
+ LOAD_DEVICE_PFN(vkCreateFence)
+ LOAD_DEVICE_PFN(vkWaitForFences)
+ LOAD_DEVICE_PFN(vkResetFences)
+ LOAD_DEVICE_PFN(vkDestroyFence)
+#undef LOAD_DEVICE_PFN
+
+ return TRUE;
+}
+
+static HRESULT select_vk_format(const struct dxgi_vk_funcs *vk_funcs,
+ VkPhysicalDevice vk_physical_device, VkSurfaceKHR vk_surface,
+ const DXGI_SWAP_CHAIN_DESC1 *swapchain_desc, VkFormat *vk_format)
+{
+ VkSurfaceFormatKHR *formats;
+ uint32_t format_count;
+ VkFormat format;
+ unsigned int i;
+ VkResult vr;
+
+ *vk_format = VK_FORMAT_UNDEFINED;
+
+ format = vkd3d_get_vk_format(swapchain_desc->Format);
+ if (format == VK_FORMAT_UNDEFINED)
+ return DXGI_ERROR_INVALID_CALL;
+
+ vr = vk_funcs->p_vkGetPhysicalDeviceSurfaceFormatsKHR(vk_physical_device, vk_surface, &format_count, NULL);
+ if (vr < 0 || !format_count)
+ {
+ WARN("Failed to get supported surface formats, vr %d.\n", vr);
+ return DXGI_ERROR_INVALID_CALL;
+ }
+
+ if (!(formats = heap_calloc(format_count, sizeof(*formats))))
+ return E_OUTOFMEMORY;
+
+ if ((vr = vk_funcs->p_vkGetPhysicalDeviceSurfaceFormatsKHR(vk_physical_device,
+ vk_surface, &format_count, formats)) < 0)
+ {
+ WARN("Failed to enumerate supported surface formats, vr %d.\n", vr);
+ heap_free(formats);
+ return DXGI_ERROR_INVALID_CALL;
+ }
+
+ for (i = 0; i < format_count; ++i)
+ {
+ if (formats[i].format == format && formats[i].colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
+ break;
+ }
+ heap_free(formats);
+
+ if (i == format_count)
+ {
+ FIXME("Failed to find suitable format for %s.\n", debug_dxgi_format(swapchain_desc->Format));
+ return DXGI_ERROR_INVALID_CALL;
+ }
+
+ *vk_format = format;
+ return S_OK;
+}
+
+static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGIFactory *factory,
+ ID3D12Device *device, ID3D12CommandQueue *queue, HWND window,
+ const DXGI_SWAP_CHAIN_DESC1 *swapchain_desc, const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *fullscreen_desc)
+{
+ const struct dxgi_vk_funcs *vk_funcs = &swapchain->vk_funcs;
+ struct vkd3d_image_resource_create_info resource_info;
+ struct VkSwapchainCreateInfoKHR vk_swapchain_desc;
+ struct VkWin32SurfaceCreateInfoKHR surface_desc;
+ VkImage vk_images[DXGI_MAX_SWAP_CHAIN_BUFFERS];
+ VkSwapchainKHR vk_swapchain = VK_NULL_HANDLE;
+ VkSurfaceKHR vk_surface = VK_NULL_HANDLE;
+ VkSurfaceCapabilitiesKHR surface_caps;
+ VkPhysicalDevice vk_physical_device;
+ VkFence vk_fence = VK_NULL_HANDLE;
+ unsigned int image_count, i, j;
+ VkFenceCreateInfo fence_desc;
+ uint32_t queue_family_index;
+ VkInstance vk_instance;
+ HRESULT hr = E_FAIL;
+ VkBool32 supported;
+ VkDevice vk_device;
+ VkFormat vk_format;
+ VkResult vr;
+
+ swapchain->IDXGISwapChain3_iface.lpVtbl = &d3d12_swapchain_vtbl;
+ swapchain->refcount = 1;
+
+ swapchain->window = window;
+ swapchain->desc = *swapchain_desc;
+ swapchain->fullscreen_desc = *fullscreen_desc;
+
+ switch (swapchain_desc->SwapEffect)
+ {
+ case DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL:
+ case DXGI_SWAP_EFFECT_FLIP_DISCARD:
+ FIXME("Ignoring swap effect %#x.\n", swapchain_desc->SwapEffect);
+ break;
+ default:
+ WARN("Invalid swap effect %#x.\n", swapchain_desc->SwapEffect);
+ return DXGI_ERROR_INVALID_CALL;
+ }
+
+ if (!init_vkd3d())
+ {
+ ERR_(winediag)("libvkd3d could not be loaded.\n");
+ return DXGI_ERROR_UNSUPPORTED;
+ }
+
+ if (swapchain_desc->BufferUsage && swapchain_desc->BufferUsage != DXGI_USAGE_RENDER_TARGET_OUTPUT)
+ FIXME("Ignoring buffer usage %#x.\n", swapchain_desc->BufferUsage);
+ if (swapchain_desc->Scaling != DXGI_SCALING_STRETCH)
+ FIXME("Ignoring scaling %#x.\n", swapchain_desc->Scaling);
+ if (swapchain_desc->AlphaMode && swapchain_desc->AlphaMode != DXGI_ALPHA_MODE_IGNORE)
+ FIXME("Ignoring alpha mode %#x.\n", swapchain_desc->AlphaMode);
+ if (swapchain_desc->Flags)
+ FIXME("Ignoring swapchain flags %#x.\n", swapchain_desc->Flags);
+
+ FIXME("Ignoring refresh rate.\n");
+ if (fullscreen_desc->ScanlineOrdering)
+ FIXME("Unhandled scanline ordering %#x.\n", fullscreen_desc->ScanlineOrdering);
+ if (fullscreen_desc->Scaling)
+ FIXME("Unhandled mode scaling %#x.\n", fullscreen_desc->Scaling);
+ if (!fullscreen_desc->Windowed)
+ FIXME("Fullscreen not supported yet.\n");
+
+ vk_instance = vkd3d_instance_get_vk_instance(vkd3d_instance_from_device(device));
+ vk_physical_device = vkd3d_get_vk_physical_device(device);
+ vk_device = vkd3d_get_vk_device(device);
+
+ if (!init_vk_funcs(&swapchain->vk_funcs, vk_device))
+ return E_FAIL;
+
+ surface_desc.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
+ surface_desc.pNext = NULL;
+ surface_desc.flags = 0;
+ surface_desc.hinstance = GetModuleHandleA("dxgi.dll");
+ surface_desc.hwnd = window;
+ if ((vr = vk_funcs->p_vkCreateWin32SurfaceKHR(vk_instance, &surface_desc, NULL, &vk_surface)) < 0)
+ {
+ WARN("Failed to create Vulkan surface, vr %d.\n", vr);
+ goto fail;
+ }
+
+ queue_family_index = vkd3d_get_vk_queue_family_index(queue);
+ if ((vr = vk_funcs->p_vkGetPhysicalDeviceSurfaceSupportKHR(vk_physical_device,
+ queue_family_index, vk_surface, &supported)) < 0 || !supported)
+ {
+ FIXME("Queue family does not support presentation, vr %d.\n", vr);
+ goto fail;
+ }
+
+ if (FAILED(hr = select_vk_format(vk_funcs, vk_physical_device, vk_surface, swapchain_desc, &vk_format)))
+ goto fail;
+ hr = E_FAIL;
+
+ if ((vr = vk_funcs->p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(vk_physical_device,
+ vk_surface, &surface_caps)) < 0)
+ {
+ WARN("Failed to get surface capabilities, vr %d.\n", vr);
+ goto fail;
+ }
+
+ if (surface_caps.maxImageCount && (swapchain_desc->BufferCount > surface_caps.maxImageCount
+ || swapchain_desc->BufferCount < surface_caps.minImageCount))
+ {
+ WARN("Buffer count %u is not supported (%u-%u).\n", swapchain_desc->BufferCount,
+ surface_caps.minImageCount, surface_caps.maxImageCount);
+ goto fail;
+ }
+
+ if (swapchain_desc->Width > surface_caps.maxImageExtent.width
+ || swapchain_desc->Width < surface_caps.minImageExtent.width
+ || swapchain_desc->Height > surface_caps.maxImageExtent.height
+ || swapchain_desc->Height < surface_caps.minImageExtent.height)
+ {
+ FIXME("Swapchain dimensions %ux%u are not supported (%u-%u x %u-%u).\n",
+ swapchain_desc->Width, swapchain_desc->Height,
+ surface_caps.minImageExtent.width, surface_caps.maxImageExtent.width,
+ surface_caps.minImageExtent.height, surface_caps.maxImageExtent.height);
+ }
+
+ if (!(surface_caps.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR))
+ {
+ FIXME("Unsupported alpha mode.\n");
+ goto fail;
+ }
+
+ vk_swapchain_desc.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
+ vk_swapchain_desc.pNext = NULL;
+ vk_swapchain_desc.flags = 0;
+ vk_swapchain_desc.surface = vk_surface;
+ vk_swapchain_desc.minImageCount = swapchain_desc->BufferCount;
+ vk_swapchain_desc.imageFormat = vk_format;
+ vk_swapchain_desc.imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
+ vk_swapchain_desc.imageExtent.width = swapchain_desc->Width;
+ vk_swapchain_desc.imageExtent.height = swapchain_desc->Height;
+ vk_swapchain_desc.imageArrayLayers = 1;
+ vk_swapchain_desc.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+ vk_swapchain_desc.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
+ vk_swapchain_desc.queueFamilyIndexCount = 0;
+ vk_swapchain_desc.pQueueFamilyIndices = NULL;
+ vk_swapchain_desc.preTransform = surface_caps.currentTransform;
+ vk_swapchain_desc.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
+ vk_swapchain_desc.presentMode = VK_PRESENT_MODE_FIFO_KHR;
+ vk_swapchain_desc.clipped = VK_TRUE;
+ vk_swapchain_desc.oldSwapchain = VK_NULL_HANDLE;
+ if ((vr = vk_funcs->p_vkCreateSwapchainKHR(vk_device, &vk_swapchain_desc, NULL, &vk_swapchain)) < 0)
+ {
+ WARN("Failed to create Vulkan swapchain, vr %d.\n", vr);
+ goto fail;
+ }
+
+ fence_desc.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+ fence_desc.pNext = NULL;
+ fence_desc.flags = 0;
+ if ((vr = vk_funcs->p_vkCreateFence(vk_device, &fence_desc, NULL, &vk_fence)) < 0)
+ {
+ WARN("Failed to create Vulkan fence, vr %d.\n", vr);
+ goto fail;
+ }
+
+ if ((vr = vk_funcs->p_vkGetSwapchainImagesKHR(vk_device, vk_swapchain, &image_count, NULL)) < 0)
+ {
+ WARN("Failed to get Vulkan swapchain images, vr %d.\n", vr);
+ goto fail;
+ }
+ if (image_count != swapchain_desc->BufferCount)
+ FIXME("Got %u swapchain images, expected %u.\n", image_count, swapchain_desc->BufferCount);
+ if (image_count > ARRAY_SIZE(vk_images))
+ goto fail;
+ if ((vr = vk_funcs->p_vkGetSwapchainImagesKHR(vk_device, vk_swapchain, &image_count, vk_images)) < 0)
+ {
+ WARN("Failed to get Vulkan swapchain images, vr %d.\n", vr);
+ goto fail;
+ }
+
+ swapchain->vk_swapchain = vk_swapchain;
+ swapchain->vk_surface = vk_surface;
+ swapchain->vk_fence = vk_fence;
+ swapchain->vk_instance = vk_instance;
+ swapchain->vk_device = vk_device;
+
+ vk_funcs->p_vkAcquireNextImageKHR(vk_device, vk_swapchain, UINT64_MAX,
+ VK_NULL_HANDLE, vk_fence, &swapchain->current_buffer_index);
+ vk_funcs->p_vkWaitForFences(vk_device, 1, &vk_fence, VK_TRUE, UINT64_MAX);
+ vk_funcs->p_vkResetFences(vk_device, 1, &vk_fence);
+
+ resource_info.type = VKD3D_STRUCTURE_TYPE_IMAGE_RESOURCE_CREATE_INFO;
+ resource_info.next = NULL;
+ resource_info.desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
+ resource_info.desc.Alignment = 0;
+ resource_info.desc.Width = swapchain_desc->Width;
+ resource_info.desc.Height = swapchain_desc->Height;
+ resource_info.desc.DepthOrArraySize = 1;
+ resource_info.desc.MipLevels = 1;
+ resource_info.desc.Format = swapchain_desc->Format;
+ resource_info.desc.SampleDesc.Count = 1;
+ resource_info.desc.SampleDesc.Quality = 0;
+ resource_info.desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
+ resource_info.desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
+ resource_info.flags = VKD3D_RESOURCE_INITIAL_STATE_TRANSITION | VKD3D_RESOURCE_PRESENT_STATE_TRANSITION;
+ resource_info.present_state = D3D12_RESOURCE_STATE_PRESENT;
+ for (i = 0; i < image_count; ++i)
+ {
+ resource_info.vk_image = vk_images[i];
+ if (SUCCEEDED(hr = vkd3d_create_image_resource(device, &resource_info, &swapchain->buffers[i])))
+ {
+ vkd3d_resource_incref(swapchain->buffers[i]);
+ ID3D12Resource_Release(swapchain->buffers[i]);
+ }
+ else
+ {
+ ERR("Failed to create vkd3d resource for Vulkan image %u, hr %#x.\n", i, hr);
+ for (j = 0; j < i; ++j)
+ {
+ vkd3d_resource_decref(swapchain->buffers[j]);
+ }
+ goto fail;
+ }
+ }
+ swapchain->buffer_count = image_count;
+
+ wined3d_private_store_init(&swapchain->private_store);
+
+ ID3D12CommandQueue_AddRef(swapchain->command_queue = queue);
+ ID3D12Device_AddRef(swapchain->device = device);
+ IWineDXGIFactory_AddRef(swapchain->factory = factory);
+
+ return S_OK;
+
+fail:
+ vk_funcs->p_vkDestroyFence(vk_device, vk_fence, NULL);
+ vk_funcs->p_vkDestroySwapchainKHR(vk_device, vk_swapchain, NULL);
+ vk_funcs->p_vkDestroySurfaceKHR(vk_instance, vk_surface, NULL);
+ return hr;
+}
+
HRESULT d3d12_swapchain_create(IWineDXGIFactory *factory, ID3D12CommandQueue *queue, HWND window,
const DXGI_SWAP_CHAIN_DESC1 *swapchain_desc, const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *fullscreen_desc,
IDXGISwapChain1 **swapchain)
{
+ DXGI_SWAP_CHAIN_FULLSCREEN_DESC default_fullscreen_desc;
struct d3d12_swapchain *object;
ID3D12Device *device;
HRESULT hr;
- if (FAILED(hr = ID3D12CommandQueue_GetDevice(queue, &IID_ID3D12Device, (void **)&device)))
+ if (!fullscreen_desc)
{
- ERR("Failed to get D3D12 device, hr %#x.\n", hr);
- return hr;
+ memset(&default_fullscreen_desc, 0, sizeof(default_fullscreen_desc));
+ default_fullscreen_desc.Windowed = TRUE;
+ fullscreen_desc = &default_fullscreen_desc;
}
if (!(object = heap_alloc_zero(sizeof(*object))))
- {
- ID3D12Device_Release(device);
return E_OUTOFMEMORY;
- }
-
- object->IDXGISwapChain3_iface.lpVtbl = &d3d12_swapchain_vtbl;
- object->refcount = 1;
-
- wined3d_private_store_init(&object->private_store);
- ID3D12CommandQueue_AddRef(object->command_queue = queue);
- object->device = device;
- IWineDXGIFactory_AddRef(object->factory = factory);
-
- object->window = window;
- object->desc = *swapchain_desc;
- if (fullscreen_desc)
+ if (FAILED(hr = ID3D12CommandQueue_GetDevice(queue, &IID_ID3D12Device, (void **)&device)))
{
- object->fullscreen_desc = *fullscreen_desc;
+ ERR("Failed to get D3D12 device, hr %#x.\n", hr);
+ heap_free(object);
+ return hr;
}
- else
+
+ hr = d3d12_swapchain_init(object, factory, device, queue, window, swapchain_desc, fullscreen_desc);
+ ID3D12Device_Release(device);
+ if (FAILED(hr))
{
- memset(&object->fullscreen_desc, 0, sizeof(object->fullscreen_desc));
- object->fullscreen_desc.Windowed = TRUE;
+ heap_free(object);
+ return hr;
}
TRACE("Created swapchain %p.\n", object);
@@ -1342,3 +1788,15 @@ HRESULT d3d12_swapchain_create(IWineDXGIFactory *factory, ID3D12CommandQueue *qu
return S_OK;
}
+
+#else
+
+HRESULT d3d12_swapchain_create(IWineDXGIFactory *factory, ID3D12CommandQueue *queue, HWND window,
+ const DXGI_SWAP_CHAIN_DESC1 *swapchain_desc, const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *fullscreen_desc,
+ IDXGISwapChain1 **swapchain)
+{
+ ERR_(winediag)("Wine was built without Direct3D 12 support.\n");
+ return DXGI_ERROR_UNSUPPORTED;
+}
+
+#endif /* SONAME_LIBVKD3D */
--
2.16.1
May 31, 2018
[PATCH] msi/tests: Remove duplicate service tests.
by Hans Leidekker
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/msi/tests/install.c | 86 +++---------------------------------------------
1 file changed, 5 insertions(+), 81 deletions(-)
diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c
index f0e4857fe1..a4726d631c 100644
--- a/dlls/msi/tests/install.c
+++ b/dlls/msi/tests/install.c
@@ -84,8 +84,7 @@ static const CHAR component_dat[] = "Component\tComponentId\tDirectory_\tAttribu
"Three\t{010B6ADD-B27D-4EDD-9B3D-34C4F7D61684}\tCHANGEDDIR\t2\t\tthree.txt\n"
"Two\t{BF03D1A6-20DA-4A65-82F3-6CAC995915CE}\tFIRSTDIR\t2\t\ttwo.txt\n"
"dangler\t{6091DF25-EF96-45F1-B8E9-A9B1420C7A3C}\tTARGETDIR\t4\t\tregdata\n"
- "component\t\tMSITESTDIR\t0\t1\tfile\n"
- "service_comp\t\tMSITESTDIR\t0\t1\tservice_file";
+ "component\t\tMSITESTDIR\t0\t1\tfile\n";
static const CHAR directory_dat[] = "Directory\tDirectory_Parent\tDefaultDir\n"
"s72\tS72\tl255\n"
@@ -106,8 +105,7 @@ static const CHAR feature_dat[] = "Feature\tFeature_Parent\tTitle\tDescription\t
"One\t\tOne\tThe One Feature\t1\t3\tMSITESTDIR\t0\n"
"Three\t\tThree\tThe Three Feature\t3\t3\tCHANGEDDIR\t0\n"
"Two\t\tTwo\tThe Two Feature\t2\t3\tFIRSTDIR\t0\n"
- "feature\t\t\t\t2\t1\tTARGETDIR\t0\n"
- "service_feature\t\t\t\t2\t1\tTARGETDIR\t0";
+ "feature\t\t\t\t2\t1\tTARGETDIR\t0\n";
static const CHAR feature_comp_dat[] = "Feature_\tComponent_\n"
"s38\ts72\n"
@@ -117,8 +115,7 @@ static const CHAR feature_comp_dat[] = "Feature_\tComponent_\n"
"One\tOne\n"
"Three\tThree\n"
"Two\tTwo\n"
- "feature\tcomponent\n"
- "service_feature\tservice_comp\n";
+ "feature\tcomponent\n";
static const CHAR file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tLanguage\tAttributes\tSequence\n"
"s72\ts72\tl255\ti4\tS72\tS20\tI2\ti2\n"
@@ -128,8 +125,7 @@ static const CHAR file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion\tL
"one.txt\tOne\tone.txt\t1000\t\t\t0\t1\n"
"three.txt\tThree\tthree.txt\t1000\t\t\t0\t3\n"
"two.txt\tTwo\ttwo.txt\t1000\t\t\t0\t2\n"
- "file\tcomponent\tfilename\t100\t\t\t8192\t1\n"
- "service_file\tservice_comp\tservice.exe\t100\t\t\t8192\t1";
+ "file\tcomponent\tfilename\t100\t\t\t8192\t1\n";
static const CHAR install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
"s72\tS255\tI2\n"
@@ -144,7 +140,6 @@ static const CHAR install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
"DuplicateFiles\t\t4500\n"
"WriteEnvironmentStrings\t\t4550\n"
"CreateShortcuts\t\t4600\n"
- "InstallServices\t\t5000\n"
"InstallFinalize\t\t6600\n"
"InstallInitialize\t\t1500\n"
"InstallValidate\t\t1400\n"
@@ -177,8 +172,6 @@ static const CHAR property_dat[] = "Property\tValue\n"
"UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
"AdminProperties\tPOSTADMIN\n"
"ROOTDRIVE\tC:\\\n"
- "SERVNAME\tTestService\n"
- "SERVDISP\tTestServiceDisp\n"
"MSIFASTINSTALL\t1\n";
static const CHAR aup_property_dat[] = "Property\tValue\n"
@@ -201,8 +194,6 @@ static const CHAR aup_property_dat[] = "Property\tValue\n"
"UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
"AdminProperties\tPOSTADMIN\n"
"ROOTDRIVE\tC:\\\n"
- "SERVNAME\tTestService\n"
- "SERVDISP\tTestServiceDisp\n"
"MSIFASTINSTALL\t1\n";
static const CHAR aup2_property_dat[] = "Property\tValue\n"
@@ -225,8 +216,6 @@ static const CHAR aup2_property_dat[] = "Property\tValue\n"
"UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
"AdminProperties\tPOSTADMIN\n"
"ROOTDRIVE\tC:\\\n"
- "SERVNAME\tTestService\n"
- "SERVDISP\tTestServiceDisp\n"
"MSIFASTINSTALL\t1\n";
static const CHAR icon_property_dat[] = "Property\tValue\n"
@@ -248,8 +237,6 @@ static const CHAR icon_property_dat[] = "Property\tValue\n"
"UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
"AdminProperties\tPOSTADMIN\n"
"ROOTDRIVE\tC:\\\n"
- "SERVNAME\tTestService\n"
- "SERVDISP\tTestServiceDisp\n"
"MSIFASTINSTALL\t1\n";
static const CHAR shortcut_dat[] = "Shortcut\tDirectory_\tName\tComponent_\tTarget\tArguments\tDescription\tHotkey\tIcon_\tIconIndex\tShowCmd\tWkDir\n"
@@ -281,8 +268,6 @@ static const CHAR up_property_dat[] = "Property\tValue\n"
"UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
"AdminProperties\tPOSTADMIN\n"
"ROOTDRIVE\tC:\\\n"
- "SERVNAME\tTestService\n"
- "SERVDISP\tTestServiceDisp\n"
"RemovePreviousVersions\t1\n"
"MSIFASTINSTALL\t1\n";
@@ -305,8 +290,6 @@ static const CHAR up2_property_dat[] = "Property\tValue\n"
"UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
"AdminProperties\tPOSTADMIN\n"
"ROOTDRIVE\tC:\\\n"
- "SERVNAME\tTestService\n"
- "SERVDISP\tTestServiceDisp\n"
"MSIFASTINSTALL\t1\n";
static const CHAR up3_property_dat[] = "Property\tValue\n"
@@ -328,8 +311,6 @@ static const CHAR up3_property_dat[] = "Property\tValue\n"
"UpgradeCode\t{4C0EAA15-0264-4E5A-8758-609EF142B92D}\n"
"AdminProperties\tPOSTADMIN\n"
"ROOTDRIVE\tC:\\\n"
- "SERVNAME\tTestService\n"
- "SERVDISP\tTestServiceDisp\n"
"RemovePreviousVersions\t1\n"
"MSIFASTINSTALL\t1\n";
@@ -341,17 +322,6 @@ static const CHAR registry_dat[] = "Registry\tRoot\tKey\tName\tValue\tComponent_
"regdata\t1\tSOFTWARE\\Wine\\msitest\tblah\tbad\tdangler\n"
"OrderTest\t1\tSOFTWARE\\Wine\\msitest\tOrderTestName\tOrderTestValue\tcomponent";
-static const CHAR service_install_dat[] = "ServiceInstall\tName\tDisplayName\tServiceType\tStartType\tErrorControl\t"
- "LoadOrderGroup\tDependencies\tStartName\tPassword\tArguments\tComponent_\tDescription\n"
- "s72\ts255\tL255\ti4\ti4\ti4\tS255\tS255\tS255\tS255\tS255\ts72\tL255\n"
- "ServiceInstall\tServiceInstall\n"
- "TestService\t[SERVNAME]\t[SERVDISP]\t2\t3\t0\t\t\tTestService\t\t\tservice_comp\t\t";
-
-static const CHAR service_control_dat[] = "ServiceControl\tName\tEvent\tArguments\tWait\tComponent_\n"
- "s72\tl255\ti2\tL255\tI2\ts72\n"
- "ServiceControl\tServiceControl\n"
- "ServiceControl\tTestService\t8\t\t0\tservice_comp";
-
/* tables for test_continuouscabs */
static const CHAR cc_component_dat[] = "Component\tComponentId\tDirectory_\tAttributes\tCondition\tKeyPath\n"
"s72\tS38\ts72\ti2\tS255\tS72\n"
@@ -859,8 +829,7 @@ static const CHAR ai_file_dat[] = "File\tComponent_\tFileName\tFileSize\tVersion
"one.txt\tOne\tone.txt\t1000\t\t\t16384\t1\n"
"three.txt\tThree\tthree.txt\t1000\t\t\t16384\t3\n"
"two.txt\tTwo\ttwo.txt\t1000\t\t\t16384\t2\n"
- "file\tcomponent\tfilename\t100\t\t\t8192\t1\n"
- "service_file\tservice_comp\tservice.exe\t100\t\t\t8192\t1";
+ "file\tcomponent\tfilename\t100\t\t\t8192\t1\n";
static const CHAR ip_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
"s72\tS255\tI2\n"
@@ -1358,8 +1327,6 @@ static const msi_table tables[] =
ADD_TABLE(media),
ADD_TABLE(property),
ADD_TABLE(registry),
- ADD_TABLE(service_install),
- ADD_TABLE(service_control)
};
static const msi_table sc_tables[] =
@@ -1399,8 +1366,6 @@ static const msi_table up_tables[] =
ADD_TABLE(media),
ADD_TABLE(up_property),
ADD_TABLE(registry),
- ADD_TABLE(service_install),
- ADD_TABLE(service_control)
};
static const msi_table up2_tables[] =
@@ -1414,8 +1379,6 @@ static const msi_table up2_tables[] =
ADD_TABLE(media),
ADD_TABLE(up2_property),
ADD_TABLE(registry),
- ADD_TABLE(service_install),
- ADD_TABLE(service_control)
};
static const msi_table up3_tables[] =
@@ -1429,8 +1392,6 @@ static const msi_table up3_tables[] =
ADD_TABLE(media),
ADD_TABLE(up3_property),
ADD_TABLE(registry),
- ADD_TABLE(service_install),
- ADD_TABLE(service_control)
};
static const msi_table up4_tables[] =
@@ -1444,8 +1405,6 @@ static const msi_table up4_tables[] =
ADD_TABLE(media),
ADD_TABLE(property),
ADD_TABLE(registry),
- ADD_TABLE(service_install),
- ADD_TABLE(service_control)
};
static const msi_table up5_tables[] =
@@ -1459,8 +1418,6 @@ static const msi_table up5_tables[] =
ADD_TABLE(media),
ADD_TABLE(up_property),
ADD_TABLE(registry),
- ADD_TABLE(service_install),
- ADD_TABLE(service_control)
};
static const msi_table up6_tables[] =
@@ -1474,8 +1431,6 @@ static const msi_table up6_tables[] =
ADD_TABLE(media),
ADD_TABLE(up2_property),
ADD_TABLE(registry),
- ADD_TABLE(service_install),
- ADD_TABLE(service_control)
};
static const msi_table up7_tables[] =
@@ -1489,8 +1444,6 @@ static const msi_table up7_tables[] =
ADD_TABLE(media),
ADD_TABLE(up3_property),
ADD_TABLE(registry),
- ADD_TABLE(service_install),
- ADD_TABLE(service_control)
};
static const msi_table cc_tables[] =
@@ -2409,7 +2362,6 @@ static void create_test_files(void)
create_cab_file("msitest.cab", MEDIA_SIZE, "four.txt\0five.txt\0");
create_file("msitest\\filename", 100);
- create_file("msitest\\service.exe", 100);
DeleteFileA("four.txt");
DeleteFileA("five.txt");
@@ -2487,7 +2439,6 @@ static void delete_test_files(void)
DeleteFileA("msitest\\second\\three.txt");
DeleteFileA("msitest\\first\\two.txt");
DeleteFileA("msitest\\one.txt");
- DeleteFileA("msitest\\service.exe");
DeleteFileA("msitest\\filename");
RemoveDirectoryA("msitest\\second");
RemoveDirectoryA("msitest\\first");
@@ -2506,7 +2457,6 @@ static void delete_pf_files(void)
ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
- ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
ok(delete_pf("msitest", FALSE), "Directory not created\n");
}
@@ -2656,24 +2606,6 @@ void create_database_wordcount(const CHAR *name, const msi_table *tables, int nu
HeapFree( GetProcessHeap(), 0, nameW );
}
-static void check_service_is_installed(void)
-{
- SC_HANDLE scm, service;
- BOOL res;
-
- scm = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
- ok(scm != NULL, "Failed to open the SC Manager\n");
-
- service = OpenServiceA(scm, "TestService", SC_MANAGER_ALL_ACCESS);
- ok(service != NULL, "Failed to open TestService\n");
-
- res = DeleteService(service);
- ok(res, "Failed to delete TestService\n");
-
- CloseServiceHandle(service);
- CloseServiceHandle(scm);
-}
-
static BOOL notify_system_change(DWORD event_type, STATEMGRSTATUS *status)
{
RESTOREPOINTINFOA spec;
@@ -2777,8 +2709,6 @@ static void test_MsiInstallProduct(void)
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
ok(!lstrcmpA(path, "OrderTestValue"), "Expected OrderTestValue, got %s\n", path);
- check_service_is_installed();
-
delete_key(HKEY_CURRENT_USER, "SOFTWARE\\Wine\\msitest", access);
/* not published, reinstall */
@@ -4823,7 +4753,6 @@ static void test_adminimage(void)
create_file("msitest\\cabout\\four.txt", 100);
create_file("msitest\\cabout\\new\\five.txt", 100);
create_file("msitest\\filename", 100);
- create_file("msitest\\service.exe", 100);
create_database_wordcount(msifile, ai_tables,
sizeof(ai_tables) / sizeof(msi_table),
@@ -4849,7 +4778,6 @@ error:
DeleteFileA("msitest\\second\\three.txt");
DeleteFileA("msitest\\first\\two.txt");
DeleteFileA("msitest\\one.txt");
- DeleteFileA("msitest\\service.exe");
DeleteFileA("msitest\\filename");
RemoveDirectoryA("msitest\\cabout\\new");
RemoveDirectoryA("msitest\\cabout");
@@ -5049,7 +4977,6 @@ static void test_preselected(void)
ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
- ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
ok(delete_pf("msitest", FALSE), "Directory not created\n");
r = MsiInstallProductA(msifile, NULL);
@@ -5065,7 +4992,6 @@ static void test_preselected(void)
ok(delete_pf("msitest\\first", FALSE), "Directory not created\n");
ok(delete_pf("msitest\\filename", TRUE), "File not installed\n");
ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
- ok(delete_pf("msitest\\service.exe", TRUE), "File not installed\n");
ok(delete_pf("msitest", FALSE), "Directory not created\n");
error:
@@ -6162,7 +6088,6 @@ static void test_wow64(void)
ok(!delete_pf("msitest\\first", FALSE), "Directory created\n");
ok(!delete_pf("msitest\\one.txt", TRUE), "File installed\n");
ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
- ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
ok(!delete_pf("msitest", FALSE), "Directory created\n");
ok(delete_pf_native("msitest\\cabout\\new\\five.txt", TRUE), "File not installed\n");
@@ -6175,7 +6100,6 @@ static void test_wow64(void)
ok(delete_pf_native("msitest\\first", FALSE), "Directory not created\n");
ok(delete_pf_native("msitest\\one.txt", TRUE), "File not installed\n");
ok(delete_pf_native("msitest\\filename", TRUE), "File not installed\n");
- ok(delete_pf_native("msitest\\service.exe", TRUE), "File not installed\n");
ok(delete_pf_native("msitest", FALSE), "Directory not created\n");
pWow64RevertWow64FsRedirection(cookie);
--
2.11.0
May 31, 2018
[PATCH] testbot/web: Move some Submit.pl variables closer to the usage.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/web/Submit.pl | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/testbot/web/Submit.pl b/testbot/web/Submit.pl
index 6451745a9..2b4e5ec14 100644
--- a/testbot/web/Submit.pl
+++ b/testbot/web/Submit.pl
@@ -509,15 +509,12 @@ sub DetermineFileType($$)
{
my ($self, $FileName) = @_;
- my $ErrMessage = undef;
- my $FileType = "unknown";
- my $DllBaseName = undef;
- my $TestUnit = undef;
if (! sysopen(FH, $FileName, O_RDONLY))
{
return ("Unable to open $FileName", "unknown", undef, undef);
}
+ my $FileType = "unknown";
my $Buffer;
if (sysread(FH, $Buffer, 0x40))
{
@@ -563,6 +560,7 @@ sub DetermineFileType($$)
close FH;
+ my ($ErrMessage, $DllBaseName, $TestUnit);
if ($FileType eq "unknown")
{
my $Impacts = GetPatchImpact($FileName);
--
2.17.0
May 31, 2018
[PATCH] testbot: Update the Job, Step and Task documentation.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/lib/WineTestBot/Jobs.pm | 24 ++++++++++++++++++++---
testbot/lib/WineTestBot/Steps.pm | 33 +++++++++++++++++++++++++++++---
testbot/lib/WineTestBot/Tasks.pm | 31 ++++++++++++++++++++++++++++++
3 files changed, 82 insertions(+), 6 deletions(-)
diff --git a/testbot/lib/WineTestBot/Jobs.pm b/testbot/lib/WineTestBot/Jobs.pm
index ef0d98e24..b1ffd3e48 100644
--- a/testbot/lib/WineTestBot/Jobs.pm
+++ b/testbot/lib/WineTestBot/Jobs.pm
@@ -28,13 +28,14 @@ WineTestBot::Job - A job submitted by a user
=head1 DESCRIPTION
A Job is created when a WineTestBot::User asks for something to be tested
-(for automatically generated Jobs this would be the batch user). There are many
+(for automatically generated Jobs this would be the batch user). A Job is
+composed of one or more WineTestBot::Step objects. There are many
paths that can result in the creation of a job:
=over
=item *
-A use submits a patch or binary to test.
+A user submits a patch or binary to test.
=item *
WineTestBot finds a patch to test on the mailing list (and has all the pieces
@@ -47,7 +48,24 @@ Job.
=back
-A Job is composed of multiple WineTestBot::Step objects.
+A Job's lifecycle is as follows:
+=over
+
+=item *
+A Job is created with Status set to queued which means it is ready to run.
+
+=item *
+As soon as one of the Step starts running, the Job's Status field is set to
+running.
+
+=item *
+Once all the Steps have completed the Job's Status is updated to reflect the
+overall result: completed, badpatch, etc.
+
+=item *
+If the Job is canceled by the user, then the Status field is set to canceled.
+
+=back
=cut
diff --git a/testbot/lib/WineTestBot/Steps.pm b/testbot/lib/WineTestBot/Steps.pm
index 635092d1a..4dc45690e 100644
--- a/testbot/lib/WineTestBot/Steps.pm
+++ b/testbot/lib/WineTestBot/Steps.pm
@@ -26,9 +26,36 @@ WineTestBot::Step - A Job's Step
=head1 DESCRIPTION
-A Job is composed of multiple Steps that each do a specific operation: build
-the test executable, or run a given test, etc. A Step is in turn composed of
-a WineTestBot::Task object for each VM it should be run on.
+A Job is composed of one or more Steps that each perform one operation. A
+Step is in turn composed of one WineTestBot::Task object for each VM that the
+Step should be run on.
+
+A Step's lifecyle is as follows:
+=over
+
+=item *
+A Step is created with Status set to queued which means it is ready to be run
+as soon as the PreviousNo Step has completed, or immediately if PreviousNo is
+not set.
+
+=item *
+Once one of the Step's Task is running the Step's Status is changed to
+running.
+
+=item *
+Once all the Tasks in the Step have completed, the Step's Status is set to one
+of the "completion" Status values according to the overall success of its
+Tasks: completed, badpatch, etc.
+
+=item *
+If the PreviousNo Step failed then the Status field and that of all its Tasks
+is set to skip; and the Step will not be run.
+
+=item *
+If a Step is canceled by the user, then the Status field is set to canceled if
+the Step was running, and to skipped if it was queued.
+
+=back
Note that the PreviousNo relation will prevent the deletion of the target Step.
It is the responsibility of the caller to delete the Steps in a suitable order,
diff --git a/testbot/lib/WineTestBot/Tasks.pm b/testbot/lib/WineTestBot/Tasks.pm
index 69d551b84..afd4fb4d3 100644
--- a/testbot/lib/WineTestBot/Tasks.pm
+++ b/testbot/lib/WineTestBot/Tasks.pm
@@ -31,6 +31,37 @@ performing that Step in a WineTestBot::VM virtual machine. For instance a Step
responsible for running a given test would have one Task object for each
virtual machine that the test must be performed in.
+A Task's lifecyle is as follows:
+=over
+
+=item *
+A Task is created with Status set to queued which means it is ready to be run
+as soon as long as the Step itself is runnable (see the WineTestBot::Step
+documentation).
+
+=item *
+Once the Task is running on the corresponding VM the Status field is set to
+running.
+
+=item *
+If running the Task fails due to a transient error the TestFailure field
+is checked. If it is lower than a configurable threshold the Status is
+reset to queued and the TestFailure field is incremented. Otherwise the
+Status is set to boterror and the Task is considered to have completed.
+
+=item *
+If the Task completes normally the Status field is set to the appropriate
+value based on the result: completed, badpatch, etc.
+
+=item *
+If the Task is canceled by the user its Status is set to canceled.
+
+=item *
+If the Task's Step cannot be run because the Step it depends on failed, then
+Status is set to skipped.
+
+=back
+
=cut
use WineTestBot::WineTestBotObjects;
--
2.17.0
May 31, 2018
[PATCH] testbot/web: Remove pointless 'cleanup' Submit.pl code.
by Francois Gouget
Objects are freed when they get out of scope. So there is no point
setting $Jobs to undef.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/web/Submit.pl | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/testbot/web/Submit.pl b/testbot/web/Submit.pl
index 2b4e5ec14..2a4521edc 100644
--- a/testbot/web/Submit.pl
+++ b/testbot/web/Submit.pl
@@ -871,21 +871,17 @@ sub OnSubmit($)
return !1;
}
- # Clean up, but save the key of the new job
- my $JobKey = $NewJob->GetKey();
- $Jobs = undef;
-
# Notify engine
my $ErrMessage = RescheduleJobs();
if (defined $ErrMessage)
{
$self->{ErrMessage} = $ErrMessage;
$self->{Page} = 4;
- $self->{JobKey} = $JobKey;
+ $self->{JobKey} = $NewJob->GetKey();
return !1;
}
- $self->Redirect("/JobDetails.pl?Key=$JobKey"); # does not return
+ $self->Redirect("/JobDetails.pl?Key=". $NewJob->GetKey()); # does not return
exit;
}
--
2.17.0
May 31, 2018
[PATCH] testbot/web: Don't hardcode the Submit.pl maximum filename length.
by Francois Gouget
Also check it before even starting the upload.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/web/Submit.pl | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/testbot/web/Submit.pl b/testbot/web/Submit.pl
index cf850788d..6451745a9 100644
--- a/testbot/web/Submit.pl
+++ b/testbot/web/Submit.pl
@@ -33,9 +33,10 @@ use File::Basename;
use ObjectModel::BasicPropertyDescriptor;
use WineTestBot::Branches;
use WineTestBot::Config;
-use WineTestBot::Jobs;
use WineTestBot::Engine::Notify;
+use WineTestBot::Jobs;
use WineTestBot::PatchUtils;
+use WineTestBot::Steps;
use WineTestBot::Utils;
use WineTestBot::VMs;
@@ -609,10 +610,11 @@ sub OnPage1Next($)
$FileName =~ m/^.*(\\|\/)(.*)/;
$FileName = $2;
}
- if (100 - 32 - 1 < length($FileName))
+ my $PropertyDescriptor = CreateSteps()->GetPropertyDescriptorByName("FileName");
+ if ($PropertyDescriptor->GetMaxLength() - 32 - 1 < length($FileName))
{
$self->{ErrField} = "File";
- $self->{ErrMessage} = "File: Name is too long";
+ $self->{ErrMessage} = "The filename is too long";
return !1;
}
my $StagingFile = $self->GetTmpStagingFullPath($FileName);
--
2.17.0
May 31, 2018
[PATCH] testbot: Adjust the StepsTasks fields.
by Francois Gouget
The StepTask class duplicates the Step and Task classes and its fields
are mostly used in read-only mode so we don't care about their exact
type too much, particularly for enums. Still, try to specify valid
lengths so we don't get errors one day if Validate() is called.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/lib/WineTestBot/StepsTasks.pm | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/testbot/lib/WineTestBot/StepsTasks.pm b/testbot/lib/WineTestBot/StepsTasks.pm
index ff94b1452..db0cc0667 100644
--- a/testbot/lib/WineTestBot/StepsTasks.pm
+++ b/testbot/lib/WineTestBot/StepsTasks.pm
@@ -162,20 +162,21 @@ sub CreateItem($)
return WineTestBot::StepTask->new($self);
}
+# Note: To simplify maintenance replace enums with simple string fields.
my @PropertyDescriptors = (
- CreateBasicPropertyDescriptor("Id", "Id", 1, 1, "N", 4),
- CreateBasicPropertyDescriptor("StepNo", "Step no", !1, 1, "N", 2),
- CreateBasicPropertyDescriptor("TaskNo", "Task no", ! 1, 1, "N", 2),
- CreateBasicPropertyDescriptor("Type", "Step type", !1, 1, "A", 6),
- CreateBasicPropertyDescriptor("Status", "Status", !1, 1, "A", 9),
- CreateItemrefPropertyDescriptor("VM", "VM", !1, 1, \&CreateVMs, ["VMName"]),
+ CreateBasicPropertyDescriptor("Id", "Id", 1, 1, "N", 4),
+ CreateBasicPropertyDescriptor("StepNo", "Step no", !1, 1, "N", 2),
+ CreateBasicPropertyDescriptor("TaskNo", "Task no", !1, 1, "N", 2),
+ CreateBasicPropertyDescriptor("Type", "Step type", !1, 1, "A", 32),
+ CreateBasicPropertyDescriptor("Status", "Status", !1, 1, "A", 32),
+ CreateItemrefPropertyDescriptor("VM", "VM", !1, 1, \&CreateVMs, ["VMName"]),
CreateBasicPropertyDescriptor("Timeout", "Timeout", !1, 1, "N", 4),
- CreateBasicPropertyDescriptor("FileName", "File name", !1, 1, "A", 64),
- CreateBasicPropertyDescriptor("FileType", "File Type", !1, 1, "A", 64),
+ CreateBasicPropertyDescriptor("FileName", "File name", !1, 1, "A", 100),
+ CreateBasicPropertyDescriptor("FileType", "File Type", !1, 1, "A", 32),
CreateBasicPropertyDescriptor("CmdLineArg", "Command line args", !1, !1, "A", 256),
CreateBasicPropertyDescriptor("Started", "Execution started", !1, !1, "DT", 19),
CreateBasicPropertyDescriptor("Ended", "Execution ended", !1, !1, "DT", 19),
- CreateBasicPropertyDescriptor("TestFailures", "Number of test failures", !1, !1, "N", 5),
+ CreateBasicPropertyDescriptor("TestFailures", "Number of test failures", !1, !1, "N", 6),
);
sub CreateStepsTasks(;$$)
--
2.17.0
May 31, 2018
Re: [PATCH 4/4] msi/tests: Test deferral of WriteIniValues and RemoveIniValues.
by Hans Leidekker
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
May 31, 2018
Re: [PATCH 3/4] msi/tests: Add a simple test for WriteIniValues.
by Hans Leidekker
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
May 31, 2018