载入中...
搜索中...
未找到
VulkanComputeShader.cpp
浏览该文件的文档.
3
4#include "common/Exception.h"
5
6#include <array>
7
8namespace eve::gpgpu {
9
11 if (!device_ || !static_cast<VkDevice>(device_->instance)) return;
12 auto &dev = *device_;
13 if (pipeline_) {
14 dev->destroyPipeline(pipeline_, device_->allocation_callbacks);
15 pipeline_ = vk::Pipeline{};
16 }
17 if (pipelineLayout_) {
18 dev->destroyPipelineLayout(pipelineLayout_, device_->allocation_callbacks);
19 pipelineLayout_ = vk::PipelineLayout{};
20 }
21 if (setLayout_) {
22 dev->destroyDescriptorSetLayout(setLayout_, device_->allocation_callbacks);
23 setLayout_ = vk::DescriptorSetLayout{};
24 }
25 if (descriptorPool_) {
26 // Sets allocated from the pool are freed with it.
27 dev->destroyDescriptorPool(descriptorPool_, device_->allocation_callbacks);
28 descriptorPool_ = vk::DescriptorPool{};
29 descriptorSet_ = vk::DescriptorSet{};
30 }
31 if (module_) {
32 dev->destroyShaderModule(module_, device_->allocation_callbacks);
33 module_ = vk::ShaderModule{};
34 }
35 if (dummyBuffer_) {
36#if defined(VKB_ENABLE_VMA)
37 if (dummyVmaAllocation_) {
38 vmaDestroyBuffer(device_->vma_allocator, static_cast<VkBuffer>(dummyBuffer_),
39 dummyVmaAllocation_);
40 dummyVmaAllocation_ = VK_NULL_HANDLE;
41 dummyBuffer_ = vk::Buffer{};
42 dummyMemory_ = vk::DeviceMemory{};
43 } else
44#endif
45 {
46 dev->destroyBuffer(dummyBuffer_, device_->allocation_callbacks);
47 dummyBuffer_ = vk::Buffer{};
48 }
49 }
50 if (dummyMemory_) {
51 dev->freeMemory(dummyMemory_, device_->allocation_callbacks);
52 dummyMemory_ = vk::DeviceMemory{};
53 }
54 device_ = nullptr;
55}
56
58 if (binding < 0 || binding >= kMaxBindings) return;
59 bindings_[size_t(binding)] = buffer;
60 descriptorsDirty_ = true;
61}
62
64 if (binding < 0 || binding >= kMaxBindings) return nullptr;
65 return bindings_[size_t(binding)];
66}
67
69 if (index < 0 || index >= kMaxFloats) return;
70 push_[size_t(index)] = value;
71}
72
74 if (index < 0 || index >= kMaxFloats) return 0.f;
75 return push_[size_t(index)];
76}
77
79 bindings_.fill(nullptr);
80 descriptorsDirty_ = true;
81}
82
84 if (!descriptorsDirty_ && descriptorSet_) return;
85
86 if (!descriptorPool_) {
87 // maxSets sets x kMaxBindings storage-buffer descriptors per set: the
88 // pool must hold the deferred backlog from multi-dispatch Sequences.
89 vk::DescriptorPoolSize poolSize{vk::DescriptorType::eStorageBuffer,
90 uint32_t(kMaxBindings) * 64};
91 vk::DescriptorPoolCreateInfo poolInfo{};
92 poolInfo.flags = vk::DescriptorPoolCreateFlagBits::eFreeDescriptorSet;
93 poolInfo.maxSets = 64;
94 poolInfo.poolSizeCount = 1;
95 poolInfo.pPoolSizes = &poolSize;
96 descriptorPool_ = device->createDescriptorPool(poolInfo, device.allocation_callbacks);
97 }
98
99 if (descriptorSet_) {
100 if (activeSequenceCount_ > 0) {
101 // A previously recorded command buffer in the open Sequence may
102 // still reference this set. Defer the free until that Sequence
103 // submits and waits; the pool is sized for the deferred backlog.
104 pendingSets_.push_back(descriptorSet_);
105 } else {
106 device->freeDescriptorSets(descriptorPool_, descriptorSet_);
107 }
108 descriptorSet_ = vk::DescriptorSet{};
109 }
110
111 vk::DescriptorSetAllocateInfo alloc{};
112 alloc.descriptorPool = descriptorPool_;
113 alloc.descriptorSetCount = 1;
114 alloc.pSetLayouts = &setLayout_;
115 auto sets = device->allocateDescriptorSets(alloc);
116 descriptorSet_ = sets[0];
117
118 // Dummy 4-byte SSBO for unused bindings (validation requires all layout slots valid).
119 if (!dummyBuffer_) {
120 using buf = vk::BufferUsageFlagBits;
121 using pfb = vk::MemoryPropertyFlagBits;
122 vkb::GenericBuffer tmp(device, buf::eStorageBuffer | buf::eTransferDst, 4, pfb::eDeviceLocal);
123 dummyBuffer_ = tmp.buffer;
124 dummyMemory_ = tmp.memory;
125#if defined(VKB_ENABLE_VMA)
126 dummyVmaAllocation_ = tmp.vma_allocation;
127#endif
128 // Without detach(), tmp's destructor frees the handles, leaving the
129 // dummy SSBO dangling: descriptor writes reference a destroyed buffer
130 // (crashes MoltenVK) and ~VulkanComputeShader double-frees it.
131 tmp.detach();
132 }
133
134 std::array<vk::DescriptorBufferInfo, kMaxBindings> infos{};
135 std::array<vk::WriteDescriptorSet, kMaxBindings> writes{};
136 for (int i = 0; i < kMaxBindings; ++i) {
137 auto *vb = dynamic_cast<VulkanGpuBuffer *>(bindings_[size_t(i)]);
138 infos[size_t(i)].buffer = (vb && vb->buffer_) ? vb->buffer_ : dummyBuffer_;
139 infos[size_t(i)].offset = 0;
140 infos[size_t(i)].range = (vb && vb->buffer_) ? vb->size_ : vk::DeviceSize(4);
141 writes[size_t(i)].dstSet = descriptorSet_;
142 writes[size_t(i)].dstBinding = uint32_t(i);
143 writes[size_t(i)].dstArrayElement = 0;
144 writes[size_t(i)].descriptorCount = 1;
145 writes[size_t(i)].descriptorType = vk::DescriptorType::eStorageBuffer;
146 writes[size_t(i)].pBufferInfo = &infos[size_t(i)];
147 }
148 device->updateDescriptorSets(kMaxBindings, writes.data(), 0, nullptr);
149
150 descriptorsDirty_ = false;
151}
152
154
158
160 if (activeSequenceCount_ > 0) return;
161 if (pendingSets_.empty()) return;
162 for (vk::DescriptorSet set : pendingSets_)
163 device->freeDescriptorSets(descriptorPool_, set);
164 pendingSets_.clear();
165}
166
167} // namespace eve::gpgpu
double value
vkb::Device & device
std::unique_ptr< gpgpu::GpuBuffer > buffer
Definition OnnxGpgpu.cpp:26
eve::action::ActionVfxBinding binding
uint32_t index
static constexpr int kMaxBindings
static constexpr int kMaxFloats
std::array< float, kMaxFloats > push_
Backend-agnostic GPU buffer for compute (storage) or CPU staging transfers. Squirrel-owned; derived c...
Definition GpuBuffer.h:18
float getFloat(int index) const override
Returns the float.
void releasePendingDescriptors(vkb::Device &device)
Release pending descriptors.
void clearBindings() override
清空全部绑定。
void bindBuffer(int binding, GpuBuffer *buffer) override
绑定/解绑 GpuBuffer 到指定 binding。
vk::DescriptorSetLayout setLayout_
std::array< GpuBuffer *, kMaxBindings > bindings_
void flushDescriptors(vkb::Device &device)
内部:把脏绑定刷成 descriptor set。
GpuBuffer * getBoundBuffer(int binding) const override
Returns the bound buffer.
~VulkanComputeShader() override
Releases VulkanComputeShader resources.
std::vector< vk::DescriptorSet > pendingSets_
void setFloat(int index, float value) override
标量 uniform 读写。
Vulkan 计算缓冲区实现(storage/vertex buffer + device memory)。
Fluids module — interactive surface fluid simulation.
Definition Fluids.h:34