2017-10-14 23:52:47 +02:00
|
|
|
#pragma once
|
|
|
|
|
2018-05-01 16:45:28 +02:00
|
|
|
#include <mutex>
|
2017-10-14 23:52:47 +02:00
|
|
|
|
2018-09-17 10:40:57 +02:00
|
|
|
#include "dxvk_bind_mask.h"
|
2017-11-20 13:21:27 +01:00
|
|
|
#include "dxvk_constant_state.h"
|
2018-01-13 22:18:32 +01:00
|
|
|
#include "dxvk_pipecache.h"
|
2017-12-07 09:38:31 +01:00
|
|
|
#include "dxvk_pipelayout.h"
|
2018-05-03 19:33:41 +02:00
|
|
|
#include "dxvk_renderpass.h"
|
2017-10-14 23:52:47 +02:00
|
|
|
#include "dxvk_resource.h"
|
2017-12-03 00:40:58 +01:00
|
|
|
#include "dxvk_shader.h"
|
2018-04-03 15:52:39 +02:00
|
|
|
#include "dxvk_stats.h"
|
2017-10-14 23:52:47 +02:00
|
|
|
|
|
|
|
namespace dxvk {
|
|
|
|
|
2018-01-16 15:00:19 +01:00
|
|
|
class DxvkDevice;
|
2018-09-21 19:42:48 +02:00
|
|
|
class DxvkPipelineManager;
|
2018-07-24 18:19:52 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* \brief Flags that describe pipeline properties
|
|
|
|
*/
|
|
|
|
enum class DxvkGraphicsPipelineFlag {
|
|
|
|
HasTransformFeedback,
|
2018-10-30 14:43:52 +01:00
|
|
|
HasFsStorageDescriptors,
|
|
|
|
HasVsStorageDescriptors,
|
2018-07-24 18:19:52 +02:00
|
|
|
};
|
|
|
|
|
2018-10-29 10:52:04 +01:00
|
|
|
using DxvkGraphicsPipelineFlags = Flags<DxvkGraphicsPipelineFlag>;
|
2018-07-24 18:19:52 +02:00
|
|
|
|
2019-01-16 19:31:38 +01:00
|
|
|
|
2019-07-23 12:41:09 +02:00
|
|
|
/**
|
|
|
|
* \brief Shaders used in graphics pipelines
|
|
|
|
*/
|
|
|
|
struct DxvkGraphicsPipelineShaders {
|
|
|
|
Rc<DxvkShader> vs;
|
|
|
|
Rc<DxvkShader> tcs;
|
|
|
|
Rc<DxvkShader> tes;
|
|
|
|
Rc<DxvkShader> gs;
|
|
|
|
Rc<DxvkShader> fs;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2017-11-17 19:49:44 +01:00
|
|
|
/**
|
|
|
|
* \brief Graphics pipeline state info
|
|
|
|
*
|
2017-11-20 13:21:27 +01:00
|
|
|
* Stores all information that is required to create
|
|
|
|
* a graphics pipeline, except the shader objects
|
|
|
|
* themselves. Also used to identify pipelines using
|
|
|
|
* the current pipeline state vector.
|
2017-11-17 19:49:44 +01:00
|
|
|
*/
|
2017-10-15 17:56:06 +02:00
|
|
|
struct DxvkGraphicsPipelineStateInfo {
|
2017-12-07 21:47:38 +01:00
|
|
|
DxvkGraphicsPipelineStateInfo();
|
|
|
|
DxvkGraphicsPipelineStateInfo(
|
|
|
|
const DxvkGraphicsPipelineStateInfo& other);
|
2017-11-20 13:21:27 +01:00
|
|
|
|
2017-12-07 21:47:38 +01:00
|
|
|
DxvkGraphicsPipelineStateInfo& operator = (
|
|
|
|
const DxvkGraphicsPipelineStateInfo& other);
|
2017-10-15 13:02:59 +02:00
|
|
|
|
2018-01-10 21:28:20 +01:00
|
|
|
bool operator == (const DxvkGraphicsPipelineStateInfo& other) const;
|
|
|
|
bool operator != (const DxvkGraphicsPipelineStateInfo& other) const;
|
2019-01-16 19:31:38 +01:00
|
|
|
|
|
|
|
bool useDynamicStencilRef() const {
|
|
|
|
return dsEnableStencilTest;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool useDynamicDepthBias() const {
|
|
|
|
return rsDepthBiasEnable;
|
|
|
|
}
|
|
|
|
|
2019-04-24 22:32:54 +02:00
|
|
|
bool useDynamicDepthBounds() const {
|
|
|
|
return dsEnableDepthBoundsTest;
|
|
|
|
}
|
|
|
|
|
2019-01-16 19:31:38 +01:00
|
|
|
bool useDynamicBlendConstants() const {
|
|
|
|
bool result = false;
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < MaxNumRenderTargets && !result; i++) {
|
|
|
|
result |= omBlendAttachments[i].blendEnable
|
|
|
|
&& (util::isBlendConstantBlendFactor(omBlendAttachments[i].srcColorBlendFactor)
|
|
|
|
|| util::isBlendConstantBlendFactor(omBlendAttachments[i].dstColorBlendFactor)
|
|
|
|
|| util::isBlendConstantBlendFactor(omBlendAttachments[i].srcAlphaBlendFactor)
|
|
|
|
|| util::isBlendConstantBlendFactor(omBlendAttachments[i].dstAlphaBlendFactor));
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
2018-01-10 21:28:20 +01:00
|
|
|
|
2018-09-17 10:40:57 +02:00
|
|
|
DxvkBindingMask bsBindingMask;
|
2018-01-10 11:44:40 +01:00
|
|
|
|
2017-12-07 21:47:38 +01:00
|
|
|
VkPrimitiveTopology iaPrimitiveTopology;
|
|
|
|
VkBool32 iaPrimitiveRestart;
|
2018-01-29 11:31:00 +01:00
|
|
|
uint32_t iaPatchVertexCount;
|
2017-10-15 13:02:59 +02:00
|
|
|
|
2017-12-07 21:47:38 +01:00
|
|
|
uint32_t ilAttributeCount;
|
|
|
|
uint32_t ilBindingCount;
|
|
|
|
VkVertexInputAttributeDescription ilAttributes[DxvkLimits::MaxNumVertexAttributes];
|
|
|
|
VkVertexInputBindingDescription ilBindings[DxvkLimits::MaxNumVertexBindings];
|
2018-04-17 17:24:16 +02:00
|
|
|
uint32_t ilDivisors[DxvkLimits::MaxNumVertexBindings];
|
2017-12-07 21:47:38 +01:00
|
|
|
|
2019-01-17 01:58:03 +01:00
|
|
|
VkBool32 rsDepthClipEnable;
|
2018-06-25 16:56:52 +02:00
|
|
|
VkBool32 rsDepthBiasEnable;
|
2017-12-07 21:47:38 +01:00
|
|
|
VkPolygonMode rsPolygonMode;
|
|
|
|
VkCullModeFlags rsCullMode;
|
|
|
|
VkFrontFace rsFrontFace;
|
|
|
|
uint32_t rsViewportCount;
|
2018-09-18 13:21:58 +02:00
|
|
|
VkSampleCountFlags rsSampleCount;
|
2017-12-07 21:47:38 +01:00
|
|
|
|
2018-09-18 13:21:58 +02:00
|
|
|
VkSampleCountFlags msSampleCount;
|
2017-12-07 21:47:38 +01:00
|
|
|
uint32_t msSampleMask;
|
|
|
|
VkBool32 msEnableAlphaToCoverage;
|
2019-03-31 22:34:03 +02:00
|
|
|
|
2017-12-07 21:47:38 +01:00
|
|
|
VkBool32 dsEnableDepthTest;
|
|
|
|
VkBool32 dsEnableDepthWrite;
|
2019-04-24 22:32:54 +02:00
|
|
|
VkBool32 dsEnableDepthBoundsTest;
|
2017-12-07 21:47:38 +01:00
|
|
|
VkBool32 dsEnableStencilTest;
|
|
|
|
VkCompareOp dsDepthCompareOp;
|
|
|
|
VkStencilOpState dsStencilOpFront;
|
|
|
|
VkStencilOpState dsStencilOpBack;
|
|
|
|
|
|
|
|
VkBool32 omEnableLogicOp;
|
|
|
|
VkLogicOp omLogicOp;
|
2018-01-16 15:00:19 +01:00
|
|
|
VkPipelineColorBlendAttachmentState omBlendAttachments[MaxNumRenderTargets];
|
2018-09-01 16:49:24 +02:00
|
|
|
VkComponentMapping omComponentMapping[MaxNumRenderTargets];
|
2019-05-06 00:04:47 +02:00
|
|
|
|
|
|
|
uint32_t scSpecConstants[MaxNumSpecConstants];
|
2017-12-07 21:47:38 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2018-04-08 21:49:30 +02:00
|
|
|
/**
|
|
|
|
* \brief Common graphics pipeline state
|
|
|
|
*
|
|
|
|
* Non-dynamic pipeline state that cannot
|
|
|
|
* be changed dynamically.
|
|
|
|
*/
|
|
|
|
struct DxvkGraphicsCommonPipelineStateInfo {
|
|
|
|
bool msSampleShadingEnable;
|
|
|
|
float msSampleShadingFactor;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2018-05-09 22:23:50 +02:00
|
|
|
/**
|
|
|
|
* \brief Graphics pipeline instance
|
|
|
|
*
|
2018-09-10 16:32:17 +02:00
|
|
|
* Stores a state vector and the
|
|
|
|
* corresponding pipeline handle.
|
2018-05-09 22:23:50 +02:00
|
|
|
*/
|
2018-09-16 10:07:45 +02:00
|
|
|
class DxvkGraphicsPipelineInstance {
|
|
|
|
|
2018-05-09 22:23:50 +02:00
|
|
|
public:
|
2018-09-16 10:07:45 +02:00
|
|
|
|
2019-06-30 23:55:52 +01:00
|
|
|
DxvkGraphicsPipelineInstance()
|
|
|
|
: m_stateVector (),
|
|
|
|
m_renderPass (VK_NULL_HANDLE),
|
|
|
|
m_pipeline (VK_NULL_HANDLE) { }
|
2019-07-30 09:41:22 +02:00
|
|
|
|
2018-05-09 22:23:50 +02:00
|
|
|
DxvkGraphicsPipelineInstance(
|
2018-09-16 10:07:45 +02:00
|
|
|
const DxvkGraphicsPipelineStateInfo& state,
|
2019-07-30 13:15:45 +02:00
|
|
|
const DxvkRenderPass* rp,
|
2018-09-16 10:07:45 +02:00
|
|
|
VkPipeline pipe)
|
|
|
|
: m_stateVector (state),
|
|
|
|
m_renderPass (rp),
|
|
|
|
m_pipeline (pipe) { }
|
|
|
|
|
2018-05-09 22:23:50 +02:00
|
|
|
/**
|
|
|
|
* \brief Checks for matching pipeline state
|
|
|
|
*
|
|
|
|
* \param [in] stateVector Graphics pipeline state
|
|
|
|
* \param [in] renderPass Render pass handle
|
|
|
|
* \returns \c true if the specialization is compatible
|
|
|
|
*/
|
|
|
|
bool isCompatible(
|
2018-09-16 10:07:45 +02:00
|
|
|
const DxvkGraphicsPipelineStateInfo& state,
|
2019-07-30 13:15:45 +02:00
|
|
|
const DxvkRenderPass* rp) {
|
2019-07-30 16:19:16 +02:00
|
|
|
return m_renderPass == rp
|
|
|
|
&& m_stateVector == state;
|
2018-05-09 22:23:50 +02:00
|
|
|
}
|
2018-09-16 10:07:45 +02:00
|
|
|
|
2018-05-09 22:23:50 +02:00
|
|
|
/**
|
|
|
|
* \brief Retrieves pipeline
|
2018-05-10 14:15:47 +02:00
|
|
|
* \returns The pipeline handle
|
2018-05-09 22:23:50 +02:00
|
|
|
*/
|
2018-09-16 10:07:45 +02:00
|
|
|
VkPipeline pipeline() const {
|
|
|
|
return m_pipeline;
|
2018-05-09 22:23:50 +02:00
|
|
|
}
|
2018-09-16 10:07:45 +02:00
|
|
|
|
2018-05-09 22:23:50 +02:00
|
|
|
private:
|
2018-09-16 10:07:45 +02:00
|
|
|
|
2018-05-09 22:23:50 +02:00
|
|
|
DxvkGraphicsPipelineStateInfo m_stateVector;
|
2019-07-30 13:15:45 +02:00
|
|
|
const DxvkRenderPass* m_renderPass;
|
2018-09-16 10:07:45 +02:00
|
|
|
VkPipeline m_pipeline;
|
2018-09-10 16:32:17 +02:00
|
|
|
|
2018-05-09 22:23:50 +02:00
|
|
|
};
|
2018-09-16 10:07:45 +02:00
|
|
|
|
2018-05-09 22:23:50 +02:00
|
|
|
|
2017-10-14 23:52:47 +02:00
|
|
|
/**
|
|
|
|
* \brief Graphics pipeline
|
|
|
|
*
|
|
|
|
* Stores the pipeline layout as well as methods to
|
|
|
|
* recompile the graphics pipeline against a given
|
|
|
|
* pipeline state vector.
|
|
|
|
*/
|
2019-07-23 13:15:06 +02:00
|
|
|
class DxvkGraphicsPipeline {
|
2017-10-14 23:52:47 +02:00
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
DxvkGraphicsPipeline(
|
2019-07-23 12:48:11 +02:00
|
|
|
DxvkPipelineManager* pipeMgr,
|
|
|
|
DxvkGraphicsPipelineShaders shaders);
|
|
|
|
|
2017-10-14 23:52:47 +02:00
|
|
|
~DxvkGraphicsPipeline();
|
|
|
|
|
2018-07-24 18:19:52 +02:00
|
|
|
/**
|
|
|
|
* \brief Returns graphics pipeline flags
|
|
|
|
* \returns Graphics pipeline property flags
|
|
|
|
*/
|
2018-10-29 10:52:04 +01:00
|
|
|
DxvkGraphicsPipelineFlags flags() const {
|
2018-07-24 18:19:52 +02:00
|
|
|
return m_flags;
|
|
|
|
}
|
|
|
|
|
2017-11-20 14:11:09 +01:00
|
|
|
/**
|
2017-12-03 00:40:58 +01:00
|
|
|
* \brief Pipeline layout
|
2017-11-20 14:11:09 +01:00
|
|
|
*
|
2017-12-03 20:23:26 +01:00
|
|
|
* Stores the pipeline layout and the descriptor set
|
|
|
|
* layout, as well as information on the resource
|
|
|
|
* slots used by the pipeline.
|
|
|
|
* \returns Pipeline layout
|
2017-11-20 14:11:09 +01:00
|
|
|
*/
|
2018-06-22 00:33:47 +02:00
|
|
|
DxvkPipelineLayout* layout() const {
|
|
|
|
return m_layout.ptr();
|
2017-11-20 14:11:09 +01:00
|
|
|
}
|
|
|
|
|
2018-09-04 02:41:34 +02:00
|
|
|
/**
|
|
|
|
* \brief Queries shader for a given stage
|
|
|
|
*
|
|
|
|
* In case no shader is specified for the
|
|
|
|
* given stage, \c nullptr will be returned.
|
|
|
|
* \param [in] stage The shader stage
|
|
|
|
* \returns Shader of the given stage
|
|
|
|
*/
|
|
|
|
Rc<DxvkShader> getShader(
|
|
|
|
VkShaderStageFlagBits stage) const;
|
|
|
|
|
2017-11-20 14:11:09 +01:00
|
|
|
/**
|
|
|
|
* \brief Pipeline handle
|
2018-01-13 22:18:32 +01:00
|
|
|
*
|
|
|
|
* Retrieves a pipeline handle for the given pipeline
|
|
|
|
* state. If necessary, a new pipeline will be created.
|
|
|
|
* \param [in] state Pipeline state vector
|
2018-05-03 19:33:41 +02:00
|
|
|
* \param [in] renderPass The render pass
|
2017-11-20 14:11:09 +01:00
|
|
|
* \returns Pipeline handle
|
|
|
|
*/
|
2017-10-15 13:02:59 +02:00
|
|
|
VkPipeline getPipelineHandle(
|
2018-05-10 14:15:47 +02:00
|
|
|
const DxvkGraphicsPipelineStateInfo& state,
|
2019-07-30 13:15:45 +02:00
|
|
|
const DxvkRenderPass* renderPass);
|
2018-05-10 14:15:47 +02:00
|
|
|
|
2019-07-30 12:14:52 +02:00
|
|
|
/**
|
|
|
|
* \brief Compiles a pipeline
|
|
|
|
*
|
|
|
|
* Asynchronously compiles the given pipeline
|
|
|
|
* and stores the result for future use.
|
|
|
|
* \param [in] state Pipeline state vector
|
|
|
|
* \param [in] renderPass The render pass
|
|
|
|
*/
|
|
|
|
void compilePipeline(
|
|
|
|
const DxvkGraphicsPipelineStateInfo& state,
|
2019-07-30 13:15:45 +02:00
|
|
|
const DxvkRenderPass* renderPass);
|
2019-07-30 12:14:52 +02:00
|
|
|
|
2017-10-14 23:52:47 +02:00
|
|
|
private:
|
|
|
|
|
2019-07-23 12:48:11 +02:00
|
|
|
Rc<vk::DeviceFn> m_vkd;
|
|
|
|
DxvkPipelineManager* m_pipeMgr;
|
2018-09-21 19:42:48 +02:00
|
|
|
|
2019-07-23 12:48:11 +02:00
|
|
|
DxvkGraphicsPipelineShaders m_shaders;
|
|
|
|
DxvkDescriptorSlotMapping m_slotMapping;
|
2019-04-03 20:01:36 +02:00
|
|
|
|
2019-07-23 12:48:11 +02:00
|
|
|
Rc<DxvkPipelineLayout> m_layout;
|
2017-10-15 13:02:59 +02:00
|
|
|
|
2018-01-12 14:25:26 +01:00
|
|
|
uint32_t m_vsIn = 0;
|
|
|
|
uint32_t m_fsOut = 0;
|
|
|
|
|
2018-10-29 10:52:04 +01:00
|
|
|
DxvkGraphicsPipelineFlags m_flags;
|
2018-04-08 21:49:30 +02:00
|
|
|
DxvkGraphicsCommonPipelineStateInfo m_common;
|
|
|
|
|
2018-05-13 15:36:44 +02:00
|
|
|
// List of pipeline instances, shared between threads
|
2018-09-16 10:07:45 +02:00
|
|
|
alignas(CACHE_LINE_SIZE) sync::Spinlock m_mutex;
|
|
|
|
std::vector<DxvkGraphicsPipelineInstance> m_pipelines;
|
2017-10-15 13:02:59 +02:00
|
|
|
|
2019-07-30 12:14:52 +02:00
|
|
|
DxvkGraphicsPipelineInstance* createInstance(
|
|
|
|
const DxvkGraphicsPipelineStateInfo& state,
|
2019-07-30 13:15:45 +02:00
|
|
|
const DxvkRenderPass* renderPass);
|
2019-07-30 12:14:52 +02:00
|
|
|
|
|
|
|
DxvkGraphicsPipelineInstance* findInstance(
|
2018-05-01 16:45:28 +02:00
|
|
|
const DxvkGraphicsPipelineStateInfo& state,
|
2019-07-30 13:15:45 +02:00
|
|
|
const DxvkRenderPass* renderPass);
|
2018-05-01 16:45:28 +02:00
|
|
|
|
2019-07-30 09:41:22 +02:00
|
|
|
VkPipeline createPipeline(
|
2018-01-10 22:54:00 +01:00
|
|
|
const DxvkGraphicsPipelineStateInfo& state,
|
2019-07-30 13:15:45 +02:00
|
|
|
const DxvkRenderPass* renderPass) const;
|
2018-01-12 14:25:26 +01:00
|
|
|
|
2018-09-16 10:07:45 +02:00
|
|
|
void destroyPipeline(
|
|
|
|
VkPipeline pipeline) const;
|
|
|
|
|
2019-04-03 20:47:58 +02:00
|
|
|
DxvkShaderModule createShaderModule(
|
2019-04-03 20:01:36 +02:00
|
|
|
const Rc<DxvkShader>& shader,
|
|
|
|
const DxvkShaderModuleCreateInfo& info) const;
|
|
|
|
|
2018-01-12 14:25:26 +01:00
|
|
|
bool validatePipelineState(
|
|
|
|
const DxvkGraphicsPipelineStateInfo& state) const;
|
|
|
|
|
2018-09-21 23:23:43 +02:00
|
|
|
void writePipelineStateToCache(
|
|
|
|
const DxvkGraphicsPipelineStateInfo& state,
|
|
|
|
const DxvkRenderPassFormat& format) const;
|
|
|
|
|
2018-02-07 16:44:30 +01:00
|
|
|
void logPipelineState(
|
2018-04-02 19:05:41 +02:00
|
|
|
LogLevel level,
|
2018-02-07 16:44:30 +01:00
|
|
|
const DxvkGraphicsPipelineStateInfo& state) const;
|
|
|
|
|
2017-10-14 23:52:47 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|