🌋
【Vulkan】UniformBufferよりも速くて簡単なPushConstantを使う
PushConstant
VulkanにはGPUにデータを高速にプッシュできるPushConstantとかいうのがあります。セットアップもかなり簡単なので最高です。ただしサイズが小さいという制限があります。
とはいえ全てのデバイスで 128 bytes は保証されていますので、そこそこ使えますね。実際にクエリしてみると RTX3090 では最大 256 bytes でした。
auto props = physicalDevice.getProperties();
std::cout << "maxPushConstantsSize: " << props.limits.maxPushConstantsSize;
// maxPushConstantsSize: 256
セットアップ
例としてCompute shaderを使います。
シェーダ
マウス位置などを入力してみます。超シンプルで、binding
とかも必要ありません。
sample.comp
layout(push_constant) uniform PushConstants {
vec2 mousePosition;
vec2 mouseMove;
} pushConstant;
C++側で構造体を作る
struct PushConstants
{
float mousePosition[2];
float mouseMove[2];
};
PushConstants pushConstants;
PipelineLayout作成時にPushConstantRangeを渡す
vk::PushConstantRange pushRange;
pushRange.setOffset(0);
pushRange.setSize(sizeof(PushConstants));
pushRange.setStageFlags(vk::ShaderStageFlagBits::eCompute);
vk::PipelineLayoutCreateInfo createInfo;
createInfo.setSetLayouts(*descSetLayout);
createInfo.setPushConstantRanges(pushRange);
vk::PipelineLayout pipelineLayout = device.createPipelineLayout(createInfo);
コマンドバッファにお願いする
commandBuffer.pushConstants(
*pipelineLayout,
vk::ShaderStageFlagBits::eCompute,
0, sizeof(PushConstants), &pushConstants);
おわりです。めっちゃ簡単。
Discussion