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