-
Notifications
You must be signed in to change notification settings - Fork 70
Expand file tree
/
Copy pathICPUGraphicsPipeline.h
More file actions
141 lines (113 loc) · 5.16 KB
/
ICPUGraphicsPipeline.h
File metadata and controls
141 lines (113 loc) · 5.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// Copyright (C) 2018-2020 - DevSH Graphics Programming Sp. z O.O.
// This file is part of the "Nabla Engine".
// For conditions of distribution and use, see copyright notice in nabla.h
#ifndef _NBL_I_CPU_GRAPHICS_PIPELINE_H_INCLUDED_
#define _NBL_I_CPU_GRAPHICS_PIPELINE_H_INCLUDED_
#include "nbl/asset/IGraphicsPipeline.h"
#include "nbl/asset/ICPURenderpass.h"
#include "nbl/asset/ICPUPipeline.h"
namespace nbl::asset
{
class ICPUGraphicsPipeline final : public ICPUPipeline<IGraphicsPipeline<ICPUPipelineLayout,ICPURenderpass>>
{
using pipeline_base_t = IGraphicsPipeline<ICPUPipelineLayout, ICPURenderpass>;
using base_t = ICPUPipeline<pipeline_base_t>;
public:
static core::smart_refctd_ptr<ICPUGraphicsPipeline> create(ICPUPipelineLayout* layout, ICPURenderpass* renderpass = nullptr)
{
auto retval = new ICPUGraphicsPipeline(layout, renderpass);
return core::smart_refctd_ptr<ICPUGraphicsPipeline>(retval,core::dont_grab);
}
constexpr static inline auto AssetType = ET_GRAPHICS_PIPELINE;
inline E_TYPE getAssetType() const override { return AssetType; }
inline const SCachedCreationParams& getCachedCreationParams() const
{
return pipeline_base_t::getCachedCreationParams();
}
inline SCachedCreationParams& getCachedCreationParams()
{
assert(isMutable());
return m_params;
}
inline std::span<const SShaderSpecInfo> getSpecInfos(const hlsl::ShaderStage stage) const override final
{
const auto stageIndex = stageToIndex(stage);
if (stageIndex != -1)
return { &m_specInfos[stageIndex], 1 };
return {};
}
inline std::span<SShaderSpecInfo> getSpecInfos(const hlsl::ShaderStage stage)
{
return base_t::getSpecInfos(stage);
}
std::span<SShaderSpecInfo> getSpecInfo(const hlsl::ShaderStage stage)
{
if (!isMutable()) return {};
const auto stageIndex = stageToIndex(stage);
if (stageIndex != -1)
return {&m_specInfos[stageIndex], 1};
return {};
}
std::span<const SShaderSpecInfo> getSpecInfo(const hlsl::ShaderStage stage) const
{
const auto stageIndex = stageToIndex(stage);
if (stageIndex != -1)
return {&m_specInfos[stageIndex], 1};
return {};
}
inline bool valid() const override
{
if (!m_layout) return false;
if (!m_layout->valid())return false;
// https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkGraphicsPipelineCreateInfo.html#VUID-VkGraphicsPipelineCreateInfo-dynamicRendering-06576
if (!m_renderpass || m_params.subpassIx >= m_renderpass->getSubpassCount()) return false;
core::bitflag<hlsl::ShaderStage> stagePresence = {};
for (auto shader_i = 0u; shader_i < m_specInfos.size(); shader_i++)
{
const auto& info = m_specInfos[shader_i];
if (info.shader)
stagePresence |= indexToStage(shader_i);
}
return hasRequiredStages(stagePresence, m_params.primitiveAssembly.primitiveType);
}
protected:
using base_t::base_t;
virtual ~ICPUGraphicsPipeline() override = default;
std::array<SShaderSpecInfo, GRAPHICS_SHADER_STAGE_COUNT> m_specInfos;
private:
explicit ICPUGraphicsPipeline(ICPUPipelineLayout* layout, ICPURenderpass* renderpass)
: base_t(layout, {}, renderpass)
{}
static inline int8_t stageToIndex(const hlsl::ShaderStage stage)
{
const auto stageIx = hlsl::findLSB(stage);
if (stageIx < 0 || stageIx >= GRAPHICS_SHADER_STAGE_COUNT || hlsl::bitCount(stage)!=1)
return -1;
return stageIx;
}
static inline hlsl::ShaderStage indexToStage(const int8_t index)
{
if (index < 0 || index > GRAPHICS_SHADER_STAGE_COUNT)
return hlsl::ShaderStage::ESS_UNKNOWN;
return static_cast<hlsl::ShaderStage>(hlsl::ShaderStage::ESS_VERTEX + index);
}
inline core::smart_refctd_ptr<base_t> clone_impl(core::smart_refctd_ptr<ICPUPipelineLayout>&& layout, uint32_t depth) const override final
{
auto* newPipeline = new ICPUGraphicsPipeline(layout.get(), m_renderpass.get());
newPipeline->m_params = m_params;
for (auto specInfo_i = 0u; specInfo_i < m_specInfos.size(); specInfo_i++)
{
newPipeline->m_specInfos[specInfo_i] = m_specInfos[specInfo_i].clone(depth);
}
return core::smart_refctd_ptr<base_t>(newPipeline, core::dont_grab);
}
inline void visitDependents_impl(std::function<bool(const IAsset*)> visit) const override
{
if (!visit(m_layout.get())) return;
if (!visit(m_renderpass.get())) return;
for (const auto& info : m_specInfos)
if (!visit(info.shader.get())) return;
}
};
}
#endif