Alexis Hetu | 38ff830 | 2018-10-18 15:08:13 -0400 | [diff] [blame] | 1 | // Copyright 2018 The SwiftShader Authors. All Rights Reserved. |
| 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 "VkBuffer.hpp" |
Antonio Maiorano | 42fd159 | 2020-04-27 11:30:40 -0400 | [diff] [blame] | 16 | #include "VkConfig.hpp" |
Alexis Hetu | 38ff830 | 2018-10-18 15:08:13 -0400 | [diff] [blame] | 17 | #include "VkDeviceMemory.hpp" |
Nicolas Capens | 318d5e0 | 2018-11-16 14:28:36 -0500 | [diff] [blame] | 18 | |
| 19 | #include <cstring> |
Alexis Hetu | 38ff830 | 2018-10-18 15:08:13 -0400 | [diff] [blame] | 20 | |
Nicolas Capens | 157ba26 | 2019-12-10 17:49:14 -0500 | [diff] [blame] | 21 | namespace vk { |
Alexis Hetu | 38ff830 | 2018-10-18 15:08:13 -0400 | [diff] [blame] | 22 | |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 23 | Buffer::Buffer(const VkBufferCreateInfo *pCreateInfo, void *mem) |
| 24 | : flags(pCreateInfo->flags) |
| 25 | , size(pCreateInfo->size) |
| 26 | , usage(pCreateInfo->usage) |
| 27 | , sharingMode(pCreateInfo->sharingMode) |
Alexis Hetu | 38ff830 | 2018-10-18 15:08:13 -0400 | [diff] [blame] | 28 | { |
Alexis Hetu | 3c5cb9c | 2019-04-02 17:12:26 -0400 | [diff] [blame] | 29 | if(pCreateInfo->sharingMode == VK_SHARING_MODE_CONCURRENT) |
| 30 | { |
| 31 | queueFamilyIndexCount = pCreateInfo->queueFamilyIndexCount; |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 32 | queueFamilyIndices = reinterpret_cast<uint32_t *>(mem); |
Alexis Hetu | 3c5cb9c | 2019-04-02 17:12:26 -0400 | [diff] [blame] | 33 | memcpy(queueFamilyIndices, pCreateInfo->pQueueFamilyIndices, sizeof(uint32_t) * queueFamilyIndexCount); |
| 34 | } |
David 'Digit' Turner | 359bc80 | 2019-08-14 17:46:07 +0200 | [diff] [blame] | 35 | |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 36 | const auto *nextInfo = reinterpret_cast<const VkBaseInStructure *>(pCreateInfo->pNext); |
Nicolas Capens | 81bc9d9 | 2019-12-16 15:05:57 -0500 | [diff] [blame] | 37 | for(; nextInfo != nullptr; nextInfo = nextInfo->pNext) |
David 'Digit' Turner | 359bc80 | 2019-08-14 17:46:07 +0200 | [diff] [blame] | 38 | { |
Nicolas Capens | 81bc9d9 | 2019-12-16 15:05:57 -0500 | [diff] [blame] | 39 | if(nextInfo->sType == VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO) |
David 'Digit' Turner | 359bc80 | 2019-08-14 17:46:07 +0200 | [diff] [blame] | 40 | { |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 41 | const auto *externalInfo = reinterpret_cast<const VkExternalMemoryBufferCreateInfo *>(nextInfo); |
David 'Digit' Turner | 359bc80 | 2019-08-14 17:46:07 +0200 | [diff] [blame] | 42 | supportedExternalMemoryHandleTypes = externalInfo->handleTypes; |
| 43 | } |
| 44 | } |
Alexis Hetu | 38ff830 | 2018-10-18 15:08:13 -0400 | [diff] [blame] | 45 | } |
| 46 | |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 47 | void Buffer::destroy(const VkAllocationCallbacks *pAllocator) |
Alexis Hetu | 38ff830 | 2018-10-18 15:08:13 -0400 | [diff] [blame] | 48 | { |
| 49 | vk::deallocate(queueFamilyIndices, pAllocator); |
| 50 | } |
| 51 | |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 52 | size_t Buffer::ComputeRequiredAllocationSize(const VkBufferCreateInfo *pCreateInfo) |
Alexis Hetu | 38ff830 | 2018-10-18 15:08:13 -0400 | [diff] [blame] | 53 | { |
Alexis Hetu | 3c5cb9c | 2019-04-02 17:12:26 -0400 | [diff] [blame] | 54 | return (pCreateInfo->sharingMode == VK_SHARING_MODE_CONCURRENT) ? sizeof(uint32_t) * pCreateInfo->queueFamilyIndexCount : 0; |
Alexis Hetu | 38ff830 | 2018-10-18 15:08:13 -0400 | [diff] [blame] | 55 | } |
| 56 | |
| 57 | const VkMemoryRequirements Buffer::getMemoryRequirements() const |
| 58 | { |
| 59 | VkMemoryRequirements memoryRequirements = {}; |
Ben Clayton | efec1b9 | 2019-03-05 17:38:16 +0000 | [diff] [blame] | 60 | if(usage & (VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)) |
| 61 | { |
| 62 | memoryRequirements.alignment = vk::MIN_TEXEL_BUFFER_OFFSET_ALIGNMENT; |
| 63 | } |
| 64 | else if(usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT) |
| 65 | { |
| 66 | memoryRequirements.alignment = vk::MIN_STORAGE_BUFFER_OFFSET_ALIGNMENT; |
| 67 | } |
| 68 | else if(usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) |
| 69 | { |
| 70 | memoryRequirements.alignment = vk::MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT; |
| 71 | } |
| 72 | else |
| 73 | { |
| 74 | memoryRequirements.alignment = REQUIRED_MEMORY_ALIGNMENT; |
Alexis Hetu | 6123455 | 2019-01-21 17:22:51 -0500 | [diff] [blame] | 75 | } |
Nicolas Capens | c3f7960 | 2018-11-13 14:06:37 -0500 | [diff] [blame] | 76 | memoryRequirements.memoryTypeBits = vk::MEMORY_TYPE_GENERIC_BIT; |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 77 | memoryRequirements.size = size; // TODO: also reserve space for a header containing |
| 78 | // the size of the buffer (for robust buffer access) |
Alexis Hetu | 38ff830 | 2018-10-18 15:08:13 -0400 | [diff] [blame] | 79 | return memoryRequirements; |
| 80 | } |
| 81 | |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 82 | bool Buffer::canBindToMemory(DeviceMemory *pDeviceMemory) const |
David 'Digit' Turner | 359bc80 | 2019-08-14 17:46:07 +0200 | [diff] [blame] | 83 | { |
| 84 | return pDeviceMemory->checkExternalMemoryHandleType(supportedExternalMemoryHandleTypes); |
| 85 | } |
| 86 | |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 87 | void Buffer::bind(DeviceMemory *pDeviceMemory, VkDeviceSize pMemoryOffset) |
Alexis Hetu | 38ff830 | 2018-10-18 15:08:13 -0400 | [diff] [blame] | 88 | { |
Alexis Hetu | 7d96f51 | 2019-06-13 18:23:56 -0400 | [diff] [blame] | 89 | memory = pDeviceMemory->getOffsetPointer(pMemoryOffset); |
Alexis Hetu | 38ff830 | 2018-10-18 15:08:13 -0400 | [diff] [blame] | 90 | } |
| 91 | |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 92 | void Buffer::copyFrom(const void *srcMemory, VkDeviceSize pSize, VkDeviceSize pOffset) |
Alexis Hetu | 2661e84 | 2018-12-07 11:36:34 -0500 | [diff] [blame] | 93 | { |
| 94 | ASSERT((pSize + pOffset) <= size); |
| 95 | |
Alexis Hetu | e0b5a4b | 2018-12-14 12:11:02 -0500 | [diff] [blame] | 96 | memcpy(getOffsetPointer(pOffset), srcMemory, pSize); |
Alexis Hetu | 2661e84 | 2018-12-07 11:36:34 -0500 | [diff] [blame] | 97 | } |
| 98 | |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 99 | void Buffer::copyTo(void *dstMemory, VkDeviceSize pSize, VkDeviceSize pOffset) const |
Alexis Hetu | 2661e84 | 2018-12-07 11:36:34 -0500 | [diff] [blame] | 100 | { |
| 101 | ASSERT((pSize + pOffset) <= size); |
| 102 | |
Alexis Hetu | e0b5a4b | 2018-12-14 12:11:02 -0500 | [diff] [blame] | 103 | memcpy(dstMemory, getOffsetPointer(pOffset), pSize); |
Alexis Hetu | 2661e84 | 2018-12-07 11:36:34 -0500 | [diff] [blame] | 104 | } |
| 105 | |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 106 | void Buffer::copyTo(Buffer *dstBuffer, const VkBufferCopy &pRegion) const |
Alexis Hetu | bb0a7f0 | 2018-12-14 16:50:43 -0500 | [diff] [blame] | 107 | { |
| 108 | copyTo(dstBuffer->getOffsetPointer(pRegion.dstOffset), pRegion.size, pRegion.srcOffset); |
| 109 | } |
| 110 | |
Alexis Hetu | 7fb0b73 | 2019-02-07 13:50:10 -0500 | [diff] [blame] | 111 | void Buffer::fill(VkDeviceSize dstOffset, VkDeviceSize fillSize, uint32_t data) |
| 112 | { |
Alexis Hetu | fb6639f | 2019-03-25 10:24:23 -0400 | [diff] [blame] | 113 | size_t bytes = (fillSize == VK_WHOLE_SIZE) ? (size - dstOffset) : fillSize; |
Alexis Hetu | 7fb0b73 | 2019-02-07 13:50:10 -0500 | [diff] [blame] | 114 | |
Alexis Hetu | fb6639f | 2019-03-25 10:24:23 -0400 | [diff] [blame] | 115 | ASSERT((bytes + dstOffset) <= size); |
| 116 | |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 117 | uint32_t *memToWrite = static_cast<uint32_t *>(getOffsetPointer(dstOffset)); |
Alexis Hetu | fb6639f | 2019-03-25 10:24:23 -0400 | [diff] [blame] | 118 | |
| 119 | // Vulkan 1.1 spec: "If VK_WHOLE_SIZE is used and the remaining size of the buffer is |
| 120 | // not a multiple of 4, then the nearest smaller multiple is used." |
| 121 | for(; bytes >= 4; bytes -= 4, memToWrite++) |
| 122 | { |
| 123 | *memToWrite = data; |
| 124 | } |
Alexis Hetu | 7fb0b73 | 2019-02-07 13:50:10 -0500 | [diff] [blame] | 125 | } |
| 126 | |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 127 | void Buffer::update(VkDeviceSize dstOffset, VkDeviceSize dataSize, const void *pData) |
Alexis Hetu | 7fb0b73 | 2019-02-07 13:50:10 -0500 | [diff] [blame] | 128 | { |
| 129 | ASSERT((dataSize + dstOffset) <= size); |
| 130 | |
| 131 | memcpy(getOffsetPointer(dstOffset), pData, dataSize); |
| 132 | } |
| 133 | |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 134 | void *Buffer::getOffsetPointer(VkDeviceSize offset) const |
Alexis Hetu | 2661e84 | 2018-12-07 11:36:34 -0500 | [diff] [blame] | 135 | { |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 136 | return reinterpret_cast<uint8_t *>(memory) + offset; |
Alexis Hetu | 377077a | 2019-03-14 15:10:51 -0400 | [diff] [blame] | 137 | } |
| 138 | |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 139 | uint8_t *Buffer::end() const |
Alexis Hetu | 377077a | 2019-03-14 15:10:51 -0400 | [diff] [blame] | 140 | { |
Ben Clayton | 2ed93ab | 2019-12-17 20:38:03 +0000 | [diff] [blame] | 141 | return reinterpret_cast<uint8_t *>(getOffsetPointer(size + 1)); |
Alexis Hetu | 2661e84 | 2018-12-07 11:36:34 -0500 | [diff] [blame] | 142 | } |
| 143 | |
Nicolas Capens | 157ba26 | 2019-12-10 17:49:14 -0500 | [diff] [blame] | 144 | } // namespace vk |