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