1
0
mirror of https://github.com/EduApps-CDG/OpenDX synced 2024-12-30 09:45:37 +01:00
OpenDX/src/dxvk/dxvk_graphics.h

304 lines
9.3 KiB
C
Raw Normal View History

2017-10-14 23:52:47 +02:00
#pragma once
#include <mutex>
2017-10-14 23:52:47 +02:00
#include "dxvk_bind_mask.h"
#include "dxvk_constant_state.h"
#include "dxvk_pipecache.h"
#include "dxvk_pipelayout.h"
#include "dxvk_renderpass.h"
2017-10-14 23:52:47 +02:00
#include "dxvk_resource.h"
#include "dxvk_shader.h"
#include "dxvk_stats.h"
2017-10-14 23:52:47 +02:00
namespace dxvk {
class DxvkDevice;
class DxvkPipelineManager;
/**
* \brief Flags that describe pipeline properties
*/
enum class DxvkGraphicsPipelineFlag {
HasTransformFeedback,
HasFsStorageDescriptors,
HasVsStorageDescriptors,
};
using DxvkGraphicsPipelineFlags = Flags<DxvkGraphicsPipelineFlag>;
/**
* \brief Graphics pipeline state info
*
* 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.
*/
struct DxvkGraphicsPipelineStateInfo {
DxvkGraphicsPipelineStateInfo();
DxvkGraphicsPipelineStateInfo(
const DxvkGraphicsPipelineStateInfo& other);
DxvkGraphicsPipelineStateInfo& operator = (
const DxvkGraphicsPipelineStateInfo& other);
2017-10-15 13:02:59 +02:00
bool operator == (const DxvkGraphicsPipelineStateInfo& other) const;
bool operator != (const DxvkGraphicsPipelineStateInfo& other) const;
bool useDynamicStencilRef() const {
return dsEnableStencilTest;
}
bool useDynamicDepthBias() const {
return rsDepthBiasEnable;
}
bool useDynamicDepthBounds() const {
return dsEnableDepthBoundsTest;
}
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;
}
DxvkBindingMask bsBindingMask;
VkPrimitiveTopology iaPrimitiveTopology;
VkBool32 iaPrimitiveRestart;
uint32_t iaPatchVertexCount;
2017-10-15 13:02:59 +02:00
uint32_t ilAttributeCount;
uint32_t ilBindingCount;
VkVertexInputAttributeDescription ilAttributes[DxvkLimits::MaxNumVertexAttributes];
VkVertexInputBindingDescription ilBindings[DxvkLimits::MaxNumVertexBindings];
uint32_t ilDivisors[DxvkLimits::MaxNumVertexBindings];
VkBool32 rsDepthClipEnable;
VkBool32 rsDepthBiasEnable;
VkPolygonMode rsPolygonMode;
VkCullModeFlags rsCullMode;
VkFrontFace rsFrontFace;
uint32_t rsViewportCount;
VkSampleCountFlags rsSampleCount;
VkSampleCountFlags msSampleCount;
uint32_t msSampleMask;
VkBool32 msEnableAlphaToCoverage;
VkBool32 dsEnableDepthTest;
VkBool32 dsEnableDepthWrite;
VkBool32 dsEnableDepthBoundsTest;
VkBool32 dsEnableStencilTest;
VkCompareOp dsDepthCompareOp;
VkStencilOpState dsStencilOpFront;
VkStencilOpState dsStencilOpBack;
VkBool32 omEnableLogicOp;
VkLogicOp omLogicOp;
VkPipelineColorBlendAttachmentState omBlendAttachments[MaxNumRenderTargets];
VkComponentMapping omComponentMapping[MaxNumRenderTargets];
uint32_t scSpecConstants[MaxNumSpecConstants];
};
/**
* \brief Common graphics pipeline state
*
* Non-dynamic pipeline state that cannot
* be changed dynamically.
*/
struct DxvkGraphicsCommonPipelineStateInfo {
bool msSampleShadingEnable;
float msSampleShadingFactor;
};
/**
* \brief Graphics pipeline instance
*
* Stores a state vector and the
* corresponding pipeline handle.
*/
class DxvkGraphicsPipelineInstance {
public:
DxvkGraphicsPipelineInstance()
: m_stateVector (),
m_renderPass (VK_NULL_HANDLE),
m_pipeline (VK_NULL_HANDLE) { }
DxvkGraphicsPipelineInstance(
const DxvkGraphicsPipelineStateInfo& state,
VkRenderPass rp,
VkPipeline pipe)
: m_stateVector (state),
m_renderPass (rp),
m_pipeline (pipe) { }
/**
* \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(
const DxvkGraphicsPipelineStateInfo& state,
VkRenderPass rp) const {
return m_stateVector == state
&& m_renderPass == rp;
}
/**
* \brief Retrieves pipeline
* \returns The pipeline handle
*/
VkPipeline pipeline() const {
return m_pipeline;
}
private:
DxvkGraphicsPipelineStateInfo m_stateVector;
VkRenderPass m_renderPass;
VkPipeline m_pipeline;
};
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.
*/
class DxvkGraphicsPipeline : public RcObject {
2017-10-14 23:52:47 +02:00
public:
DxvkGraphicsPipeline(
DxvkPipelineManager* pipeMgr,
const Rc<DxvkShader>& vs,
const Rc<DxvkShader>& tcs,
const Rc<DxvkShader>& tes,
const Rc<DxvkShader>& gs,
const Rc<DxvkShader>& fs);
2017-10-14 23:52:47 +02:00
~DxvkGraphicsPipeline();
/**
* \brief Returns graphics pipeline flags
* \returns Graphics pipeline property flags
*/
DxvkGraphicsPipelineFlags flags() const {
return m_flags;
}
/**
* \brief Pipeline layout
*
* Stores the pipeline layout and the descriptor set
* layout, as well as information on the resource
* slots used by the pipeline.
* \returns Pipeline layout
*/
DxvkPipelineLayout* layout() const {
return m_layout.ptr();
}
/**
* \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;
/**
* \brief Pipeline handle
*
* 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
* \returns Pipeline handle
*/
2017-10-15 13:02:59 +02:00
VkPipeline getPipelineHandle(
const DxvkGraphicsPipelineStateInfo& state,
const DxvkRenderPass& renderPass);
2017-10-14 23:52:47 +02:00
private:
struct PipelineStruct {
DxvkGraphicsPipelineStateInfo stateVector;
VkRenderPass renderPass;
VkPipeline pipeline;
};
Rc<vk::DeviceFn> m_vkd;
DxvkPipelineManager* m_pipeMgr;
DxvkDescriptorSlotMapping m_slotMapping;
Rc<DxvkShader> m_vs;
Rc<DxvkShader> m_tcs;
Rc<DxvkShader> m_tes;
Rc<DxvkShader> m_gs;
Rc<DxvkShader> m_fs;
Rc<DxvkPipelineLayout> m_layout;
2017-10-15 13:02:59 +02:00
uint32_t m_vsIn = 0;
uint32_t m_fsOut = 0;
DxvkGraphicsPipelineFlags m_flags;
DxvkGraphicsCommonPipelineStateInfo m_common;
2018-05-13 15:36:44 +02:00
// List of pipeline instances, shared between threads
alignas(CACHE_LINE_SIZE) sync::Spinlock m_mutex;
std::vector<DxvkGraphicsPipelineInstance> m_pipelines;
2017-10-15 13:02:59 +02:00
const DxvkGraphicsPipelineInstance* findInstance(
const DxvkGraphicsPipelineStateInfo& state,
VkRenderPass renderPass) const;
VkPipeline compilePipeline(
const DxvkGraphicsPipelineStateInfo& state,
const DxvkRenderPass& renderPass) const;
void destroyPipeline(
VkPipeline pipeline) const;
DxvkShaderModule createShaderModule(
const Rc<DxvkShader>& shader,
const DxvkShaderModuleCreateInfo& info) const;
bool validatePipelineState(
const DxvkGraphicsPipelineStateInfo& state) const;
2018-09-21 23:23:43 +02:00
void writePipelineStateToCache(
const DxvkGraphicsPipelineStateInfo& state,
const DxvkRenderPassFormat& format) const;
void logPipelineState(
LogLevel level,
const DxvkGraphicsPipelineStateInfo& state) const;
2017-10-14 23:52:47 +02:00
};
}