8void Graphics::ensureGpuVertexPool() {
9 if (gpuVertexPool_.positions.buffer)
return;
10 constexpr uint32_t kInitialVertices = 256u << 10;
11 constexpr uint32_t kInitialIndices = 768u << 10;
12 const auto hostMem = kHostVisibleCoherent;
13 gpuVertexPool_.positions = vkb::GenericBuffer(device, vk::BufferUsageFlagBits::eStorageBuffer,
14 kInitialVertices *
sizeof(glm::vec4), hostMem);
15 gpuVertexPool_.normals = vkb::GenericBuffer(device, vk::BufferUsageFlagBits::eStorageBuffer,
16 kInitialVertices *
sizeof(glm::vec4), hostMem);
17 gpuVertexPool_.uvs = vkb::GenericBuffer(device, vk::BufferUsageFlagBits::eStorageBuffer,
18 kInitialVertices *
sizeof(glm::vec2), hostMem);
19 gpuVertexPool_.indices = vkb::GenericBuffer(device, vk::BufferUsageFlagBits::eStorageBuffer,
20 kInitialIndices *
sizeof(uint32_t), hostMem);
21 gpuVertexPool_.vertexCount = 0;
22 gpuVertexPool_.indexCount = 0;
25void Graphics::growGpuVertexPool(uint32_t needVertices, uint32_t needIndices) {
29 const uint32_t oldVerts = gpuVertexPool_.vertexCount;
30 const uint32_t oldInds = gpuVertexPool_.indexCount;
31 const auto hostMem = kHostVisibleCoherent;
32 auto copyInto = [&](vkb::GenericBuffer& dst, vkb::GenericBuffer& src, vk::DeviceSize oldBytes,
33 vk::DeviceSize newBytes) {
34 vkb::GenericBuffer grown(device, vk::BufferUsageFlagBits::eStorageBuffer, newBytes, hostMem);
36 void* srcMap = src.map();
37 void* dstMap = grown.map();
38 std::memcpy(dstMap, srcMap, oldBytes);
43 dst = std::move(grown);
47 const auto capacity = [](uint32_t needed) {
48 return uint32_t(std::min(uint64_t(needed) * 2u, uint64_t(UINT32_MAX)));
50 const uint32_t newVerts =
51 std::max(
capacity(needVertices), uint32_t(gpuVertexPool_.positions.size /
sizeof(glm::vec4)));
52 const uint32_t newInds = std::max(
capacity(needIndices), uint32_t(gpuVertexPool_.indices.size /
sizeof(uint32_t)));
53 copyInto(gpuVertexPool_.positions, gpuVertexPool_.positions, vk::DeviceSize(oldVerts) *
sizeof(glm::vec4),
54 vk::DeviceSize(newVerts) *
sizeof(glm::vec4));
55 copyInto(gpuVertexPool_.normals, gpuVertexPool_.normals, vk::DeviceSize(oldVerts) *
sizeof(glm::vec4),
56 vk::DeviceSize(newVerts) *
sizeof(glm::vec4));
57 copyInto(gpuVertexPool_.uvs, gpuVertexPool_.uvs, vk::DeviceSize(oldVerts) *
sizeof(glm::vec2),
58 vk::DeviceSize(newVerts) *
sizeof(glm::vec2));
59 copyInto(gpuVertexPool_.indices, gpuVertexPool_.indices, vk::DeviceSize(oldInds) *
sizeof(uint32_t),
60 vk::DeviceSize(newInds) *
sizeof(uint32_t));
61 bindGpuVertexPoolBindless();
64void Graphics::bindGpuVertexPoolBindless() {
65 if (bindlessSets_.empty() || !gpuVertexPool_.positions.buffer)
return;
66 auto bufWrite = [&](vk::DescriptorSet set, uint32_t
binding, vk::Buffer
buffer, vk::DeviceSize
size) {
68 vk::WriteDescriptorSet
w{};
71 w.descriptorCount = 1;
72 w.descriptorType = vk::DescriptorType::eStorageBuffer;
73 w.pBufferInfo = &
info;
74 device->updateDescriptorSets(1, &
w, 0,
nullptr);
76 const uint32_t cap = [&]() {
77 const vk::DeviceSize
bytes = gpuVertexPool_.positions.size;
78 return uint32_t(
bytes /
sizeof(glm::vec4));
80 const uint32_t indCap = uint32_t(gpuVertexPool_.indices.size /
sizeof(uint32_t));
81 for (vk::DescriptorSet set : bindlessSets_) {
82 bufWrite(set, 18, gpuVertexPool_.positions.buffer, vk::DeviceSize(cap) *
sizeof(glm::vec4));
83 bufWrite(set, 19, gpuVertexPool_.normals.buffer, vk::DeviceSize(cap) *
sizeof(glm::vec4));
84 bufWrite(set, 20, gpuVertexPool_.uvs.buffer, vk::DeviceSize(cap) *
sizeof(glm::vec2));
85 bufWrite(set, 21, gpuVertexPool_.indices.buffer, vk::DeviceSize(indCap) *
sizeof(uint32_t));
89void Graphics::appendGpuMeshToPool(GpuMesh& gpu,
const std::vector<MeshVertex>*
vertices,
90 const std::vector<uint32_t>*
indices) {
91 if (!gpu.vertices.buffer || !gpu.indices.buffer)
return;
92 ensureGpuVertexPool();
93 const uint32_t nVerts = gpu.record.vertexCount;
94 const uint32_t nInds = gpu.record.indexCount;
95 if (nVerts == 0 || nInds == 0)
return;
96 const uint32_t newVerts = gpuVertexPool_.vertexCount + nVerts;
97 const uint32_t newInds = gpuVertexPool_.indexCount + nInds;
98 const uint32_t capVerts = uint32_t(gpuVertexPool_.positions.size /
sizeof(glm::vec4));
99 const uint32_t capInds = uint32_t(gpuVertexPool_.indices.size /
sizeof(uint32_t));
100 if (newVerts > capVerts || newInds > capInds) {
101 growGpuVertexPool(newVerts, newInds);
106 if (!vMap || !iMap)
return;
107 auto*
verts =
static_cast<const MeshVertex*
>(vMap);
108 auto* posDst =
static_cast<glm::vec4*
>(gpuVertexPool_.positions.map());
109 auto* nrmDst =
static_cast<glm::vec4*
>(gpuVertexPool_.normals.map());
110 auto* uvDst =
static_cast<glm::vec2*
>(gpuVertexPool_.uvs.map());
111 auto* idxDst =
static_cast<uint32_t*
>(gpuVertexPool_.indices.map());
112 if (!posDst || !nrmDst || !uvDst || !idxDst) {
113 if (!
vertices) gpu.vertices.unmap();
114 if (!
indices) gpu.indices.unmap();
117 posDst += gpuVertexPool_.vertexCount;
118 nrmDst += gpuVertexPool_.vertexCount;
119 uvDst += gpuVertexPool_.vertexCount;
120 idxDst += gpuVertexPool_.indexCount;
121 for (uint32_t i = 0; i < nVerts; ++i) {
122 posDst[i] = glm::vec4(
verts[i].
pos, 0.f);
124 uvDst[i] =
verts[i].uv;
126 if (!
indices && gpu.indexType == vk::IndexType::eUint16) {
127 const auto* src16 =
static_cast<const uint16_t*
>(iMap);
128 for (uint32_t i = 0; i < nInds; ++i) idxDst[i] = uint32_t(src16[i]);
130 const auto* src32 =
static_cast<const uint32_t*
>(iMap);
131 for (uint32_t i = 0; i < nInds; ++i) idxDst[i] = src32[i];
133 gpuVertexPool_.positions.unmap();
134 gpuVertexPool_.normals.unmap();
135 gpuVertexPool_.uvs.unmap();
136 gpuVertexPool_.indices.unmap();
137 if (!
vertices) gpu.vertices.unmap();
138 if (!
indices) gpu.indices.unmap();
141 gpu.record.vertexOffset = gpuVertexPool_.vertexCount;
142 gpu.record.indexOffset = gpuVertexPool_.indexCount;
143 gpu.record.firstIndex = 0;
144 gpu.record.vertexBase = 0;
145 gpuVertexPool_.vertexCount = newVerts;
146 gpuVertexPool_.indexCount = newInds;
149uint32_t Graphics::registerMeshRecord(GpuMesh* gpu,
const std::vector<MeshVertex>*
vertices,
150 const std::vector<uint32_t>*
indices) {
156 if (gpu->record.vertexCount == 0 && gpu->vertices.buffer) {
157 const uint32_t
vertexCount = uint32_t(gpu->vertices.size /
sizeof(MeshVertex));
159 gpu->record.indexCount = gpu->indexCount;
160 gpu->record.indexType = gpu->indexType == vk::IndexType::eUint16 ? 0
u : 1u;
163 const auto*
verts =
static_cast<const MeshVertex*
>(map);
164 glm::vec3 minv(1e30f), maxv(-1e30f);
166 minv = glm::min(minv,
verts[i].
pos);
167 maxv = glm::max(maxv,
verts[i].
pos);
169 const glm::vec3
center = (minv + maxv) * 0.5f;
172 gpu->record.boundsCenterRadius = glm::vec4(
center,
radius);
174 if (map && !
vertices) gpu->vertices.unmap();
179 const uint32_t
idx = uint32_t(meshTableRecords_.size());
180 meshTableRecords_.push_back(gpu->record);
181 meshRecordOwners_.push_back(gpu);
182 gpu->gpuRecordIndex =
idx;
std::vector< std::uint32_t > verts
std::uint32_t vertexCount
std::vector< std::uint32_t > indices
std::unique_ptr< gpgpu::GpuBuffer > buffer
eve::action::ActionVfxBinding binding
std::vector< Point > vertices
constexpr uint32_t kInvalidBindlessSlot