Intel® Graphics Performance Analyzers Utilities for Vulkan* aims to lower the barrier of entry to working with Vulkan by providing developer friendly abstractions. If you’ve spent any time working with Vulkan, the modern open standard for 3D graphics and computing, you’ve likely run into some common pain points. Vulkan’s verbosity and minimal C interface leave plenty of room for user error. While the validation layer is a great tool for tracking down code that does not follow the specification, it’s only useful after the code is written.
Intel® GPA Utilities for Vulkan* empowers developers by assisting in writing compliant code from the start. This is accomplished via initializers for Vulkan structures, reference-counted Vulkan objects, automatic resource creation for common use cases, deep comparisons for Vulkan structures, and more.
Consider VkFramebuffer. This is a complex object comprised of a VkRenderPass and some number of VkImageViews, which themselves reference VkImage objects bound to various VkDeviceMemory objects. These all need to be compatible with each other and with the VkPipelines they’ll be used with. A frequent need in Intel® GPA's Graphics Frame Analyzer is to mirror the behavior of a tooled application as closely as possible with a set of modifications applied. Managing this complexity for both correctness and lifetime becomes difficult quickly. Here’s a short example illustrating how some of this complexity can be abstracted…
VkResult create_render_target_with_custom_attachments(
const gvk::Framebuffer& applicationFramebuffer,
const std::vector<VkImageView>& customAttachments,
gvk::RenderTarget* pRenderTarget
)
{
// gvk handles provide a templatized get<>() to retrieve various pieces of data
// such as create infos, parent handles, etc.
auto framebufferCreateInfo = applicationFramebuffer.get<VkFramebufferCreateInfo>();
// We'll replace the provided attachments with our own. Note that we could be
// using framebufferCreateInfo.get<const std::vector<gvk::ImageView>&>() or
// framebufferCreateInfo.get<gvk::RenderPass>() to inspect the application
// object for more detail...in this case we'll allow RenderTarget creation to
// take care of creating any necessary resources that we didn't provide.
framebufferCreateInfo.attachmentCount = customAttachments.size();
framebufferCreateInfo.pAttachments = customAttachments.data();
// Here we're using gvk::get_default<>() with a gvk type, but it also works for
// vk types...in general it sets up objects with sensible defaults and sTypes
// where appropriate.
auto renderTargetCreateInfo = gvk::get_default<gvk::RenderTarget::CreateInfo>();
renderTargetCreateInfo.pFramebufferCreateInfo = &framebufferCreateInfo;
// After resource creation, object sharing with other systems is straightforward
// since gvk handles maintain reference counts. Note that nothing prevents a
// gvk::RenderTarget from referencing a raw VkImageView(s), but lifetime will
// not be managed.
const auto& device = applicationFramebuffer.get<gvk::Device>();
return gvk::RenderTarget::create(device, &renderTargetCreateInfo, nullptr, pRenderTarget);
}
Utilities are also provided for working with SPIR-V using glslang and SPIRV-Cross…
// We start by preparing a gvk::spirv::ShaderInfo object.
gvk::spirv::ShaderInfo shaderInfo { };
shaderInfo.language = gvk::spirv::ShadingLanguage::Glsl;
shaderInfo.stage = VK_SHADER_STAGE_RAYGEN_BIT_KHR;
shaderInfo.lineOffset = __LINE__;
shaderInfo.source = R"(
// FROM : https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VK_KHR_ray_tracing_pipeline.html
#version 460 core
#extension GL_EXT_ray_tracing : require
layout(set = 0, binding = 0, rgba8) uniform image2D image;
layout(set = 0, binding = 1) uniform accelerationStructureEXT accelerationStructure;
layout(location = 0) rayPayloadEXT float payload;
void main()
{
}
)";
// Create a gvk::spirv::Context and compile the shader (error checking omitted).
// Internally, gvk::spirv::Context uses glslang to compile the provided GLSL
// (and in the future HLSL) to SPIR-V.
gvk::spirv::Context spirvContext;
gvk::spirv::Context::create(&gvk::get_default<gvk::spirv::Context::CreateInfo>(), &spirvContext);
spirvContext.compile(&shaderInfo);
// Prepare a gvk::spirv::BindingInfo with our shader(s). SPIRV-Cross is used
// internally to reflect the SPIR-V and provide VkDescriptorSetLayoutBindings.
auto bindingInfo = gvk::get_default<gvk::spirv::BindingInfo>();
bindingInfo.add_shader(shaderInfo);
// Now we create a gvk::PipelineLayout using the gvk::spirv::BindingInfo that
// will have one binding of type VK_DESCRIPTOR_TYPE_STORAGE_IMAGE and one of
// type VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR.
gvk::PipelineLayout pipelineLayout;
gvk::spirv::create_pipeline_layout(device, bindingInfo, nullptr, &pipelineLayout);
Linking into an existing CMake project utilizes CMake’s FetchContent module. Somewhere in your CMakeLists, add the following...
include(FetchContent)
set(GVK_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(GVK_BUILD_SAMPLES OFF CACHE BOOL "" FORCE)
FetchContent_Declare(
gvk
GIT_REPOSITORY "https://github.com/intel/gvk.git"
GIT_TAG <desired commit hash/tag>
)
FetchContent_MakeAvailable(gvk)
…then…
target_link_libraries(someTarget PUBLIC gvk)
…or link individual modules…
target_link_libraries(someTarget PUBLIC gvk-core gvk-xml)
Everything in the project is generated from the Vulkan XML specification. This ensures that the library stays up to date with the Vulkan API, including extensions, promotions, deprecations, etc. The XML parser and code generation utilities used by the project are also made available for any consuming projects.
Intel® GPA Utilities for Vulkan* is an open-source toolset. We welcome contributions from the community. Keep an eye on https://github.com/intel/gvk and Intel(R) GPA Framework for updates and more info…this project is in its early days and there’s more coming down the pipeline to assist Vulkan developers in their day-to-day engineering.
Notices & Disclaimers
Intel technologies may require enabled hardware, software or service activation.
No product or component can be absolutely secure.
Your costs and results may vary.
© Intel Corporation. Intel, the Intel logo, and other Intel marks are trademarks of Intel Corporation or its subsidiaries. Other names and brands may be claimed as the property of others.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.