-
Notifications
You must be signed in to change notification settings - Fork 69
Expand file tree
/
Copy pathICPUMeshPipeline.h
More file actions
149 lines (121 loc) · 5.61 KB
/
ICPUMeshPipeline.h
File metadata and controls
149 lines (121 loc) · 5.61 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
142
143
144
145
146
147
148
149
#ifndef _NBL_I_CPU_MESH_PIPELINE_H_INCLUDED_
#define _NBL_I_CPU_MESH_PIPELINE_H_INCLUDED_
#include "nbl/asset/IMeshPipeline.h"
#include "nbl/asset/ICPURenderpass.h"
#include "nbl/asset/ICPUPipeline.h"
namespace nbl::asset
{
class ICPUMeshPipeline final : public ICPUPipeline<IMeshPipeline<ICPUPipelineLayout,ICPURenderpass>>
{
using pipeline_base_t = IMeshPipeline<ICPUPipelineLayout, ICPURenderpass>;
using base_t = ICPUPipeline<pipeline_base_t>;
public:
static core::smart_refctd_ptr<ICPUMeshPipeline> create(ICPUPipelineLayout* layout, ICPURenderpass* renderpass = nullptr)
{
auto retval = new ICPUMeshPipeline(layout, renderpass);
return core::smart_refctd_ptr<ICPUMeshPipeline>(retval,core::dont_grab);
}
constexpr static inline auto AssetType = ET_MESH_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
{
switch (stage) {
case hlsl::ShaderStage::ESS_TASK: return { &m_specInfos[0], 1 };
case hlsl::ShaderStage::ESS_MESH: return { &m_specInfos[1], 1 };
case hlsl::ShaderStage::ESS_FRAGMENT: return { &m_specInfos[2], 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 {};
switch (stage) {
case hlsl::ShaderStage::ESS_TASK: return { &m_specInfos[0], 1 };
case hlsl::ShaderStage::ESS_MESH: return { &m_specInfos[1], 1 };
case hlsl::ShaderStage::ESS_FRAGMENT: return { &m_specInfos[2], 1 };
}
return {};
}
std::span<const SShaderSpecInfo> getSpecInfo(const hlsl::ShaderStage stage) const
{
switch (stage) {
case hlsl::ShaderStage::ESS_TASK: return { &m_specInfos[0], 1 };
case hlsl::ShaderStage::ESS_MESH: return { &m_specInfos[1], 1 };
case hlsl::ShaderStage::ESS_FRAGMENT: return { &m_specInfos[2], 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);
}
protected:
using base_t::base_t;
virtual ~ICPUMeshPipeline() override = default;
std::array<SShaderSpecInfo, MESH_SHADER_STAGE_COUNT> m_specInfos;
private:
explicit ICPUMeshPipeline(ICPUPipelineLayout* layout, ICPURenderpass* renderpass)
: base_t(layout, {}, renderpass)
{}
static inline int8_t stageToIndex(const hlsl::ShaderStage stage)
{
switch(stage){
case hlsl::ShaderStage::ESS_TASK: return 0;
case hlsl::ShaderStage::ESS_MESH: return 1;
case hlsl::ShaderStage::ESS_FRAGMENT: return 2;
}
return -1;
}
static inline hlsl::ShaderStage indexToStage(const int8_t index)
{
switch (index) {
case 0: return hlsl::ShaderStage::ESS_TASK;
case 1: return hlsl::ShaderStage::ESS_MESH;
case 2: return hlsl::ShaderStage::ESS_FRAGMENT;
}
return hlsl::ShaderStage::ESS_UNKNOWN;
}
inline core::smart_refctd_ptr<base_t> clone_impl(core::smart_refctd_ptr<ICPUPipelineLayout>&& layout, uint32_t depth) const override final
{
auto* newPipeline = new ICPUMeshPipeline(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