21 const std::shared_ptr<Allocator>& allocator) {
22 return std::shared_ptr<HostBuffer>(
new HostBuffer(allocator));
25 HostBuffer::HostBuffer(
const std::shared_ptr<Allocator>& allocator)
26 : allocator_(allocator) {
31 device_buffers_[i].push_back(allocator->CreateBuffer(desc));
38 label_ = std::move(label);
44 auto [range, device_buffer] = EmplaceInternal(buffer, length, align);
48 return BufferView{std::move(device_buffer), range};
52 auto [range, device_buffer] = EmplaceInternal(buffer, length);
56 return BufferView{std::move(device_buffer), range};
62 auto [range, device_buffer] = EmplaceInternal(length, align, cb);
66 return BufferView{std::move(device_buffer), range};
72 .current_buffer = current_buffer_,
73 .total_buffer_count = device_buffers_[frame_index_].size(),
77 void HostBuffer::MaybeCreateNewBuffer() {
79 if (current_buffer_ >= device_buffers_[frame_index_].size()) {
83 device_buffers_[frame_index_].push_back(allocator_->CreateBuffer(desc));
88 std::tuple<Range, std::shared_ptr<DeviceBuffer>> HostBuffer::EmplaceInternal(
91 const EmplaceProc& cb) {
99 DeviceBufferDescriptor desc;
102 auto device_buffer = allocator_->CreateBuffer(desc);
103 if (!device_buffer) {
107 cb(device_buffer->OnGetContents());
108 device_buffer->Flush(Range{0, length});
110 return std::make_tuple(Range{0, length}, device_buffer);
114 if (align > 0 && offset_ % align) {
115 padding = align - (offset_ % align);
118 MaybeCreateNewBuffer();
123 auto current_buffer = GetCurrentBuffer();
124 auto contents = current_buffer->OnGetContents();
125 cb(contents + offset_);
126 Range output_range(offset_, length);
127 current_buffer->Flush(output_range);
130 return std::make_tuple(output_range, std::move(current_buffer));
133 std::tuple<Range, std::shared_ptr<DeviceBuffer>> HostBuffer::EmplaceInternal(
139 DeviceBufferDescriptor desc;
142 auto device_buffer = allocator_->CreateBuffer(desc);
143 if (!device_buffer) {
147 if (!device_buffer->CopyHostBuffer(
static_cast<const uint8_t*
>(buffer),
152 return std::make_tuple(Range{0, length}, device_buffer);
155 auto old_length = GetLength();
157 MaybeCreateNewBuffer();
159 old_length = GetLength();
161 auto current_buffer = GetCurrentBuffer();
162 auto contents = current_buffer->OnGetContents();
164 ::memmove(contents + old_length, buffer, length);
165 current_buffer->Flush(Range{old_length, length});
168 return std::make_tuple(Range{old_length, length}, std::move(current_buffer));
171 std::tuple<Range, std::shared_ptr<DeviceBuffer>>
172 HostBuffer::EmplaceInternal(
const void* buffer,
size_t length,
size_t align) {
173 if (align == 0 || (GetLength() % align) == 0) {
174 return EmplaceInternal(buffer, length);
178 auto padding = align - (GetLength() % align);
182 MaybeCreateNewBuffer();
186 return EmplaceInternal(buffer, length);
192 while (device_buffers_[frame_index_].size() > current_buffer_ + 1) {
193 device_buffers_[frame_index_].pop_back();
197 current_buffer_ = 0u;