Skip to content

Commit 94706a3

Browse files
authored
Merge pull request #1003 from Devsh-Graphics-Programming/pipeline-exec-info
Added support for VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES
2 parents e052156 + 83b2158 commit 94706a3

17 files changed

Lines changed: 299 additions & 17 deletions

include/nbl/asset/IPipeline.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@ namespace nbl::asset
2323
Vulkan supports multiple types of pipelines:
2424
- graphics pipeline
2525
- compute pipeline
26-
- TODO: Raytracing
26+
- raytracing pipeline
2727
*/
2828
class IPipelineBase
2929
{
3030
public:
3131
// TODO: tbf these shouldn't even be laying around in `nbl::asset`, we should probably move to `nbl::video::IGPUPipelineBase`
32-
enum class CreationFlags : uint64_t
32+
enum class CreationFlags : uint64_t
3333
{
3434
NONE = 0, // disallowed in maintanance5
3535
DISABLE_OPTIMIZATIONS = 1 << 0,
@@ -47,10 +47,8 @@ class IPipelineBase
4747
// This is for NV-raytracing extension. Now this is done via IDeferredOperation
4848
//DEFER_COMPILE_NV = 1<<5,
4949

50-
// We use Renderdoc to take care of this for us,
51-
// we won't be parsing the statistics and internal representation ourselves.
52-
//CAPTURE_STATISTICS = 1<<6,
53-
//CAPTURE_INTERNAL_REPRESENTATIONS = 1<<7,
50+
CAPTURE_STATISTICS = 1<<6,
51+
CAPTURE_INTERNAL_REPRESENTATIONS = 1<<7,
5452

5553
// Will soon be deprecated due to
5654
// https://github.com/Devsh-Graphics-Programming/Nabla/issues/854

include/nbl/asset/IRayTracingPipeline.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ class IRayTracingPipelineBase : public virtual core::IReferenceCounted
3131
NO_NULL_MISS_SHADERS = 1<<16,
3232
NO_NULL_INTERSECTION_SHADERS = 1<<17,
3333
ALLOW_MOTION = 1<<20,
34+
CAPTURE_STATISTICS = base_flag(CAPTURE_STATISTICS),
35+
CAPTURE_INTERNAL_REPRESENTATIONS = base_flag(CAPTURE_INTERNAL_REPRESENTATIONS),
3436
};
3537
#undef base_flag
3638

include/nbl/video/CVulkanRayTracingPipeline.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ class CVulkanRayTracingPipeline final : public IGPURayTracingPipeline
2525

2626
inline VkPipeline getInternalObject() const { return m_vkPipeline; }
2727

28+
void populateExecutableInfo(bool includeInternalRepresentations) override;
29+
2830
virtual const SShaderGroupHandle& getRaygen() const override;
2931
virtual std::span<const SShaderGroupHandle> getMissHandles() const override;
3032
virtual std::span<const SShaderGroupHandle> getHitHandles() const override;

include/nbl/video/IGPUComputePipeline.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ class IGPUComputePipeline : public IGPUPipeline<asset::IComputePipeline<const IG
3838
DISPATCH_BASE = 1<<4,
3939
FAIL_ON_PIPELINE_COMPILE_REQUIRED = base_flag(FAIL_ON_PIPELINE_COMPILE_REQUIRED),
4040
EARLY_RETURN_ON_FAILURE = base_flag(EARLY_RETURN_ON_FAILURE),
41+
CAPTURE_STATISTICS = base_flag(CAPTURE_STATISTICS),
42+
CAPTURE_INTERNAL_REPRESENTATIONS = base_flag(CAPTURE_INTERNAL_REPRESENTATIONS),
4143
// Not Supported Yet
4244
//CREATE_LIBRARY = base_flag(CREATE_LIBRARY),
4345
// Not Supported Yet

include/nbl/video/IGPUGraphicsPipeline.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ class IGPUGraphicsPipeline : public IGPUPipeline<asset::IGraphicsPipeline<const
2929
VIEW_INDEX_FROM_DEVICE_INDEX = 1<<3,
3030
FAIL_ON_PIPELINE_COMPILE_REQUIRED = base_flag(FAIL_ON_PIPELINE_COMPILE_REQUIRED),
3131
EARLY_RETURN_ON_FAILURE = base_flag(EARLY_RETURN_ON_FAILURE),
32+
CAPTURE_STATISTICS = base_flag(CAPTURE_STATISTICS),
33+
CAPTURE_INTERNAL_REPRESENTATIONS = base_flag(CAPTURE_INTERNAL_REPRESENTATIONS),
3234
};
3335
#undef base_flag
3436

include/nbl/video/IGPUPipeline.h

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "nbl/video/SPipelineCreationParams.h"
1111
#include "nbl/asset/ICPUPipeline.h"
1212
#include "nbl/asset/IPipeline.h"
13+
#include "nbl/system/to_string.h"
1314

1415
namespace nbl::video
1516
{
@@ -127,6 +128,21 @@ class IGPUPipelineBase {
127128

128129
using SShaderEntryMap = SShaderSpecInfo::entry_map_t;
129130

131+
// Per-executable info from VK_KHR_pipeline_executable_properties
132+
struct SExecutableInfo
133+
{
134+
std::string name;
135+
std::string description;
136+
core::bitflag<hlsl::ShaderStage> stages = hlsl::ShaderStage::ESS_UNKNOWN;
137+
uint32_t subgroupSize = 0;
138+
std::string statistics;
139+
std::string internalRepresentations;
140+
};
141+
142+
inline std::span<const SExecutableInfo> getExecutableInfo() const { return m_executableInfo; }
143+
144+
protected:
145+
core::vector<SExecutableInfo> m_executableInfo;
130146
};
131147

132148
// Common Base class for pipelines
@@ -142,6 +158,55 @@ class IGPUPipeline : public IBackendObject, public PipelineNonBackendObjectBase,
142158
{}
143159
virtual ~IGPUPipeline() = default;
144160

161+
virtual void populateExecutableInfo(bool includeInternalRepresentations) = 0;
162+
163+
};
164+
165+
}
166+
167+
namespace nbl::system::impl
168+
{
169+
170+
template<>
171+
struct to_string_helper<video::IGPUPipelineBase::SExecutableInfo>
172+
{
173+
static std::string __call(const video::IGPUPipelineBase::SExecutableInfo& info)
174+
{
175+
std::string result;
176+
result += "======== ";
177+
result += info.name;
178+
result += " ========\n";
179+
result += info.description;
180+
result += "\nSubgroup Size: ";
181+
result += std::to_string(info.subgroupSize);
182+
if (!info.statistics.empty())
183+
{
184+
result += "\n";
185+
result += info.statistics;
186+
}
187+
if (!info.internalRepresentations.empty())
188+
{
189+
result += "\n";
190+
result += info.internalRepresentations;
191+
}
192+
return result;
193+
}
194+
};
195+
196+
// Another version for core::vector?
197+
template<>
198+
struct to_string_helper<std::span<const video::IGPUPipelineBase::SExecutableInfo>>
199+
{
200+
static std::string __call(const std::span<const video::IGPUPipelineBase::SExecutableInfo>& infos)
201+
{
202+
std::string result;
203+
for (const auto& info : infos)
204+
{
205+
result += to_string_helper<video::IGPUPipelineBase::SExecutableInfo>::__call(info);
206+
result += "\n";
207+
}
208+
return result;
209+
}
145210
};
146211

147212
}

include/nbl/video/ILogicalDevice.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
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
@@ -1273,6 +1274,20 @@ class NBL_API2 ILogicalDevice : public core::IReferenceCounted, public IDeviceMe
12731274
return {};
12741275
}
12751276

1277+
// CAPTURE_STATISTICS and CAPTURE_INTERNAL_REPRESENTATIONS require pipelineExecutableInfo feature
1278+
constexpr auto CaptureStatsFlag = CreationParams::FLAGS::CAPTURE_STATISTICS;
1279+
constexpr auto CaptureIRFlag = CreationParams::FLAGS::CAPTURE_INTERNAL_REPRESENTATIONS;
1280+
if (ci.getFlags().hasFlags(CaptureStatsFlag) && !getEnabledFeatures().pipelineExecutableInfo)
1281+
{
1282+
NBL_LOG_ERROR("CAPTURE_STATISTICS flag requires `pipelineExecutableInfo` feature (params[%d])", i);
1283+
return {};
1284+
}
1285+
if (ci.getFlags().hasFlags(CaptureIRFlag) && !getEnabledFeatures().pipelineExecutableInfo)
1286+
{
1287+
NBL_LOG_ERROR("CAPTURE_INTERNAL_REPRESENTATIONS flag requires `pipelineExecutableInfo` feature (params[%d])", i);
1288+
return {};
1289+
}
1290+
12761291
retval += validation;
12771292
}
12781293
return retval;

src/nbl/video/CVulkanComputePipeline.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "nbl/video/CVulkanComputePipeline.h"
22

33
#include "nbl/video/CVulkanLogicalDevice.h"
4+
#include "nbl/video/CVulkanPipelineExecutableInfo.h"
45

56
namespace nbl::video
67
{
@@ -12,6 +13,12 @@ CVulkanComputePipeline::~CVulkanComputePipeline()
1213
vk->vk.vkDestroyPipeline(vulkanDevice->getInternalObject(), m_pipeline, nullptr);
1314
}
1415

16+
void CVulkanComputePipeline::populateExecutableInfo(bool includeInternalRepresentations)
17+
{
18+
const CVulkanLogicalDevice* vulkanDevice = static_cast<const CVulkanLogicalDevice*>(getOriginDevice());
19+
populateExecutableInfoFromVulkan(m_executableInfo, vulkanDevice->getFunctionTable(), vulkanDevice->getInternalObject(), m_pipeline, includeInternalRepresentations);
20+
}
21+
1522
void CVulkanComputePipeline::setObjectDebugName(const char* label) const
1623
{
1724
IBackendObject::setObjectDebugName(label);

src/nbl/video/CVulkanComputePipeline.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,18 @@ class CVulkanComputePipeline final : public IGPUComputePipeline
1717
CVulkanComputePipeline(
1818
const SCreationParams& params,
1919
const VkPipeline pipeline
20-
) : IGPUComputePipeline(params), m_pipeline(pipeline) {}
20+
) : IGPUComputePipeline(params), m_pipeline(pipeline)
21+
{
22+
if (params.flags.hasFlags(SCreationParams::FLAGS::CAPTURE_STATISTICS))
23+
populateExecutableInfo(params.flags.hasFlags(SCreationParams::FLAGS::CAPTURE_INTERNAL_REPRESENTATIONS));
24+
}
2125

2226
inline const void* getNativeHandle() const override { return &m_pipeline; }
2327

2428
inline VkPipeline getInternalObject() const { return m_pipeline; }
25-
29+
30+
void populateExecutableInfo(bool includeInternalRepresentations) override;
31+
2632
void setObjectDebugName(const char* label) const override;
2733

2834
private:

0 commit comments

Comments
 (0)