blob: a2e874dd660aa8aa91eae3e8e3f69df768128492 [file] [log] [blame]
// Copyright 2019 The Amber Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/vulkan/buffer_backed_descriptor.h"
#include <cstring>
#include "src/vulkan/command_buffer.h"
#include "src/vulkan/device.h"
namespace amber {
namespace vulkan {
BufferBackedDescriptor::BufferBackedDescriptor(Buffer* buffer,
DescriptorType type,
Device* device,
uint32_t desc_set,
uint32_t binding,
Pipeline* pipeline)
: Descriptor(type, device, desc_set, binding), pipeline_(pipeline) {
AddAmberBuffer(buffer);
}
BufferBackedDescriptor::~BufferBackedDescriptor() = default;
Result BufferBackedDescriptor::RecordCopyBufferDataToTransferResourceIfNeeded(
CommandBuffer* command_buffer,
Buffer* buffer,
Resource* transfer_resource) {
transfer_resource->UpdateMemoryWithRawData(*buffer->ValuePtr());
// If the resource is read-only, keep the buffer data; Amber won't copy
// read-only resources back into the host buffers, so it makes sense to
// leave the buffer intact.
if (!transfer_resource->IsReadOnly())
buffer->ValuePtr()->clear();
transfer_resource->CopyToDevice(command_buffer);
return {};
}
Result BufferBackedDescriptor::RecordCopyTransferResourceToHost(
CommandBuffer* command_buffer,
Resource* transfer_resource) {
if (!transfer_resource->IsReadOnly()) {
transfer_resource->CopyToHost(command_buffer);
}
return {};
}
Result BufferBackedDescriptor::MoveTransferResourceToBufferOutput(
Resource* transfer_resource,
Buffer* buffer) {
// No need to move read only resources to an output buffer.
if (transfer_resource->IsReadOnly()) {
return {};
}
void* resource_memory_ptr = transfer_resource->HostAccessibleMemoryPtr();
if (!resource_memory_ptr) {
return Result(
"Vulkan: BufferBackedDescriptor::MoveTransferResourceToBufferOutput() "
"no host accessible memory pointer");
}
if (!buffer->ValuePtr()->empty()) {
return Result(
"Vulkan: BufferBackedDescriptor::MoveTransferResourceToBufferOutput() "
"output buffer is not empty");
}
auto size_in_bytes = transfer_resource->GetSizeInBytes();
buffer->SetElementCount(size_in_bytes / buffer->GetFormat()->SizeInBytes());
buffer->ValuePtr()->resize(size_in_bytes);
std::memcpy(buffer->ValuePtr()->data(), resource_memory_ptr, size_in_bytes);
return {};
}
bool BufferBackedDescriptor::IsReadOnly() const {
switch (type_) {
case DescriptorType::kUniformBuffer:
case DescriptorType::kUniformBufferDynamic:
case DescriptorType::kUniformTexelBuffer:
case DescriptorType::kSampledImage:
case DescriptorType::kCombinedImageSampler:
return true;
case DescriptorType::kStorageBuffer:
case DescriptorType::kStorageBufferDynamic:
case DescriptorType::kStorageTexelBuffer:
case DescriptorType::kStorageImage:
return false;
default:
assert(false && "Unexpected descriptor type");
return false;
}
}
} // namespace vulkan
} // namespace amber