• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/index_buffer.h"
16 
17 #include <cstring>
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 
IndexBuffer(Device * device)26 IndexBuffer::IndexBuffer(Device* device) : device_(device) {}
27 
28 IndexBuffer::~IndexBuffer() = default;
29 
SendIndexData(CommandBuffer * command,Buffer * buffer)30 Result IndexBuffer::SendIndexData(CommandBuffer* command, Buffer* buffer) {
31   if (transfer_buffer_) {
32     return Result(
33         "IndexBuffer::SendIndexData must be called once when it is created");
34   }
35 
36   if (buffer->ElementCount() == 0)
37     return Result("IndexBuffer::SendIndexData |buffer| is empty");
38 
39   if (buffer->GetFormat()->IsUint32())
40     index_type_ = VK_INDEX_TYPE_UINT32;
41   else if (buffer->GetFormat()->IsUint16())
42     index_type_ = VK_INDEX_TYPE_UINT16;
43   else if (buffer->GetFormat()->IsUint8())
44     index_type_ = VK_INDEX_TYPE_UINT8_EXT;
45   else
46     return Result("IndexBuffer::SendIndexData unexpected index buffer format");
47 
48   transfer_buffer_ =
49       MakeUnique<TransferBuffer>(device_, buffer->GetSizeInBytes(), nullptr);
50   Result r = transfer_buffer_->AddUsageFlags(VK_BUFFER_USAGE_INDEX_BUFFER_BIT |
51                                              VK_BUFFER_USAGE_TRANSFER_DST_BIT);
52   if (!r.IsSuccess())
53     return r;
54 
55   r = transfer_buffer_->Initialize();
56   if (!r.IsSuccess())
57     return r;
58 
59   std::memcpy(transfer_buffer_->HostAccessibleMemoryPtr(),
60               buffer->ValuePtr()->data(), buffer->GetSizeInBytes());
61 
62   transfer_buffer_->CopyToDevice(command);
63   return {};
64 }
65 
BindToCommandBuffer(CommandBuffer * command)66 Result IndexBuffer::BindToCommandBuffer(CommandBuffer* command) {
67   if (!transfer_buffer_) {
68     return Result(
69         "IndexBuffer::BindToCommandBuffer |transfer_buffer_| is nullptr");
70   }
71 
72   device_->GetPtrs()->vkCmdBindIndexBuffer(command->GetVkCommandBuffer(),
73                                            transfer_buffer_->GetVkBuffer(), 0,
74                                            index_type_);
75   return {};
76 }
77 
78 }  // namespace vulkan
79 }  // namespace amber
80