diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index bcefd0c4c..2f76185f3 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -133,6 +133,37 @@ namespace dxvk { } + DxvkGraphicsPipelineVertexInputLibrary::DxvkGraphicsPipelineVertexInputLibrary( + DxvkDevice* device, + const DxvkGraphicsPipelineVertexInputState& state, + VkPipelineCache cache) + : m_device(device) { + auto vk = m_device->vkd(); + + VkGraphicsPipelineLibraryCreateInfoEXT libInfo = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT }; + libInfo.flags = VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT; + + VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &libInfo }; + info.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR; + info.pVertexInputState = &state.viInfo; + info.pInputAssemblyState = &state.iaInfo; + info.basePipelineIndex = -1; + + VkResult vr = vk->vkCreateGraphicsPipelines(vk->device(), + cache, 1, &info, nullptr, &m_pipeline); + + if (vr) + throw DxvkError("Failed to create vertex input pipeline library"); + } + + + DxvkGraphicsPipelineVertexInputLibrary::~DxvkGraphicsPipelineVertexInputLibrary() { + auto vk = m_device->vkd(); + + vk->vkDestroyPipeline(vk->device(), m_pipeline, nullptr); + } + + DxvkGraphicsPipelineFragmentOutputState::DxvkGraphicsPipelineFragmentOutputState() { } diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 20e63787b..e640c1be9 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -47,6 +47,35 @@ namespace dxvk { }; + /** + * \brief Vertex input pipeline library + * + * Creates a Vulkan pipeline object for a + * given vertex input state vector. + */ + class DxvkGraphicsPipelineVertexInputLibrary { + + public: + + DxvkGraphicsPipelineVertexInputLibrary( + DxvkDevice* device, + const DxvkGraphicsPipelineVertexInputState& state, + VkPipelineCache cache); + + ~DxvkGraphicsPipelineVertexInputLibrary(); + + VkPipeline getHandle() const { + return m_pipeline; + } + + private: + + DxvkDevice* m_device; + VkPipeline m_pipeline; + + }; + + /** * \brief Fragment output info for graphics pipelines * diff --git a/src/dxvk/dxvk_pipemanager.cpp b/src/dxvk/dxvk_pipemanager.cpp index da6943e18..9fca1ccb7 100644 --- a/src/dxvk/dxvk_pipemanager.cpp +++ b/src/dxvk/dxvk_pipemanager.cpp @@ -77,6 +77,22 @@ namespace dxvk { } + DxvkGraphicsPipelineVertexInputLibrary* DxvkPipelineManager::createVertexInputLibrary( + const DxvkGraphicsPipelineVertexInputState& state) { + std::lock_guard lock(m_mutex); + + auto pair = m_vertexInputLibraries.find(state); + if (pair != m_vertexInputLibraries.end()) + return &pair->second; + + auto iter = m_vertexInputLibraries.emplace( + std::piecewise_construct, + std::tuple(state), + std::tuple(m_device, state, m_cache->handle())); + return &iter.first->second; + } + + void DxvkPipelineManager::registerShader( const Rc& shader) { if (m_stateCache != nullptr) diff --git a/src/dxvk/dxvk_pipemanager.h b/src/dxvk/dxvk_pipemanager.h index be69be3aa..508e8ac72 100644 --- a/src/dxvk/dxvk_pipemanager.h +++ b/src/dxvk/dxvk_pipemanager.h @@ -65,7 +65,16 @@ namespace dxvk { */ DxvkGraphicsPipeline* createGraphicsPipeline( const DxvkGraphicsPipelineShaders& shaders); - + + /** + * \brief Retrieves a vertex input pipeline library + * + * \param [in] state Vertex input state + * \returns Pipeline library object + */ + DxvkGraphicsPipelineVertexInputLibrary* createVertexInputLibrary( + const DxvkGraphicsPipelineVertexInputState& state); + /* * \brief Registers a shader * @@ -125,6 +134,11 @@ namespace dxvk { DxvkGraphicsPipeline, DxvkHash, DxvkEq> m_graphicsPipelines; + std::unordered_map< + DxvkGraphicsPipelineVertexInputState, + DxvkGraphicsPipelineVertexInputLibrary, + DxvkHash, DxvkEq> m_vertexInputLibraries; + DxvkBindingSetLayout* createDescriptorSetLayout( const DxvkBindingSetLayoutKey& key);