From bfd20ef1c8d80b0514197209c6f2d516fc78c9f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Thu, 29 Mar 2018 18:21:46 +0200 Subject: [PATCH] libs/vkd3d: Add support for custom PRESENT state transitions. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Józef Kucia Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- demos/demo_xcb.h | 31 ++++++++++++++++--------------- include/vkd3d.h | 20 ++++++++++++++------ libs/vkd3d/command.c | 28 +++++++++++++++++++--------- libs/vkd3d/resource.c | 16 +++++++++++----- libs/vkd3d/vkd3d_private.h | 3 ++- 5 files changed, 62 insertions(+), 36 deletions(-) diff --git a/demos/demo_xcb.h b/demos/demo_xcb.h index 9980b506..053db0df 100644 --- a/demos/demo_xcb.h +++ b/demos/demo_xcb.h @@ -307,13 +307,13 @@ static inline void demo_set_idle_func(struct demo *demo, static inline struct demo_swapchain *demo_swapchain_create(ID3D12CommandQueue *command_queue, struct demo_window *window, const struct demo_swapchain_desc *desc) { + struct vkd3d_image_resource_create_info resource_create_info; struct VkSwapchainCreateInfoKHR vk_swapchain_desc; struct VkXcbSurfaceCreateInfoKHR surface_desc; VkSwapchainKHR vk_swapchain = VK_NULL_HANDLE; uint32_t format_count, queue_family_index; VkSurfaceCapabilitiesKHR surface_caps; VkPhysicalDevice vk_physical_device; - D3D12_RESOURCE_DESC resource_desc; VkFence vk_fence = VK_NULL_HANDLE; struct demo_swapchain *swapchain; unsigned int image_count, i, j; @@ -446,22 +446,23 @@ static inline struct demo_swapchain *demo_swapchain_create(ID3D12CommandQueue *c vkWaitForFences(vk_device, 1, &vk_fence, VK_TRUE, UINT64_MAX); vkResetFences(vk_device, 1, &vk_fence); - resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; - resource_desc.Alignment = 0; - resource_desc.Width = desc->width; - resource_desc.Height = desc->height; - resource_desc.DepthOrArraySize = 1; - resource_desc.MipLevels = 1; - resource_desc.Format = desc->format; - resource_desc.SampleDesc.Count = 1; - resource_desc.SampleDesc.Quality = 0; - resource_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; - resource_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; + resource_create_info.desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + resource_create_info.desc.Alignment = 0; + resource_create_info.desc.Width = desc->width; + resource_create_info.desc.Height = desc->height; + resource_create_info.desc.DepthOrArraySize = 1; + resource_create_info.desc.MipLevels = 1; + resource_create_info.desc.Format = desc->format; + resource_create_info.desc.SampleDesc.Count = 1; + resource_create_info.desc.SampleDesc.Quality = 0; + resource_create_info.desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + resource_create_info.desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; + resource_create_info.flags = VKD3D_RESOURCE_INITIAL_STATE_TRANSITION | VKD3D_RESOURCE_PRESENT_STATE_TRANSITION; + resource_create_info.present_state = D3D12_RESOURCE_STATE_PRESENT; for (i = 0; i < image_count; ++i) { - if (FAILED(vkd3d_create_image_resource(d3d12_device, &resource_desc, vk_images[i], - VKD3D_RESOURCE_INITIAL_STATE_TRANSITION | VKD3D_RESOURCE_SWAPCHAIN_IMAGE, - &swapchain->buffers[i]))) + resource_create_info.vk_image = vk_images[i]; + if (FAILED(vkd3d_create_image_resource(d3d12_device, &resource_create_info, &swapchain->buffers[i]))) { for (j = 0; j < i; ++j) { diff --git a/include/vkd3d.h b/include/vkd3d.h index 6ec85dbf..692b58d7 100644 --- a/include/vkd3d.h +++ b/include/vkd3d.h @@ -73,9 +73,17 @@ struct vkd3d_device_create_info LUID adapter_luid; }; -/* resource flags */ +/* vkd3d_image_resource_create_info flags */ #define VKD3D_RESOURCE_INITIAL_STATE_TRANSITION 0x00000001 -#define VKD3D_RESOURCE_SWAPCHAIN_IMAGE 0x00000002 +#define VKD3D_RESOURCE_PRESENT_STATE_TRANSITION 0x00000002 + +struct vkd3d_image_resource_create_info +{ + VkImage vk_image; + D3D12_RESOURCE_DESC desc; + unsigned int flags; + D3D12_RESOURCE_STATES present_state; +}; #ifndef VKD3D_NO_PROTOTYPES @@ -96,8 +104,8 @@ uint32_t vkd3d_get_vk_queue_family_index(ID3D12CommandQueue *queue); VkQueue vkd3d_acquire_vk_queue(ID3D12CommandQueue *queue); void vkd3d_release_vk_queue(ID3D12CommandQueue *queue); -HRESULT vkd3d_create_image_resource(ID3D12Device *device, const D3D12_RESOURCE_DESC *desc, - VkImage vk_image, unsigned int resource_flags, ID3D12Resource **resource); +HRESULT vkd3d_create_image_resource(ID3D12Device *device, + const struct vkd3d_image_resource_create_info *create_info, ID3D12Resource **resource); ULONG vkd3d_resource_decref(ID3D12Resource *resource); ULONG vkd3d_resource_incref(ID3D12Resource *resource); @@ -131,8 +139,8 @@ typedef uint32_t (*PFN_vkd3d_get_vk_queue_family_index)(ID3D12CommandQueue *queu typedef VkQueue (*PFN_vkd3d_acquire_vk_queue)(ID3D12CommandQueue *queue); typedef void (*PFN_vkd3d_release_vk_queue)(ID3D12CommandQueue *queue); -typedef HRESULT (*PFN_vkd3d_create_image_resource)(ID3D12Device *device, const D3D12_RESOURCE_DESC *desc, - VkImage vk_image, unsigned int resource_flags, ID3D12Resource **resource); +typedef HRESULT (*PFN_vkd3d_create_image_resource)(ID3D12Device *device, + const struct vkd3d_image_resource_create_info *create_info, ID3D12Resource **resource); typedef ULONG (*PFN_vkd3d_resource_decref)(ID3D12Resource *resource); typedef ULONG (*PFN_vkd3d_resource_incref)(ID3D12Resource *resource); diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index 1c0a18ae..39094c24 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -1150,7 +1150,8 @@ static void d3d12_command_list_invalidate_bindings(struct d3d12_command_list *li } } -static bool vk_barrier_parameters_from_d3d12_resource_state(unsigned int state, bool is_swapchain_image, +static bool vk_barrier_parameters_from_d3d12_resource_state(unsigned int state, + bool is_swapchain_image, D3D12_RESOURCE_STATES present_state, VkAccessFlags *access_mask, VkPipelineStageFlags *stage_flags, VkImageLayout *image_layout) { switch (state) @@ -1164,10 +1165,18 @@ static bool vk_barrier_parameters_from_d3d12_resource_state(unsigned int state, * state when GPU finishes execution of a command list. */ if (is_swapchain_image) { - *access_mask = VK_ACCESS_MEMORY_READ_BIT; - *stage_flags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - if (image_layout) - *image_layout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + if (present_state == D3D12_RESOURCE_STATE_PRESENT) + { + *access_mask = VK_ACCESS_MEMORY_READ_BIT; + *stage_flags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + if (image_layout) + *image_layout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + } + else + { + vk_barrier_parameters_from_d3d12_resource_state(present_state, + false, 0, access_mask, stage_flags, image_layout); + } } else { @@ -1353,7 +1362,7 @@ static void d3d12_command_list_transition_resource_to_initial_state(struct d3d12 VK_IMAGE_LAYOUT_PREINITIALIZED : VK_IMAGE_LAYOUT_UNDEFINED; if (!vk_barrier_parameters_from_d3d12_resource_state(resource->initial_state, - resource->flags & VKD3D_RESOURCE_SWAPCHAIN_IMAGE, + resource->flags & VKD3D_RESOURCE_PRESENT_STATE_TRANSITION, resource->present_state, &barrier.dstAccessMask, &dst_stage_mask, &barrier.newLayout)) { FIXME("Unhandled state %#x.\n", resource->initial_state); @@ -2877,14 +2886,14 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResourceBarrier(ID3D12GraphicsC sub_resource_idx = transition->Subresource; if (!vk_barrier_parameters_from_d3d12_resource_state(transition->StateBefore, - resource->flags & VKD3D_RESOURCE_SWAPCHAIN_IMAGE, + resource->flags & VKD3D_RESOURCE_PRESENT_STATE_TRANSITION, resource->present_state, &src_access_mask, &src_stage_mask, &layout_before)) { FIXME("Unhandled state %#x.\n", transition->StateBefore); continue; } if (!vk_barrier_parameters_from_d3d12_resource_state(transition->StateAfter, - resource->flags & VKD3D_RESOURCE_SWAPCHAIN_IMAGE, + resource->flags & VKD3D_RESOURCE_PRESENT_STATE_TRANSITION, resource->present_state, &dst_access_mask, &dst_stage_mask, &layout_after)) { FIXME("Unhandled state %#x.\n", transition->StateAfter); @@ -2905,7 +2914,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResourceBarrier(ID3D12GraphicsC resource = unsafe_impl_from_ID3D12Resource(uav->pResource); vk_barrier_parameters_from_d3d12_resource_state(D3D12_RESOURCE_STATE_UNORDERED_ACCESS, - resource && (resource->flags & VKD3D_RESOURCE_SWAPCHAIN_IMAGE), + resource && (resource->flags & VKD3D_RESOURCE_PRESENT_STATE_TRANSITION), + resource ? resource->present_state : 0, &access_mask, &stage_mask, &image_layout); src_access_mask = dst_access_mask = access_mask; src_stage_mask = dst_stage_mask = stage_mask; diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index 81135d37..4746ee2c 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -797,28 +797,34 @@ HRESULT d3d12_committed_resource_create(struct d3d12_device *device, return S_OK; } -HRESULT vkd3d_create_image_resource(ID3D12Device *device, const D3D12_RESOURCE_DESC *desc, - VkImage vk_image, unsigned int resource_flags, ID3D12Resource **resource) +HRESULT vkd3d_create_image_resource(ID3D12Device *device, + const struct vkd3d_image_resource_create_info *create_info, ID3D12Resource **resource) { struct d3d12_device *d3d12_device = unsafe_impl_from_ID3D12Device(device); struct d3d12_resource *object; + TRACE("device %p, create_info %p, resource %p.\n", device, create_info, resource); + if (!(object = vkd3d_malloc(sizeof(*object)))) return E_OUTOFMEMORY; object->ID3D12Resource_iface.lpVtbl = &d3d12_resource_vtbl; object->refcount = 1; object->internal_refcount = 1; - object->desc = *desc; - object->u.vk_image = vk_image; + object->desc = create_info->desc; + object->u.vk_image = create_info->vk_image; object->vk_memory = VK_NULL_HANDLE; object->flags = VKD3D_RESOURCE_EXTERNAL; - object->flags |= resource_flags & VKD3D_RESOURCE_PUBLIC_FLAGS; + object->flags |= create_info->flags & VKD3D_RESOURCE_PUBLIC_FLAGS; object->map_count = 0; object->map_data = NULL; memset(&object->heap_properties, 0, sizeof(object->heap_properties)); object->heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT; object->initial_state = D3D12_RESOURCE_STATE_COMMON; + if (create_info->flags & VKD3D_RESOURCE_PRESENT_STATE_TRANSITION) + object->present_state = create_info->present_state; + else + object->present_state = D3D12_RESOURCE_STATE_COMMON; object->device = d3d12_device; ID3D12Device_AddRef(&d3d12_device->ID3D12Device_iface); diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 988522f9..cf3112e8 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -175,7 +175,7 @@ HRESULT d3d12_fence_create(struct d3d12_device *device, UINT64 initial_value, D3D12_FENCE_FLAGS flags, struct d3d12_fence **fence) DECLSPEC_HIDDEN; #define VKD3D_RESOURCE_PUBLIC_FLAGS \ - (VKD3D_RESOURCE_INITIAL_STATE_TRANSITION | VKD3D_RESOURCE_SWAPCHAIN_IMAGE) + (VKD3D_RESOURCE_INITIAL_STATE_TRANSITION | VKD3D_RESOURCE_PRESENT_STATE_TRANSITION) #define VKD3D_RESOURCE_EXTERNAL 0x00000004 /* ID3D12Resource */ @@ -202,6 +202,7 @@ struct d3d12_resource D3D12_HEAP_PROPERTIES heap_properties; D3D12_HEAP_FLAGS heap_flags; D3D12_RESOURCE_STATES initial_state; + D3D12_RESOURCE_STATES present_state; struct d3d12_device *device; };