Jan Sikorski : wined3d: Create null vertex bindings and attributes for unbound shader inputs.

Alexandre Julliard julliard at winehq.org
Tue Apr 27 16:09:00 CDT 2021


Module: wine
Branch: master
Commit: d94746314e88df57a2ee8291de3db6e0e37dc9e6
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=d94746314e88df57a2ee8291de3db6e0e37dc9e6

Author: Jan Sikorski <jsikorski at codeweavers.com>
Date:   Tue Apr 27 21:23:18 2021 +0200

wined3d: Create null vertex bindings and attributes for unbound shader inputs.

Signed-off-by: Jan Sikorski <jsikorski at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/wined3d/context_vk.c | 84 ++++++++++++++++++++++++++++++++++++++++++++---
 dlls/wined3d/device.c     |  2 +-
 2 files changed, 80 insertions(+), 6 deletions(-)

diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c
index 8719d54644b..fbc1e294fcd 100644
--- a/dlls/wined3d/context_vk.c
+++ b/dlls/wined3d/context_vk.c
@@ -2004,19 +2004,36 @@ static void wined3d_context_vk_update_blend_state(const struct wined3d_context_v
     }
 }
 
+static VkFormat vk_format_from_component_type(enum wined3d_component_type component_type)
+{
+    switch (component_type)
+    {
+        case WINED3D_TYPE_UINT:
+            return VK_FORMAT_R32G32B32A32_UINT;
+        case WINED3D_TYPE_INT:
+            return VK_FORMAT_R32G32B32A32_SINT;
+        case WINED3D_TYPE_UNKNOWN:
+        case WINED3D_TYPE_FLOAT:
+            return VK_FORMAT_R32G32B32A32_SFLOAT;
+    }
+    return VK_FORMAT_UNDEFINED;
+}
+
 static bool wined3d_context_vk_update_graphics_pipeline_key(struct wined3d_context_vk *context_vk,
-        const struct wined3d_state *state, VkPipelineLayout vk_pipeline_layout)
+        const struct wined3d_state *state, VkPipelineLayout vk_pipeline_layout, uint32_t *null_buffer_binding)
 {
     unsigned int i, attribute_count, binding_count, divisor_count, stage_count;
     const struct wined3d_d3d_info *d3d_info = context_vk->c.d3d_info;
     struct wined3d_graphics_pipeline_key_vk *key;
     VkPipelineShaderStageCreateInfo *stage;
     struct wined3d_stream_info stream_info;
+    struct wined3d_shader *vertex_shader;
     VkPrimitiveTopology vk_topology;
     VkShaderModule module;
     bool update = false;
     uint32_t mask;
 
+    *null_buffer_binding = ~0u;
     key = &context_vk->graphics.pipeline_key_vk;
 
     if (context_vk->c.shader_update_mask & ~(1u << WINED3D_SHADER_TYPE_COMPUTE))
@@ -2041,14 +2058,15 @@ static bool wined3d_context_vk_update_graphics_pipeline_key(struct wined3d_conte
             || wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_STREAMSRC)
             || wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX)))
     {
+        VkVertexInputAttributeDescription *a;
+        VkVertexInputBindingDescription *b;
+
         wined3d_stream_info_from_declaration(&stream_info, state, d3d_info);
         divisor_count = 0;
         for (i = 0, mask = 0, attribute_count = 0, binding_count = 0; i < ARRAY_SIZE(stream_info.elements); ++i)
         {
             VkVertexInputBindingDivisorDescriptionEXT *d;
             struct wined3d_stream_info_element *e;
-            VkVertexInputAttributeDescription *a;
-            VkVertexInputBindingDescription *b;
             uint32_t binding;
 
             if (!(stream_info.use_map & (1u << i)))
@@ -2080,6 +2098,55 @@ static bool wined3d_context_vk_update_graphics_pipeline_key(struct wined3d_conte
             }
         }
 
+        vertex_shader = state->shader[WINED3D_SHADER_TYPE_VERTEX];
+        if (vertex_shader && (mask = ~stream_info.use_map & vertex_shader->reg_maps.input_registers))
+        {
+            struct wined3d_shader_signature_element *element;
+            struct wined3d_shader_signature *signature;
+            uint32_t null_binding, location;
+
+            for (i = 0; i < ARRAY_SIZE(state->streams); ++i)
+            {
+                if (!state->streams[i].buffer)
+                {
+                    null_binding = i;
+                    break;
+                }
+            }
+
+            if (i == ARRAY_SIZE(state->streams))
+            {
+                ERR("No streams left for a null buffer binding.\n");
+            }
+            else
+            {
+                signature = &vertex_shader->input_signature;
+                for (i = 0; i < signature->element_count; ++i)
+                {
+                    element = &signature->elements[i];
+                    location = element->register_idx;
+
+                    if (!(mask & (1u << location)) || element->sysval_semantic)
+                        continue;
+                    mask &= ~(1u << location);
+
+                    a = &key->attributes[attribute_count++];
+                    a->location = location;
+                    a->binding = null_binding;
+                    a->format = vk_format_from_component_type(element->component_type);
+                    a->offset = 0;
+                }
+
+                if (mask != (~stream_info.use_map & vertex_shader->reg_maps.input_registers))
+                {
+                    b = &key->bindings[binding_count++];
+                    *null_buffer_binding = b->binding = null_binding;
+                    b->stride = 0;
+                    b->inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
+                }
+            }
+        }
+
         key->input_desc.pNext = NULL;
         key->input_desc.vertexBindingDescriptionCount = binding_count;
         key->input_desc.vertexAttributeDescriptionCount = attribute_count;
@@ -2991,6 +3058,7 @@ VkCommandBuffer wined3d_context_vk_apply_draw_state(struct wined3d_context_vk *c
     VkSampleCountFlagBits sample_count;
     VkCommandBuffer vk_command_buffer;
     struct wined3d_buffer *buffer;
+    uint32_t null_buffer_binding;
     unsigned int i;
 
     if (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_SHADER(WINED3D_SHADER_TYPE_PIXEL))
@@ -3120,8 +3188,8 @@ VkCommandBuffer wined3d_context_vk_apply_draw_state(struct wined3d_context_vk *c
         return VK_NULL_HANDLE;
     }
 
-    if (wined3d_context_vk_update_graphics_pipeline_key(context_vk, state, context_vk->graphics.vk_pipeline_layout)
-            || !context_vk->graphics.vk_pipeline)
+    if (wined3d_context_vk_update_graphics_pipeline_key(context_vk, state, context_vk->graphics.vk_pipeline_layout,
+            &null_buffer_binding) || !context_vk->graphics.vk_pipeline)
     {
         if (!(context_vk->graphics.vk_pipeline = wined3d_context_vk_get_graphics_pipeline(context_vk)))
         {
@@ -3131,6 +3199,12 @@ VkCommandBuffer wined3d_context_vk_apply_draw_state(struct wined3d_context_vk *c
 
         VK_CALL(vkCmdBindPipeline(vk_command_buffer,
                 VK_PIPELINE_BIND_POINT_GRAPHICS, context_vk->graphics.vk_pipeline));
+        if (null_buffer_binding != ~0u)
+        {
+            VkDeviceSize offset = 0;
+            VK_CALL(vkCmdBindVertexBuffers(vk_command_buffer, null_buffer_binding, 1,
+                    &device_vk->null_resources_vk.buffer_info.buffer, &offset));
+        }
     }
 
     if (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_STENCIL_REF) && dsv)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index bf4c37756a7..f3d7cff74bf 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -652,7 +652,7 @@ bool wined3d_device_vk_create_null_resources(struct wined3d_device_vk *device_vk
     vk_info = context_vk->vk_info;
 
     usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT
-            | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
+            | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
     memory_type = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
     if (!wined3d_context_vk_create_bo(context_vk, 16, usage, memory_type, &r->bo))
         return false;




More information about the wine-cvs mailing list