• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Amber Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "src/vulkan/buffer_descriptor.h"
16 
17 #include <vector>
18 
19 #include "src/make_unique.h"
20 #include "src/vulkan/command_buffer.h"
21 #include "src/vulkan/device.h"
22 
23 namespace amber {
24 namespace vulkan {
25 
BufferDescriptor(Buffer * buffer,DescriptorType type,Device * device,uint32_t desc_set,uint32_t binding)26 BufferDescriptor::BufferDescriptor(Buffer* buffer,
27                                    DescriptorType type,
28                                    Device* device,
29                                    uint32_t desc_set,
30                                    uint32_t binding)
31     : BufferBackedDescriptor(buffer, type, device, desc_set, binding) {}
32 
33 BufferDescriptor::~BufferDescriptor() = default;
34 
CreateResourceIfNeeded()35 Result BufferDescriptor::CreateResourceIfNeeded() {
36   if (!transfer_buffers_.empty()) {
37     return Result(
38         "Vulkan: BufferDescriptor::CreateResourceIfNeeded() must be called "
39         "only when |transfer_buffers| is empty");
40   }
41 
42   transfer_buffers_.reserve(GetAmberBuffers().size());
43 
44   for (const auto& amber_buffer : GetAmberBuffers()) {
45     if (amber_buffer->ValuePtr()->empty())
46       continue;
47 
48     uint32_t size_in_bytes =
49         amber_buffer ? static_cast<uint32_t>(amber_buffer->ValuePtr()->size())
50                      : 0;
51     transfer_buffers_.emplace_back(MakeUnique<TransferBuffer>(
52         device_, size_in_bytes, amber_buffer->GetFormat()));
53     VkBufferUsageFlags flags =
54         VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
55     if (IsUniformBuffer() || IsUniformBufferDynamic()) {
56       flags |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
57     } else if (IsStorageBuffer() || IsStorageBufferDynamic()) {
58       flags |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
59     } else if (IsUniformTexelBuffer()) {
60       flags |= VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
61     } else if (IsStorageTexelBuffer()) {
62       flags |= VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
63     } else {
64       return Result("Unexpected buffer type when deciding usage flags");
65     }
66 
67     Result r = transfer_buffers_.back()->Initialize(flags);
68     if (!r.IsSuccess())
69       return r;
70   }
71 
72   is_descriptor_set_update_needed_ = true;
73   return {};
74 }
75 
MoveResourceToBufferOutput()76 Result BufferDescriptor::MoveResourceToBufferOutput() {
77   Result r = BufferBackedDescriptor::MoveResourceToBufferOutput();
78 
79   transfer_buffers_.clear();
80 
81   return r;
82 }
83 
UpdateDescriptorSetIfNeeded(VkDescriptorSet descriptor_set)84 void BufferDescriptor::UpdateDescriptorSetIfNeeded(
85     VkDescriptorSet descriptor_set) {
86   if (!is_descriptor_set_update_needed_)
87     return;
88 
89   std::vector<VkDescriptorBufferInfo> buffer_infos;
90   std::vector<VkBufferView> buffer_views;
91 
92   for (const auto& buffer : transfer_buffers_) {
93     VkDescriptorBufferInfo buffer_info;
94     buffer_info.buffer = buffer->GetVkBuffer();
95     buffer_info.offset = 0;
96     buffer_info.range = VK_WHOLE_SIZE;
97     buffer_infos.push_back(buffer_info);
98 
99     if (IsUniformTexelBuffer() || IsStorageTexelBuffer()) {
100       buffer_views.push_back(*buffer->GetVkBufferView());
101     }
102   }
103 
104   VkWriteDescriptorSet write = VkWriteDescriptorSet();
105   write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
106   write.dstSet = descriptor_set;
107   write.dstBinding = binding_;
108   write.dstArrayElement = 0;
109   write.descriptorCount = static_cast<uint32_t>(buffer_infos.size());
110   write.descriptorType = GetVkDescriptorType();
111   write.pBufferInfo = buffer_infos.data();
112   write.pTexelBufferView = buffer_views.data();
113 
114   device_->GetPtrs()->vkUpdateDescriptorSets(device_->GetVkDevice(), 1, &write,
115                                              0, nullptr);
116   is_descriptor_set_update_needed_ = false;
117 }
118 
GetResources()119 std::vector<Resource*> BufferDescriptor::GetResources() {
120   std::vector<Resource*> ret;
121   for (auto& b : transfer_buffers_) {
122     ret.push_back(b.get());
123   }
124   return ret;
125 }
126 
127 }  // namespace vulkan
128 }  // namespace amber
129