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"
16 #include "VkConfig.h"
17 #include "VkDeviceMemory.hpp"
18
19 #include <cstring>
20
21 namespace vk
22 {
23
Buffer(const VkBufferCreateInfo * pCreateInfo,void * mem)24 Buffer::Buffer(const VkBufferCreateInfo* pCreateInfo, void* mem) :
25 flags(pCreateInfo->flags), size(pCreateInfo->size), usage(pCreateInfo->usage),
26 sharingMode(pCreateInfo->sharingMode), queueFamilyIndexCount(pCreateInfo->queueFamilyIndexCount),
27 queueFamilyIndices(reinterpret_cast<uint32_t*>(mem))
28 {
29 size_t queueFamilyIndicesSize = sizeof(uint32_t) * queueFamilyIndexCount;
30 memcpy(queueFamilyIndices, pCreateInfo->pQueueFamilyIndices, queueFamilyIndicesSize);
31 }
32
destroy(const VkAllocationCallbacks * pAllocator)33 void Buffer::destroy(const VkAllocationCallbacks* pAllocator)
34 {
35 vk::deallocate(queueFamilyIndices, pAllocator);
36 }
37
ComputeRequiredAllocationSize(const VkBufferCreateInfo * pCreateInfo)38 size_t Buffer::ComputeRequiredAllocationSize(const VkBufferCreateInfo* pCreateInfo)
39 {
40 return sizeof(uint32_t) * pCreateInfo->queueFamilyIndexCount;
41 }
42
getMemoryRequirements() const43 const VkMemoryRequirements Buffer::getMemoryRequirements() const
44 {
45 VkMemoryRequirements memoryRequirements = {};
46 if(usage & (VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT))
47 {
48 memoryRequirements.alignment = vk::MIN_TEXEL_BUFFER_OFFSET_ALIGNMENT;
49 }
50 else if(usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)
51 {
52 memoryRequirements.alignment = vk::MIN_STORAGE_BUFFER_OFFSET_ALIGNMENT;
53 }
54 else if(usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)
55 {
56 memoryRequirements.alignment = vk::MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT;
57 }
58 else
59 {
60 memoryRequirements.alignment = REQUIRED_MEMORY_ALIGNMENT;
61 }
62 memoryRequirements.memoryTypeBits = vk::MEMORY_TYPE_GENERIC_BIT;
63 memoryRequirements.size = size; // TODO: also reserve space for a header containing
64 // the size of the buffer (for robust buffer access)
65 return memoryRequirements;
66 }
67
bind(VkDeviceMemory pDeviceMemory,VkDeviceSize pMemoryOffset)68 void Buffer::bind(VkDeviceMemory pDeviceMemory, VkDeviceSize pMemoryOffset)
69 {
70 memory = Cast(pDeviceMemory)->getOffsetPointer(pMemoryOffset);
71 }
72
copyFrom(const void * srcMemory,VkDeviceSize pSize,VkDeviceSize pOffset)73 void Buffer::copyFrom(const void* srcMemory, VkDeviceSize pSize, VkDeviceSize pOffset)
74 {
75 ASSERT((pSize + pOffset) <= size);
76
77 memcpy(getOffsetPointer(pOffset), srcMemory, pSize);
78 }
79
copyTo(void * dstMemory,VkDeviceSize pSize,VkDeviceSize pOffset) const80 void Buffer::copyTo(void* dstMemory, VkDeviceSize pSize, VkDeviceSize pOffset) const
81 {
82 ASSERT((pSize + pOffset) <= size);
83
84 memcpy(dstMemory, getOffsetPointer(pOffset), pSize);
85 }
86
copyTo(Buffer * dstBuffer,const VkBufferCopy & pRegion) const87 void Buffer::copyTo(Buffer* dstBuffer, const VkBufferCopy& pRegion) const
88 {
89 copyTo(dstBuffer->getOffsetPointer(pRegion.dstOffset), pRegion.size, pRegion.srcOffset);
90 }
91
fill(VkDeviceSize dstOffset,VkDeviceSize fillSize,uint32_t data)92 void Buffer::fill(VkDeviceSize dstOffset, VkDeviceSize fillSize, uint32_t data)
93 {
94 ASSERT((fillSize + dstOffset) <= size);
95
96 memset(getOffsetPointer(dstOffset), data, fillSize);
97 }
98
update(VkDeviceSize dstOffset,VkDeviceSize dataSize,const void * pData)99 void Buffer::update(VkDeviceSize dstOffset, VkDeviceSize dataSize, const void* pData)
100 {
101 ASSERT((dataSize + dstOffset) <= size);
102
103 memcpy(getOffsetPointer(dstOffset), pData, dataSize);
104 }
105
getOffsetPointer(VkDeviceSize offset) const106 void* Buffer::getOffsetPointer(VkDeviceSize offset) const
107 {
108 return reinterpret_cast<char*>(memory) + offset;
109 }
110
111 } // namespace vk
112