Skip to content

Rework pipeline shader spec info #871

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 89 commits into
base: stagesless_shaders
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
dc41722
Implement mutable shader spec info
Apr 28, 2025
7fe3431
Rework IGPUGraphicsPipeline
Apr 28, 2025
8dbe9c7
Rework IGPUComputePipeline.h
Apr 28, 2025
436e6e1
Remove default value for mutable template parameter
Apr 29, 2025
2e367d1
Implement IGPUPipeline and refactor SCreationParams
May 5, 2025
a9d5aaf
Fix gpu graphics pipeline stage validation
May 5, 2025
51b69c1
Fix compute pipeline
May 5, 2025
fa759be
Implement cpu graphics pipeline validation
May 5, 2025
de8813f
Implement compute pipeline validation
May 5, 2025
37ab1ce
Add FLAGS alias
May 7, 2025
a0ecd50
Fix clone_impl to return smart pointer
May 7, 2025
7890981
Add final decoration to ICPUComputePipeline
May 7, 2025
9a14aa1
Make cpu pipeline constructor private
May 7, 2025
9bb9d14
Add layout validation to compute pipeline validation
May 7, 2025
bcb096f
Refactor getSpecInfo
May 7, 2025
278eb71
Move stageToIndex and indexToStage
May 7, 2025
68bbcff
Add constraint to template parameter of ICPUPipeline and IGPUPipeline
May 7, 2025
8ec0415
Rework IGPUPipeline SSpecConstantValue
May 7, 2025
57136e8
Rework SShaderSpecInfo for ICPUPIpeline
May 7, 2025
7983e62
Move cloneSpecInfo into SShaderSpecInfo
May 7, 2025
071f1eb
Remove valid virtual function from ICPUPipeline to IAsset
May 7, 2025
b8f8ba0
Remove getShaders from SShaderSpecInfo
May 7, 2025
f661366
Rename isValidStagePresence to hasRequiredStages
May 7, 2025
8c10cbd
Rework IGPUGraphicsPipeline to have individual shaderSpecInfo per stages
May 7, 2025
71056f2
Add IGPUPipelineLayout to IGPUPipeline
May 7, 2025
11255d4
Implement ICPURayTracingPipeline
May 8, 2025
8c549fb
Add computeDependants virtual function to IAsset
May 12, 2025
01c4ac6
Implement computeDependants for ICPUComputePipeline
May 12, 2025
d9efa1a
Implement compute pipeline base
May 12, 2025
0b791b5
Fix discardDependantsContents and anyDependantDiscardedContents to us…
May 13, 2025
e8e43b1
Add Ray Tracing Pipeline Asset to IAsset
May 13, 2025
b9db6aa
Remove unnecessary specInfo assignment in clone method
May 13, 2025
2ae6f78
Move subgroup argument to computePipelineBase
May 13, 2025
8de6d9a
Remove getDependantCount and getDependant and getDependant_impl from …
May 13, 2025
3f65992
Implement computeDependants for ICPUGraphicsPIpeline
May 13, 2025
89b8daa
Implement computeDependants for ICPURayTracingPIpeline
May 13, 2025
434d73e
Fix IGraphicsPIpeline constructor
May 13, 2025
1cd1771
Remove SUBGROUP_SIZE from IPIpeline
May 13, 2025
5823a84
Refactor IRayTracingPipeline to use new SShaderSpecInfo scheme
May 13, 2025
10ec458
Remove Subgroup related argument from IGPUPipeline
May 13, 2025
39904f7
Refactor IGPUComputePipeline to use IComputePipeline
May 13, 2025
2ce032f
Refactor IGPURayTracingPipeline to use new SShaderSpecInfo scheme
May 13, 2025
058657b
Restore deleted comments
May 13, 2025
a3905be
Merge branch 'stagesless_shaders' into rework_pipeline_shader_spec_info
May 14, 2025
59fcc93
Implement all computeDependants for IAssets
May 15, 2025
6884d45
Add non const computeDependants to IAsset and its child classes
May 16, 2025
2ac65f6
Refactor anyDependantDiscardedContents and discardDependantsContents
May 16, 2025
5c13a93
Remove impl_valid and rework SSpecializatioNValidationResult
May 20, 2025
9f43c02
Return Subgroup size to IPipelineBase
May 22, 2025
bae94c5
Fix missing bracket for getLayout
May 22, 2025
0d8fe94
Return Subgroup Size to every SShaderSpecInfo
May 22, 2025
4ed04c8
Fix stagePresence typo
May 22, 2025
7e2fd2c
Move clone_impl to private
May 22, 2025
c01392c
Implement getSpecInfoVec for ICPURayTracingPipeline
May 22, 2025
7b3c0ed
Fix getSpecInfoVec
May 22, 2025
96db32b
Implement ICPURayTracingPIpeline valid
May 22, 2025
98f3153
Fix ICPUSkeleton.h computeDependants
May 23, 2025
30f35af
Small fixes
May 23, 2025
2983ff0
Remove redundant final specifier
May 23, 2025
e218e77
Remove const so it can be cast to IAsset*
May 23, 2025
b58e486
Fix RenderpassIndependentPipeline
May 23, 2025
1f3a477
Fix SpirvIntrospector
May 23, 2025
d042f42
Add some utility function to IGPURayTracingPipeline SShaderGroup
May 23, 2025
c4de7c2
Fix debloat logic in logical device
May 23, 2025
f1fe089
Remove unused funciton in ILogicalDevice.cpp
May 23, 2025
2eea2b0
Fix layout constness on IComputePipeline
May 26, 2025
969bcb8
Fix ICPUAcclerationStructure to use computeDependantsImpl
May 26, 2025
3e96339
Fix ICPUAnimationLibrary to use computeDependantsImpl
May 26, 2025
6de189d
Remove layout constness from ICPUComputePipeline
May 26, 2025
b0fe090
Move ICPUDescriptorSet computeDependantsImpl to header
May 26, 2025
1d764ec
Remove layout constness from cpu graphics pipeline
May 26, 2025
377f25d
Remove layout constness from cpu pipeline
May 26, 2025
8809bda
Use computeDependantsImpl in cpu pipeline layout
May 26, 2025
3c0b3ba
Fix argument pack passing on IGPUPipeline
May 26, 2025
53b45ec
Remove layout constness from cpu ray tracing pipeline
May 26, 2025
e249931
Add cached parameter to SCreationParams for gpu compute pipeline
May 26, 2025
006dd7d
Remove layout constness on IPipeline
May 26, 2025
389c358
Fix IGPURayTracingPipeline construction
May 26, 2025
81df19b
Fix debloatedHitSpecData error in ILogicalDevice
May 26, 2025
2d97ce8
Fix CComputeBlit
May 26, 2025
68095da
Fix error in ILogicalDevice.cpp due to removed getShaders method
May 27, 2025
98e1759
Fix all errors in CVulkanLogicalDevice
May 27, 2025
59ccb22
Add get shader count for creationParams
May 27, 2025
bc9befb
Move shader stage validation out of commonCreatePipelines
May 27, 2025
b8d53cc
Fix vulkan ray tracing creation
May 28, 2025
f26201e
Another fix to CCOmputeBlit
May 28, 2025
edac59f
Fix AssetConvert to use the current SpecInfo
May 29, 2025
a31cc66
Small fixes to asset and video
May 29, 2025
08ece5d
Fix CComputeBlit
May 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 26 additions & 42 deletions include/nbl/asset/ICPUComputePipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,71 +17,55 @@ class ICPUComputePipeline : public ICPUPipeline<IPipeline<ICPUPipelineLayout>>
using base_t = ICPUPipeline<IPipeline<ICPUPipelineLayout>>;

public:
struct SCreationParams final : IPipeline<ICPUPipelineLayout>::SCreationParams
{
IPipelineBase::SShaderSpecInfo<true> shader;
};
static core::smart_refctd_ptr<ICPUComputePipeline> create(const SCreationParams& params)
explicit ICPUComputePipeline(const ICPUPipelineLayout* layout):
base_t(core::smart_refctd_ptr<ICPUPipelineLayout>(layout))
{}

static core::smart_refctd_ptr<ICPUComputePipeline> create(const ICPUPipelineLayout* layout)
{
if (!params.layout)
return nullptr;
auto retval = new ICPUComputePipeline(core::smart_refctd_ptr<const ICPUPipelineLayout>(params.layout));

if (!retval->setSpecInfo(params.shader))
{
retval->drop();
return nullptr;
}
auto retval = new ICPUComputePipeline(layout);
return core::smart_refctd_ptr<ICPUComputePipeline>(retval,core::dont_grab);
}

inline core::smart_refctd_ptr<IAsset> clone(uint32_t _depth = ~0u) const override final
inline base_t* clone_impl(core::smart_refctd_ptr<const ICPUPipelineLayout>&& layout, uint32_t depth) const override final
{
core::smart_refctd_ptr<ICPUPipelineLayout> layout;
if (_depth>0u && m_layout)
layout = core::smart_refctd_ptr_static_cast<ICPUPipelineLayout>(m_layout->clone(_depth-1u));

auto cp = new ICPUComputePipeline(std::move(layout));
if (m_specInfo.shader)
{
SShaderSpecInfo<true> specInfo = m_specInfo;
if (_depth > 0u)
{
specInfo.shader = core::smart_refctd_ptr_static_cast<IShader>(m_specInfo.shader->clone(_depth - 1u));
}
cp->setSpecInfo(specInfo);
}
return core::smart_refctd_ptr<ICPUComputePipeline>(cp,core::dont_grab);
auto newPipeline = new ICPUComputePipeline(std::move(layout));
newPipeline->m_specInfo = newPipeline->cloneSpecInfo(m_specInfo, depth);
return newPipeline;
}

constexpr static inline auto AssetType = ET_COMPUTE_PIPELINE;
inline E_TYPE getAssetType() const override { return AssetType; }

//!
inline size_t getDependantCount() const override {return 2;}
//!
inline size_t getDependantCount() const override { return 2; }

inline virtual std::span<SShaderSpecInfo> getSpecInfo(hlsl::ShaderStage stage) override final
{
if (stage==hlsl::ShaderStage::ESS_COMPUTE && isMutable())
return {&m_specInfo,1};
return {};
}

inline virtual bool valid() const override final
{
return m_specInfo.valid();
}

protected:
using base_t::base_t;
virtual ~ICPUComputePipeline() = default;

inline IAsset* getDependant_impl(const size_t ix) override
inline IAsset* getDependant_impl(const size_t ix) override
{
if (ix!=0)
return m_specInfo.shader.get();
return const_cast<ICPUPipelineLayout*>(m_layout.get());
}

inline bool setSpecInfo(const IPipelineBase::SShaderSpecInfo<true>& info)
{
const auto specSize = info.valid();
if (specSize < 0) return false;
if (info.stage != hlsl::ESS_COMPUTE) return false;
m_specInfo = info;
return true;
}

private:
SShaderSpecInfo<true> m_specInfo;
SShaderSpecInfo m_specInfo;

};

Expand Down
190 changes: 80 additions & 110 deletions include/nbl/asset/ICPUGraphicsPipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,135 +13,105 @@
namespace nbl::asset
{

class ICPUGraphicsPipeline final : public ICPUPipeline<IGraphicsPipeline<IPipelineBase::SShaderSpecInfo<true>, ICPUPipelineLayout,ICPURenderpass>>
class ICPUGraphicsPipeline final : public ICPUPipeline<IGraphicsPipeline<ICPUPipelineLayout,ICPURenderpass>>
{
using pipeline_base_t = IGraphicsPipeline<SShaderSpecInfo<true>,ICPUPipelineLayout, ICPURenderpass>;
using pipeline_base_t = IGraphicsPipeline<ICPUPipelineLayout, ICPURenderpass>;
using base_t = ICPUPipeline<pipeline_base_t>;

public:
struct SCreationParams final : pipeline_base_t::SCreationParams
{
private:
friend class ICPUGraphicsPipeline;
template<typename ExtraLambda>
inline bool impl_valid(ExtraLambda&& extra) const
{
return pipeline_base_t::SCreationParams::impl_valid(std::move(extra));
}
};

static core::smart_refctd_ptr<ICPUGraphicsPipeline> create(const SCreationParams& params)
{
// we'll validate the specialization info later when attempting to set it
if (!params.impl_valid([](const SShaderSpecInfo<true>& info)->bool{return true;}))
return nullptr;
auto retval = new ICPUGraphicsPipeline(params);
for (const auto spec : params.shaders)
explicit ICPUGraphicsPipeline(const ICPUPipelineLayout* layout)
: base_t(layout, {}, {})
{}

static core::smart_refctd_ptr<ICPUGraphicsPipeline> create(const ICPUPipelineLayout* layout)
{
if (spec.shader) retval->setSpecInfo(spec);
auto retval = new ICPUGraphicsPipeline(layout);
return core::smart_refctd_ptr<ICPUGraphicsPipeline>(retval,core::dont_grab);
}
return core::smart_refctd_ptr<ICPUGraphicsPipeline>(retval,core::dont_grab);
}

inline core::smart_refctd_ptr<IAsset> clone(uint32_t _depth = ~0u) const override final
{
core::smart_refctd_ptr<ICPUPipelineLayout> layout;
if (_depth>0u && m_layout)
layout = core::smart_refctd_ptr_static_cast<ICPUPipelineLayout>(m_layout->clone(_depth-1u));

auto* cp = [&] {
std::array<SShaderSpecInfo<true>, GRAPHICS_SHADER_STAGE_COUNT> _shaders;
inline base_t* clone_impl(core::smart_refctd_ptr<const ICPUPipelineLayout>&& layout, uint32_t depth) const override final
{
auto* newPipeline = new ICPUGraphicsPipeline(layout.get());
for (auto i = 0; i < GRAPHICS_SHADER_STAGE_COUNT; i++)
_shaders[i] = m_specInfos[i];
const SCreationParams params = { {
.shaders = _shaders,
.cached = m_params,
.renderpass = m_renderpass.get()
} };
return new ICPUGraphicsPipeline(params);
}();
for (auto specInfo : m_specInfos)
{
if (specInfo.shader)
newPipeline->m_specInfos[i] = m_specInfos[i];
newPipeline->m_params = m_params;
newPipeline->m_renderpass = m_renderpass;

for (auto specInfo_i = 0u; specInfo_i < m_specInfos.size(); specInfo_i++)
{
newPipeline->m_specInfos[specInfo_i] = newPipeline->cloneSpecInfo(m_specInfos[specInfo_i], depth);
}

return newPipeline;
}

constexpr static inline auto AssetType = ET_GRAPHICS_PIPELINE;
inline E_TYPE getAssetType() const override { return AssetType; }

inline size_t getDependantCount() const override
{
auto stageCount = 2; // the layout and renderpass
for (const auto& info : m_specInfos)
{
auto newSpecInfo = specInfo;
if (_depth>0u)
{
newSpecInfo.shader = core::smart_refctd_ptr_static_cast<IShader>(specInfo.shader->clone(_depth-1u));
}
cp->setSpecInfo(newSpecInfo);
if (info.shader)
stageCount++;
}
}

return core::smart_refctd_ptr<ICPUGraphicsPipeline>(cp,core::dont_grab);
}


constexpr static inline auto AssetType = ET_GRAPHICS_PIPELINE;
inline E_TYPE getAssetType() const override { return AssetType; }

inline size_t getDependantCount() const override
{
auto stageCount = 2; // the layout and renderpass
for (const auto& info : m_specInfos)
{
if (info.shader)
stageCount++;
}
return stageCount;
}

// extras for this class
inline const SCachedCreationParams& getCachedCreationParams() const {return base_t::getCachedCreationParams();}
return stageCount;
}

inline SCachedCreationParams& getCachedCreationParams()
{
assert(isMutable());
return m_params;
}

inline virtual std::span<SShaderSpecInfo> getSpecInfo(hlsl::ShaderStage stage) override final
{
const auto stageIndex = stageToIndex(stage);
if (isMutable() && stageIndex != -1)
{
return { &m_specInfos[stageIndex], 1 };
}
return {};
}

inline virtual bool valid() const override final
{
if (!m_layout) 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 isValidStagePresence(stagePresence, m_params.primitiveAssembly.primitiveType);
}

protected:
using base_t::base_t;
~ICPUGraphicsPipeline() = default;

inline IAsset* getDependant_impl(const size_t ix) override
{
if (ix==0)
return const_cast<ICPUPipelineLayout*>(m_layout.get());
if (ix==1)
return m_renderpass.get();
size_t stageCount = 0;
for (auto& specInfo : m_specInfos)
{
if (specInfo.shader)
using base_t::base_t;
virtual ~ICPUGraphicsPipeline() override = default;

inline IAsset* getDependant_impl(const size_t ix) override
{
if ((stageCount++)==ix-2)
return specInfo.shader.get();
if (ix==0)
return const_cast<ICPUPipelineLayout*>(m_layout.get());
if (ix==1)
return m_renderpass.get();
size_t stageCount = 0;
for (auto& specInfo : m_specInfos)
{
if (specInfo.shader)
if ((stageCount++)==ix-2) return specInfo.shader.get();
}
return nullptr;
}
}
return nullptr;
}

inline int8_t stageToIndex(const hlsl::ShaderStage stage) const
{
const auto stageIx = hlsl::findLSB(stage);
if (stageIx<0 || stageIx>= GRAPHICS_SHADER_STAGE_COUNT || hlsl::bitCount(stage)!=1)
return -1;
return stageIx;
}

inline bool setSpecInfo(const SShaderSpecInfo<true>& info)
{
assert(isMutable());
const auto specSize = info.valid();
if (specSize<0) return false;
const auto stage = info.stage;
const auto stageIx = stageToIndex(stage);
if (stageIx<0) return false;
m_specInfos[stageIx] = info;
return true;
}

SShaderSpecInfo<true> m_specInfos[GRAPHICS_SHADER_STAGE_COUNT];

std::array<SShaderSpecInfo, GRAPHICS_SHADER_STAGE_COUNT> m_specInfos;
};

}
Expand Down
Loading