FCT
载入中...
搜索中...
未找到
VK_IndexBuffer.cpp
浏览该文件的文档.
1//
2// Created by Administrator on 2025/4/10.
3//
5#include "./VK_IndexBuffer.h"
7
8namespace FCT
9{
10 namespace RHI
11 {
16
22 {
23 if (m_isCreated) {
24 destroy();
25 }
26
27 uint32_t bufferSize = static_cast<uint32_t>(m_size * m_stride);
28 uint32_t bufferCount = (m_updateFrequency == UpdateFrequency::PerFrame) ?
29 m_ctx->maxFrameInFlight() : 1;
30
31 m_buffers.resize(bufferCount);
32 m_memories.resize(bufferCount);
33 m_dirtyFlags.resize(bufferCount, 0);
34
35 for (uint32_t i = 0; i < bufferCount; i++) {
36 vk::BufferCreateInfo bufferInfo;
37 bufferInfo.size = bufferSize;
38 bufferInfo.usage = vk::BufferUsageFlagBits::eIndexBuffer;
39 bufferInfo.sharingMode = vk::SharingMode::eExclusive;
40
41 m_buffers[i] = m_ctx->getDevice().createBuffer(bufferInfo);
42
43 vk::MemoryRequirements memRequirements = m_ctx->getDevice().getBufferMemoryRequirements(m_buffers[i]);
44
45 vk::MemoryAllocateInfo allocInfo;
46 allocInfo.allocationSize = memRequirements.size;
47 allocInfo.memoryTypeIndex = m_ctx->findMemoryType(
48 memRequirements.memoryTypeBits,
49 vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent
50 );
51
52 m_memories[i] = m_ctx->getDevice().allocateMemory(allocInfo);
53 m_ctx->getDevice().bindBufferMemory(m_buffers[i], m_memories[i], 0);
54 }
55
56 m_isCreated = true;
57
59 }
60 void VK_IndexBuffer::mapBuffer(void* data, uint32_t size, uint32_t frameIndex)
61 {
62 if (!m_isCreated || !data || size == 0) {
63 return;
64 }
65
67 if (frameIndex >= m_buffers.size()) {
68 frameIndex = frameIndex % m_buffers.size();
69 }
70
71 checkAndResizeIfNeeded(frameIndex);
72
73 } else {
74 frameIndex = 0;
75 }
76
77 void* mappedData = m_ctx->getDevice().mapMemory(m_memories[frameIndex], 0, size);
78 memcpy(mappedData, data, size);
79 m_ctx->getDevice().unmapMemory(m_memories[frameIndex]);
80 }
81
82 void VK_IndexBuffer::mapBuffer(void* data, uint32_t size)
83 {
84 uint32_t frameIndex = 0;
86 frameIndex = m_ctx->currentFrameIndex();
87 }
88 mapBuffer(data, size, frameIndex);
89 }
90
92 {
93 if (m_isCreated) {
94 m_ctx->getDevice().waitIdle();
95
96 for (size_t i = 0; i < m_buffers.size(); i++) {
97 if (m_buffers[i]) {
98 m_ctx->getDevice().destroyBuffer(m_buffers[i]);
99 }
100
101 if (m_memories[i]) {
102 m_ctx->getDevice().freeMemory(m_memories[i]);
103 }
104 }
105
106 m_buffers.clear();
107 m_memories.clear();
108
109 m_isCreated = false;
110 }
111 }
113 {
114 auto cmd = static_cast<VK_CommandBuffer*>(cmdBuffer);
115 if (m_isCreated) {
116 uint32_t frameIndex = 0;
118 frameIndex = m_ctx->currentSubmitFrameIndex();
119 checkAndResizeIfNeeded(frameIndex);
120 }
121
122 if (frameIndex < m_buffers.size() && m_buffers[frameIndex]) {
123 cmd->commandBuffer().bindIndexBuffer(m_buffers[frameIndex], 0, getIndexType());
124 }
125 }
126 }
128 {
129 if (frameIndex < m_dirtyFlags.size() && m_dirtyFlags[frameIndex]) {
130 uint32_t currentFrame = m_ctx->currentFrameIndex();
131
132 if (currentFrame != frameIndex && currentFrame < m_buffers.size()) {
133 resizeBuffer(m_size, frameIndex);
134
135 m_dirtyFlags[frameIndex] = 0;
136 }
137 }
138 }
139 void VK_IndexBuffer::resizeBuffer(size_t size, uint32_t frameIndex)
140 {
141 if (size == m_size || !m_isCreated) {
142 return;
143 }
144
145 if (frameIndex >= m_buffers.size()) {
146 frameIndex = frameIndex % m_buffers.size();
147 }
148
149 size_t oldSize = m_size;
150 uint32_t oldBufferSize = static_cast<uint32_t>(oldSize * m_stride);
151 uint32_t newBufferSize = static_cast<uint32_t>(size * m_stride);
152
153 void* tempData = nullptr;
154 uint32_t copySize = static_cast<uint32_t>(std::min(oldSize, size) * m_stride);
155
156 if (copySize > 0) {
157 tempData = malloc(copySize);
158 if (tempData) {
159 void* srcData = m_ctx->getDevice().mapMemory(m_memories[frameIndex], 0, copySize);
160 memcpy(tempData, srcData, copySize);
161 m_ctx->getDevice().unmapMemory(m_memories[frameIndex]);
162 }
163 }
164
165 m_size = size;
166
167 if (m_buffers[frameIndex]) {
168 m_ctx->getDevice().destroyBuffer(m_buffers[frameIndex]);
169 }
170
171 if (m_memories[frameIndex]) {
172 m_ctx->getDevice().freeMemory(m_memories[frameIndex]);
173 }
174
175 vk::BufferCreateInfo bufferInfo;
176 bufferInfo.size = newBufferSize;
177 bufferInfo.usage = vk::BufferUsageFlagBits::eIndexBuffer;
178 bufferInfo.sharingMode = vk::SharingMode::eExclusive;
179
180 m_buffers[frameIndex] = m_ctx->getDevice().createBuffer(bufferInfo);
181
182 vk::MemoryRequirements memRequirements = m_ctx->getDevice().getBufferMemoryRequirements(m_buffers[frameIndex]);
183
184 vk::MemoryAllocateInfo allocInfo;
185 allocInfo.allocationSize = memRequirements.size;
186 allocInfo.memoryTypeIndex = m_ctx->findMemoryType(
187 memRequirements.memoryTypeBits,
188 vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent
189 );
190
191 m_memories[frameIndex] = m_ctx->getDevice().allocateMemory(allocInfo);
192 m_ctx->getDevice().bindBufferMemory(m_buffers[frameIndex], m_memories[frameIndex], 0);
193
194 if (tempData && copySize > 0) {
195 void* mappedData = m_ctx->getDevice().mapMemory(m_memories[frameIndex], 0, copySize);
196 memcpy(mappedData, tempData, copySize);
197 m_ctx->getDevice().unmapMemory(m_memories[frameIndex]);
198 free(tempData);
199 }
200
201 if (frameIndex < m_dirtyFlags.size()) {
202 m_dirtyFlags[frameIndex] = 0;
203 }
204 }
205
206 void VK_IndexBuffer::resize(size_t size)
207 {
208 if (size == m_size) {
209 return;
210 }
211
213 uint32_t currentFrame = m_ctx->currentFrameIndex();
214
215 resizeBuffer(size, currentFrame);
216
217 for (uint32_t i = 0; i < m_dirtyFlags.size(); i++) {
218 if (i != currentFrame) {
219 m_dirtyFlags[i] = 1;
220 }
221 }
222 } else {
223 resizeBuffer(size, 0);
224 }
225 }
226 vk::IndexType VK_IndexBuffer::getIndexType() const
227 {
228 switch (m_stride)
229 {
230 case 1:
231 return vk::IndexType::eUint8;
232 case 2:
233 return vk::IndexType::eUint16;
234 case 4:
235 return vk::IndexType::eUint32;
236 default:
237 return vk::IndexType::eUint32;
238 }
239 }
240 }
241}
UpdateFrequency m_updateFrequency
void checkAndResizeIfNeeded(uint32_t frameIndex)
void resizeBuffer(size_t size, uint32_t frameIndex)
void mapBuffer(void *data, uint32_t size, uint32_t frameIndex)
void bind(CommandBuffer *cmdBuffer)
std::vector< vk::DeviceMemory > m_memories
vk::IndexType getIndexType() const
std::vector< vk::Buffer > m_buffers
void resize(size_t size) override
std::vector< uint8_t > m_dirtyFlags