FCT
载入中...
搜索中...
未找到
VK_VertexBuffer.cpp
浏览该文件的文档.
1//
2// Created by Administrator on 2025/4/9.
3//
4
5#include "./VK_VertexBuffer.h"
8
9namespace FCT
10{
11 namespace RHI
12 {
20
22 {
23 for (size_t i = 0; i < m_buffers.size(); ++i)
24 {
25 if (m_buffers[i])
26 {
27 m_ctx->getDevice().destroyBuffer(m_buffers[i]);
28 }
29
30 if (m_memories[i])
31 {
32 m_ctx->getDevice().freeMemory(m_memories[i]);
33 }
34 }
35 }
36
37 void VK_VertexBuffer::createSingleBuffer(vk::Buffer& buffer, vk::DeviceMemory& memory)
38 {
39 vk::BufferCreateInfo bufferInfo{};
40 bufferInfo.size = m_size * m_stride;
41 bufferInfo.usage = vk::BufferUsageFlagBits::eVertexBuffer;
42 bufferInfo.sharingMode = vk::SharingMode::eExclusive;
43 buffer = m_ctx->getDevice().createBuffer(bufferInfo);
44 vk::MemoryRequirements memRequirements = m_ctx->getDevice().getBufferMemoryRequirements(buffer);
45 vk::MemoryAllocateInfo allocInfo{};
46 allocInfo.allocationSize = memRequirements.size;
47 allocInfo.memoryTypeIndex = m_ctx->findMemoryType(memRequirements.memoryTypeBits,
48 vk::MemoryPropertyFlagBits::eHostVisible |
49 vk::MemoryPropertyFlagBits::eHostCoherent);
50 memory = m_ctx->getDevice().allocateMemory(allocInfo);
51 m_ctx->getDevice().bindBufferMemory(buffer, memory, 0);
52 }
53
54 void VK_VertexBuffer::resize(uint32_t newSize)
55 {
56 if (newSize == m_size)
57 return;
58
59 m_newSize = newSize;
60 m_pendingResize = true;
61
63 {
64 m_dirtyFrames.resize(1, true);
65 }
66 else
67 {
68 uint32_t frameCount = m_ctx->maxFrameInFlight();
69 m_dirtyFrames.resize(frameCount, true);
70 }
71
73 {
75 }
76 else
77 {
78 uint32_t currentFrame = m_ctx->currentFrameIndex();
79 resizeBufferIfNeeded(currentFrame);
80 }
81 }
82
83 void VK_VertexBuffer::resizeBufferIfNeeded(uint32_t frameIndex)
84 {
85 if (frameIndex >= m_buffers.size() || frameIndex >= m_dirtyFrames.size())
86 return;
87
88 if (!m_dirtyFrames[frameIndex])
89 return;
90
91 vk::Buffer oldBuffer = m_buffers[frameIndex];
92 vk::DeviceMemory oldMemory = m_memories[frameIndex];
93
95
96 createSingleBuffer(m_buffers[frameIndex], m_memories[frameIndex]);
97
98 if (oldBuffer)
99 {
100 m_ctx->getDevice().destroyBuffer(oldBuffer);
101 }
102
103 if (oldMemory)
104 {
105 m_ctx->getDevice().freeMemory(oldMemory);
106 }
107
108 m_dirtyFrames[frameIndex] = false;
109
110 bool allResized = true;
111 for (bool dirty : m_dirtyFrames)
112 {
113 if (dirty)
114 {
115 allResized = false;
116 break;
117 }
118 }
119
120 if (allResized)
121 {
122 m_pendingResize = false;
123 }
124 }
125
127 {
129 {
130 m_buffers.resize(1);
131 m_memories.resize(1);
132 m_dirtyFrames.resize(1, false);
134 }
135 else
136 {
137 uint32_t frameCount = m_ctx->maxFrameInFlight();
138 m_buffers.resize(frameCount);
139 m_memories.resize(frameCount);
140 m_dirtyFrames.resize(frameCount, false);
141
142 for (uint32_t i = 0; i < frameCount; ++i)
143 {
145 }
146 }
147
148 m_pendingResize = false;
149 }
150
151 void VK_VertexBuffer::mapBuffer(void* data, uint32_t size)
152 {
154 {
156
157 void* mappedData = m_ctx->getDevice().mapMemory(m_memories[0], 0, size, vk::MemoryMapFlags());
158 memcpy(mappedData, data, size);
159 m_ctx->getDevice().unmapMemory(m_memories[0]);
160 }
161 else
162 {
163 uint32_t currentFrame = m_ctx->currentFrameIndex();
164
165 resizeBufferIfNeeded(currentFrame);
166
167 void* mappedData = m_ctx->getDevice().mapMemory(m_memories[currentFrame], 0, size, vk::MemoryMapFlags());
168 memcpy(mappedData, data, size);
169 m_ctx->getDevice().unmapMemory(m_memories[currentFrame]);
170 }
171 }
172
173 void VK_VertexBuffer::mapBuffer(void* data, uint32_t size, uint32_t frameIndex)
174 {
176 {
178
179 void* mappedData = m_ctx->getDevice().mapMemory(m_memories[0], 0, size, vk::MemoryMapFlags());
180 memcpy(mappedData, data, size);
181 m_ctx->getDevice().unmapMemory(m_memories[0]);
182 }
183 else
184 {
185 uint32_t index = frameIndex % m_ctx->maxFrameInFlight();
186
188
189 void* mappedData = m_ctx->getDevice().mapMemory(m_memories[index], 0, size, vk::MemoryMapFlags());
190 memcpy(mappedData, data, size);
191 m_ctx->getDevice().unmapMemory(m_memories[index]);
192 }
193 }
194
195 void VK_VertexBuffer::bind(CommandBuffer* srcCmd, uint32_t slot, uint32_t srcOffset)
196 {
197 VK_CommandBuffer* cmd = static_cast<VK_CommandBuffer*>(srcCmd);
198 vk::DeviceSize offset = static_cast<vk::DeviceSize>(srcOffset);
199
201 {
203
204 cmd->commandBuffer().bindVertexBuffers(slot, 1, &m_buffers[0], &offset);
205 }
206 else
207 {
208 uint32_t currentFrame = m_ctx->currentSubmitFrameIndex();
209
210 resizeBufferIfNeeded(currentFrame);
211
212 cmd->commandBuffer().bindVertexBuffers(slot, 1, &m_buffers[currentFrame], &offset);
213 }
214 }
215 }
216}
void resizeBufferIfNeeded(uint32_t frameIndex)
void mapBuffer(void *data, uint32_t size) override
void bind(CommandBuffer *srcCmd, uint32_t slot, uint32_t offset) override
void createSingleBuffer(vk::Buffer &buffer, vk::DeviceMemory &memory)
std::vector< vk::Buffer > m_buffers
std::vector< vk::DeviceMemory > m_memories
std::vector< uint8_t > m_dirtyFrames
UpdateFrequency m_updateFrequency