6 #include "fml/status.h"
17 #include "vulkan/vulkan_core.h"
28 const std::shared_ptr<CommandEncoderVK>& encoder,
29 vk::DescriptorSet& vk_desc_set,
30 std::vector<vk::DescriptorImageInfo>& images,
31 std::vector<vk::WriteDescriptorSet>& writes) {
37 if (!encoder->Track(texture) ||
44 vk::DescriptorImageInfo image_info;
45 image_info.imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal;
47 image_info.imageView = texture_vk.GetImageView();
48 images.push_back(image_info);
50 vk::WriteDescriptorSet write_set;
51 write_set.dstSet = vk_desc_set;
52 write_set.dstBinding = slot.
binding;
53 write_set.descriptorCount = 1u;
54 write_set.descriptorType = vk::DescriptorType::eCombinedImageSampler;
55 write_set.pImageInfo = &images.back();
57 writes.push_back(write_set);
65 const std::shared_ptr<CommandEncoderVK>& encoder,
66 vk::DescriptorSet& vk_desc_set,
67 const std::vector<DescriptorSetLayout>& desc_set,
68 std::vector<vk::DescriptorBufferInfo>& buffers,
69 std::vector<vk::WriteDescriptorSet>& writes) {
73 auto device_buffer = buffer_view->GetDeviceBuffer(allocator);
75 VALIDATION_LOG <<
"Failed to get device buffer for vertex binding";
84 if (!encoder->Track(device_buffer)) {
90 vk::DescriptorBufferInfo buffer_info;
91 buffer_info.buffer = buffer;
92 buffer_info.offset = offset;
94 buffers.push_back(buffer_info);
100 std::find_if(desc_set.begin(), desc_set.end(),
102 return layout.binding == uniform.binding;
104 if (layout_it == desc_set.end()) {
105 VALIDATION_LOG <<
"Failed to get descriptor set layout for binding "
109 auto layout = *layout_it;
111 vk::WriteDescriptorSet write_set;
112 write_set.dstSet = vk_desc_set;
113 write_set.dstBinding = uniform.
binding;
114 write_set.descriptorCount = 1u;
116 write_set.pBufferInfo = &buffers.back();
118 writes.push_back(write_set);
125 const std::shared_ptr<CommandEncoderVK>& encoder,
126 const std::vector<Command>& commands,
128 if (commands.empty()) {
129 return std::vector<vk::DescriptorSet>{};
135 size_t buffer_count = 0;
136 size_t samplers_count = 0;
137 size_t subpass_count = 0;
138 std::vector<vk::DescriptorSetLayout> layouts;
139 layouts.reserve(commands.size());
141 for (
const auto& command : commands) {
142 buffer_count += command.vertex_bindings.buffers.size();
143 buffer_count += command.fragment_bindings.buffers.size();
144 samplers_count += command.fragment_bindings.sampled_images.size();
146 command.pipeline->GetDescriptor().UsesSubpassInput() ? 1 : 0;
148 layouts.emplace_back(
151 auto descriptor_result = encoder->AllocateDescriptorSets(
152 buffer_count, samplers_count, subpass_count, layouts);
153 if (!descriptor_result.ok()) {
154 return descriptor_result.status();
156 auto descriptor_sets = descriptor_result.value();
157 if (descriptor_sets.empty()) {
158 return fml::Status();
163 std::vector<vk::DescriptorImageInfo> images;
164 std::vector<vk::DescriptorBufferInfo> buffers;
165 std::vector<vk::WriteDescriptorSet> writes;
166 images.reserve(samplers_count + subpass_count);
167 buffers.reserve(buffer_count);
168 writes.reserve(samplers_count + buffer_count + subpass_count);
171 auto desc_index = 0u;
172 for (
const auto& command : commands) {
173 auto desc_set = command.pipeline->GetDescriptor()
174 .GetVertexDescriptor()
175 ->GetDescriptorSetLayouts();
177 if (!
BindBuffers(command.vertex_bindings, allocator, encoder,
178 descriptor_sets[desc_index], desc_set, buffers, writes) ||
179 !
BindBuffers(command.fragment_bindings, allocator, encoder,
180 descriptor_sets[desc_index], desc_set, buffers, writes) ||
181 !
BindImages(command.fragment_bindings, allocator, encoder,
182 descriptor_sets[desc_index], images, writes)) {
183 return fml::Status(fml::StatusCode::kUnknown,
184 "Failed to bind texture or buffer.");
187 if (command.pipeline->GetDescriptor().UsesSubpassInput()) {
188 vk::DescriptorImageInfo image_info;
189 image_info.imageLayout = vk::ImageLayout::eGeneral;
190 image_info.sampler = VK_NULL_HANDLE;
192 images.push_back(image_info);
194 vk::WriteDescriptorSet write_set;
195 write_set.dstSet = descriptor_sets[desc_index];
197 write_set.descriptorCount = 1u;
198 write_set.descriptorType = vk::DescriptorType::eInputAttachment;
199 write_set.pImageInfo = &images.back();
201 writes.push_back(write_set);
206 context.
GetDevice().updateDescriptorSets(writes, {});
207 return descriptor_sets;
212 const std::shared_ptr<CommandEncoderVK>& encoder,
213 const std::vector<ComputeCommand>& commands) {
214 if (commands.empty()) {
215 return std::vector<vk::DescriptorSet>{};
220 size_t buffer_count = 0;
221 size_t samplers_count = 0;
222 std::vector<vk::DescriptorSetLayout> layouts;
223 layouts.reserve(commands.size());
225 for (
const auto& command : commands) {
226 buffer_count += command.bindings.buffers.size();
227 samplers_count += command.bindings.sampled_images.size();
229 layouts.emplace_back(
232 auto descriptor_result =
233 encoder->AllocateDescriptorSets(buffer_count, samplers_count, 0, layouts);
234 if (!descriptor_result.ok()) {
235 return descriptor_result.status();
237 auto descriptor_sets = descriptor_result.value();
238 if (descriptor_sets.empty()) {
239 return fml::Status();
243 std::vector<vk::DescriptorImageInfo> images;
244 std::vector<vk::DescriptorBufferInfo> buffers;
245 std::vector<vk::WriteDescriptorSet> writes;
246 images.reserve(samplers_count);
247 buffers.reserve(buffer_count);
248 writes.reserve(samplers_count + buffer_count);
251 auto desc_index = 0u;
252 for (
const auto& command : commands) {
253 auto desc_set = command.pipeline->GetDescriptor().GetDescriptorSetLayouts();
255 if (!
BindBuffers(command.bindings, allocator, encoder,
256 descriptor_sets[desc_index], desc_set, buffers, writes) ||
257 !
BindImages(command.bindings, allocator, encoder,
258 descriptor_sets[desc_index], images, writes)) {
259 return fml::Status(fml::StatusCode::kUnknown,
260 "Failed to bind texture or buffer.");
265 context.
GetDevice().updateDescriptorSets(writes, {});
266 return descriptor_sets;