1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-14 09:23:53 +01:00

[dxvk] Introduce distinction between base and optimized pipelines

We need to know what kind of pipeline we're binding in order to apply
the correct dynamic state.
This commit is contained in:
Philip Rebohle 2022-07-06 03:39:43 +02:00
parent e01ffc02a8
commit 90454438b2
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
3 changed files with 43 additions and 8 deletions

View File

@ -4500,14 +4500,40 @@ namespace dxvk {
: DxvkContextFlag::GpDirtyStencilRef);
// Retrieve and bind actual Vulkan pipeline handle
VkPipeline pipeline = m_state.gp.pipeline->getPipelineHandle(m_state.gp.state);
auto pipelineInfo = m_state.gp.pipeline->getPipelineHandle(m_state.gp.state);
if (unlikely(!pipeline))
if (unlikely(!pipelineInfo.first))
return false;
m_cmd->cmdBindPipeline(
VK_PIPELINE_BIND_POINT_GRAPHICS,
pipeline);
pipelineInfo.first);
// For pipelines created from graphics pipeline libraries, we need
// to apply a bunch of dynamic state that is otherwise static
if (pipelineInfo.second == DxvkGraphicsPipelineType::BasePipeline) {
m_cmd->cmdSetRasterizerState(
m_state.gp.state.rs.cullMode(),
m_state.gp.state.rs.frontFace());
m_cmd->cmdSetDepthState(
m_state.gp.state.ds.enableDepthTest(),
m_state.gp.state.ds.enableDepthWrite(),
m_state.gp.state.ds.depthCompareOp());
m_cmd->cmdSetStencilState(
m_state.gp.state.ds.enableStencilTest(),
m_state.gp.state.dsFront.state(),
m_state.gp.state.dsBack.state());
if (m_device->features().core.features.depthBounds) {
m_cmd->cmdSetDepthBoundsState(
m_state.gp.state.ds.enableDepthBoundsTest());
}
if (!m_state.gp.state.rs.depthBiasEnable())
m_cmd->cmdSetDepthBias(0.0f, 0.0f, 0.0f);
}
// Emit barrier based on pipeline properties, in order to avoid
// accidental write-after-read hazards after the render pass.

View File

@ -524,14 +524,14 @@ namespace dxvk {
}
VkPipeline DxvkGraphicsPipeline::getPipelineHandle(
std::pair<VkPipeline, DxvkGraphicsPipelineType> DxvkGraphicsPipeline::getPipelineHandle(
const DxvkGraphicsPipelineStateInfo& state) {
DxvkGraphicsPipelineInstance* instance = this->findInstance(state);
if (unlikely(!instance)) {
// Exit early if the state vector is invalid
if (!this->validatePipelineState(state, true))
return VK_NULL_HANDLE;
return std::make_pair(VK_NULL_HANDLE, DxvkGraphicsPipelineType::FastPipeline);
// Prevent other threads from adding new instances and check again
std::lock_guard<dxvk::mutex> lock(m_mutex);
@ -545,7 +545,7 @@ namespace dxvk {
}
}
return instance->handle;
return std::make_pair(instance->handle, DxvkGraphicsPipelineType::FastPipeline);
}

View File

@ -230,6 +230,15 @@ namespace dxvk {
};
/**
* \brief Graphics pipeline type
*/
enum class DxvkGraphicsPipelineType : uint32_t {
BasePipeline = 0, ///< Unoptimized pipeline using graphics pipeline libraries
FastPipeline = 1, ///< Monolithic pipeline with less dynamic state
};
/**
* \brief Graphics pipeline instance
*
@ -327,9 +336,9 @@ 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
* \returns Pipeline handle
* \returns Pipeline handle and handle type
*/
VkPipeline getPipelineHandle(
std::pair<VkPipeline, DxvkGraphicsPipelineType> getPipelineHandle(
const DxvkGraphicsPipelineStateInfo& state);
/**