1414#include " nbl/video/IGPUCommandBuffer.h"
1515#include " nbl/video/CThreadSafeQueueAdapter.h"
1616#include " nbl/video/CJITIncludeLoader.h"
17+ #include " nbl/system/to_string.h"
1718
1819#include " git_info.h"
1920#define NBL_LOG_FUNCTION m_logger.log
@@ -1033,24 +1034,45 @@ class NBL_API2 ILogicalDevice : public core::IReferenceCounted, public IDeviceMe
10331034 const std::span<const IGPURayTracingPipeline::SCreationParams> params,
10341035 core::smart_refctd_ptr<IGPURayTracingPipeline>* const output);
10351036
1036- // Pipeline executable statistics report (VK_KHR_pipeline_executable_properties).
1037- // Pipeline must have been created with CAPTURE_STATISTICS flag.
1038- // If includeInternalRepresentations is true, also includes shader IR/assembly
1039- // (pipeline must have been created with CAPTURE_INTERNAL_REPRESENTATIONS flag).
1037+ // Per-executable info from VK_KHR_pipeline_executable_properties
1038+ struct SPipelineExecutableInfo
1039+ {
1040+ std::string name;
1041+ std::string description;
1042+ core::bitflag<hlsl::ShaderStage> stages = hlsl::ShaderStage::ESS_UNKNOWN;
1043+ uint32_t subgroupSize = 0 ;
1044+ std::string statistics;
1045+ std::string internalRepresentations;
1046+ };
1047+
1048+ // Query pipeline executable properties (VK_KHR_pipeline_executable_properties).
1049+ // Pipeline must have been created with CAPTURE_STATISTICS flag for statistics.
1050+ // Pipeline must have been created with CAPTURE_INTERNAL_REPRESENTATIONS flag for IR.
10401051 template <typename Pipeline>
1041- std::string getPipelineExecutableReport (const Pipeline* pipeline, bool includeInternalRepresentations = false )
1052+ core::vector<SPipelineExecutableInfo> getPipelineExecutableProperties (const Pipeline* pipeline, bool includeInternalRepresentations = false )
10421053 {
10431054 if (!pipeline)
10441055 {
10451056 NBL_LOG_ERROR (" Null pipeline" );
10461057 return {};
10471058 }
1048- if (!getEnabledFeatures ().pipelineExecutableInfo )
1059+ using flags_t = Pipeline::SCreationParams::FLAGS;
1060+ if (!pipeline->getCreationFlags ().hasFlags (flags_t ::CAPTURE_STATISTICS))
10491061 {
1050- NBL_LOG_ERROR (" Feature `pipelineExecutableInfo` is not enabled " );
1062+ NBL_LOG_ERROR (" Pipeline was not created with CAPTURE_STATISTICS flag " );
10511063 return {};
10521064 }
1053- return getPipelineExecutableReport_impl (pipeline->getNativeHandle (), includeInternalRepresentations);
1065+ if (includeInternalRepresentations && !pipeline->getCreationFlags ().hasFlags (flags_t ::CAPTURE_INTERNAL_REPRESENTATIONS))
1066+ {
1067+ NBL_LOG_ERROR (" Pipeline was not created with CAPTURE_INTERNAL_REPRESENTATIONS flag" );
1068+ return {};
1069+ }
1070+ auto properties = getPipelineExecutableProperties_impl (pipeline, includeInternalRepresentations);
1071+ if (properties.empty ())
1072+ {
1073+ NBL_LOG_ERROR (" Driver returned 0 executables for pipeline created with CAPTURE_STATISTICS flag. This pipeline type may not be supported by the driver's VK_KHR_pipeline_executable_properties implementation." );
1074+ }
1075+ return properties;
10541076 }
10551077
10561078 // queries
@@ -1293,6 +1315,20 @@ class NBL_API2 ILogicalDevice : public core::IReferenceCounted, public IDeviceMe
12931315 return {};
12941316 }
12951317
1318+ // CAPTURE_STATISTICS and CAPTURE_INTERNAL_REPRESENTATIONS require pipelineExecutableInfo feature
1319+ constexpr auto CaptureStatsFlag = CreationParams::FLAGS::CAPTURE_STATISTICS;
1320+ constexpr auto CaptureIRFlag = CreationParams::FLAGS::CAPTURE_INTERNAL_REPRESENTATIONS;
1321+ if (ci.getFlags ().hasFlags (CaptureStatsFlag) && !getEnabledFeatures ().pipelineExecutableInfo )
1322+ {
1323+ NBL_LOG_ERROR (" CAPTURE_STATISTICS flag requires `pipelineExecutableInfo` feature (params[%d])" , i);
1324+ return {};
1325+ }
1326+ if (ci.getFlags ().hasFlags (CaptureIRFlag) && !getEnabledFeatures ().pipelineExecutableInfo )
1327+ {
1328+ NBL_LOG_ERROR (" CAPTURE_INTERNAL_REPRESENTATIONS flag requires `pipelineExecutableInfo` feature (params[%d])" , i);
1329+ return {};
1330+ }
1331+
12961332 retval += validation;
12971333 }
12981334 return retval;
@@ -1316,7 +1352,9 @@ class NBL_API2 ILogicalDevice : public core::IReferenceCounted, public IDeviceMe
13161352 const SSpecializationValidationResult& validation
13171353 ) = 0;
13181354
1319- virtual std::string getPipelineExecutableReport_impl (const void * nativeHandle, bool includeInternalRepresentations) = 0;
1355+ virtual core::vector<SPipelineExecutableInfo> getPipelineExecutableProperties_impl (const IGPUComputePipeline* pipeline, bool includeInternalRepresentations) = 0;
1356+ virtual core::vector<SPipelineExecutableInfo> getPipelineExecutableProperties_impl (const IGPUGraphicsPipeline* pipeline, bool includeInternalRepresentations) = 0;
1357+ virtual core::vector<SPipelineExecutableInfo> getPipelineExecutableProperties_impl (const IGPURayTracingPipeline* pipeline, bool includeInternalRepresentations) = 0;
13201358
13211359 virtual core::smart_refctd_ptr<IQueryPool> createQueryPool_impl (const IQueryPool::SCreationParams& params) = 0;
13221360 virtual bool getQueryPoolResults_impl (const IQueryPool* const queryPool, const uint32_t firstQuery, const uint32_t queryCount, void * const pData, const size_t stride, const core::bitflag<IQueryPool::RESULTS_FLAGS> flags) = 0;
@@ -1627,5 +1665,51 @@ inline bool ILogicalDevice::validateMemoryBarrier(const uint32_t queueFamilyInde
16271665
16281666} // namespace nbl::video
16291667
1668+ namespace nbl ::system::impl
1669+ {
1670+
1671+ template <>
1672+ struct to_string_helper <video::ILogicalDevice::SPipelineExecutableInfo>
1673+ {
1674+ static std::string __call (const video::ILogicalDevice::SPipelineExecutableInfo& info)
1675+ {
1676+ std::string result;
1677+ result += " ======== " ;
1678+ result += info.name ;
1679+ result += " ========\n " ;
1680+ result += info.description ;
1681+ result += " \n Subgroup Size: " ;
1682+ result += std::to_string (info.subgroupSize );
1683+ if (!info.statistics .empty ())
1684+ {
1685+ result += " \n " ;
1686+ result += info.statistics ;
1687+ }
1688+ if (!info.internalRepresentations .empty ())
1689+ {
1690+ result += " \n " ;
1691+ result += info.internalRepresentations ;
1692+ }
1693+ return result;
1694+ }
1695+ };
1696+
1697+ template <>
1698+ struct to_string_helper <core::vector<video::ILogicalDevice::SPipelineExecutableInfo>>
1699+ {
1700+ static std::string __call (const core::vector<video::ILogicalDevice::SPipelineExecutableInfo>& infos)
1701+ {
1702+ std::string result;
1703+ for (const auto & info : infos)
1704+ {
1705+ result += to_string_helper<video::ILogicalDevice::SPipelineExecutableInfo>::__call (info);
1706+ result += " \n " ;
1707+ }
1708+ return result;
1709+ }
1710+ };
1711+
1712+ }
1713+
16301714#include " nbl/undef_logging_macros.h"
16311715#endif // _NBL_VIDEO_I_LOGICAL_DEVICE_H_INCLUDED_
0 commit comments