1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-03-13 19:29:14 +01:00

[dxvk] Implement fragment output pipeline libraries

This commit is contained in:
Philip Rebohle 2022-07-05 12:56:56 +02:00
parent 578c136239
commit 3b10efbc30
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
4 changed files with 120 additions and 1 deletions

View File

@ -141,7 +141,7 @@ namespace dxvk {
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;
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;
@ -250,6 +250,21 @@ namespace dxvk {
}
bool DxvkGraphicsPipelineFragmentOutputState::useDynamicBlendConstants() const {
bool result = false;
for (uint32_t i = 0; i < MaxNumRenderTargets && !result; i++) {
result = cbAttachments[i].blendEnable
&& (util::isBlendConstantBlendFactor(cbAttachments[i].srcColorBlendFactor)
|| util::isBlendConstantBlendFactor(cbAttachments[i].dstColorBlendFactor)
|| util::isBlendConstantBlendFactor(cbAttachments[i].srcAlphaBlendFactor)
|| util::isBlendConstantBlendFactor(cbAttachments[i].dstAlphaBlendFactor));
}
return result;
}
bool DxvkGraphicsPipelineFragmentOutputState::eq(const DxvkGraphicsPipelineFragmentOutputState& other) const {
bool eq = rtInfo.colorAttachmentCount == other.rtInfo.colorAttachmentCount
&& rtInfo.depthAttachmentFormat == other.rtInfo.depthAttachmentFormat
@ -322,6 +337,49 @@ namespace dxvk {
}
DxvkGraphicsPipelineFragmentOutputLibrary::DxvkGraphicsPipelineFragmentOutputLibrary(
DxvkDevice* device,
const DxvkGraphicsPipelineFragmentOutputState& state,
VkPipelineCache cache)
: m_device(device) {
auto vk = m_device->vkd();
VkDynamicState dynamicState = VK_DYNAMIC_STATE_BLEND_CONSTANTS;
VkPipelineDynamicStateCreateInfo dyInfo = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO };
if (state.useDynamicBlendConstants()) {
dyInfo.dynamicStateCount = 1;
dyInfo.pDynamicStates = &dynamicState;
}
// pNext is non-const for some reason, but this is only an input
// structure, so we should be able to safely use const_cast.
VkGraphicsPipelineLibraryCreateInfoEXT libInfo = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT };
libInfo.pNext = const_cast<VkPipelineRenderingCreateInfoKHR*>(&state.rtInfo);
libInfo.flags = VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT;
VkGraphicsPipelineCreateInfo info = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, &libInfo };
info.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR;
info.pColorBlendState = &state.cbInfo;
info.pMultisampleState = &state.msInfo;
info.pDynamicState = &dyInfo;
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");
}
DxvkGraphicsPipelineFragmentOutputLibrary::~DxvkGraphicsPipelineFragmentOutputLibrary() {
auto vk = m_device->vkd();
vk->vkDestroyPipeline(vk->device(), m_pipeline, nullptr);
}
DxvkGraphicsPipelinePreRasterizationState::DxvkGraphicsPipelinePreRasterizationState() {
}

View File

@ -99,12 +99,43 @@ namespace dxvk {
std::array<VkPipelineColorBlendAttachmentState, MaxNumRenderTargets> cbAttachments = { };
std::array<VkFormat, MaxNumRenderTargets> rtColorFormats = { };
bool useDynamicBlendConstants() const;
bool eq(const DxvkGraphicsPipelineFragmentOutputState& other) const;
size_t hash() const;
};
/**
* \brief Vertex input pipeline library
*
* Creates a Vulkan pipeline object for a
* given vertex input state vector.
*/
class DxvkGraphicsPipelineFragmentOutputLibrary {
public:
DxvkGraphicsPipelineFragmentOutputLibrary(
DxvkDevice* device,
const DxvkGraphicsPipelineFragmentOutputState& state,
VkPipelineCache cache);
~DxvkGraphicsPipelineFragmentOutputLibrary();
VkPipeline getHandle() const {
return m_pipeline;
}
private:
DxvkDevice* m_device;
VkPipeline m_pipeline;
};
/**
* \brief Pre-rasterization info for graphics pipelines
*

View File

@ -93,6 +93,22 @@ namespace dxvk {
}
DxvkGraphicsPipelineFragmentOutputLibrary* DxvkPipelineManager::createFragmentOutputLibrary(
const DxvkGraphicsPipelineFragmentOutputState& state) {
std::lock_guard<dxvk::mutex> lock(m_mutex);
auto pair = m_fragmentOutputLibraries.find(state);
if (pair != m_fragmentOutputLibraries.end())
return &pair->second;
auto iter = m_fragmentOutputLibraries.emplace(
std::piecewise_construct,
std::tuple(state),
std::tuple(m_device, state, m_cache->handle()));
return &iter.first->second;
}
void DxvkPipelineManager::registerShader(
const Rc<DxvkShader>& shader) {
if (m_stateCache != nullptr)

View File

@ -75,6 +75,15 @@ namespace dxvk {
DxvkGraphicsPipelineVertexInputLibrary* createVertexInputLibrary(
const DxvkGraphicsPipelineVertexInputState& state);
/**
* \brief Retrieves a fragment output pipeline library
*
* \param [in] state Fragment output state
* \returns Pipeline library object
*/
DxvkGraphicsPipelineFragmentOutputLibrary* createFragmentOutputLibrary(
const DxvkGraphicsPipelineFragmentOutputState& state);
/*
* \brief Registers a shader
*
@ -139,6 +148,11 @@ namespace dxvk {
DxvkGraphicsPipelineVertexInputLibrary,
DxvkHash, DxvkEq> m_vertexInputLibraries;
std::unordered_map<
DxvkGraphicsPipelineFragmentOutputState,
DxvkGraphicsPipelineFragmentOutputLibrary,
DxvkHash, DxvkEq> m_fragmentOutputLibraries;
DxvkBindingSetLayout* createDescriptorSetLayout(
const DxvkBindingSetLayoutKey& key);