mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-04-13 05:43:18 -07:00
vkd3d: Use Vulkan timeline semaphores for D3D12 fences.
D3D12 supports signalling a fence to a lower value, while Vulkan timeline semaphores do not. On the GPU side this is handled by simply submitting the signal anyway, if a test for this passes on device creation, because working around this is impractical. For CPU signals the Vulkan semaphore is replaced with a new one at the lower value only if no waits and/or signals are pending on the GPU. Otherwise, a fixme is emitted. Partly based on a vkd3d-proton patch by Hans-Kristian Arntzen (not including the handling of lower fence values). The old implementation is used if KHR_timeline_semaphore is not available or GPU signals do not work for a lower value. Signed-off-by: Conor McCarthy <cmccarthy@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
e3045090a8
commit
22d8665300
File diff suppressed because it is too large
Load Diff
@ -129,6 +129,7 @@ static const struct vkd3d_optional_extension_info optional_device_extensions[] =
|
|||||||
VK_EXTENSION(KHR_MAINTENANCE3, KHR_maintenance3),
|
VK_EXTENSION(KHR_MAINTENANCE3, KHR_maintenance3),
|
||||||
VK_EXTENSION(KHR_PUSH_DESCRIPTOR, KHR_push_descriptor),
|
VK_EXTENSION(KHR_PUSH_DESCRIPTOR, KHR_push_descriptor),
|
||||||
VK_EXTENSION(KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE, KHR_sampler_mirror_clamp_to_edge),
|
VK_EXTENSION(KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE, KHR_sampler_mirror_clamp_to_edge),
|
||||||
|
VK_EXTENSION(KHR_TIMELINE_SEMAPHORE, KHR_timeline_semaphore),
|
||||||
/* EXT extensions */
|
/* EXT extensions */
|
||||||
VK_EXTENSION(EXT_CALIBRATED_TIMESTAMPS, EXT_calibrated_timestamps),
|
VK_EXTENSION(EXT_CALIBRATED_TIMESTAMPS, EXT_calibrated_timestamps),
|
||||||
VK_EXTENSION(EXT_CONDITIONAL_RENDERING, EXT_conditional_rendering),
|
VK_EXTENSION(EXT_CONDITIONAL_RENDERING, EXT_conditional_rendering),
|
||||||
@ -791,6 +792,7 @@ struct vkd3d_physical_device_info
|
|||||||
VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT texel_buffer_alignment_properties;
|
VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT texel_buffer_alignment_properties;
|
||||||
VkPhysicalDeviceTransformFeedbackPropertiesEXT xfb_properties;
|
VkPhysicalDeviceTransformFeedbackPropertiesEXT xfb_properties;
|
||||||
VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT vertex_divisor_properties;
|
VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT vertex_divisor_properties;
|
||||||
|
VkPhysicalDeviceTimelineSemaphorePropertiesKHR timeline_semaphore_properties;
|
||||||
|
|
||||||
VkPhysicalDeviceProperties2KHR properties2;
|
VkPhysicalDeviceProperties2KHR properties2;
|
||||||
|
|
||||||
@ -803,6 +805,7 @@ struct vkd3d_physical_device_info
|
|||||||
VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT texel_buffer_alignment_features;
|
VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT texel_buffer_alignment_features;
|
||||||
VkPhysicalDeviceTransformFeedbackFeaturesEXT xfb_features;
|
VkPhysicalDeviceTransformFeedbackFeaturesEXT xfb_features;
|
||||||
VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT vertex_divisor_features;
|
VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT vertex_divisor_features;
|
||||||
|
VkPhysicalDeviceTimelineSemaphoreFeaturesKHR timeline_semaphore_features;
|
||||||
|
|
||||||
VkPhysicalDeviceFeatures2 features2;
|
VkPhysicalDeviceFeatures2 features2;
|
||||||
};
|
};
|
||||||
@ -814,11 +817,13 @@ static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *i
|
|||||||
VkPhysicalDeviceDescriptorIndexingPropertiesEXT *descriptor_indexing_properties;
|
VkPhysicalDeviceDescriptorIndexingPropertiesEXT *descriptor_indexing_properties;
|
||||||
VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *vertex_divisor_properties;
|
VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *vertex_divisor_properties;
|
||||||
VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT *buffer_alignment_properties;
|
VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT *buffer_alignment_properties;
|
||||||
|
VkPhysicalDeviceTimelineSemaphorePropertiesKHR *timeline_semaphore_properties;
|
||||||
VkPhysicalDeviceDescriptorIndexingFeaturesEXT *descriptor_indexing_features;
|
VkPhysicalDeviceDescriptorIndexingFeaturesEXT *descriptor_indexing_features;
|
||||||
VkPhysicalDeviceRobustness2FeaturesEXT *robustness2_features;
|
VkPhysicalDeviceRobustness2FeaturesEXT *robustness2_features;
|
||||||
VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *vertex_divisor_features;
|
VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *vertex_divisor_features;
|
||||||
VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT *buffer_alignment_features;
|
VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT *buffer_alignment_features;
|
||||||
VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT *demote_features;
|
VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT *demote_features;
|
||||||
|
VkPhysicalDeviceTimelineSemaphoreFeaturesKHR *timeline_semaphore_features;
|
||||||
VkPhysicalDeviceDepthClipEnableFeaturesEXT *depth_clip_features;
|
VkPhysicalDeviceDepthClipEnableFeaturesEXT *depth_clip_features;
|
||||||
VkPhysicalDeviceMaintenance3Properties *maintenance3_properties;
|
VkPhysicalDeviceMaintenance3Properties *maintenance3_properties;
|
||||||
VkPhysicalDeviceTransformFeedbackPropertiesEXT *xfb_properties;
|
VkPhysicalDeviceTransformFeedbackPropertiesEXT *xfb_properties;
|
||||||
@ -838,6 +843,8 @@ static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *i
|
|||||||
buffer_alignment_properties = &info->texel_buffer_alignment_properties;
|
buffer_alignment_properties = &info->texel_buffer_alignment_properties;
|
||||||
vertex_divisor_features = &info->vertex_divisor_features;
|
vertex_divisor_features = &info->vertex_divisor_features;
|
||||||
vertex_divisor_properties = &info->vertex_divisor_properties;
|
vertex_divisor_properties = &info->vertex_divisor_properties;
|
||||||
|
timeline_semaphore_features = &info->timeline_semaphore_features;
|
||||||
|
timeline_semaphore_properties = &info->timeline_semaphore_properties;
|
||||||
xfb_features = &info->xfb_features;
|
xfb_features = &info->xfb_features;
|
||||||
xfb_properties = &info->xfb_properties;
|
xfb_properties = &info->xfb_properties;
|
||||||
|
|
||||||
@ -859,6 +866,8 @@ static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *i
|
|||||||
vk_prepend_struct(&info->features2, xfb_features);
|
vk_prepend_struct(&info->features2, xfb_features);
|
||||||
vertex_divisor_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT;
|
vertex_divisor_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT;
|
||||||
vk_prepend_struct(&info->features2, vertex_divisor_features);
|
vk_prepend_struct(&info->features2, vertex_divisor_features);
|
||||||
|
timeline_semaphore_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR;
|
||||||
|
vk_prepend_struct(&info->features2, timeline_semaphore_features);
|
||||||
|
|
||||||
if (vulkan_info->KHR_get_physical_device_properties2)
|
if (vulkan_info->KHR_get_physical_device_properties2)
|
||||||
VK_CALL(vkGetPhysicalDeviceFeatures2KHR(physical_device, &info->features2));
|
VK_CALL(vkGetPhysicalDeviceFeatures2KHR(physical_device, &info->features2));
|
||||||
@ -877,6 +886,8 @@ static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *i
|
|||||||
vk_prepend_struct(&info->properties2, xfb_properties);
|
vk_prepend_struct(&info->properties2, xfb_properties);
|
||||||
vertex_divisor_properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT;
|
vertex_divisor_properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT;
|
||||||
vk_prepend_struct(&info->properties2, vertex_divisor_properties);
|
vk_prepend_struct(&info->properties2, vertex_divisor_properties);
|
||||||
|
timeline_semaphore_properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES_KHR;
|
||||||
|
vk_prepend_struct(&info->properties2, timeline_semaphore_properties);
|
||||||
|
|
||||||
if (vulkan_info->KHR_get_physical_device_properties2)
|
if (vulkan_info->KHR_get_physical_device_properties2)
|
||||||
VK_CALL(vkGetPhysicalDeviceProperties2KHR(physical_device, &info->properties2));
|
VK_CALL(vkGetPhysicalDeviceProperties2KHR(physical_device, &info->properties2));
|
||||||
@ -1465,6 +1476,7 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device,
|
|||||||
vulkan_info->rasterization_stream = physical_device_info->xfb_properties.transformFeedbackRasterizationStreamSelect;
|
vulkan_info->rasterization_stream = physical_device_info->xfb_properties.transformFeedbackRasterizationStreamSelect;
|
||||||
vulkan_info->transform_feedback_queries = physical_device_info->xfb_properties.transformFeedbackQueries;
|
vulkan_info->transform_feedback_queries = physical_device_info->xfb_properties.transformFeedbackQueries;
|
||||||
vulkan_info->max_vertex_attrib_divisor = max(physical_device_info->vertex_divisor_properties.maxVertexAttribDivisor, 1);
|
vulkan_info->max_vertex_attrib_divisor = max(physical_device_info->vertex_divisor_properties.maxVertexAttribDivisor, 1);
|
||||||
|
vulkan_info->timeline_semaphore_properties = physical_device_info->timeline_semaphore_properties;
|
||||||
|
|
||||||
device->feature_options.DoublePrecisionFloatShaderOps = features->shaderFloat64;
|
device->feature_options.DoublePrecisionFloatShaderOps = features->shaderFloat64;
|
||||||
device->feature_options.OutputMergerLogicOp = features->logicOp;
|
device->feature_options.OutputMergerLogicOp = features->logicOp;
|
||||||
@ -1589,6 +1601,8 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device,
|
|||||||
vulkan_info->EXT_shader_demote_to_helper_invocation = false;
|
vulkan_info->EXT_shader_demote_to_helper_invocation = false;
|
||||||
if (!physical_device_info->texel_buffer_alignment_features.texelBufferAlignment)
|
if (!physical_device_info->texel_buffer_alignment_features.texelBufferAlignment)
|
||||||
vulkan_info->EXT_texel_buffer_alignment = false;
|
vulkan_info->EXT_texel_buffer_alignment = false;
|
||||||
|
if (!physical_device_info->timeline_semaphore_features.timelineSemaphore)
|
||||||
|
vulkan_info->KHR_timeline_semaphore = false;
|
||||||
|
|
||||||
vulkan_info->texel_buffer_alignment_properties = physical_device_info->texel_buffer_alignment_properties;
|
vulkan_info->texel_buffer_alignment_properties = physical_device_info->texel_buffer_alignment_properties;
|
||||||
|
|
||||||
@ -1939,6 +1953,75 @@ static bool d3d12_is_64k_msaa_supported(struct d3d12_device *device)
|
|||||||
&& info.Alignment <= 0x10000;
|
&& info.Alignment <= 0x10000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* A lower value can be signalled on a D3D12 fence. Vulkan timeline semaphores
|
||||||
|
* do not support this, but test if it works anyway. */
|
||||||
|
static bool d3d12_is_timeline_semaphore_supported(const struct d3d12_device *device)
|
||||||
|
{
|
||||||
|
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
||||||
|
VkTimelineSemaphoreSubmitInfoKHR timeline_submit_info;
|
||||||
|
VkSemaphore timeline_semaphore;
|
||||||
|
VkSubmitInfo submit_info;
|
||||||
|
bool result = false;
|
||||||
|
uint64_t value = 0;
|
||||||
|
VkQueue vk_queue;
|
||||||
|
VkResult vr;
|
||||||
|
|
||||||
|
if (!device->vk_info.KHR_timeline_semaphore)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ((vr = vkd3d_create_timeline_semaphore(device, 1, &timeline_semaphore)) < 0)
|
||||||
|
{
|
||||||
|
WARN("Failed to create timeline semaphore, vr %d.\n", vr);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(vk_queue = vkd3d_queue_acquire(device->direct_queue)))
|
||||||
|
{
|
||||||
|
ERR("Failed to acquire queue %p.\n", device->direct_queue);
|
||||||
|
VK_CALL(vkDestroySemaphore(device->vk_device, timeline_semaphore, NULL));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
|
submit_info.pNext = &timeline_submit_info;
|
||||||
|
submit_info.waitSemaphoreCount = 0;
|
||||||
|
submit_info.pWaitSemaphores = NULL;
|
||||||
|
submit_info.pWaitDstStageMask = NULL;
|
||||||
|
submit_info.commandBufferCount = 0;
|
||||||
|
submit_info.pCommandBuffers = NULL;
|
||||||
|
submit_info.signalSemaphoreCount = 1;
|
||||||
|
submit_info.pSignalSemaphores = &timeline_semaphore;
|
||||||
|
|
||||||
|
timeline_submit_info.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR;
|
||||||
|
timeline_submit_info.pNext = NULL;
|
||||||
|
timeline_submit_info.pSignalSemaphoreValues = &value;
|
||||||
|
timeline_submit_info.signalSemaphoreValueCount = 1;
|
||||||
|
timeline_submit_info.waitSemaphoreValueCount = 0;
|
||||||
|
timeline_submit_info.pWaitSemaphoreValues = NULL;
|
||||||
|
|
||||||
|
vr = VK_CALL(vkQueueSubmit(vk_queue, 1, &submit_info, VK_NULL_HANDLE));
|
||||||
|
|
||||||
|
if (vr >= 0)
|
||||||
|
{
|
||||||
|
if ((vr = VK_CALL(vkQueueWaitIdle(vk_queue))) < 0)
|
||||||
|
WARN("Failed to wait for queue, vr %d.\n", vr);
|
||||||
|
|
||||||
|
if ((vr = VK_CALL(vkGetSemaphoreCounterValueKHR(device->vk_device, timeline_semaphore, &value))) < 0)
|
||||||
|
ERR("Failed to get Vulkan semaphore status, vr %d.\n", vr);
|
||||||
|
else if (!(result = !value))
|
||||||
|
WARN("Disabling timeline semaphore use due to incompatible behaviour.\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WARN("Failed to submit signal operation, vr %d.\n", vr);
|
||||||
|
}
|
||||||
|
|
||||||
|
vkd3d_queue_release(device->direct_queue);
|
||||||
|
VK_CALL(vkDestroySemaphore(device->vk_device, timeline_semaphore, NULL));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT vkd3d_create_vk_device(struct d3d12_device *device,
|
static HRESULT vkd3d_create_vk_device(struct d3d12_device *device,
|
||||||
const struct vkd3d_device_create_info *create_info)
|
const struct vkd3d_device_create_info *create_info)
|
||||||
{
|
{
|
||||||
@ -2037,6 +2120,10 @@ static HRESULT vkd3d_create_vk_device(struct d3d12_device *device,
|
|||||||
}
|
}
|
||||||
|
|
||||||
device->feature_options4.MSAA64KBAlignedTextureSupported = d3d12_is_64k_msaa_supported(device);
|
device->feature_options4.MSAA64KBAlignedTextureSupported = d3d12_is_64k_msaa_supported(device);
|
||||||
|
device->use_timeline_semaphores = d3d12_is_timeline_semaphore_supported(device)
|
||||||
|
&& vkd3d_queue_init_timeline_semaphore(device->direct_queue, device)
|
||||||
|
&& vkd3d_queue_init_timeline_semaphore(device->compute_queue, device)
|
||||||
|
&& vkd3d_queue_init_timeline_semaphore(device->copy_queue, device);
|
||||||
|
|
||||||
TRACE("Created Vulkan device %p.\n", vk_device);
|
TRACE("Created Vulkan device %p.\n", vk_device);
|
||||||
|
|
||||||
|
@ -59,6 +59,7 @@
|
|||||||
#define VKD3D_MAX_SHADER_EXTENSIONS 3u
|
#define VKD3D_MAX_SHADER_EXTENSIONS 3u
|
||||||
#define VKD3D_MAX_SHADER_STAGES 5u
|
#define VKD3D_MAX_SHADER_STAGES 5u
|
||||||
#define VKD3D_MAX_VK_SYNC_OBJECTS 4u
|
#define VKD3D_MAX_VK_SYNC_OBJECTS 4u
|
||||||
|
#define VKD3D_MAX_FENCE_WAITING_QUEUES 4u
|
||||||
#define VKD3D_MAX_DESCRIPTOR_SETS 64u
|
#define VKD3D_MAX_DESCRIPTOR_SETS 64u
|
||||||
/* D3D12 binding tier 3 has a limit of 2048 samplers. */
|
/* D3D12 binding tier 3 has a limit of 2048 samplers. */
|
||||||
#define VKD3D_MAX_DESCRIPTOR_SET_SAMPLERS 2048u
|
#define VKD3D_MAX_DESCRIPTOR_SET_SAMPLERS 2048u
|
||||||
@ -125,6 +126,7 @@ struct vkd3d_vulkan_info
|
|||||||
bool KHR_maintenance3;
|
bool KHR_maintenance3;
|
||||||
bool KHR_push_descriptor;
|
bool KHR_push_descriptor;
|
||||||
bool KHR_sampler_mirror_clamp_to_edge;
|
bool KHR_sampler_mirror_clamp_to_edge;
|
||||||
|
bool KHR_timeline_semaphore;
|
||||||
/* EXT device extensions */
|
/* EXT device extensions */
|
||||||
bool EXT_calibrated_timestamps;
|
bool EXT_calibrated_timestamps;
|
||||||
bool EXT_conditional_rendering;
|
bool EXT_conditional_rendering;
|
||||||
@ -150,6 +152,8 @@ struct vkd3d_vulkan_info
|
|||||||
|
|
||||||
VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT texel_buffer_alignment_properties;
|
VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT texel_buffer_alignment_properties;
|
||||||
|
|
||||||
|
VkPhysicalDeviceTimelineSemaphorePropertiesKHR timeline_semaphore_properties;
|
||||||
|
|
||||||
unsigned int shader_extension_count;
|
unsigned int shader_extension_count;
|
||||||
enum vkd3d_shader_spirv_extension shader_extensions[VKD3D_MAX_SHADER_EXTENSIONS];
|
enum vkd3d_shader_spirv_extension shader_extensions[VKD3D_MAX_SHADER_EXTENSIONS];
|
||||||
|
|
||||||
@ -348,6 +352,7 @@ struct vkd3d_fence_worker
|
|||||||
struct vkd3d_enqueued_fence
|
struct vkd3d_enqueued_fence
|
||||||
{
|
{
|
||||||
VkFence vk_fence;
|
VkFence vk_fence;
|
||||||
|
VkSemaphore vk_semaphore;
|
||||||
struct vkd3d_waiting_fence waiting_fence;
|
struct vkd3d_waiting_fence waiting_fence;
|
||||||
} *enqueued_fences;
|
} *enqueued_fences;
|
||||||
size_t enqueued_fences_size;
|
size_t enqueued_fences_size;
|
||||||
@ -357,6 +362,12 @@ struct vkd3d_fence_worker
|
|||||||
size_t vk_fences_size;
|
size_t vk_fences_size;
|
||||||
struct vkd3d_waiting_fence *fences;
|
struct vkd3d_waiting_fence *fences;
|
||||||
size_t fences_size;
|
size_t fences_size;
|
||||||
|
VkSemaphore *vk_semaphores;
|
||||||
|
size_t vk_semaphores_size;
|
||||||
|
uint64_t *semaphore_wait_values;
|
||||||
|
size_t semaphore_wait_values_size;
|
||||||
|
|
||||||
|
void (*wait_for_gpu_fences)(struct vkd3d_fence_worker *worker);
|
||||||
|
|
||||||
struct d3d12_device *device;
|
struct d3d12_device *device;
|
||||||
};
|
};
|
||||||
@ -511,6 +522,12 @@ struct vkd3d_signaled_semaphore
|
|||||||
bool is_acquired;
|
bool is_acquired;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct vkd3d_pending_fence_wait
|
||||||
|
{
|
||||||
|
const struct vkd3d_queue *queue;
|
||||||
|
uint64_t pending_value;
|
||||||
|
};
|
||||||
|
|
||||||
/* ID3D12Fence */
|
/* ID3D12Fence */
|
||||||
struct d3d12_fence
|
struct d3d12_fence
|
||||||
{
|
{
|
||||||
@ -530,6 +547,11 @@ struct d3d12_fence
|
|||||||
size_t events_size;
|
size_t events_size;
|
||||||
size_t event_count;
|
size_t event_count;
|
||||||
|
|
||||||
|
VkSemaphore timeline_semaphore;
|
||||||
|
uint64_t pending_timeline_value;
|
||||||
|
struct vkd3d_pending_fence_wait gpu_waits[VKD3D_MAX_FENCE_WAITING_QUEUES];
|
||||||
|
unsigned int gpu_wait_count;
|
||||||
|
|
||||||
struct list semaphores;
|
struct list semaphores;
|
||||||
unsigned int semaphore_count;
|
unsigned int semaphore_count;
|
||||||
|
|
||||||
@ -545,6 +567,9 @@ struct d3d12_fence
|
|||||||
HRESULT d3d12_fence_create(struct d3d12_device *device, uint64_t initial_value,
|
HRESULT d3d12_fence_create(struct d3d12_device *device, uint64_t initial_value,
|
||||||
D3D12_FENCE_FLAGS flags, struct d3d12_fence **fence);
|
D3D12_FENCE_FLAGS flags, struct d3d12_fence **fence);
|
||||||
|
|
||||||
|
VkResult vkd3d_create_timeline_semaphore(const struct d3d12_device *device, uint64_t initial_value,
|
||||||
|
VkSemaphore *timeline_semaphore);
|
||||||
|
|
||||||
/* ID3D12Heap */
|
/* ID3D12Heap */
|
||||||
struct d3d12_heap
|
struct d3d12_heap
|
||||||
{
|
{
|
||||||
@ -1284,6 +1309,9 @@ struct vkd3d_queue
|
|||||||
VkQueueFlags vk_queue_flags;
|
VkQueueFlags vk_queue_flags;
|
||||||
uint32_t timestamp_bits;
|
uint32_t timestamp_bits;
|
||||||
|
|
||||||
|
VkSemaphore wait_completion_semaphore;
|
||||||
|
uint64_t pending_wait_completion_value;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
VkSemaphore vk_semaphore;
|
VkSemaphore vk_semaphore;
|
||||||
@ -1298,6 +1326,7 @@ struct vkd3d_queue
|
|||||||
VkQueue vkd3d_queue_acquire(struct vkd3d_queue *queue);
|
VkQueue vkd3d_queue_acquire(struct vkd3d_queue *queue);
|
||||||
HRESULT vkd3d_queue_create(struct d3d12_device *device, uint32_t family_index,
|
HRESULT vkd3d_queue_create(struct d3d12_device *device, uint32_t family_index,
|
||||||
const VkQueueFamilyProperties *properties, struct vkd3d_queue **queue);
|
const VkQueueFamilyProperties *properties, struct vkd3d_queue **queue);
|
||||||
|
bool vkd3d_queue_init_timeline_semaphore(struct vkd3d_queue *queue, struct d3d12_device *device);
|
||||||
void vkd3d_queue_destroy(struct vkd3d_queue *queue, struct d3d12_device *device);
|
void vkd3d_queue_destroy(struct vkd3d_queue *queue, struct d3d12_device *device);
|
||||||
void vkd3d_queue_release(struct vkd3d_queue *queue);
|
void vkd3d_queue_release(struct vkd3d_queue *queue);
|
||||||
|
|
||||||
@ -1456,6 +1485,7 @@ struct d3d12_device
|
|||||||
VkDescriptorPoolSize vk_pool_sizes[VKD3D_DESCRIPTOR_POOL_COUNT];
|
VkDescriptorPoolSize vk_pool_sizes[VKD3D_DESCRIPTOR_POOL_COUNT];
|
||||||
struct vkd3d_vk_descriptor_heap_layout vk_descriptor_heap_layouts[VKD3D_SET_INDEX_COUNT];
|
struct vkd3d_vk_descriptor_heap_layout vk_descriptor_heap_layouts[VKD3D_SET_INDEX_COUNT];
|
||||||
bool use_vk_heaps;
|
bool use_vk_heaps;
|
||||||
|
bool use_timeline_semaphores;
|
||||||
};
|
};
|
||||||
|
|
||||||
HRESULT d3d12_device_create(struct vkd3d_instance *instance,
|
HRESULT d3d12_device_create(struct vkd3d_instance *instance,
|
||||||
|
@ -195,6 +195,11 @@ VK_DEVICE_EXT_PFN(vkGetDescriptorSetLayoutSupportKHR)
|
|||||||
/* VK_KHR_push_descriptor */
|
/* VK_KHR_push_descriptor */
|
||||||
VK_DEVICE_EXT_PFN(vkCmdPushDescriptorSetKHR)
|
VK_DEVICE_EXT_PFN(vkCmdPushDescriptorSetKHR)
|
||||||
|
|
||||||
|
/* VK_KHR_timeline_semaphore */
|
||||||
|
VK_DEVICE_EXT_PFN(vkGetSemaphoreCounterValueKHR)
|
||||||
|
VK_DEVICE_EXT_PFN(vkWaitSemaphoresKHR)
|
||||||
|
VK_DEVICE_EXT_PFN(vkSignalSemaphoreKHR)
|
||||||
|
|
||||||
/* VK_EXT_calibrated_timestamps */
|
/* VK_EXT_calibrated_timestamps */
|
||||||
VK_DEVICE_EXT_PFN(vkGetCalibratedTimestampsEXT)
|
VK_DEVICE_EXT_PFN(vkGetCalibratedTimestampsEXT)
|
||||||
|
|
||||||
|
@ -33240,7 +33240,9 @@ static void test_queue_wait(void)
|
|||||||
command_list = context.list;
|
command_list = context.list;
|
||||||
queue = context.queue;
|
queue = context.queue;
|
||||||
|
|
||||||
queue2 = create_command_queue(device, D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL);
|
/* 'queue2' must not map to the same command queue as 'queue', or Wait() before GPU signal will fail.
|
||||||
|
* Using a compute queue fixes this on most hardware, but it may still fail on low spec hardware. */
|
||||||
|
queue2 = create_command_queue(device, D3D12_COMMAND_LIST_TYPE_COMPUTE, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL);
|
||||||
|
|
||||||
event = create_event();
|
event = create_event();
|
||||||
ok(event, "Failed to create event.\n");
|
ok(event, "Failed to create event.\n");
|
||||||
@ -33305,12 +33307,6 @@ static void test_queue_wait(void)
|
|||||||
check_readback_data_uint(&rb, NULL, 0xff00ff00, 0);
|
check_readback_data_uint(&rb, NULL, 0xff00ff00, 0);
|
||||||
release_resource_readback(&rb);
|
release_resource_readback(&rb);
|
||||||
|
|
||||||
if (!vkd3d_test_platform_is_windows())
|
|
||||||
{
|
|
||||||
skip("Wait() is not implemented yet.\n"); /* FIXME */
|
|
||||||
goto skip_tests;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Wait() before CPU signal */
|
/* Wait() before CPU signal */
|
||||||
update_buffer_data(cb, 0, sizeof(blue), &blue);
|
update_buffer_data(cb, 0, sizeof(blue), &blue);
|
||||||
queue_wait(queue, fence, 2);
|
queue_wait(queue, fence, 2);
|
||||||
@ -33386,7 +33382,6 @@ static void test_queue_wait(void)
|
|||||||
check_readback_data_uint(&rb, NULL, 0xff00ff00, 0);
|
check_readback_data_uint(&rb, NULL, 0xff00ff00, 0);
|
||||||
release_resource_readback(&rb);
|
release_resource_readback(&rb);
|
||||||
|
|
||||||
skip_tests:
|
|
||||||
/* Signal() and Wait() in the same command queue */
|
/* Signal() and Wait() in the same command queue */
|
||||||
update_buffer_data(cb, 0, sizeof(blue), &blue);
|
update_buffer_data(cb, 0, sizeof(blue), &blue);
|
||||||
queue_signal(queue, fence, 7);
|
queue_signal(queue, fence, 7);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user