🌋

【Vulkan】UniformBufferよりも速くて簡単なPushConstantを使う

2022/04/30に公開

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