From 46ff2c276476698198ca319abe2f56f4bb1db529 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Thu, 4 Jul 2019 16:41:10 +0200 Subject: [PATCH] vkd3d: Add support for VK_EXT_texel_buffer_alignment. 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 --- README | 2 +- configure.ac | 2 +- libs/vkd3d/device.c | 42 ++++++++++++++++++++++++++++++++++---- libs/vkd3d/resource.c | 37 +++++++++++++++++++++++++++------ libs/vkd3d/vkd3d_private.h | 3 +++ 5 files changed, 74 insertions(+), 12 deletions(-) diff --git a/README b/README index 2e42249e..2f2f3952 100644 --- a/README +++ b/README @@ -9,7 +9,7 @@ similar, but not identical, to Direct3D 12. Building vkd3d ============== -Vkd3d depends on SPIRV-Headers and Vulkan-Headers (>= 1.1.101). +Vkd3d depends on SPIRV-Headers and Vulkan-Headers (>= 1.1.113). Vkd3d generates some of its headers from IDL files. If you are using the release tarballs, then these headers are pre-generated and are included. If diff --git a/configure.ac b/configure.ac index 02f9028e..e2d61316 100644 --- a/configure.ac +++ b/configure.ac @@ -67,7 +67,7 @@ AS_IF([test "x$ac_cv_header_spirv_unified1_GLSL_std_450_h" != "xyes" \ -a "x$ac_cv_header_vulkan_GLSL_std_450_h" != "xyes"], [AC_MSG_ERROR([GLSL.std.450.h not found.])]) -VKD3D_CHECK_VULKAN_HEADER_VERSION([101], [AC_MSG_ERROR([Vulkan headers are too old, 1.1.101 is required.])]) +VKD3D_CHECK_VULKAN_HEADER_VERSION([113], [AC_MSG_ERROR([Vulkan headers are too old, 1.1.113 is required.])]) dnl Check for libraries m4_ifdef([PKG_PROG_PKG_CONFIG], [PKG_PROG_PKG_CONFIG], [m4_fatal([pkg-config autoconf macros not found.])]) diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index 2fd13f6c..b9ac8297 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -133,6 +133,7 @@ static const struct vkd3d_optional_extension_info optional_device_extensions[] = {VK_EXT_DEBUG_MARKER_EXTENSION_NAME, offsetof(struct vkd3d_vulkan_info, EXT_debug_marker)}, {VK_EXT_DEPTH_CLIP_ENABLE_EXTENSION_NAME, offsetof(struct vkd3d_vulkan_info, EXT_depth_clip_enable)}, {VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, offsetof(struct vkd3d_vulkan_info, EXT_descriptor_indexing)}, + {VK_EXT_TEXEL_BUFFER_ALIGNMENT_EXTENSION_NAME, offsetof(struct vkd3d_vulkan_info, EXT_texel_buffer_alignment)}, {VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, offsetof(struct vkd3d_vulkan_info, EXT_transform_feedback)}, {VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, @@ -662,6 +663,7 @@ struct vkd3d_physical_device_info /* properties */ VkPhysicalDeviceDescriptorIndexingPropertiesEXT descriptor_indexing_properties; VkPhysicalDeviceMaintenance3Properties maintenance3_properties; + VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT texel_buffer_alignment_properties; VkPhysicalDeviceTransformFeedbackPropertiesEXT xfb_properties; VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT vertex_divisor_properties; @@ -671,6 +673,7 @@ struct vkd3d_physical_device_info VkPhysicalDeviceConditionalRenderingFeaturesEXT conditional_rendering_features; VkPhysicalDeviceDepthClipEnableFeaturesEXT depth_clip_features; VkPhysicalDeviceDescriptorIndexingFeaturesEXT descriptor_indexing_features; + VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT texel_buffer_alignment_features; VkPhysicalDeviceTransformFeedbackFeaturesEXT xfb_features; VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT vertex_divisor_features; @@ -683,8 +686,10 @@ static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *i VkPhysicalDeviceConditionalRenderingFeaturesEXT *conditional_rendering_features; VkPhysicalDeviceDescriptorIndexingPropertiesEXT *descriptor_indexing_properties; VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *vertex_divisor_properties; + VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT *buffer_alignment_properties; VkPhysicalDeviceDescriptorIndexingFeaturesEXT *descriptor_indexing_features; VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *vertex_divisor_features; + VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT *buffer_alignment_features; VkPhysicalDeviceDepthClipEnableFeaturesEXT *depth_clip_features; VkPhysicalDeviceMaintenance3Properties *maintenance3_properties; VkPhysicalDeviceTransformFeedbackPropertiesEXT *xfb_properties; @@ -698,6 +703,8 @@ static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *i descriptor_indexing_features = &info->descriptor_indexing_features; descriptor_indexing_properties = &info->descriptor_indexing_properties; maintenance3_properties = &info->maintenance3_properties; + buffer_alignment_features = &info->texel_buffer_alignment_features; + buffer_alignment_properties = &info->texel_buffer_alignment_properties; vertex_divisor_features = &info->vertex_divisor_features; vertex_divisor_properties = &info->vertex_divisor_properties; xfb_features = &info->xfb_features; @@ -708,8 +715,10 @@ static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *i depth_clip_features->pNext = conditional_rendering_features; descriptor_indexing_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT; descriptor_indexing_features->pNext = depth_clip_features; + buffer_alignment_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT; + buffer_alignment_features->pNext = descriptor_indexing_features; xfb_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT; - xfb_features->pNext = descriptor_indexing_features; + xfb_features->pNext = buffer_alignment_features; vertex_divisor_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT; vertex_divisor_features->pNext = xfb_features; @@ -724,8 +733,10 @@ static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *i maintenance3_properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES; descriptor_indexing_properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT; descriptor_indexing_properties->pNext = maintenance3_properties; + buffer_alignment_properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT; + buffer_alignment_properties->pNext = descriptor_indexing_properties; xfb_properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT; - xfb_properties->pNext = descriptor_indexing_properties; + xfb_properties->pNext = buffer_alignment_properties; vertex_divisor_properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT; vertex_divisor_properties->pNext = xfb_properties; @@ -800,6 +811,7 @@ static void vkd3d_trace_physical_device_limits(const struct vkd3d_physical_devic const VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *divisor_properties; const VkPhysicalDeviceLimits *limits = &info->properties2.properties.limits; const VkPhysicalDeviceDescriptorIndexingPropertiesEXT *descriptor_indexing; + const VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT *buffer_alignment; const VkPhysicalDeviceMaintenance3Properties *maintenance3; const VkPhysicalDeviceTransformFeedbackPropertiesEXT *xfb; @@ -979,6 +991,17 @@ static void vkd3d_trace_physical_device_limits(const struct vkd3d_physical_devic TRACE(" maxPerSetDescriptors: %u.\n", maintenance3->maxPerSetDescriptors); TRACE(" maxMemoryAllocationSize: %#"PRIx64".\n", maintenance3->maxMemoryAllocationSize); + buffer_alignment = &info->texel_buffer_alignment_properties; + TRACE(" VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT:\n"); + TRACE(" storageTexelBufferOffsetAlignmentBytes: %#"PRIx64".\n", + buffer_alignment->storageTexelBufferOffsetAlignmentBytes); + TRACE(" storageTexelBufferOffsetSingleTexelAlignment: %#x.\n", + buffer_alignment->storageTexelBufferOffsetSingleTexelAlignment); + TRACE(" uniformTexelBufferOffsetAlignmentBytes: %#"PRIx64".\n", + buffer_alignment->uniformTexelBufferOffsetAlignmentBytes); + TRACE(" uniformTexelBufferOffsetSingleTexelAlignment: %#x.\n", + buffer_alignment->uniformTexelBufferOffsetSingleTexelAlignment); + xfb = &info->xfb_properties; TRACE(" VkPhysicalDeviceTransformFeedbackPropertiesEXT:\n"); TRACE(" maxTransformFeedbackStreams: %u.\n", xfb->maxTransformFeedbackStreams); @@ -1000,6 +1023,7 @@ static void vkd3d_trace_physical_device_limits(const struct vkd3d_physical_devic static void vkd3d_trace_physical_device_features(const struct vkd3d_physical_device_info *info) { const VkPhysicalDeviceConditionalRenderingFeaturesEXT *conditional_rendering_features; + const VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT *buffer_alignment_features; const VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *divisor_features; const VkPhysicalDeviceDescriptorIndexingFeaturesEXT *descriptor_indexing; const VkPhysicalDeviceDepthClipEnableFeaturesEXT *depth_clip_features; @@ -1118,6 +1142,10 @@ static void vkd3d_trace_physical_device_features(const struct vkd3d_physical_dev TRACE(" VkPhysicalDeviceDepthClipEnableFeaturesEXT:\n"); TRACE(" depthClipEnable: %#x.\n", depth_clip_features->depthClipEnable); + buffer_alignment_features = &info->texel_buffer_alignment_features; + TRACE(" VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT:\n"); + TRACE(" texelBufferAlignment: %#x.\n", buffer_alignment_features->texelBufferAlignment); + xfb = &info->xfb_features; TRACE(" VkPhysicalDeviceTransformFeedbackFeaturesEXT:\n"); TRACE(" transformFeedback: %#x.\n", xfb->transformFeedback); @@ -1342,8 +1370,14 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device, *user_extension_supported, vulkan_info, "device", device->vkd3d_instance->config_flags & VKD3D_CONFIG_FLAG_VULKAN_DEBUG); - vulkan_info->EXT_conditional_rendering = physical_device_info->conditional_rendering_features.conditionalRendering; - vulkan_info->EXT_depth_clip_enable = physical_device_info->depth_clip_features.depthClipEnable; + if (!physical_device_info->conditional_rendering_features.conditionalRendering) + vulkan_info->EXT_conditional_rendering = false; + if (!physical_device_info->depth_clip_features.depthClipEnable) + vulkan_info->EXT_depth_clip_enable = false; + if (!physical_device_info->texel_buffer_alignment_features.texelBufferAlignment) + vulkan_info->EXT_texel_buffer_alignment = false; + + vulkan_info->texel_buffer_alignment_properties = physical_device_info->texel_buffer_alignment_properties; if (get_spec_version(vk_extensions, count, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME) >= 3) { diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index 9d563303..e0e1aadf 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -1772,13 +1772,40 @@ void d3d12_desc_copy(struct d3d12_desc *dst, const struct d3d12_desc *src, } } +static VkDeviceSize vkd3d_get_required_texel_buffer_alignment(const struct d3d12_device *device, + const struct vkd3d_format *format) +{ + const VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT *properties; + const struct vkd3d_vulkan_info *vk_info = &device->vk_info; + VkDeviceSize alignment; + + if (vk_info->EXT_texel_buffer_alignment) + { + properties = &vk_info->texel_buffer_alignment_properties; + + alignment = max(properties->storageTexelBufferOffsetAlignmentBytes, + properties->uniformTexelBufferOffsetAlignmentBytes); + + if (properties->storageTexelBufferOffsetSingleTexelAlignment + && properties->uniformTexelBufferOffsetSingleTexelAlignment) + { + assert(!vkd3d_format_is_compressed(format)); + return min(format->byte_count, alignment); + } + + return alignment; + } + + return vk_info->device_limits.minTexelBufferOffsetAlignment; +} + static bool vkd3d_create_vk_buffer_view(struct d3d12_device *device, VkBuffer vk_buffer, const struct vkd3d_format *format, VkDeviceSize offset, VkDeviceSize range, VkBufferView *vk_view) { const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; - const struct vkd3d_vulkan_info *vk_info = &device->vk_info; struct VkBufferViewCreateInfo view_desc; + VkDeviceSize alignment; VkResult vr; if (vkd3d_format_is_compressed(format)) @@ -1787,11 +1814,9 @@ static bool vkd3d_create_vk_buffer_view(struct d3d12_device *device, return false; } - if (offset % vk_info->device_limits.minTexelBufferOffsetAlignment) - { - FIXME("Offset %#"PRIx64" violates the minimum required alignment %#"PRIx64".\n", - offset, vk_info->device_limits.minTexelBufferOffsetAlignment); - } + alignment = vkd3d_get_required_texel_buffer_alignment(device, format); + if (offset % alignment) + FIXME("Offset %#"PRIx64" violates the required alignment %#"PRIx64".\n", offset, alignment); view_desc.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO; view_desc.pNext = NULL; diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 0ea501c9..6e2dc2b2 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -102,6 +102,7 @@ struct vkd3d_vulkan_info bool EXT_debug_marker; bool EXT_depth_clip_enable; bool EXT_descriptor_indexing; + bool EXT_texel_buffer_alignment; bool EXT_transform_feedback; bool EXT_vertex_attribute_divisor; @@ -114,6 +115,8 @@ struct vkd3d_vulkan_info VkPhysicalDeviceLimits device_limits; VkPhysicalDeviceSparseProperties sparse_properties; + VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT texel_buffer_alignment_properties; + D3D_FEATURE_LEVEL max_feature_level; };