mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-11-21 16:46:41 -08:00
libs/vkd3d: Add support for custom PRESENT state transitions.
Signed-off-by: Józef Kucia <jkucia@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
fd36cefbe2
commit
bfd20ef1c8
@ -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,
|
static inline struct demo_swapchain *demo_swapchain_create(ID3D12CommandQueue *command_queue,
|
||||||
struct demo_window *window, const struct demo_swapchain_desc *desc)
|
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 VkSwapchainCreateInfoKHR vk_swapchain_desc;
|
||||||
struct VkXcbSurfaceCreateInfoKHR surface_desc;
|
struct VkXcbSurfaceCreateInfoKHR surface_desc;
|
||||||
VkSwapchainKHR vk_swapchain = VK_NULL_HANDLE;
|
VkSwapchainKHR vk_swapchain = VK_NULL_HANDLE;
|
||||||
uint32_t format_count, queue_family_index;
|
uint32_t format_count, queue_family_index;
|
||||||
VkSurfaceCapabilitiesKHR surface_caps;
|
VkSurfaceCapabilitiesKHR surface_caps;
|
||||||
VkPhysicalDevice vk_physical_device;
|
VkPhysicalDevice vk_physical_device;
|
||||||
D3D12_RESOURCE_DESC resource_desc;
|
|
||||||
VkFence vk_fence = VK_NULL_HANDLE;
|
VkFence vk_fence = VK_NULL_HANDLE;
|
||||||
struct demo_swapchain *swapchain;
|
struct demo_swapchain *swapchain;
|
||||||
unsigned int image_count, i, j;
|
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);
|
vkWaitForFences(vk_device, 1, &vk_fence, VK_TRUE, UINT64_MAX);
|
||||||
vkResetFences(vk_device, 1, &vk_fence);
|
vkResetFences(vk_device, 1, &vk_fence);
|
||||||
|
|
||||||
resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
|
resource_create_info.desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
|
||||||
resource_desc.Alignment = 0;
|
resource_create_info.desc.Alignment = 0;
|
||||||
resource_desc.Width = desc->width;
|
resource_create_info.desc.Width = desc->width;
|
||||||
resource_desc.Height = desc->height;
|
resource_create_info.desc.Height = desc->height;
|
||||||
resource_desc.DepthOrArraySize = 1;
|
resource_create_info.desc.DepthOrArraySize = 1;
|
||||||
resource_desc.MipLevels = 1;
|
resource_create_info.desc.MipLevels = 1;
|
||||||
resource_desc.Format = desc->format;
|
resource_create_info.desc.Format = desc->format;
|
||||||
resource_desc.SampleDesc.Count = 1;
|
resource_create_info.desc.SampleDesc.Count = 1;
|
||||||
resource_desc.SampleDesc.Quality = 0;
|
resource_create_info.desc.SampleDesc.Quality = 0;
|
||||||
resource_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
|
resource_create_info.desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
|
||||||
resource_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
|
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)
|
for (i = 0; i < image_count; ++i)
|
||||||
{
|
{
|
||||||
if (FAILED(vkd3d_create_image_resource(d3d12_device, &resource_desc, vk_images[i],
|
resource_create_info.vk_image = vk_images[i];
|
||||||
VKD3D_RESOURCE_INITIAL_STATE_TRANSITION | VKD3D_RESOURCE_SWAPCHAIN_IMAGE,
|
if (FAILED(vkd3d_create_image_resource(d3d12_device, &resource_create_info, &swapchain->buffers[i])))
|
||||||
&swapchain->buffers[i])))
|
|
||||||
{
|
{
|
||||||
for (j = 0; j < i; ++j)
|
for (j = 0; j < i; ++j)
|
||||||
{
|
{
|
||||||
|
@ -73,9 +73,17 @@ struct vkd3d_device_create_info
|
|||||||
LUID adapter_luid;
|
LUID adapter_luid;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* resource flags */
|
/* vkd3d_image_resource_create_info flags */
|
||||||
#define VKD3D_RESOURCE_INITIAL_STATE_TRANSITION 0x00000001
|
#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
|
#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);
|
VkQueue vkd3d_acquire_vk_queue(ID3D12CommandQueue *queue);
|
||||||
void vkd3d_release_vk_queue(ID3D12CommandQueue *queue);
|
void vkd3d_release_vk_queue(ID3D12CommandQueue *queue);
|
||||||
|
|
||||||
HRESULT vkd3d_create_image_resource(ID3D12Device *device, const D3D12_RESOURCE_DESC *desc,
|
HRESULT vkd3d_create_image_resource(ID3D12Device *device,
|
||||||
VkImage vk_image, unsigned int resource_flags, ID3D12Resource **resource);
|
const struct vkd3d_image_resource_create_info *create_info, ID3D12Resource **resource);
|
||||||
ULONG vkd3d_resource_decref(ID3D12Resource *resource);
|
ULONG vkd3d_resource_decref(ID3D12Resource *resource);
|
||||||
ULONG vkd3d_resource_incref(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 VkQueue (*PFN_vkd3d_acquire_vk_queue)(ID3D12CommandQueue *queue);
|
||||||
typedef void (*PFN_vkd3d_release_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,
|
typedef HRESULT (*PFN_vkd3d_create_image_resource)(ID3D12Device *device,
|
||||||
VkImage vk_image, unsigned int resource_flags, ID3D12Resource **resource);
|
const struct vkd3d_image_resource_create_info *create_info, ID3D12Resource **resource);
|
||||||
typedef ULONG (*PFN_vkd3d_resource_decref)(ID3D12Resource *resource);
|
typedef ULONG (*PFN_vkd3d_resource_decref)(ID3D12Resource *resource);
|
||||||
typedef ULONG (*PFN_vkd3d_resource_incref)(ID3D12Resource *resource);
|
typedef ULONG (*PFN_vkd3d_resource_incref)(ID3D12Resource *resource);
|
||||||
|
|
||||||
|
@ -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)
|
VkAccessFlags *access_mask, VkPipelineStageFlags *stage_flags, VkImageLayout *image_layout)
|
||||||
{
|
{
|
||||||
switch (state)
|
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. */
|
* state when GPU finishes execution of a command list. */
|
||||||
if (is_swapchain_image)
|
if (is_swapchain_image)
|
||||||
{
|
{
|
||||||
*access_mask = VK_ACCESS_MEMORY_READ_BIT;
|
if (present_state == D3D12_RESOURCE_STATE_PRESENT)
|
||||||
*stage_flags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
{
|
||||||
if (image_layout)
|
*access_mask = VK_ACCESS_MEMORY_READ_BIT;
|
||||||
*image_layout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
*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
|
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;
|
VK_IMAGE_LAYOUT_PREINITIALIZED : VK_IMAGE_LAYOUT_UNDEFINED;
|
||||||
|
|
||||||
if (!vk_barrier_parameters_from_d3d12_resource_state(resource->initial_state,
|
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))
|
&barrier.dstAccessMask, &dst_stage_mask, &barrier.newLayout))
|
||||||
{
|
{
|
||||||
FIXME("Unhandled state %#x.\n", resource->initial_state);
|
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;
|
sub_resource_idx = transition->Subresource;
|
||||||
|
|
||||||
if (!vk_barrier_parameters_from_d3d12_resource_state(transition->StateBefore,
|
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))
|
&src_access_mask, &src_stage_mask, &layout_before))
|
||||||
{
|
{
|
||||||
FIXME("Unhandled state %#x.\n", transition->StateBefore);
|
FIXME("Unhandled state %#x.\n", transition->StateBefore);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!vk_barrier_parameters_from_d3d12_resource_state(transition->StateAfter,
|
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))
|
&dst_access_mask, &dst_stage_mask, &layout_after))
|
||||||
{
|
{
|
||||||
FIXME("Unhandled state %#x.\n", transition->StateAfter);
|
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);
|
resource = unsafe_impl_from_ID3D12Resource(uav->pResource);
|
||||||
vk_barrier_parameters_from_d3d12_resource_state(D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
|
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);
|
&access_mask, &stage_mask, &image_layout);
|
||||||
src_access_mask = dst_access_mask = access_mask;
|
src_access_mask = dst_access_mask = access_mask;
|
||||||
src_stage_mask = dst_stage_mask = stage_mask;
|
src_stage_mask = dst_stage_mask = stage_mask;
|
||||||
|
@ -797,28 +797,34 @@ HRESULT d3d12_committed_resource_create(struct d3d12_device *device,
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT vkd3d_create_image_resource(ID3D12Device *device, const D3D12_RESOURCE_DESC *desc,
|
HRESULT vkd3d_create_image_resource(ID3D12Device *device,
|
||||||
VkImage vk_image, unsigned int resource_flags, ID3D12Resource **resource)
|
const struct vkd3d_image_resource_create_info *create_info, ID3D12Resource **resource)
|
||||||
{
|
{
|
||||||
struct d3d12_device *d3d12_device = unsafe_impl_from_ID3D12Device(device);
|
struct d3d12_device *d3d12_device = unsafe_impl_from_ID3D12Device(device);
|
||||||
struct d3d12_resource *object;
|
struct d3d12_resource *object;
|
||||||
|
|
||||||
|
TRACE("device %p, create_info %p, resource %p.\n", device, create_info, resource);
|
||||||
|
|
||||||
if (!(object = vkd3d_malloc(sizeof(*object))))
|
if (!(object = vkd3d_malloc(sizeof(*object))))
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
object->ID3D12Resource_iface.lpVtbl = &d3d12_resource_vtbl;
|
object->ID3D12Resource_iface.lpVtbl = &d3d12_resource_vtbl;
|
||||||
object->refcount = 1;
|
object->refcount = 1;
|
||||||
object->internal_refcount = 1;
|
object->internal_refcount = 1;
|
||||||
object->desc = *desc;
|
object->desc = create_info->desc;
|
||||||
object->u.vk_image = vk_image;
|
object->u.vk_image = create_info->vk_image;
|
||||||
object->vk_memory = VK_NULL_HANDLE;
|
object->vk_memory = VK_NULL_HANDLE;
|
||||||
object->flags = VKD3D_RESOURCE_EXTERNAL;
|
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_count = 0;
|
||||||
object->map_data = NULL;
|
object->map_data = NULL;
|
||||||
memset(&object->heap_properties, 0, sizeof(object->heap_properties));
|
memset(&object->heap_properties, 0, sizeof(object->heap_properties));
|
||||||
object->heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT;
|
object->heap_properties.Type = D3D12_HEAP_TYPE_DEFAULT;
|
||||||
object->initial_state = D3D12_RESOURCE_STATE_COMMON;
|
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;
|
object->device = d3d12_device;
|
||||||
ID3D12Device_AddRef(&d3d12_device->ID3D12Device_iface);
|
ID3D12Device_AddRef(&d3d12_device->ID3D12Device_iface);
|
||||||
|
|
||||||
|
@ -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;
|
UINT64 initial_value, D3D12_FENCE_FLAGS flags, struct d3d12_fence **fence) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
#define VKD3D_RESOURCE_PUBLIC_FLAGS \
|
#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
|
#define VKD3D_RESOURCE_EXTERNAL 0x00000004
|
||||||
|
|
||||||
/* ID3D12Resource */
|
/* ID3D12Resource */
|
||||||
@ -202,6 +202,7 @@ struct d3d12_resource
|
|||||||
D3D12_HEAP_PROPERTIES heap_properties;
|
D3D12_HEAP_PROPERTIES heap_properties;
|
||||||
D3D12_HEAP_FLAGS heap_flags;
|
D3D12_HEAP_FLAGS heap_flags;
|
||||||
D3D12_RESOURCE_STATES initial_state;
|
D3D12_RESOURCE_STATES initial_state;
|
||||||
|
D3D12_RESOURCE_STATES present_state;
|
||||||
|
|
||||||
struct d3d12_device *device;
|
struct d3d12_device *device;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user