[PATCH vkd3d 03/10] vkd3d: Implement d3d12_command_list_SOSetTargets().

Józef Kucia joseph.kucia at gmail.com
Mon Jan 14 10:05:40 CST 2019


From: Józef Kucia <jkucia at codeweavers.com>

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
 libs/vkd3d/command.c       | 62 +++++++++++++++++++++++++++++++++++++-
 libs/vkd3d/vkd3d_private.h |  3 ++
 2 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c
index ce4af4e6a6fd..8402668f3a05 100644
--- a/libs/vkd3d/command.c
+++ b/libs/vkd3d/command.c
@@ -1754,6 +1754,9 @@ static void d3d12_command_list_reset_state(struct d3d12_command_list *list,
 
     list->state = NULL;
 
+    memset(list->so_counter_buffers, 0, sizeof(list->so_counter_buffers));
+    memset(list->so_counter_buffer_offsets, 0, sizeof(list->so_counter_buffer_offsets));
+
     ID3D12GraphicsCommandList_SetPipelineState(iface, initial_pipeline_state);
 }
 
@@ -3609,7 +3612,64 @@ static void STDMETHODCALLTYPE d3d12_command_list_IASetVertexBuffers(ID3D12Graphi
 static void STDMETHODCALLTYPE d3d12_command_list_SOSetTargets(ID3D12GraphicsCommandList *iface,
         UINT start_slot, UINT view_count, const D3D12_STREAM_OUTPUT_BUFFER_VIEW *views)
 {
-    FIXME("iface %p, start_slot %u, view_count %u, views %p stub!\n", iface, start_slot, view_count, views);
+    struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList(iface);
+    VkDeviceSize offsets[ARRAY_SIZE(list->so_counter_buffers)];
+    VkDeviceSize sizes[ARRAY_SIZE(list->so_counter_buffers)];
+    VkBuffer buffers[ARRAY_SIZE(list->so_counter_buffers)];
+    struct vkd3d_gpu_va_allocator *gpu_va_allocator;
+    const struct vkd3d_vk_device_procs *vk_procs;
+    struct d3d12_resource *resource;
+    unsigned int i, first, count;
+
+    TRACE("iface %p, start_slot %u, view_count %u, views %p.\n", iface, start_slot, view_count, views);
+
+    d3d12_command_list_end_current_render_pass(list);
+
+    if (!list->device->vk_info.EXT_transform_feedback)
+    {
+        FIXME("Transform feedback is not supported by Vulkan implementation.\n");
+        return;
+    }
+
+    if (start_slot >= ARRAY_SIZE(buffers) || view_count > ARRAY_SIZE(buffers) - start_slot)
+    {
+        WARN("Invalid start slot %u / view count %u.\n", start_slot, view_count);
+        return;
+    }
+
+    vk_procs = &list->device->vk_procs;
+    gpu_va_allocator = &list->device->gpu_va_allocator;
+
+    count = 0;
+    first = start_slot;
+    for (i = 0; i < view_count; ++i)
+    {
+        if (views[i].BufferLocation && views[i].SizeInBytes)
+        {
+            resource = vkd3d_gpu_va_allocator_dereference(gpu_va_allocator, views[i].BufferLocation);
+            buffers[count] = resource->u.vk_buffer;
+            offsets[count] = views[i].BufferLocation - resource->gpu_address;
+            sizes[count] = views[i].SizeInBytes;
+
+            resource = vkd3d_gpu_va_allocator_dereference(gpu_va_allocator, views[i].BufferFilledSizeLocation);
+            list->so_counter_buffers[start_slot + i] = resource->u.vk_buffer;
+            list->so_counter_buffer_offsets[start_slot + i] = views[i].BufferFilledSizeLocation - resource->gpu_address;
+            ++count;
+        }
+        else
+        {
+            if (count)
+                VK_CALL(vkCmdBindTransformFeedbackBuffersEXT(list->vk_command_buffer, first, count, buffers, offsets, sizes));
+            count = 0;
+            first = start_slot + i + 1;
+
+            list->so_counter_buffers[start_slot + i] = VK_NULL_HANDLE;
+            list->so_counter_buffer_offsets[start_slot + i] = 0;
+        }
+    }
+
+    if (count)
+        VK_CALL(vkCmdBindTransformFeedbackBuffersEXT(list->vk_command_buffer, first, count, buffers, offsets, sizes));
 }
 
 static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12GraphicsCommandList *iface,
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index 3b78a5e2c55d..62245b1e57a0 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -794,6 +794,9 @@ struct d3d12_command_list
     struct d3d12_command_allocator *allocator;
     struct d3d12_device *device;
 
+    VkBuffer so_counter_buffers[D3D12_SO_BUFFER_SLOT_COUNT];
+    VkDeviceSize so_counter_buffer_offsets[D3D12_SO_BUFFER_SLOT_COUNT];
+
     struct vkd3d_private_store private_store;
 };
 
-- 
2.19.2




More information about the wine-devel mailing list