[PATCH 1/2] vkd3d: Implement ID3D12GraphicsCommandList::SetPredication().

Conor McCarthy cmccarthy at codeweavers.com
Fri Jun 14 09:11:04 CDT 2019


Predicate arguments which are only non-zero in bit 32 or higher are
not supported. Predicates will not be applied to clear and copy
commands because Vulkan does not support predication of these
command classes.

Signed-off-by: Conor McCarthy <cmccarthy at codeweavers.com>
---
 libs/vkd3d/command.c       | 63 +++++++++++++++++++++++++++++++++++++-
 libs/vkd3d/device.c        | 12 ++++++++
 libs/vkd3d/vkd3d_private.h |  3 ++
 libs/vkd3d/vulkan_procs.h  |  4 +++
 4 files changed, 81 insertions(+), 1 deletion(-)

diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c
index 75556f5..32534e5 100644
--- a/libs/vkd3d/command.c
+++ b/libs/vkd3d/command.c
@@ -2288,6 +2288,8 @@ static void d3d12_command_list_reset_state(struct d3d12_command_list *list,
 
     list->xfb_enabled = false;
 
+    list->is_predicated = false;
+
     list->current_framebuffer = VK_NULL_HANDLE;
     list->current_pipeline = VK_NULL_HANDLE;
     list->pso_render_pass = VK_NULL_HANDLE;
@@ -4910,8 +4912,67 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResolveQueryData(ID3D12Graphics
 static void STDMETHODCALLTYPE d3d12_command_list_SetPredication(ID3D12GraphicsCommandList1 *iface,
         ID3D12Resource *buffer, UINT64 aligned_buffer_offset, D3D12_PREDICATION_OP operation)
 {
-    FIXME("iface %p, buffer %p, aligned_buffer_offset %#"PRIx64", operation %#x stub!\n",
+    struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList1(iface);
+    const struct vkd3d_vulkan_info *vk_info = &list->device->vk_info;
+    struct d3d12_resource *resource = unsafe_impl_from_ID3D12Resource(buffer);
+    const struct vkd3d_vk_device_procs *vk_procs;
+
+    TRACE("iface %p, buffer %p, aligned_buffer_offset %#"PRIx64", operation %#x.\n",
             iface, buffer, aligned_buffer_offset, operation);
+
+    if (!vk_info->EXT_conditional_rendering)
+    {
+        FIXME("Vulkan conditional rendering extension not present. Conditional rendering not supported.\n");
+        return;
+    }
+
+    vk_procs = &list->device->vk_procs;
+
+    if (resource)
+    {
+        VkConditionalRenderingBeginInfoEXT cond_info;
+        if (aligned_buffer_offset & (sizeof(UINT64) - 1))
+        {
+            WARN("Unaligned predicate argument buffer offset.\n");
+            return;
+        }
+        if (!d3d12_resource_is_buffer(resource))
+        {
+            WARN("Predicate arguments must be stored in a buffer.\n");
+            return;
+        }
+
+        FIXME("Predication doesn't support clear and copy commands, and predication "
+                "values are treated as 32-bit values.\n");
+        cond_info.sType = VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT;
+        cond_info.pNext = NULL;
+        cond_info.buffer = resource->u.vk_buffer;
+        cond_info.offset = aligned_buffer_offset;
+        switch (operation)
+        {
+        case D3D12_PREDICATION_OP_EQUAL_ZERO:
+            cond_info.flags = 0;
+            break;
+        case D3D12_PREDICATION_OP_NOT_EQUAL_ZERO:
+            cond_info.flags = VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT;
+            break;
+        default:
+            WARN("Unknown predication op %#x.\n", operation);
+            return;
+        }
+
+        /* Must end any current predication before beginning a new one */
+        if (list->is_predicated)
+            VK_CALL(vkCmdEndConditionalRenderingEXT(list->vk_command_buffer));
+
+        VK_CALL(vkCmdBeginConditionalRenderingEXT(list->vk_command_buffer, &cond_info));
+        list->is_predicated = true;
+    }
+    else
+    {
+        VK_CALL(vkCmdEndConditionalRenderingEXT(list->vk_command_buffer));
+        list->is_predicated = false;
+    }
 }
 
 static void STDMETHODCALLTYPE d3d12_command_list_SetMarker(ID3D12GraphicsCommandList1 *iface,
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index fa10bb8..217c1c8 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -142,6 +142,7 @@ static const struct vkd3d_optional_extension_info optional_device_extensions[] =
     {VK_KHR_MAINTENANCE3_EXTENSION_NAME, offsetof(struct vkd3d_vulkan_info, KHR_maintenance3)},
     {VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME, offsetof(struct vkd3d_vulkan_info, KHR_push_descriptor)},
     /* EXT extensions */
+    {VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME, offsetof(struct vkd3d_vulkan_info, EXT_conditional_rendering)},
     {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)},
@@ -673,6 +674,7 @@ struct vkd3d_physical_device_info
     VkPhysicalDeviceProperties2KHR properties2;
 
     /* features */
+    VkPhysicalDeviceConditionalRenderingFeaturesEXT conditional_rendering_features;
     VkPhysicalDeviceDepthClipEnableFeaturesEXT depth_clip_features;
     VkPhysicalDeviceDescriptorIndexingFeaturesEXT descriptor_indexing_features;
     VkPhysicalDeviceTransformFeedbackFeaturesEXT xfb_features;
@@ -684,6 +686,7 @@ struct vkd3d_physical_device_info
 static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *info, struct d3d12_device *device)
 {
     const struct vkd3d_vk_instance_procs *vk_procs = &device->vkd3d_instance->vk_procs;
+    VkPhysicalDeviceConditionalRenderingFeaturesEXT *conditional_rendering_features;
     VkPhysicalDeviceDescriptorIndexingPropertiesEXT *descriptor_indexing_properties;
     VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *vertex_divisor_properties;
     VkPhysicalDeviceDescriptorIndexingFeaturesEXT *descriptor_indexing_features;
@@ -696,6 +699,7 @@ static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *i
     struct vkd3d_vulkan_info *vulkan_info = &device->vk_info;
 
     memset(info, 0, sizeof(*info));
+    conditional_rendering_features = &info->conditional_rendering_features;
     depth_clip_features = &info->depth_clip_features;
     descriptor_indexing_features = &info->descriptor_indexing_features;
     descriptor_indexing_properties = &info->descriptor_indexing_properties;
@@ -705,7 +709,9 @@ static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *i
     xfb_features = &info->xfb_features;
     xfb_properties = &info->xfb_properties;
 
+    conditional_rendering_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT;
     depth_clip_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT;
+    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;
     xfb_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT;
@@ -999,6 +1005,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 VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *divisor_features;
     const VkPhysicalDeviceDescriptorIndexingFeaturesEXT *descriptor_indexing;
     const VkPhysicalDeviceDepthClipEnableFeaturesEXT *depth_clip_features;
@@ -1109,6 +1116,10 @@ static void vkd3d_trace_physical_device_features(const struct vkd3d_physical_dev
     TRACE("    runtimeDescriptorArray: %#x.\n",
             descriptor_indexing->runtimeDescriptorArray);
 
+    conditional_rendering_features = &info->conditional_rendering_features;
+    TRACE("  VkPhysicalDeviceConditionalRenderingFeaturesEXT:\n");
+    TRACE("    conditionalRendering: %#x.\n", conditional_rendering_features->conditionalRendering);
+
     depth_clip_features = &info->depth_clip_features;
     TRACE("  VkPhysicalDeviceDepthClipEnableFeaturesEXT:\n");
     TRACE("    depthClipEnable: %#x.\n", depth_clip_features->depthClipEnable);
@@ -1337,6 +1348,7 @@ 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 (get_spec_version(vk_extensions, count, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME) >= 3)
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index 3af8a95..e0d563f 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -97,6 +97,7 @@ struct vkd3d_vulkan_info
     bool KHR_maintenance3;
     bool KHR_push_descriptor;
     /* EXT device extensions */
+    bool EXT_conditional_rendering;
     bool EXT_debug_marker;
     bool EXT_depth_clip_enable;
     bool EXT_descriptor_indexing;
@@ -907,6 +908,8 @@ struct d3d12_command_list
 
     bool xfb_enabled;
 
+    bool is_predicated;
+
     VkFramebuffer current_framebuffer;
     VkPipeline current_pipeline;
     VkRenderPass pso_render_pass;
diff --git a/libs/vkd3d/vulkan_procs.h b/libs/vkd3d/vulkan_procs.h
index a55fb07..702cfd2 100644
--- a/libs/vkd3d/vulkan_procs.h
+++ b/libs/vkd3d/vulkan_procs.h
@@ -192,6 +192,10 @@ VK_DEVICE_EXT_PFN(vkGetDescriptorSetLayoutSupportKHR)
 /* VK_KHR_push_descriptor */
 VK_DEVICE_EXT_PFN(vkCmdPushDescriptorSetKHR)
 
+/* VK_EXT_conditional_rendering */
+VK_DEVICE_EXT_PFN(vkCmdBeginConditionalRenderingEXT)
+VK_DEVICE_EXT_PFN(vkCmdEndConditionalRenderingEXT)
+
 /* VK_EXT_debug_marker */
 VK_DEVICE_EXT_PFN(vkDebugMarkerSetObjectNameEXT)
 
-- 
2.21.0




More information about the wine-devel mailing list