-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathStagingBuffer.cpp
More file actions
134 lines (114 loc) · 3.32 KB
/
StagingBuffer.cpp
File metadata and controls
134 lines (114 loc) · 3.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include "StagingBuffer.hpp"
#include "UniformBuffer.hpp"
namespace nu
{
StagingBuffer::Ptr StagingBuffer::createStagingBuffer(VulkanBuffer& dstBuffer)
{
StagingBuffer::Ptr stagingBuffer = StagingBuffer::Ptr(new StagingBuffer(dstBuffer));
if (stagingBuffer != nullptr)
{
if (!stagingBuffer->init())
{
stagingBuffer.reset();
}
}
return stagingBuffer;
}
StagingBuffer::~StagingBuffer()
{
}
bool StagingBuffer::map(uint32_t offset, uint32_t size)
{
assert(mBuffer->isBoundToMemoryBlock());
return mBuffer->getMemoryBlock()->map(offset, size);
}
bool StagingBuffer::read(void* data)
{
assert(mBuffer->isBoundToMemoryBlock());
return mBuffer->getMemoryBlock()->read(data);
}
bool StagingBuffer::write(const void* data)
{
assert(mBuffer->isBoundToMemoryBlock());
return mBuffer->getMemoryBlock()->write(data);
}
bool StagingBuffer::unmap()
{
assert(mBuffer->isBoundToMemoryBlock());
return mBuffer->getMemoryBlock()->unmap();
}
bool StagingBuffer::mapWriteUnmap(uint32_t offset, uint32_t dataSize, void* data, bool unmap, void** readPointer)
{
assert(mBuffer->isBoundToMemoryBlock());
VulkanMemoryBlock* memoryBlock = mBuffer->getMemoryBlock();
if (!memoryBlock->map(offset, dataSize))
{
return false;
}
if (readPointer != nullptr)
{
if (!memoryBlock->read(&readPointer))
{
return false;
}
}
if (!memoryBlock->write(data))
{
return false;
}
if (unmap)
{
memoryBlock->unmap();
}
mNeedToSend = true;
return true;
}
void StagingBuffer::send(VulkanCommandBuffer* commandBuffer)
{
mNeedToSend = false;
VulkanBufferTransition preTransferTransition = {
&mDstBuffer, // Buffer* buffer
VK_ACCESS_UNIFORM_READ_BIT, // VkAccessFlags currentAccess
VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags newAccess
VK_QUEUE_FAMILY_IGNORED, // uint32_t currentQueueFamily
VK_QUEUE_FAMILY_IGNORED // uint32_t newQueueFamily
};
commandBuffer->setBufferMemoryBarrier(VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, { preTransferTransition });
std::vector<VkBufferCopy> regions = {
{
0, // VkDeviceSize srcOffset
0, // VkDeviceSize dstOffset
mBuffer->getSize() // VkDeviceSize size
}
};
// TODO : Use srcOffset & dstOffset
commandBuffer->copyDataBetweenBuffers(mBuffer.get(), &mDstBuffer, regions);
VulkanBufferTransition postTransferTransition = {
&mDstBuffer, // Buffer* buffer
VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags currentAccess
VK_ACCESS_UNIFORM_READ_BIT, // VkAccessFlags newAccess
VK_QUEUE_FAMILY_IGNORED, // uint32_t currentQueueFamily
VK_QUEUE_FAMILY_IGNORED // uint32_t newQueueFamily
};
commandBuffer->setBufferMemoryBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, { postTransferTransition });
}
bool StagingBuffer::needToSend() const
{
return mNeedToSend;
}
StagingBuffer::StagingBuffer(VulkanBuffer& dstBuffer)
: mDstBuffer(dstBuffer)
, mBuffer(nullptr)
, mNeedToSend(false)
{
}
bool StagingBuffer::init()
{
mBuffer = mDstBuffer.getDevice().createBuffer(mDstBuffer.getSize(), VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
if (!mBuffer || !mBuffer->allocateMemoryBlock(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT))
{
return false;
}
return true;
}
} // namespace nu