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:
parent
e01ffc02a8
commit
90454438b2
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user