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; - return VK_NULL_HANDLE; + 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; + + 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; };