Skip to content

IShader, no more conversions, stage is now part of spec info. #839

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

Closed
wants to merge 69 commits into from
Closed
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
6fd47aa
first commit that turns IGPUShader and ICPUShader into one IShader an…
Feb 21, 2025
92a58ea
Asset Converter should work after this change
Feb 21, 2025
7e3d71c
correct the eggregious typos, add TODOs
Feb 21, 2025
2370636
touch up the Vulkan Pipelines to not hold onto shaders
Feb 21, 2025
38dd6e5
fix more typos, and add one more TODO
Feb 21, 2025
499f57b
Create pipeline now use spir-v directly
Mar 27, 2025
40d744e
Remove constructor. this overload conflict with another constructor.
Mar 27, 2025
e7beb7e
FIx spirv introspector
Mar 27, 2025
782bf4c
Fix CComputeBlit to use IShader
Mar 27, 2025
a2f7d91
Merge branch 'master' into stagesless_shaders
Mar 27, 2025
82dc575
Fix asset converter to support the new IShader
Mar 27, 2025
19b0c21
Fix NSC to use AssetMetadata to get shader stage
Mar 28, 2025
7be8def
use std::string_view for shader entry points
Apr 1, 2025
1a8ea98
remove getObjectDebugName from IShader
Apr 1, 2025
a428d4d
disable IShader patching
Apr 1, 2025
8028703
Disable IShader patching
Apr 1, 2025
36e6f33
Fix by adding static to getLoogingLabel
Apr 1, 2025
7c548b7
Enable HLSLMetadata to support multiple shader stages
Apr 1, 2025
64875ac
Expose more option in ISPIRVOptimizer
Apr 2, 2025
94cc246
Implement ISPIRVDebloater
Apr 2, 2025
565fd4a
expose dead constant elim optimization in ISPIRVOptimizer
Apr 2, 2025
08d4e70
Expose more options in ISPIRVOptimizer
Apr 2, 2025
0bf0601
make the noun plural in optimization pass
Apr 2, 2025
6ddea53
add more optimization pass to spirv debloater
Apr 2, 2025
31724ef
improve optimization name for trim capabilities. plural instead of si…
Apr 2, 2025
d5c6081
Add missing comma
Apr 7, 2025
cfb4bd1
Rework ISPIRVDebloater algorithm
Apr 7, 2025
48055b6
Move SPIRV_VERSION as constant
Apr 7, 2025
690cbb5
Validate entry points parameter
Apr 7, 2025
52c03a8
Handle unsupported execution model failure case
Apr 7, 2025
550dc3f
Fix wrong error log message placement
Apr 7, 2025
24d7f33
Refactor ISPIRVDebloater::Result naming and add operator bool
Apr 7, 2025
80297ed
Set default value for logger
Apr 7, 2025
247c7c3
Add comparison operator to EntryPoint so it can be inserterd to set
Apr 7, 2025
488d383
Implement more ergonomic overload
Apr 7, 2025
b1068a5
Move spirv debloater to ILogicalDevice
Apr 8, 2025
3e1b375
More fixes on moving ISPIRVDebloater to ILogicalDevice
Apr 8, 2025
c5b252b
Add agressive dce to optimization pass
Apr 8, 2025
9c9a742
Initialize m_spirvDebloater
Apr 8, 2025
78d20c2
Add dead member removal to the optimization pass.
Apr 8, 2025
5b119de
Add more optimization pass
Apr 9, 2025
a508eb1
Use core::set for entryPoints in debloat
Apr 11, 2025
f0eef49
improve naming from shaderStage to stage
Apr 11, 2025
d226301
Improve spirv optimizer passes mapping logic
Apr 11, 2025
7c43412
Remove spirv override argument
Apr 11, 2025
419016b
Add comment about spirv layout
Apr 11, 2025
7258912
Fix debloat by adding const to return type
Apr 11, 2025
2b85156
Pass reserved vector instead of pointer to shader when debloating
Apr 11, 2025
1670efa
Merge branch 'master' into stagesless_shaders
Apr 11, 2025
da73442
Some fixes to make nabla compile after merging with ray tracing pipel…
Apr 14, 2025
0ec9cf1
run debloat shaders on each module instead of each entry point
Apr 14, 2025
d18de3b
Refactor ray tracing to use SPIRVDebloater
Apr 14, 2025
597516f
Remove unfoundEntryPoint and use a counter to make it more efficient
Apr 14, 2025
9f3f823
print debug information in spirv debloater in debug mode
Apr 14, 2025
2e89fa2
Fix spirvdebloater when debloat is not needed
Apr 15, 2025
4d5af4e
Fix optimizer to remove array maps.
Apr 16, 2025
977c92e
Add inline modifier
Apr 16, 2025
7675c23
Validate that shader is spirv
Apr 16, 2025
716330c
Return null shader when spirv is null instead of shader that contain …
Apr 16, 2025
44a09a9
Fix some logic regarding entry point collection when debloating
Apr 16, 2025
4295b84
Fix SPIRVIntrospector use IShader
Apr 16, 2025
eda3310
Add assert that reserve is working for outShaders
Apr 16, 2025
4e8f41c
Remove IShader as template parameter for IRayTracingPipeline
Apr 16, 2025
2560e3e
Merge branch 'master' into stagesless_shaders
Apr 20, 2025
2b90640
Ray Tracing Pipeline interface does not need ShaderType
Apr 21, 2025
659ac5a
Add validate option to skip block layout validation
Apr 23, 2025
def49f7
Set pipeline name from shader
Apr 23, 2025
8d608bd
Merge branch 'master' into stagesless_shaders
May 13, 2025
7d6ede4
Fix outputReverseMap so it can hold IShader
May 13, 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
26 changes: 13 additions & 13 deletions include/nbl/asset/IRayTracingPipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class IRayTracingPipeline : public IPipeline<PipelineLayoutType>, public IRayTra
#undef base_flag

protected:
using SpecInfo = ShaderType::SSpecInfo;
using SpecInfo = IPipelineBase::SShaderSpecInfo;
template<typename ExtraLambda>
inline bool impl_valid(ExtraLambda&& extra) const
{
Expand All @@ -94,10 +94,10 @@ class IRayTracingPipeline : public IPipeline<PipelineLayoutType>, public IRayTra
{
if (!extra(info))
return false;
const auto stage = info.shader->getStage();
if ((stage & ~ICPUShader::E_SHADER_STAGE::ESS_ALL_RAY_TRACING) != 0)
const auto stage = info.stage;
if ((stage & ~IShader::E_SHADER_STAGE::ESS_ALL_RAY_TRACING) != 0)
return false;
if (!std::has_single_bit<std::underlying_type_t<ICPUShader::E_SHADER_STAGE>>(stage))
if (!std::has_single_bit<std::underlying_type_t<IShader::E_SHADER_STAGE>>(stage))
return false;
}
else
Expand All @@ -107,12 +107,12 @@ class IRayTracingPipeline : public IPipeline<PipelineLayoutType>, public IRayTra
}
}

auto getShaderStage = [this](size_t index) -> ICPUShader::E_SHADER_STAGE
auto getShaderStage = [this](size_t index) -> IShader::E_SHADER_STAGE
{
return shaders[index].shader->getStage();
return shaders[index].stage;
};

auto isValidShaderIndex = [this, getShaderStage](size_t index, ICPUShader::E_SHADER_STAGE expectedStage, bool is_unused_shader_forbidden) -> bool
auto isValidShaderIndex = [this, getShaderStage](size_t index, IShader::E_SHADER_STAGE expectedStage, bool is_unused_shader_forbidden) -> bool
{
if (index == SShaderGroupsParams::SIndex::Unused)
return !is_unused_shader_forbidden;
Expand All @@ -123,7 +123,7 @@ class IRayTracingPipeline : public IPipeline<PipelineLayoutType>, public IRayTra
return true;
};

if (!isValidShaderIndex(shaderGroups.raygen.index, ICPUShader::E_SHADER_STAGE::ESS_RAYGEN, true))
if (!isValidShaderIndex(shaderGroups.raygen.index, IShader::E_SHADER_STAGE::ESS_RAYGEN, true))
{
return false;
}
Expand All @@ -132,33 +132,33 @@ class IRayTracingPipeline : public IPipeline<PipelineLayoutType>, public IRayTra
{
// https://docs.vulkan.org/spec/latest/chapters/pipelines.html#VUID-VkRayTracingPipelineCreateInfoKHR-flags-03470
if (!isValidShaderIndex(shaderGroup.anyHit,
ICPUShader::E_SHADER_STAGE::ESS_ANY_HIT,
IShader::E_SHADER_STAGE::ESS_ANY_HIT,
bool(flags & FLAGS::NO_NULL_ANY_HIT_SHADERS)))
return false;

// https://docs.vulkan.org/spec/latest/chapters/pipelines.html#VUID-VkRayTracingPipelineCreateInfoKHR-flags-03471
if (!isValidShaderIndex(shaderGroup.closestHit,
ICPUShader::E_SHADER_STAGE::ESS_CLOSEST_HIT,
IShader::E_SHADER_STAGE::ESS_CLOSEST_HIT,
bool(flags & FLAGS::NO_NULL_CLOSEST_HIT_SHADERS)))
return false;

if (!isValidShaderIndex(shaderGroup.intersection,
ICPUShader::E_SHADER_STAGE::ESS_INTERSECTION,
IShader::E_SHADER_STAGE::ESS_INTERSECTION,
false))
return false;
}

for (const auto& shaderGroup : shaderGroups.misses)
{
if (!isValidShaderIndex(shaderGroup.index,
ICPUShader::E_SHADER_STAGE::ESS_MISS,
IShader::E_SHADER_STAGE::ESS_MISS,
false))
return false;
}

for (const auto& shaderGroup : shaderGroups.callables)
{
if (!isValidShaderIndex(shaderGroup.index, ICPUShader::E_SHADER_STAGE::ESS_CALLABLE, false))
if (!isValidShaderIndex(shaderGroup.index, IShader::E_SHADER_STAGE::ESS_CALLABLE, false))
return false;
}
return true;
Expand Down
2 changes: 1 addition & 1 deletion include/nbl/asset/utils/ISPIRVDebloater.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class ISPIRVDebloater final : public core::IReferenceCounted
{
const auto buffer = shader->getContent();
const auto result = debloat(buffer, entryPoints, logger);
if (result && result.spirv.get() != nullptr)
if (result && result.spirv.get() == nullptr)
{
return core::smart_refctd_ptr<const IShader>(shader);
}
Expand Down
6 changes: 0 additions & 6 deletions include/nbl/video/CVulkanRayTracingPipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,11 @@

#include "nbl/video/IGPURayTracingPipeline.h"

#include "nbl/video/CVulkanShader.h"


namespace nbl::video
{

class CVulkanRayTracingPipeline final : public IGPURayTracingPipeline
{
using ShaderRef = core::smart_refctd_ptr<const CVulkanShader>;
using ShaderContainer = core::smart_refctd_dynamic_array<ShaderRef>;
using GeneralGroupStackSizeContainer = core::smart_refctd_dynamic_array<uint16_t>;
using HitGroupStackSizeContainer = core::smart_refctd_dynamic_array<SHitGroupStackSize>;

Expand Down Expand Up @@ -45,7 +40,6 @@ class CVulkanRayTracingPipeline final : public IGPURayTracingPipeline
~CVulkanRayTracingPipeline() override;

const VkPipeline m_vkPipeline;
ShaderContainer m_shaders;
ShaderGroupHandleContainer m_shaderGroupHandles;
uint16_t m_raygenStackSize;
core::smart_refctd_dynamic_array<uint16_t> m_missStackSizes;
Expand Down
8 changes: 4 additions & 4 deletions include/nbl/video/IGPURayTracingPipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
namespace nbl::video
{

class IGPURayTracingPipeline : public IBackendObject, public asset::IRayTracingPipeline<const IGPUPipelineLayout, const IGPUShader>
class IGPURayTracingPipeline : public IBackendObject, public asset::IRayTracingPipeline<const IGPUPipelineLayout, const asset::IShader>
{
using pipeline_t = asset::IRayTracingPipeline<const IGPUPipelineLayout,const IGPUShader>;
using pipeline_t = asset::IRayTracingPipeline<const IGPUPipelineLayout,const asset::IShader>;

public:

Expand Down Expand Up @@ -42,7 +42,7 @@ class IGPURayTracingPipeline : public IBackendObject, public asset::IRayTracingP
.count=0,
.dataSize=0,
};
const bool valid = pipeline_t::SCreationParams::impl_valid([&retval](const IGPUShader::SSpecInfo& info)->bool
const bool valid = pipeline_t::SCreationParams::impl_valid([&retval](const SShaderSpecInfo& info)->bool
{
const auto dataSize = info.valid();
if (dataSize<0)
Expand All @@ -61,7 +61,7 @@ class IGPURayTracingPipeline : public IBackendObject, public asset::IRayTracingP
return retval;
}

inline std::span<const IGPUShader::SSpecInfo> getShaders() const { return shaders; }
inline std::span<const SShaderSpecInfo> getShaders() const { return shaders; }

};

Expand Down
50 changes: 20 additions & 30 deletions src/nbl/asset/utils/ISPIRVDebloater.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
#include "nbl/system/ILogger.h"
#include "spirv-tools/libspirv.hpp"

#include <iostream>

using namespace nbl::asset;

static constexpr spv_target_env SPIRV_VERSION = spv_target_env::SPV_ENV_UNIVERSAL_1_6;
Expand All @@ -28,21 +26,21 @@ ISPIRVDebloater::ISPIRVDebloater()
}

// This is for debugging temporarily. will be reworked after finish testing
static void printCapabilities(const uint32_t* spirv, uint32_t spirvDwordCount)
static void printCapabilities(const uint32_t* spirv, uint32_t spirvDwordCount,nbl::system::logger_opt_ptr logger)
{
spvtools::SpirvTools core(SPV_ENV_UNIVERSAL_1_6);
spvtools::SpirvTools core(SPIRV_VERSION);
std::string disassembly;
core.Disassemble(spirv, spirvDwordCount, &disassembly, SPV_BINARY_TO_TEXT_OPTION_NO_HEADER);
std::stringstream ss(disassembly);
std::string to;
const auto stringsToFind = std::array{ "OpCapability", "= OpFunction", "= OpRayQueryGetIntersectionTriangleVertexPositionsKHR", "OpFunctionEnd", "OpSpecConstant", "=OpType", "OpName" };
while(std::getline(ss,to,'\n')){
const auto stringsToFind = std::array{ "OpCapability", "= OpFunction","OpFunctionEnd", "OpSpecConstant", "=OpType"};
while(std::getline(ss, to, '\n')){
if (to.size() > 1 && to.back() == ',') continue;
for (const auto& stringToFind: stringsToFind)
{
if (to.find(stringToFind) != std::string::npos)
{
std::cout << to <<std::endl;
logger.log("%s", nbl::system::ILogger::ELL_DEBUG, to.c_str());
}
}
}
Expand Down Expand Up @@ -82,9 +80,6 @@ ISPIRVDebloater::Result ISPIRVDebloater::debloat(const ICPUBuffer* spirvBuffer,
const auto* spirv = static_cast<const uint32_t*>(spirvBuffer->getPointer());
const auto spirvDwordCount = spirvBuffer->getSize() / 4;

std::cout << "Before strip capabilities: " << std::endl;
printCapabilities(spirv, spirvDwordCount);

if (entryPoints.empty())
{
logger.log("Cannot retain zero multiple entry points!", system::ILogger::ELL_ERROR);
Expand All @@ -94,20 +89,7 @@ ISPIRVDebloater::Result ISPIRVDebloater::debloat(const ICPUBuffer* spirvBuffer,
};
}

// We will remove found entry point one by one. We set all entry points as unfound initially
core::set<EntryPoint> unfoundEntryPoints;
for (const auto& entryPoint : entryPoints)
{
if (unfoundEntryPoints.find(entryPoint) != unfoundEntryPoints.end())
{
logger.log("Cannot retain multiple entry points with the same name and stage!", system::ILogger::ELL_ERROR);
return Result{
nullptr,
false
};
}
unfoundEntryPoints.insert(entryPoint);
}
auto foundEntryPoint = 0;

const bool isInputSpirvValid = validate(spirv, spirvDwordCount, logger);
if (!isInputSpirvValid)
Expand Down Expand Up @@ -194,10 +176,10 @@ ISPIRVDebloater::Result ISPIRVDebloater::debloat(const ICPUBuffer* spirvBuffer,
};
}

auto findEntryPointIt = unfoundEntryPoints.find(entryPoint);
if (findEntryPointIt != unfoundEntryPoints.end())
auto findEntryPointIt = entryPoints.find(entryPoint);
if (findEntryPointIt != entryPoints.end())
{
unfoundEntryPoints.erase(findEntryPointIt);
foundEntryPoint += 1; // a valid spirv will have unique entry points, so this should works
} else
{
if (needDebloat == false)
Expand All @@ -213,7 +195,7 @@ ISPIRVDebloater::Result ISPIRVDebloater::debloat(const ICPUBuffer* spirvBuffer,
minimizedSpirv.insert(minimizedSpirv.end(), spirv + curOffset, spirv + offset);
}

const auto wereAllEntryPointsFound = unfoundEntryPoints.empty();
const auto wereAllEntryPointsFound = foundEntryPoint == entryPoints.size();
if (!wereAllEntryPointsFound)
{
logger.log("Some entry point that is requested to be retained is not found in SPIR-V", system::ILogger::ELL_ERROR);
Expand Down Expand Up @@ -252,10 +234,18 @@ ISPIRVDebloater::Result ISPIRVDebloater::debloat(const ICPUBuffer* spirvBuffer,
assert(validate(minimizedSpirv.data(), minimizedSpirv.size(), logger));

auto debloatedSpirv = m_optimizer->optimize(minimizedSpirv.data(), minimizedSpirv.size(), logger);

#ifdef _NBL_DEBUG
logger.log("Before stripping capabilities:", nbl::system::ILogger::ELL_DEBUG);
printCapabilities(spirv, spirvDwordCount, logger);
logger.log("\n", nbl::system::ILogger::ELL_DEBUG);

const auto* debloatedSpirvBuffer = static_cast<const uint32_t*>(debloatedSpirv->getPointer());
const auto debloatedSpirvDwordCount = debloatedSpirv->getSize() / 4;
std::cout << "After strip capabilities: " << std::endl;
printCapabilities(debloatedSpirvBuffer, debloatedSpirvDwordCount);
logger.log("After stripping capabilities:", nbl::system::ILogger::ELL_DEBUG);
printCapabilities(debloatedSpirvBuffer, debloatedSpirvDwordCount, logger);
logger.log("\n", nbl::system::ILogger::ELL_DEBUG);
#endif

return {
.spirv = std::move(debloatedSpirv),
Expand Down
6 changes: 5 additions & 1 deletion src/nbl/video/CVulkanLogicalDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1466,6 +1466,8 @@ void CVulkanLogicalDevice::createRayTracingPipelines_impl(
for (const auto& info : createInfos)
maxShaderGroups += info.shaderGroups.getShaderGroupCount();
core::vector<VkRayTracingPipelineCreateInfoKHR> vk_createInfos(createInfos.size(), { VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_KHR,nullptr });
core::vector<VkShaderModuleCreateInfo> vk_shaderModule(maxShaderStages,{VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,nullptr, 0});
core::vector<std::string> entryPoints(maxShaderStages);
core::vector<VkPipelineShaderStageRequiredSubgroupSizeCreateInfo> vk_requiredSubgroupSize(maxShaderStages,{
VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO,nullptr
});
Expand All @@ -1476,6 +1478,8 @@ void CVulkanLogicalDevice::createRayTracingPipelines_impl(
core::vector<uint8_t> specializationData(validation.dataSize);

auto outCreateInfo = vk_createInfos.data();
auto outShaderModule = vk_shaderModule.data();
auto outEntryPoints = entryPoints.data();
auto outRequiredSubgroupSize = vk_requiredSubgroupSize.data();
auto outShaderStage = vk_shaderStage.data();
auto outShaderGroup = vk_shaderGroup.data();
Expand Down Expand Up @@ -1514,7 +1518,7 @@ void CVulkanLogicalDevice::createRayTracingPipelines_impl(
outCreateInfo->pStages = outShaderStage;
for (const auto& specInfo : info.shaders)
{
*(outShaderStage++) = getVkShaderStageCreateInfoFrom(specInfo,outRequiredSubgroupSize,outSpecInfo,outSpecMapEntry,outSpecData);
*(outShaderStage++) = getVkShaderStageCreateInfoFrom(specInfo, outShaderModule, outEntryPoints, outRequiredSubgroupSize, outSpecInfo,outSpecMapEntry,outSpecData);
}
outCreateInfo->stageCount = std::distance<decltype(outCreateInfo->pStages)>(outCreateInfo->pStages,outShaderStage);
assert(outCreateInfo->stageCount != 0);
Expand Down
4 changes: 0 additions & 4 deletions src/nbl/video/CVulkanRayTracingPipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,11 @@ namespace nbl::video
ShaderGroupHandleContainer&& shaderGroupHandles) :
IGPURayTracingPipeline(params),
m_vkPipeline(vk_pipeline),
m_shaders(core::make_refctd_dynamic_array<ShaderContainer>(params.shaders.size())),
m_missStackSizes(core::make_refctd_dynamic_array<GeneralGroupStackSizeContainer>(params.shaderGroups.misses.size())),
m_hitGroupStackSizes(core::make_refctd_dynamic_array<HitGroupStackSizeContainer>(params.shaderGroups.hits.size())),
m_callableStackSizes(core::make_refctd_dynamic_array<GeneralGroupStackSizeContainer>(params.shaderGroups.hits.size())),
m_shaderGroupHandles(std::move(shaderGroupHandles))
{
for (size_t shaderIx = 0; shaderIx < params.shaders.size(); shaderIx++)
m_shaders->operator[](shaderIx) = ShaderRef(static_cast<const CVulkanShader*>(params.shaders[shaderIx].shader));

const auto* vulkanDevice = static_cast<const CVulkanLogicalDevice*>(getOriginDevice());
auto* vk = vulkanDevice->getFunctionTable();

Expand Down
Loading