Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/adapter_vk.c | 77 +++++++-
dlls/wined3d/context_vk.c | 320 ++++++++++++++++++++++++++++++++-
dlls/wined3d/wined3d_private.h | 31 ++++
3 files changed, 418 insertions(+), 10 deletions(-)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c
index 7d152d70b06..0249c4c7af1 100644
--- a/dlls/wined3d/adapter_vk.c
+++ b/dlls/wined3d/adapter_vk.c
@@ -398,12 +398,80 @@ static const struct wined3d_allocator_ops wined3d_allocator_vk_ops =
.allocator_destroy_chunk = wined3d_allocator_vk_destroy_chunk,
};
+static const struct
+{
+ const char *name;
+ unsigned int core_since_version;
+}
+vulkan_device_extensions[] =
+{
+ {VK_KHR_MAINTENANCE1_EXTENSION_NAME, VK_API_VERSION_1_1},
+ {VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, VK_API_VERSION_1_1},
+};
+
+static bool enable_vulkan_device_extensions(VkPhysicalDevice physical_device, uint32_t *extension_count,
+ const char *enabled_extensions[], const struct wined3d_vk_info *vk_info)
+{
+ VkExtensionProperties *extensions = NULL;
+ bool success = false, found;
+ unsigned int i, j, count;
+ VkResult vr;
+
+ *extension_count = 0;
+
+ if ((vr = VK_CALL(vkEnumerateDeviceExtensionProperties(physical_device, NULL, &count, NULL))) < 0)
+ {
+ ERR("Failed to enumerate device extensions, vr %s.\n", wined3d_debug_vkresult(vr));
+ goto done;
+ }
+ if (!(extensions = heap_calloc(count, sizeof(*extensions))))
+ {
+ WARN("Out of memory.\n");
+ goto done;
+ }
+ if ((vr = VK_CALL(vkEnumerateDeviceExtensionProperties(physical_device, NULL, &count, extensions))) < 0)
+ {
+ ERR("Failed to enumerate device extensions, vr %s.\n", wined3d_debug_vkresult(vr));
+ goto done;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(vulkan_device_extensions); ++i)
+ {
+ if (vulkan_device_extensions[i].core_since_version <= vk_info->api_version)
+ continue;
+
+ for (j = 0, found = false; j < count; ++j)
+ {
+ if (!strcmp(extensions[j].extensionName, vulkan_device_extensions[i].name))
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ WARN("Required extension '%s' is not available.\n", vulkan_device_extensions[i].name);
+ goto done;
+ }
+
+ TRACE("Enabling instance extension '%s'.\n", vulkan_device_extensions[i].name);
+ enabled_extensions[(*extension_count)++] = vulkan_device_extensions[i].name;
+ }
+ success = true;
+
+done:
+ heap_free(extensions);
+ return success;
+}
+
static HRESULT adapter_vk_create_device(struct wined3d *wined3d, const struct wined3d_adapter *adapter,
enum wined3d_device_type device_type, HWND focus_window, unsigned int flags, BYTE surface_alignment,
const enum wined3d_feature_level *levels, unsigned int level_count,
struct wined3d_device_parent *device_parent, struct wined3d_device **device)
{
const struct wined3d_adapter_vk *adapter_vk = wined3d_adapter_vk_const(adapter);
+ const char *enabled_device_extensions[ARRAY_SIZE(vulkan_device_extensions)];
const struct wined3d_vk_info *vk_info = &adapter_vk->vk_info;
static const float priorities[] = {1.0f};
struct wined3d_device_vk *device_vk;
@@ -441,8 +509,13 @@ static HRESULT adapter_vk_create_device(struct wined3d *wined3d, const struct wi
device_info.pQueueCreateInfos = &queue_info;
device_info.enabledLayerCount = 0;
device_info.ppEnabledLayerNames = NULL;
- device_info.enabledExtensionCount = 0;
- device_info.ppEnabledExtensionNames = NULL;
+ device_info.ppEnabledExtensionNames = enabled_device_extensions;
+ if (!enable_vulkan_device_extensions(physical_device,
+ &device_info.enabledExtensionCount, enabled_device_extensions, vk_info))
+ {
+ hr = E_FAIL;
+ goto fail;
+ }
device_info.pEnabledFeatures = &features;
if ((vr = VK_CALL(vkCreateDevice(physical_device, &device_info, NULL, &vk_device))) < 0)
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c
index 08ce3db7ccc..d13bb5d82e1 100644
--- a/dlls/wined3d/context_vk.c
+++ b/dlls/wined3d/context_vk.c
@@ -772,6 +772,21 @@ static void wined3d_context_vk_destroy_bo_slab(struct wine_rb_entry *entry, void
}
}
+static void wined3d_context_vk_destroy_graphics_pipeline(struct wine_rb_entry *entry, void *ctx)
+{
+ struct wined3d_graphics_pipeline_vk *pipeline_vk = WINE_RB_ENTRY_VALUE(entry,
+ struct wined3d_graphics_pipeline_vk, entry);
+ struct wined3d_context_vk *context_vk = ctx;
+ const struct wined3d_vk_info *vk_info;
+ struct wined3d_device_vk *device_vk;
+
+ vk_info = context_vk->vk_info;
+ device_vk = wined3d_device_vk(context_vk->c.device);
+
+ VK_CALL(vkDestroyPipeline(device_vk->vk_device, pipeline_vk->vk_pipeline, NULL));
+ heap_free(pipeline_vk);
+}
+
static void wined3d_context_vk_destroy_pipeline_layout(struct wine_rb_entry *entry, void *ctx)
{
struct wined3d_pipeline_layout_vk *layout = WINE_RB_ENTRY_VALUE(entry,
@@ -1041,6 +1056,7 @@ void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk)
heap_free(context_vk->retired.objects);
wined3d_shader_descriptor_writes_vk_cleanup(&context_vk->descriptor_writes);
+ wine_rb_destroy(&context_vk->graphics_pipelines, wined3d_context_vk_destroy_graphics_pipeline, context_vk);
wine_rb_destroy(&context_vk->pipeline_layouts, wined3d_context_vk_destroy_pipeline_layout, context_vk);
wine_rb_destroy(&context_vk->render_passes, wined3d_context_vk_destroy_render_pass, context_vk);
@@ -1239,6 +1255,68 @@ static int wined3d_pipeline_layout_vk_compare(const void *key, const struct wine
return memcmp(a->bindings, b->bindings, a->binding_count * sizeof(*a->bindings));
}
+static int wined3d_graphics_pipeline_vk_compare(const void *key, const struct wine_rb_entry *entry)
+{
+ const struct wined3d_graphics_pipeline_key_vk *a = key;
+ const struct wined3d_graphics_pipeline_key_vk *b = &WINE_RB_ENTRY_VALUE(entry,
+ const struct wined3d_graphics_pipeline_vk, entry)->key;
+ unsigned int i;
+ int ret;
+
+ if (a->pipeline_desc.stageCount != b->pipeline_desc.stageCount)
+ return a->pipeline_desc.stageCount - b->pipeline_desc.stageCount;
+ for (i = 0; i < a->pipeline_desc.stageCount; ++i)
+ {
+ if (a->stages[i].module != b->stages[i].module)
+ return a->stages[i].module - b->stages[i].module;
+ }
+
+ if (a->input_desc.vertexAttributeDescriptionCount != b->input_desc.vertexAttributeDescriptionCount)
+ return a->input_desc.vertexAttributeDescriptionCount - b->input_desc.vertexAttributeDescriptionCount;
+ if ((ret = memcmp(a->attributes, b->attributes,
+ a->input_desc.vertexAttributeDescriptionCount * sizeof(*a->attributes))))
+ return ret;
+ if (a->input_desc.vertexBindingDescriptionCount != b->input_desc.vertexBindingDescriptionCount)
+ return a->input_desc.vertexBindingDescriptionCount - b->input_desc.vertexBindingDescriptionCount;
+ if ((ret = memcmp(a->bindings, b->bindings,
+ a->input_desc.vertexBindingDescriptionCount * sizeof(*a->bindings))))
+ return ret;
+
+ if (a->ia_desc.topology != b->ia_desc.topology)
+ return a->ia_desc.topology - b->ia_desc.topology;
+ if (a->ia_desc.primitiveRestartEnable != b->ia_desc.primitiveRestartEnable)
+ return a->ia_desc.primitiveRestartEnable - b->ia_desc.primitiveRestartEnable;
+
+ if ((ret = memcmp(&a->viewport, &b->viewport, sizeof(a->viewport))))
+ return ret;
+
+ if ((ret = memcmp(&a->scissor, &b->scissor, sizeof(a->scissor))))
+ return ret;
+
+ if ((ret = memcmp(&a->rs_desc, &b->rs_desc, sizeof(a->rs_desc))))
+ return ret;
+
+ if ((ret = memcmp(&a->ms_desc, &b->ms_desc, sizeof(a->ms_desc))))
+ return ret;
+
+ if ((ret = memcmp(&a->ds_desc, &b->ds_desc, sizeof(a->ds_desc))))
+ return ret;
+
+ if (a->blend_desc.attachmentCount != b->blend_desc.attachmentCount)
+ return a->blend_desc.attachmentCount - b->blend_desc.attachmentCount;
+ if ((ret = memcmp(a->blend_attachments, b->blend_attachments,
+ a->blend_desc.attachmentCount * sizeof(*a->blend_attachments))))
+ return ret;
+
+ if (a->pipeline_desc.layout != b->pipeline_desc.layout)
+ return a->pipeline_desc.layout - b->pipeline_desc.layout;
+
+ if (a->pipeline_desc.renderPass != b->pipeline_desc.renderPass)
+ return a->pipeline_desc.renderPass - b->pipeline_desc.renderPass;
+
+ return 0;
+}
+
static int wined3d_bo_slab_vk_compare(const void *key, const struct wine_rb_entry *entry)
{
const struct wined3d_bo_slab_vk *slab = WINE_RB_ENTRY_VALUE(entry, const struct wined3d_bo_slab_vk, entry);
@@ -1251,6 +1329,197 @@ static int wined3d_bo_slab_vk_compare(const void *key, const struct wine_rb_entr
return k->size - slab->bo.size;
}
+static void wined3d_context_vk_init_graphics_pipeline_key(struct wined3d_context_vk *context_vk)
+{
+ struct wined3d_graphics_pipeline_key_vk *key;
+ VkPipelineShaderStageCreateInfo *stage;
+ unsigned int i;
+
+ key = &context_vk->graphics.pipeline_key_vk;
+ memset(key, 0, sizeof(*key));
+
+ for (i = 0; i < ARRAY_SIZE(context_vk->graphics.vk_modules); ++i)
+ {
+ stage = &key->stages[i];
+ stage->sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
+ stage->pName = "main";
+ }
+
+ key->input_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
+ key->input_desc.pVertexBindingDescriptions = key->bindings;
+ key->input_desc.pVertexAttributeDescriptions = key->attributes;
+
+ key->ia_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
+ key->ia_desc.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
+
+ key->vp_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
+ key->vp_desc.viewportCount = 1;
+ key->vp_desc.pViewports = &key->viewport;
+ key->vp_desc.scissorCount = 1;
+ key->vp_desc.pScissors = &key->scissor;
+
+ key->rs_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
+ key->rs_desc.lineWidth = 1.0f;
+
+ key->ms_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
+
+ key->ds_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
+ key->ds_desc.maxDepthBounds = 1.0f;
+
+ key->blend_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
+ key->blend_desc.logicOp = VK_LOGIC_OP_COPY;
+ key->blend_desc.pAttachments = key->blend_attachments;
+ key->blend_desc.blendConstants[0] = 1.0f;
+ key->blend_desc.blendConstants[1] = 1.0f;
+ key->blend_desc.blendConstants[2] = 1.0f;
+ key->blend_desc.blendConstants[3] = 1.0f;
+
+ key->dynamic_desc.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
+
+ key->pipeline_desc.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
+ key->pipeline_desc.pStages = key->stages;
+ key->pipeline_desc.pVertexInputState = &key->input_desc;
+ key->pipeline_desc.pInputAssemblyState = &key->ia_desc;
+ key->pipeline_desc.pViewportState = &key->vp_desc;
+ key->pipeline_desc.pRasterizationState = &key->rs_desc;
+ key->pipeline_desc.pMultisampleState = &key->ms_desc;
+ key->pipeline_desc.pDepthStencilState = &key->ds_desc;
+ key->pipeline_desc.pColorBlendState = &key->blend_desc;
+ key->pipeline_desc.pDynamicState = &key->dynamic_desc;
+ key->pipeline_desc.basePipelineIndex = -1;
+}
+
+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_d3d_info *d3d_info = context_vk->c.d3d_info;
+ unsigned int i, attribute_count, binding_count, stage_count;
+ struct wined3d_graphics_pipeline_key_vk *key;
+ VkPipelineShaderStageCreateInfo *stage;
+ struct wined3d_stream_info stream_info;
+ VkShaderModule module;
+ bool update = false;
+ uint32_t mask;
+
+ key = &context_vk->graphics.pipeline_key_vk;
+
+ if (context_vk->c.shader_update_mask & ~(1u << WINED3D_SHADER_TYPE_COMPUTE))
+ {
+ stage_count = 0;
+ for (i = 0; i < ARRAY_SIZE(context_vk->graphics.vk_modules); ++i)
+ {
+ if (!(module = context_vk->graphics.vk_modules[i]))
+ continue;
+
+ stage = &key->stages[stage_count++];
+ stage->stage = vk_shader_stage_from_wined3d(i);
+ stage->module = module;
+ }
+
+ key->pipeline_desc.stageCount = stage_count;
+
+ update = true;
+ }
+
+ if (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_VDECL)
+ || 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)))
+ {
+ wined3d_stream_info_from_declaration(&stream_info, state, d3d_info);
+ for (i = 0, mask = 0, attribute_count = 0, binding_count = 0; i < ARRAY_SIZE(stream_info.elements); ++i)
+ {
+ struct wined3d_stream_info_element *e;
+ VkVertexInputAttributeDescription *a;
+ VkVertexInputBindingDescription *b;
+ uint32_t binding;
+
+ if (!(stream_info.use_map & (1u << i)))
+ continue;
+
+ a = &key->attributes[attribute_count++];
+ e = &stream_info.elements[i];
+ binding = e->stream_idx;
+
+ a->location = i;
+ a->binding = binding;
+ a->format = wined3d_format_vk(e->format)->vk_format;
+ a->offset = (UINT_PTR)e->data.addr - state->streams[binding].offset;
+
+ if (mask & (1u << binding))
+ continue;
+ mask |= 1u << binding;
+
+ b = &key->bindings[binding_count++];
+ b->binding = binding;
+ b->stride = e->stride;
+ b->inputRate = e->divisor ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX;
+ }
+
+ key->input_desc.vertexBindingDescriptionCount = binding_count;
+ key->input_desc.vertexAttributeDescriptionCount = attribute_count;
+
+ update = true;
+ }
+
+ if (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_VIEWPORT))
+ {
+ key->viewport.x = state->viewports[0].x;
+ key->viewport.y = state->viewports[0].y;
+ key->viewport.width = state->viewports[0].width;
+ key->viewport.height = state->viewports[0].height;
+ key->viewport.minDepth = state->viewports[0].min_z;
+ key->viewport.maxDepth = state->viewports[0].max_z;
+
+ key->scissor.offset.x = key->viewport.x;
+ key->scissor.offset.y = key->viewport.y;
+ key->scissor.extent.width = key->viewport.width;
+ key->scissor.extent.height = key->viewport.height;
+ key->viewport.y += key->viewport.height;
+ key->viewport.height = -key->viewport.height;
+
+ update = true;
+ }
+
+ if (key->ms_desc.rasterizationSamples != context_vk->sample_count)
+ {
+ key->ms_desc.rasterizationSamples = context_vk->sample_count;
+
+ update = true;
+ }
+
+ if (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_FRAMEBUFFER))
+ {
+ key->blend_desc.attachmentCount = context_vk->rt_count;
+
+ memset(key->blend_attachments, 0, sizeof(key->blend_attachments));
+ for (i = 0; i < context_vk->rt_count; ++i)
+ {
+ key->blend_attachments[i].colorWriteMask = VK_COLOR_COMPONENT_R_BIT
+ | VK_COLOR_COMPONENT_G_BIT
+ | VK_COLOR_COMPONENT_B_BIT
+ | VK_COLOR_COMPONENT_A_BIT;
+ }
+
+ update = true;
+ }
+
+ if (key->pipeline_desc.layout != vk_pipeline_layout)
+ {
+ key->pipeline_desc.layout = vk_pipeline_layout;
+
+ update = true;
+ }
+
+ if (key->pipeline_desc.renderPass != context_vk->vk_render_pass)
+ {
+ key->pipeline_desc.renderPass = context_vk->vk_render_pass;
+
+ update = true;
+ }
+
+ return update;
+}
+
static bool wined3d_context_vk_begin_render_pass(struct wined3d_context_vk *context_vk,
VkCommandBuffer vk_command_buffer, const struct wined3d_state *state, const struct wined3d_vk_info *vk_info)
{
@@ -1274,6 +1543,7 @@ static bool wined3d_context_vk_begin_render_pass(struct wined3d_context_vk *cont
fb_layer_count = limits->maxFramebufferLayers;
attachment_count = 0;
+ context_vk->rt_count = 0;
for (i = 0; i < ARRAY_SIZE(state->fb.render_targets); ++i)
{
if (!(view = state->fb.render_targets[i]) || view->format->id == WINED3DFMT_NULL)
@@ -1289,6 +1559,7 @@ static bool wined3d_context_vk_begin_render_pass(struct wined3d_context_vk *cont
fb_height = view->height;
if (view->layer_count < fb_layer_count)
fb_layer_count = view->layer_count;
+ context_vk->rt_count = i + 1;
++attachment_count;
}
@@ -1766,9 +2037,33 @@ fail:
static VkPipeline wined3d_context_vk_get_graphics_pipeline(struct wined3d_context_vk *context_vk)
{
- FIXME("Not implemented.\n");
+ struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
+ const struct wined3d_vk_info *vk_info = context_vk->vk_info;
+ struct wined3d_graphics_pipeline_vk *pipeline_vk;
+ struct wined3d_graphics_pipeline_key_vk *key;
+ struct wine_rb_entry *entry;
+ VkResult vr;
+
+ key = &context_vk->graphics.pipeline_key_vk;
+ if ((entry = wine_rb_get(&context_vk->graphics_pipelines, key)))
+ return WINE_RB_ENTRY_VALUE(entry, struct wined3d_graphics_pipeline_vk, entry)->vk_pipeline;
- return VK_NULL_HANDLE;
+ if (!(pipeline_vk = heap_alloc(sizeof(*pipeline_vk))))
+ return VK_NULL_HANDLE;
+ pipeline_vk->key = *key;
+
+ if ((vr = VK_CALL(vkCreateGraphicsPipelines(device_vk->vk_device,
+ VK_NULL_HANDLE, 1, &key->pipeline_desc, NULL, &pipeline_vk->vk_pipeline))) < 0)
+ {
+ WARN("Failed to create graphics pipeline, vr %s.\n", wined3d_debug_vkresult(vr));
+ heap_free(pipeline_vk);
+ return VK_NULL_HANDLE;
+ }
+
+ if (wine_rb_put(&context_vk->graphics_pipelines, &pipeline_vk->key, &pipeline_vk->entry) == -1)
+ ERR("Failed to insert pipeline.\n");
+
+ return pipeline_vk->vk_pipeline;
}
static void wined3d_context_vk_load_shader_resources(struct wined3d_context_vk *context_vk,
@@ -1960,7 +2255,6 @@ VkCommandBuffer wined3d_context_vk_apply_draw_state(struct wined3d_context_vk *c
ERR("No pipeline layout set.\n");
return VK_NULL_HANDLE;
}
- context_vk->c.shader_update_mask &= 1u << WINED3D_SHADER_TYPE_COMPUTE;
context_vk->c.update_shader_resource_bindings = 1;
context_vk->c.update_unordered_access_view_bindings = 1;
}
@@ -1991,12 +2285,18 @@ VkCommandBuffer wined3d_context_vk_apply_draw_state(struct wined3d_context_vk *c
return VK_NULL_HANDLE;
}
- if (!(context_vk->graphics.vk_pipeline = wined3d_context_vk_get_graphics_pipeline(context_vk)))
+ if (wined3d_context_vk_update_graphics_pipeline_key(context_vk, state, context_vk->graphics.vk_pipeline_layout)
+ || !context_vk->graphics.vk_pipeline)
{
- ERR("Failed to get graphics pipeline.\n");
- return VK_NULL_HANDLE;
+ if (!(context_vk->graphics.vk_pipeline = wined3d_context_vk_get_graphics_pipeline(context_vk)))
+ {
+ ERR("Failed to get graphics pipeline.\n");
+ return VK_NULL_HANDLE;
+ }
+
+ VK_CALL(vkCmdBindPipeline(vk_command_buffer,
+ VK_PIPELINE_BIND_POINT_GRAPHICS, context_vk->graphics.vk_pipeline));
}
- VK_CALL(vkCmdBindPipeline(vk_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, context_vk->graphics.vk_pipeline));
if (wined3d_context_is_graphics_state_dirty(&context_vk->c, STATE_INDEXBUFFER) && state->index_buffer)
{
@@ -2039,6 +2339,7 @@ VkCommandBuffer wined3d_context_vk_apply_draw_state(struct wined3d_context_vk *c
}
memset(context_vk->c.dirty_graphics_states, 0, sizeof(context_vk->c.dirty_graphics_states));
+ context_vk->c.shader_update_mask &= 1u << WINED3D_SHADER_TYPE_COMPUTE;
return vk_command_buffer;
}
@@ -2063,7 +2364,6 @@ VkCommandBuffer wined3d_context_vk_apply_compute_state(struct wined3d_context_vk
ERR("No compute pipeline set.\n");
return VK_NULL_HANDLE;
}
- context_vk->c.shader_update_mask &= ~(1u << WINED3D_SHADER_TYPE_COMPUTE);
context_vk->c.update_compute_shader_resource_bindings = 1;
context_vk->c.update_compute_unordered_access_view_bindings = 1;
context_vk->update_compute_pipeline = 1;
@@ -2107,6 +2407,7 @@ VkCommandBuffer wined3d_context_vk_apply_compute_state(struct wined3d_context_vk
}
memset(context_vk->c.dirty_compute_states, 0, sizeof(context_vk->c.dirty_compute_states));
+ context_vk->c.shader_update_mask &= ~(1u << WINED3D_SHADER_TYPE_COMPUTE);
return vk_command_buffer;
}
@@ -2139,8 +2440,11 @@ HRESULT wined3d_context_vk_init(struct wined3d_context_vk *context_vk, struct wi
}
context_vk->current_command_buffer.id = 1;
+ wined3d_context_vk_init_graphics_pipeline_key(context_vk);
+
wine_rb_init(&context_vk->render_passes, wined3d_render_pass_vk_compare);
wine_rb_init(&context_vk->pipeline_layouts, wined3d_pipeline_layout_vk_compare);
+ wine_rb_init(&context_vk->graphics_pipelines, wined3d_graphics_pipeline_vk_compare);
wine_rb_init(&context_vk->bo_slab_available, wined3d_bo_slab_vk_compare);
return WINED3D_OK;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index a56d1f59ecc..84391470657 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -2320,6 +2320,34 @@ struct wined3d_pipeline_layout_vk
VkDescriptorSetLayout vk_set_layout;
};
+struct wined3d_graphics_pipeline_key_vk
+{
+ VkPipelineShaderStageCreateInfo stages[WINED3D_SHADER_TYPE_GRAPHICS_COUNT];
+ VkVertexInputAttributeDescription attributes[MAX_ATTRIBS];
+ VkVertexInputBindingDescription bindings[MAX_ATTRIBS];
+ VkViewport viewport;
+ VkRect2D scissor;
+ VkPipelineColorBlendAttachmentState blend_attachments[WINED3D_MAX_RENDER_TARGETS];
+
+ VkPipelineVertexInputStateCreateInfo input_desc;
+ VkPipelineInputAssemblyStateCreateInfo ia_desc;
+ VkPipelineViewportStateCreateInfo vp_desc;
+ VkPipelineRasterizationStateCreateInfo rs_desc;
+ VkPipelineMultisampleStateCreateInfo ms_desc;
+ VkPipelineDepthStencilStateCreateInfo ds_desc;
+ VkPipelineColorBlendStateCreateInfo blend_desc;
+ VkPipelineDynamicStateCreateInfo dynamic_desc;
+
+ VkGraphicsPipelineCreateInfo pipeline_desc;
+};
+
+struct wined3d_graphics_pipeline_vk
+{
+ struct wine_rb_entry entry;
+ struct wined3d_graphics_pipeline_key_vk key;
+ VkPipeline vk_pipeline;
+};
+
enum wined3d_shader_descriptor_type
{
WINED3D_SHADER_DESCRIPTOR_TYPE_CBV,
@@ -2363,6 +2391,7 @@ struct wined3d_context_vk
struct
{
VkShaderModule vk_modules[WINED3D_SHADER_TYPE_GRAPHICS_COUNT];
+ struct wined3d_graphics_pipeline_key_vk pipeline_key_vk;
VkPipeline vk_pipeline;
VkPipelineLayout vk_pipeline_layout;
VkDescriptorSetLayout vk_set_layout;
@@ -2395,10 +2424,12 @@ struct wined3d_context_vk
VkDescriptorPool vk_descriptor_pool;
VkSampleCountFlagBits sample_count;
+ unsigned int rt_count;
struct wined3d_retired_objects_vk retired;
struct wine_rb_tree render_passes;
struct wine_rb_tree pipeline_layouts;
+ struct wine_rb_tree graphics_pipelines;
struct wine_rb_tree bo_slab_available;
};
--
2.20.1