[PATCH vkd3d 5/6] vkd3d: Make pipeline state responsible for creating Vulkan pipelines.

Józef Kucia joseph.kucia at gmail.com
Wed Oct 24 06:16:28 CDT 2018


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

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
 libs/vkd3d/command.c       | 149 +------------------------------------
 libs/vkd3d/state.c         | 148 +++++++++++++++++++++++++++++++++++-
 libs/vkd3d/vkd3d_private.h |   7 ++
 3 files changed, 157 insertions(+), 147 deletions(-)

diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c
index d8a65622507d..7e7b3ee5d9c7 100644
--- a/libs/vkd3d/command.c
+++ b/libs/vkd3d/command.c
@@ -1818,148 +1818,6 @@ static bool d3d12_command_list_update_current_framebuffer(struct d3d12_command_l
     return true;
 }
 
-static VkPipeline d3d12_command_list_get_or_create_pipeline(struct d3d12_command_list *list,
-        struct d3d12_graphics_pipeline_state *state)
-{
-    struct VkVertexInputBindingDescription bindings[D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
-    const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs;
-    struct VkPipelineVertexInputStateCreateInfo input_desc;
-    struct VkPipelineInputAssemblyStateCreateInfo ia_desc;
-    struct VkPipelineColorBlendStateCreateInfo blend_desc;
-    struct VkGraphicsPipelineCreateInfo pipeline_desc;
-    struct d3d12_device *device = list->device;
-    struct vkd3d_pipeline_key pipeline_key;
-    size_t binding_count = 0;
-    VkPipeline vk_pipeline;
-    unsigned int i;
-    uint32_t mask;
-    VkResult vr;
-
-    static const struct VkPipelineViewportStateCreateInfo vp_desc =
-    {
-        .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
-        .pNext = NULL,
-        .flags = 0,
-        .viewportCount = 1,
-        .pViewports = NULL,
-        .scissorCount = 1,
-        .pScissors = NULL,
-    };
-    static const enum VkDynamicState dynamic_states[] =
-    {
-        VK_DYNAMIC_STATE_VIEWPORT,
-        VK_DYNAMIC_STATE_SCISSOR,
-        VK_DYNAMIC_STATE_BLEND_CONSTANTS,
-        VK_DYNAMIC_STATE_STENCIL_REFERENCE,
-    };
-    static const struct VkPipelineDynamicStateCreateInfo dynamic_desc =
-    {
-        .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
-        .pNext = NULL,
-        .flags = 0,
-        .dynamicStateCount = ARRAY_SIZE(dynamic_states),
-        .pDynamicStates = dynamic_states,
-    };
-
-    memset(&pipeline_key, 0, sizeof(pipeline_key));
-    pipeline_key.state = state;
-    pipeline_key.topology = list->primitive_topology;
-
-    for (i = 0, mask = 0; i < state->attribute_count; ++i)
-    {
-        struct VkVertexInputBindingDescription *b;
-        uint32_t binding;
-
-        binding = state->attributes[i].binding;
-        if (mask & (1u << binding))
-            continue;
-
-        if (binding_count == ARRAY_SIZE(bindings))
-        {
-            FIXME("Maximum binding count exceeded.\n");
-            break;
-        }
-
-        mask |= 1u << binding;
-        b = &bindings[binding_count];
-        b->binding = binding;
-        b->stride = list->strides[binding];
-        b->inputRate = state->input_rates[binding];
-
-        if (!b->stride)
-            FIXME("Invalid stride for input slot %u.\n", binding);
-
-        pipeline_key.strides[binding_count] = list->strides[binding];
-
-        ++binding_count;
-    }
-
-    if ((vk_pipeline = d3d12_device_find_cached_pipeline(device, &pipeline_key)))
-        return vk_pipeline;
-
-    input_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
-    input_desc.pNext = NULL;
-    input_desc.flags = 0;
-    input_desc.vertexBindingDescriptionCount = binding_count;
-    input_desc.pVertexBindingDescriptions = bindings;
-    input_desc.vertexAttributeDescriptionCount = state->attribute_count;
-    input_desc.pVertexAttributeDescriptions = state->attributes;
-
-    ia_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
-    ia_desc.pNext = NULL;
-    ia_desc.flags = 0;
-    ia_desc.topology = list->primitive_topology;
-    ia_desc.primitiveRestartEnable = VK_FALSE;
-
-    blend_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
-    blend_desc.pNext = NULL;
-    blend_desc.flags = 0;
-    blend_desc.logicOpEnable = VK_FALSE;
-    blend_desc.logicOp = VK_LOGIC_OP_COPY;
-    blend_desc.attachmentCount = state->attachment_count - state->rt_idx;
-    blend_desc.pAttachments = state->blend_attachments;
-    blend_desc.blendConstants[0] = D3D12_DEFAULT_BLEND_FACTOR_RED;
-    blend_desc.blendConstants[1] = D3D12_DEFAULT_BLEND_FACTOR_GREEN;
-    blend_desc.blendConstants[2] = D3D12_DEFAULT_BLEND_FACTOR_BLUE;
-    blend_desc.blendConstants[3] = D3D12_DEFAULT_BLEND_FACTOR_ALPHA;
-
-    pipeline_desc.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
-    pipeline_desc.pNext = NULL;
-    pipeline_desc.flags = 0;
-    pipeline_desc.stageCount = state->stage_count;
-    pipeline_desc.pStages = state->stages;
-    pipeline_desc.pVertexInputState = &input_desc;
-    pipeline_desc.pInputAssemblyState = &ia_desc;
-    pipeline_desc.pTessellationState = NULL;
-    pipeline_desc.pViewportState = &vp_desc;
-    pipeline_desc.pRasterizationState = &state->rs_desc;
-    pipeline_desc.pMultisampleState = &state->ms_desc;
-    pipeline_desc.pDepthStencilState = &state->ds_desc;
-    pipeline_desc.pColorBlendState = &blend_desc;
-    pipeline_desc.pDynamicState = &dynamic_desc;
-    pipeline_desc.layout = state->root_signature->vk_pipeline_layout;
-    pipeline_desc.renderPass = state->render_pass;
-    pipeline_desc.subpass = 0;
-    pipeline_desc.basePipelineHandle = VK_NULL_HANDLE;
-    pipeline_desc.basePipelineIndex = -1;
-    if ((vr = VK_CALL(vkCreateGraphicsPipelines(device->vk_device, device->vk_pipeline_cache,
-            1, &pipeline_desc, NULL, &vk_pipeline))) < 0)
-    {
-        WARN("Failed to create Vulkan graphics pipeline, vr %d.\n", vr);
-        return VK_NULL_HANDLE;
-    }
-
-    if (d3d12_device_put_pipeline_to_cache(device, &pipeline_key, vk_pipeline, &state->compiled_pipelines))
-        return vk_pipeline;
-
-    /* Other thread compiled the pipeline before us. */
-    VK_CALL(vkDestroyPipeline(device->vk_device, vk_pipeline, NULL));
-    vk_pipeline = d3d12_device_find_cached_pipeline(device, &pipeline_key);
-    if (!vk_pipeline)
-        ERR("Could not get the pipeline compiled by other thread from the cache.\n");
-    return vk_pipeline;
-}
-
 static bool d3d12_command_list_update_current_pipeline(struct d3d12_command_list *list)
 {
     const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs;
@@ -1968,13 +1826,14 @@ static bool d3d12_command_list_update_current_pipeline(struct d3d12_command_list
     if (list->current_pipeline != VK_NULL_HANDLE)
         return true;
 
-    if (list->state->vk_bind_point != VK_PIPELINE_BIND_POINT_GRAPHICS)
+    if (!d3d12_pipeline_state_is_graphics(list->state))
     {
-        WARN("Pipeline state %p has bind point %#x.\n", list->state, list->state->vk_bind_point);
+        WARN("Pipeline state %p is not a graphics pipeline.\n", list->state);
         return false;
     }
 
-    if (!(vk_pipeline = d3d12_command_list_get_or_create_pipeline(list, &list->state->u.graphics)))
+    if (!(vk_pipeline = d3d12_pipeline_state_get_or_create_pipeline(list->state,
+            list->primitive_topology, list->strides)))
         return false;
 
     VK_CALL(vkCmdBindPipeline(list->vk_command_buffer, list->state->vk_bind_point, vk_pipeline));
diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c
index db761d884756..7ee5f4dc19c5 100644
--- a/libs/vkd3d/state.c
+++ b/libs/vkd3d/state.c
@@ -1093,7 +1093,7 @@ static ULONG STDMETHODCALLTYPE d3d12_pipeline_state_Release(ID3D12PipelineState
         const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
         unsigned int i;
 
-        if (state->vk_bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS)
+        if (d3d12_pipeline_state_is_graphics(state))
         {
             struct d3d12_graphics_pipeline_state *graphics = &state->u.graphics;
 
@@ -1105,7 +1105,7 @@ static ULONG STDMETHODCALLTYPE d3d12_pipeline_state_Release(ID3D12PipelineState
 
             d3d12_device_destroy_compiled_pipelines(device, &graphics->compiled_pipelines);
         }
-        else if (state->vk_bind_point == VK_PIPELINE_BIND_POINT_COMPUTE)
+        else if (d3d12_pipeline_state_is_compute(state))
         {
             VK_CALL(vkDestroyPipeline(device->vk_device, state->u.compute.vk_pipeline, NULL));
         }
@@ -2234,3 +2234,147 @@ HRESULT d3d12_pipeline_state_create_graphics(struct d3d12_device *device,
 
     return S_OK;
 }
+
+VkPipeline d3d12_pipeline_state_get_or_create_pipeline(struct d3d12_pipeline_state *state,
+        VkPrimitiveTopology topology, const uint32_t *strides)
+{
+    struct VkVertexInputBindingDescription bindings[D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
+    const struct vkd3d_vk_device_procs *vk_procs = &state->device->vk_procs;
+    struct d3d12_graphics_pipeline_state *graphics = &state->u.graphics;
+    struct VkPipelineVertexInputStateCreateInfo input_desc;
+    struct VkPipelineInputAssemblyStateCreateInfo ia_desc;
+    struct VkPipelineColorBlendStateCreateInfo blend_desc;
+    struct VkGraphicsPipelineCreateInfo pipeline_desc;
+    struct d3d12_device *device = state->device;
+    struct vkd3d_pipeline_key pipeline_key;
+    size_t binding_count = 0;
+    VkPipeline vk_pipeline;
+    unsigned int i;
+    uint32_t mask;
+    VkResult vr;
+
+    static const struct VkPipelineViewportStateCreateInfo vp_desc =
+    {
+        .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
+        .pNext = NULL,
+        .flags = 0,
+        .viewportCount = 1,
+        .pViewports = NULL,
+        .scissorCount = 1,
+        .pScissors = NULL,
+    };
+    static const enum VkDynamicState dynamic_states[] =
+    {
+        VK_DYNAMIC_STATE_VIEWPORT,
+        VK_DYNAMIC_STATE_SCISSOR,
+        VK_DYNAMIC_STATE_BLEND_CONSTANTS,
+        VK_DYNAMIC_STATE_STENCIL_REFERENCE,
+    };
+    static const struct VkPipelineDynamicStateCreateInfo dynamic_desc =
+    {
+        .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
+        .pNext = NULL,
+        .flags = 0,
+        .dynamicStateCount = ARRAY_SIZE(dynamic_states),
+        .pDynamicStates = dynamic_states,
+    };
+
+    assert(d3d12_pipeline_state_is_graphics(state));
+
+    memset(&pipeline_key, 0, sizeof(pipeline_key));
+    pipeline_key.topology = topology;
+
+    for (i = 0, mask = 0; i < graphics->attribute_count; ++i)
+    {
+        struct VkVertexInputBindingDescription *b;
+        uint32_t binding;
+
+        binding = graphics->attributes[i].binding;
+        if (mask & (1u << binding))
+            continue;
+
+        if (binding_count == ARRAY_SIZE(bindings))
+        {
+            FIXME("Maximum binding count exceeded.\n");
+            break;
+        }
+
+        mask |= 1u << binding;
+        b = &bindings[binding_count];
+        b->binding = binding;
+        b->stride = strides[binding];
+        b->inputRate = graphics->input_rates[binding];
+
+        if (!b->stride)
+            FIXME("Invalid stride for input slot %u.\n", binding);
+
+        pipeline_key.strides[binding_count] = strides[binding];
+
+        ++binding_count;
+    }
+
+    if ((vk_pipeline = d3d12_device_find_cached_pipeline(device, &pipeline_key)))
+        return vk_pipeline;
+
+    input_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
+    input_desc.pNext = NULL;
+    input_desc.flags = 0;
+    input_desc.vertexBindingDescriptionCount = binding_count;
+    input_desc.pVertexBindingDescriptions = bindings;
+    input_desc.vertexAttributeDescriptionCount = graphics->attribute_count;
+    input_desc.pVertexAttributeDescriptions = graphics->attributes;
+
+    ia_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
+    ia_desc.pNext = NULL;
+    ia_desc.flags = 0;
+    ia_desc.topology = topology;
+    ia_desc.primitiveRestartEnable = VK_FALSE;
+
+    blend_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
+    blend_desc.pNext = NULL;
+    blend_desc.flags = 0;
+    blend_desc.logicOpEnable = VK_FALSE;
+    blend_desc.logicOp = VK_LOGIC_OP_COPY;
+    blend_desc.attachmentCount = graphics->attachment_count - graphics->rt_idx;
+    blend_desc.pAttachments = graphics->blend_attachments;
+    blend_desc.blendConstants[0] = D3D12_DEFAULT_BLEND_FACTOR_RED;
+    blend_desc.blendConstants[1] = D3D12_DEFAULT_BLEND_FACTOR_GREEN;
+    blend_desc.blendConstants[2] = D3D12_DEFAULT_BLEND_FACTOR_BLUE;
+    blend_desc.blendConstants[3] = D3D12_DEFAULT_BLEND_FACTOR_ALPHA;
+
+    pipeline_desc.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
+    pipeline_desc.pNext = NULL;
+    pipeline_desc.flags = 0;
+    pipeline_desc.stageCount = graphics->stage_count;
+    pipeline_desc.pStages = graphics->stages;
+    pipeline_desc.pVertexInputState = &input_desc;
+    pipeline_desc.pInputAssemblyState = &ia_desc;
+    pipeline_desc.pTessellationState = NULL;
+    pipeline_desc.pViewportState = &vp_desc;
+    pipeline_desc.pRasterizationState = &graphics->rs_desc;
+    pipeline_desc.pMultisampleState = &graphics->ms_desc;
+    pipeline_desc.pDepthStencilState = &graphics->ds_desc;
+    pipeline_desc.pColorBlendState = &blend_desc;
+    pipeline_desc.pDynamicState = &dynamic_desc;
+    pipeline_desc.layout = graphics->root_signature->vk_pipeline_layout;
+    pipeline_desc.renderPass = graphics->render_pass;
+    pipeline_desc.subpass = 0;
+    pipeline_desc.basePipelineHandle = VK_NULL_HANDLE;
+    pipeline_desc.basePipelineIndex = -1;
+    if ((vr = VK_CALL(vkCreateGraphicsPipelines(device->vk_device, device->vk_pipeline_cache,
+            1, &pipeline_desc, NULL, &vk_pipeline))) < 0)
+    {
+        WARN("Failed to create Vulkan graphics pipeline, vr %d.\n", vr);
+        return VK_NULL_HANDLE;
+    }
+
+    if (d3d12_device_put_pipeline_to_cache(device, &pipeline_key, vk_pipeline, &graphics->compiled_pipelines))
+        return vk_pipeline;
+
+    /* Other thread compiled the pipeline before us. */
+    VK_CALL(vkDestroyPipeline(device->vk_device, vk_pipeline, NULL));
+    vk_pipeline = d3d12_device_find_cached_pipeline(device, &pipeline_key);
+    if (!vk_pipeline)
+        ERR("Could not get the pipeline compiled by other thread from the cache.\n");
+    return vk_pipeline;
+}
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index cb3d597a18a1..99a59cb7d018 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -558,10 +558,17 @@ static inline bool d3d12_pipeline_state_is_compute(const struct d3d12_pipeline_s
     return state && state->vk_bind_point == VK_PIPELINE_BIND_POINT_COMPUTE;
 }
 
+static inline bool d3d12_pipeline_state_is_graphics(const struct d3d12_pipeline_state *state)
+{
+    return state && state->vk_bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS;
+}
+
 HRESULT d3d12_pipeline_state_create_compute(struct d3d12_device *device,
         const D3D12_COMPUTE_PIPELINE_STATE_DESC *desc, struct d3d12_pipeline_state **state) DECLSPEC_HIDDEN;
 HRESULT d3d12_pipeline_state_create_graphics(struct d3d12_device *device,
         const D3D12_GRAPHICS_PIPELINE_STATE_DESC *desc, struct d3d12_pipeline_state **state) DECLSPEC_HIDDEN;
+VkPipeline d3d12_pipeline_state_get_or_create_pipeline(struct d3d12_pipeline_state *state,
+        VkPrimitiveTopology topology, const uint32_t *strides) DECLSPEC_HIDDEN;
 bool d3d12_pipeline_state_is_render_pass_compatible(const struct d3d12_pipeline_state *state_a,
         const struct d3d12_pipeline_state *state_b) DECLSPEC_HIDDEN;
 struct d3d12_pipeline_state *unsafe_impl_from_ID3D12PipelineState(ID3D12PipelineState *iface) DECLSPEC_HIDDEN;
-- 
2.18.1




More information about the wine-devel mailing list