1 // Copyright 2019 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_backed_descriptor.h"
16 
17 #include <cstring>
18 
19 #include "src/vulkan/command_buffer.h"
20 #include "src/vulkan/device.h"
21 
22 namespace amber {
23 namespace vulkan {
24 
BufferBackedDescriptor(Buffer * buffer,DescriptorType type,Device * device,uint32_t desc_set,uint32_t binding,Pipeline * pipeline)25 BufferBackedDescriptor::BufferBackedDescriptor(Buffer* buffer,
26                                                DescriptorType type,
27                                                Device* device,
28                                                uint32_t desc_set,
29                                                uint32_t binding,
30                                                Pipeline* pipeline)
31     : Descriptor(type, device, desc_set, binding), pipeline_(pipeline) {
32   AddAmberBuffer(buffer);
33 }
34 
35 BufferBackedDescriptor::~BufferBackedDescriptor() = default;
36 
RecordCopyBufferDataToTransferResourceIfNeeded(CommandBuffer * command_buffer,Buffer * buffer,Resource * transfer_resource)37 Result BufferBackedDescriptor::RecordCopyBufferDataToTransferResourceIfNeeded(
38     CommandBuffer* command_buffer,
39     Buffer* buffer,
40     Resource* transfer_resource) {
41   transfer_resource->UpdateMemoryWithRawData(*buffer->ValuePtr());
42   // If the resource is read-only, keep the buffer data; Amber won't copy
43   // read-only resources back into the host buffers, so it makes sense to
44   // leave the buffer intact.
45   if (!transfer_resource->IsReadOnly())
46     buffer->ValuePtr()->clear();
47 
48   transfer_resource->CopyToDevice(command_buffer);
49   return {};
50 }
51 
RecordCopyTransferResourceToHost(CommandBuffer * command_buffer,Resource * transfer_resource)52 Result BufferBackedDescriptor::RecordCopyTransferResourceToHost(
53     CommandBuffer* command_buffer,
54     Resource* transfer_resource) {
55   if (!transfer_resource->IsReadOnly()) {
56     transfer_resource->CopyToHost(command_buffer);
57   }
58 
59   return {};
60 }
61 
MoveTransferResourceToBufferOutput(Resource * transfer_resource,Buffer * buffer)62 Result BufferBackedDescriptor::MoveTransferResourceToBufferOutput(
63     Resource* transfer_resource,
64     Buffer* buffer) {
65   // No need to move read only resources to an output buffer.
66   if (transfer_resource->IsReadOnly()) {
67     return {};
68   }
69 
70   void* resource_memory_ptr = transfer_resource->HostAccessibleMemoryPtr();
71   if (!resource_memory_ptr) {
72     return Result(
73         "Vulkan: BufferBackedDescriptor::MoveTransferResourceToBufferOutput() "
74         "no host accessible memory pointer");
75   }
76 
77   if (!buffer->ValuePtr()->empty()) {
78     return Result(
79         "Vulkan: BufferBackedDescriptor::MoveTransferResourceToBufferOutput() "
80         "output buffer is not empty");
81   }
82 
83   auto size_in_bytes = transfer_resource->GetSizeInBytes();
84   buffer->SetElementCount(size_in_bytes / buffer->GetFormat()->SizeInBytes());
85   buffer->ValuePtr()->resize(size_in_bytes);
86   std::memcpy(buffer->ValuePtr()->data(), resource_memory_ptr, size_in_bytes);
87 
88   return {};
89 }
90 
IsReadOnly() const91 bool BufferBackedDescriptor::IsReadOnly() const {
92   switch (type_) {
93     case DescriptorType::kUniformBuffer:
94     case DescriptorType::kUniformBufferDynamic:
95     case DescriptorType::kUniformTexelBuffer:
96     case DescriptorType::kSampledImage:
97     case DescriptorType::kCombinedImageSampler:
98       return true;
99     case DescriptorType::kStorageBuffer:
100     case DescriptorType::kStorageBufferDynamic:
101     case DescriptorType::kStorageTexelBuffer:
102     case DescriptorType::kStorageImage:
103       return false;
104     default:
105       assert(false && "Unexpected descriptor type");
106       return false;
107   }
108 }
109 
110 }  // namespace vulkan
111 }  // namespace amber
112