mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-11-30 04:24:11 +01:00
[dxvk] Move render pass out of pipeline state vector
This commit is contained in:
parent
59d4f1a1fb
commit
3a3b1eda59
@ -1712,8 +1712,9 @@ namespace dxvk {
|
||||
for (uint32_t i = m_state.gp.state.ilBindingCount; i < MaxNumVertexBindings; i++)
|
||||
m_state.gp.state.ilBindings[i].stride = 0;
|
||||
|
||||
m_gpActivePipeline = m_state.gp.pipeline != nullptr
|
||||
? m_state.gp.pipeline->getPipelineHandle(m_state.gp.state, m_cmd->statCounters())
|
||||
m_gpActivePipeline = m_state.gp.pipeline != nullptr && m_state.om.framebuffer != nullptr
|
||||
? m_state.gp.pipeline->getPipelineHandle(m_state.gp.state,
|
||||
m_state.om.framebuffer->getRenderPass(), m_cmd->statCounters())
|
||||
: VK_NULL_HANDLE;
|
||||
|
||||
if (m_gpActivePipeline != VK_NULL_HANDLE) {
|
||||
@ -1911,7 +1912,6 @@ namespace dxvk {
|
||||
auto fb = m_device->createFramebuffer(m_state.om.renderTargets);
|
||||
|
||||
m_state.gp.state.msSampleCount = fb->getSampleCount();
|
||||
m_state.gp.state.omRenderPass = fb->getDefaultRenderPassHandle();
|
||||
m_state.om.framebuffer = fb;
|
||||
|
||||
m_flags.set(DxvkContextFlag::GpDirtyPipelineState);
|
||||
|
@ -110,6 +110,14 @@ namespace dxvk {
|
||||
return m_renderPass->getHandle(ops);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Retrieves render pass
|
||||
* \returns Render pass reference
|
||||
*/
|
||||
const DxvkRenderPass& getRenderPass() const {
|
||||
return *m_renderPass;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Depth-stencil target
|
||||
* \returns Depth-stencil target
|
||||
|
@ -77,32 +77,34 @@ namespace dxvk {
|
||||
|
||||
VkPipeline DxvkGraphicsPipeline::getPipelineHandle(
|
||||
const DxvkGraphicsPipelineStateInfo& state,
|
||||
const DxvkRenderPass& renderPass,
|
||||
DxvkStatCounters& stats) {
|
||||
VkPipeline pipeline = VK_NULL_HANDLE;
|
||||
VkRenderPass renderPassHandle = renderPass.getDefaultHandle();
|
||||
|
||||
{ std::lock_guard<sync::Spinlock> lock(m_mutex);
|
||||
|
||||
if (this->findPipeline(state, pipeline))
|
||||
if (this->findPipeline(state, renderPassHandle, pipeline))
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
// If no pipeline exists with the given state vector,
|
||||
// create a new one and add it to the pipeline set.
|
||||
VkPipeline newPipeline = this->validatePipelineState(state)
|
||||
? this->compilePipeline(state, m_basePipeline)
|
||||
? this->compilePipeline(state, renderPassHandle, m_basePipeline)
|
||||
: VK_NULL_HANDLE;
|
||||
|
||||
{ std::lock_guard<sync::Spinlock> lock(m_mutex);
|
||||
|
||||
// Discard the pipeline if another thread
|
||||
// was faster compiling the same pipeline
|
||||
if (this->findPipeline(state, pipeline)) {
|
||||
if (this->findPipeline(state, renderPassHandle, pipeline)) {
|
||||
m_vkd->vkDestroyPipeline(m_vkd->device(), newPipeline, nullptr);
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
// Add new pipeline to the set
|
||||
m_pipelines.push_back({ state, newPipeline });
|
||||
m_pipelines.push_back({ state, renderPassHandle, newPipeline });
|
||||
|
||||
if (m_basePipeline == VK_NULL_HANDLE)
|
||||
m_basePipeline = newPipeline;
|
||||
@ -115,9 +117,11 @@ namespace dxvk {
|
||||
|
||||
bool DxvkGraphicsPipeline::findPipeline(
|
||||
const DxvkGraphicsPipelineStateInfo& state,
|
||||
VkRenderPass renderPass,
|
||||
VkPipeline& pipeline) const {
|
||||
for (const PipelineStruct& pair : m_pipelines) {
|
||||
if (pair.stateVector == state) {
|
||||
if (pair.stateVector == state
|
||||
&& pair.renderPass == renderPass) {
|
||||
pipeline = pair.pipeline;
|
||||
return true;
|
||||
}
|
||||
@ -129,6 +133,7 @@ namespace dxvk {
|
||||
|
||||
VkPipeline DxvkGraphicsPipeline::compilePipeline(
|
||||
const DxvkGraphicsPipelineStateInfo& state,
|
||||
VkRenderPass renderPass,
|
||||
VkPipeline baseHandle) const {
|
||||
if (Logger::logLevel() <= LogLevel::Debug) {
|
||||
Logger::debug("Compiling graphics pipeline...");
|
||||
@ -297,7 +302,7 @@ namespace dxvk {
|
||||
info.pColorBlendState = &cbInfo;
|
||||
info.pDynamicState = &dyInfo;
|
||||
info.layout = m_layout->pipelineLayout();
|
||||
info.renderPass = state.omRenderPass;
|
||||
info.renderPass = renderPass;
|
||||
info.subpass = 0;
|
||||
info.basePipelineHandle = baseHandle;
|
||||
info.basePipelineIndex = -1;
|
||||
@ -331,10 +336,6 @@ namespace dxvk {
|
||||
|
||||
bool DxvkGraphicsPipeline::validatePipelineState(
|
||||
const DxvkGraphicsPipelineStateInfo& state) const {
|
||||
// Make sure that we have an active render pass
|
||||
if (state.omRenderPass == VK_NULL_HANDLE)
|
||||
return false;
|
||||
|
||||
// Validate vertex input - each input slot consumed by the
|
||||
// vertex shader must be provided by the input layout.
|
||||
uint32_t providedVertexInputs = 0;
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "dxvk_constant_state.h"
|
||||
#include "dxvk_pipecache.h"
|
||||
#include "dxvk_pipelayout.h"
|
||||
#include "dxvk_renderpass.h"
|
||||
#include "dxvk_resource.h"
|
||||
#include "dxvk_shader.h"
|
||||
#include "dxvk_stats.h"
|
||||
@ -73,7 +74,6 @@ namespace dxvk {
|
||||
|
||||
VkBool32 omEnableLogicOp;
|
||||
VkLogicOp omLogicOp;
|
||||
VkRenderPass omRenderPass;
|
||||
VkPipelineColorBlendAttachmentState omBlendAttachments[MaxNumRenderTargets];
|
||||
};
|
||||
|
||||
@ -129,17 +129,20 @@ namespace dxvk {
|
||||
* Retrieves a pipeline handle for the given pipeline
|
||||
* state. If necessary, a new pipeline will be created.
|
||||
* \param [in] state Pipeline state vector
|
||||
* \param [in] renderPass The render pass
|
||||
* \param [in,out] stats Stat counter
|
||||
* \returns Pipeline handle
|
||||
*/
|
||||
VkPipeline getPipelineHandle(
|
||||
const DxvkGraphicsPipelineStateInfo& state,
|
||||
const DxvkRenderPass& renderPass,
|
||||
DxvkStatCounters& stats);
|
||||
|
||||
private:
|
||||
|
||||
struct PipelineStruct {
|
||||
DxvkGraphicsPipelineStateInfo stateVector;
|
||||
VkRenderPass renderPass;
|
||||
VkPipeline pipeline;
|
||||
};
|
||||
|
||||
@ -167,10 +170,12 @@ namespace dxvk {
|
||||
|
||||
bool findPipeline(
|
||||
const DxvkGraphicsPipelineStateInfo& state,
|
||||
VkRenderPass renderPass,
|
||||
VkPipeline& pipeline) const;
|
||||
|
||||
VkPipeline compilePipeline(
|
||||
const DxvkGraphicsPipelineStateInfo& state,
|
||||
VkRenderPass renderPass,
|
||||
VkPipeline baseHandle) const;
|
||||
|
||||
void destroyPipelines();
|
||||
|
@ -4,6 +4,21 @@
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
bool DxvkRenderPassFormat::matches(const DxvkRenderPassFormat& fmt) const {
|
||||
bool eq = sampleCount == fmt.sampleCount;
|
||||
|
||||
for (uint32_t i = 0; i < MaxNumRenderTargets && eq; i++) {
|
||||
eq &= color[i].format == fmt.color[i].format
|
||||
&& color[i].layout == fmt.color[i].layout;
|
||||
}
|
||||
|
||||
eq &= depth.format == fmt.depth.format
|
||||
&& depth.layout == fmt.depth.layout;
|
||||
|
||||
return eq;
|
||||
}
|
||||
|
||||
|
||||
DxvkRenderPass::DxvkRenderPass(
|
||||
const Rc<vk::DeviceFn>& vkd,
|
||||
const DxvkRenderPassFormat& fmt)
|
||||
@ -23,19 +38,8 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
bool DxvkRenderPass::hasCompatibleFormat(
|
||||
const DxvkRenderPassFormat& fmt) const {
|
||||
bool eq = m_format.sampleCount == fmt.sampleCount;
|
||||
|
||||
for (uint32_t i = 0; i < MaxNumRenderTargets && eq; i++) {
|
||||
eq &= m_format.color[i].format == fmt.color[i].format
|
||||
&& m_format.color[i].layout == fmt.color[i].layout;
|
||||
}
|
||||
|
||||
eq &= m_format.depth.format == fmt.depth.format
|
||||
&& m_format.depth.layout == fmt.depth.layout;
|
||||
|
||||
return eq;
|
||||
bool DxvkRenderPass::hasCompatibleFormat(const DxvkRenderPassFormat& fmt) const {
|
||||
return m_format.matches(fmt);
|
||||
}
|
||||
|
||||
|
||||
|
@ -31,6 +31,8 @@ namespace dxvk {
|
||||
VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
|
||||
DxvkAttachmentFormat depth;
|
||||
DxvkAttachmentFormat color[MaxNumRenderTargets];
|
||||
|
||||
bool matches(const DxvkRenderPassFormat& fmt) const;
|
||||
};
|
||||
|
||||
|
||||
@ -94,6 +96,14 @@ namespace dxvk {
|
||||
|
||||
~DxvkRenderPass();
|
||||
|
||||
/**
|
||||
* \brief Retrieves render pass format
|
||||
* \returns The render pass format
|
||||
*/
|
||||
DxvkRenderPassFormat format() const {
|
||||
return m_format;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Checks whether a format is compatible
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user