【Vulkan】シェーダリフレクションで手動バインディングから解放されたい
10319 ワード
シェーダとC++間のバインディングを手作業で一致させるのは大変つらい気持ちになります。
こんな感じ。
sample.rgen
#version 460
#extension GL_EXT_ray_tracing : enable
layout(binding = 0, set = 0) uniform accelerationStructureEXT topLevelAS;
layout(binding = 1, set = 0, rgba8) uniform image2D inputImage;
void main()
{
}
sample.cpp
std::vector<vk::DescriptorSetLayoutBinding> bindings{
{ 0, vk::DescriptorType::eAccelerationStructureKHR,
1, vk::ShaderStageFlagBits::eRaygenKHR},
{ 1, vk::DescriptorType::eStorageImage,
1, vk::ShaderStageFlagBits::eRaygenKHR},
};
なのでSPIRV-Crossを使って、シェーダからバインディング情報を取得しましょう。
こんな感じ。
#include <spirv_glsl.hpp>
// spirvコードを読み込む
std::vector<unsigned int> code = readFile("...");
// 今回は数字ではなく変数名で対応をとれるようにしてみます
std::unordered_map<std::string, vk::DescriptorSetLayoutBinding> bindingMap;
// 情報を取得する
spirv_cross::CompilerGLSL glsl{ spvShader };
spirv_cross::ShaderResources resources = glsl.get_shader_resources();
for (auto&& resource : resources.acceleration_structures) {
vk::DescriptorSetLayoutBinding binding;
binding.binding = glsl.get_decoration(resource.id, spv::DecorationBinding);
binding.descriptorType = vk::DescriptorType::eAccelerationStructureKHR;
map[resource.name] = binding;
}
for (auto&& resource : resources.storage_images) {
vk::DescriptorSetLayoutBinding binding;
binding.binding = glsl.get_decoration(resource.id, spv::DecorationBinding);
binding.descriptorType = vk::DescriptorType::eStorageImage;
map[resource.name] = binding;
}
// ...他のリソースも同様
こうすれば、バインディングの数値から解放され、以下のような使い方が可能になります。番号だけでなくディスクリプタタイプなども取れるので、いろいろ手間が省けます。
// 疑似コード
Accel accel;
Image image;
DescriptorSet descSet;
descSet.update(bindingMap["topLevelAS"], accel);
descSet.update(bindingMap["inputImage"], image);
嬉しい!
おわり。
Author And Source
この問題について(【Vulkan】シェーダリフレクションで手動バインディングから解放されたい), 我々は、より多くの情報をここで見つけました https://zenn.dev/nishiki/articles/15df3ab1837df8著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Collection and Share based on the CC protocol