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