More level mesh buffer fun
This commit is contained in:
parent
356ad2fe9f
commit
d28a3571b5
5 changed files with 359 additions and 244 deletions
|
|
@ -4,6 +4,13 @@
|
|||
|
||||
LevelMesh::LevelMesh()
|
||||
{
|
||||
LevelMeshLimits limits;
|
||||
limits.MaxVertices = 12;
|
||||
limits.MaxIndexes = 3 * 4;
|
||||
limits.MaxSurfaces = 1;
|
||||
limits.MaxUniforms = 1;
|
||||
Reset(limits);
|
||||
|
||||
// Default portal
|
||||
LevelMeshPortal portal;
|
||||
Portals.Push(portal);
|
||||
|
|
@ -11,38 +18,35 @@ LevelMesh::LevelMesh()
|
|||
AddEmptyMesh();
|
||||
UpdateCollision();
|
||||
|
||||
Mesh.MaxVertices = std::max(Mesh.Vertices.Size() * 2, (unsigned int)10000);
|
||||
Mesh.MaxIndexes = std::max(Mesh.Indexes.Size() * 2, (unsigned int)10000);
|
||||
Mesh.MaxSurfaces = std::max(Mesh.SurfaceIndexes.Size() * 2, (unsigned int)10000);
|
||||
Mesh.MaxUniforms = std::max(Mesh.Uniforms.Size() * 2, (unsigned int)10000);
|
||||
Mesh.MaxSurfaceIndexes = std::max(Mesh.SurfaceIndexes.Size() * 2, (unsigned int)10000);
|
||||
Mesh.MaxNodes = (int)std::max(Collision->get_nodes().size() * 2, (size_t)10000);
|
||||
Mesh.MaxLights = 100'000;
|
||||
Mesh.MaxLightIndexes = 4 * 1024 * 1024;
|
||||
}
|
||||
|
||||
void LevelMesh::AddEmptyMesh()
|
||||
{
|
||||
GeometryAllocInfo ginfo = AllocGeometry(12, 3 * 4);
|
||||
|
||||
// Default empty mesh (we can't make it completely empty since vulkan doesn't like that)
|
||||
float minval = -100001.0f;
|
||||
float maxval = -100000.0f;
|
||||
Mesh.Vertices.Push({ minval, minval, minval });
|
||||
Mesh.Vertices.Push({ maxval, minval, minval });
|
||||
Mesh.Vertices.Push({ maxval, maxval, minval });
|
||||
Mesh.Vertices.Push({ minval, minval, minval });
|
||||
Mesh.Vertices.Push({ minval, maxval, minval });
|
||||
Mesh.Vertices.Push({ maxval, maxval, minval });
|
||||
Mesh.Vertices.Push({ minval, minval, maxval });
|
||||
Mesh.Vertices.Push({ maxval, minval, maxval });
|
||||
Mesh.Vertices.Push({ maxval, maxval, maxval });
|
||||
Mesh.Vertices.Push({ minval, minval, maxval });
|
||||
Mesh.Vertices.Push({ minval, maxval, maxval });
|
||||
Mesh.Vertices.Push({ maxval, maxval, maxval });
|
||||
ginfo.Vertices[0] = { minval, minval, minval };
|
||||
ginfo.Vertices[1] = { maxval, minval, minval };
|
||||
ginfo.Vertices[2] = { maxval, maxval, minval };
|
||||
ginfo.Vertices[3] = { minval, minval, minval };
|
||||
ginfo.Vertices[4] = { minval, maxval, minval };
|
||||
ginfo.Vertices[5] = { maxval, maxval, minval };
|
||||
ginfo.Vertices[6] = { minval, minval, maxval };
|
||||
ginfo.Vertices[7] = { maxval, minval, maxval };
|
||||
ginfo.Vertices[8] = { maxval, maxval, maxval };
|
||||
ginfo.Vertices[9] = { minval, minval, maxval };
|
||||
ginfo.Vertices[10] = { minval, maxval, maxval };
|
||||
ginfo.Vertices[11] = { maxval, maxval, maxval };
|
||||
|
||||
for (int i = 0; i < 3 * 4; i++)
|
||||
Mesh.Indexes.Push(i);
|
||||
ginfo.Indexes[i] = i;
|
||||
|
||||
UploadAll();
|
||||
Mesh.IndexCount = ginfo.IndexCount;
|
||||
|
||||
UploadPortals();
|
||||
}
|
||||
|
||||
LevelMeshSurface* LevelMesh::Trace(const FVector3& start, FVector3 direction, float maxDist)
|
||||
|
|
@ -109,7 +113,7 @@ LevelMeshTileStats LevelMesh::GatherTilePixelStats()
|
|||
|
||||
void LevelMesh::UpdateCollision()
|
||||
{
|
||||
Collision = std::make_unique<TriangleMeshShape>(Mesh.Vertices.Data(), Mesh.Vertices.Size(), Mesh.Indexes.Data(), Mesh.Indexes.Size());
|
||||
Collision = std::make_unique<TriangleMeshShape>(Mesh.Vertices.Data(), Mesh.Vertices.Size(), Mesh.Indexes.Data(), Mesh.IndexCount);
|
||||
UploadCollision();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include "hw_levelmeshsurface.h"
|
||||
#include "hw_materialstate.h"
|
||||
#include "hw_surfaceuniforms.h"
|
||||
#include "engineerrors.h"
|
||||
#include <memory>
|
||||
|
||||
#include <dp_rect_pack.h>
|
||||
|
|
@ -44,12 +45,32 @@ struct UniformsAllocInfo
|
|||
int Count = 0;
|
||||
};
|
||||
|
||||
struct SurfaceAllocInfo
|
||||
{
|
||||
LevelMeshSurface* Surface = nullptr;
|
||||
int Index = 0;
|
||||
};
|
||||
|
||||
struct LightAllocInfo
|
||||
{
|
||||
LevelMeshLight* Light = nullptr;
|
||||
int Index = 0;
|
||||
};
|
||||
|
||||
struct MeshBufferRange
|
||||
{
|
||||
int Offset = 0;
|
||||
int Size = 0;
|
||||
int Start = 0;
|
||||
int End = 0;
|
||||
|
||||
bool operator<(const MeshBufferRange& other) const { return Offset < other.Offset; }
|
||||
int Count() const { return End - Start; }
|
||||
};
|
||||
|
||||
struct LevelMeshLimits
|
||||
{
|
||||
int MaxVertices = 0;
|
||||
int MaxSurfaces = 0;
|
||||
int MaxUniforms = 0;
|
||||
int MaxIndexes = 0;
|
||||
};
|
||||
|
||||
class LevelMesh
|
||||
|
|
@ -71,20 +92,18 @@ public:
|
|||
GeometryAllocInfo AllocGeometry(int vertexCount, int indexCount)
|
||||
{
|
||||
GeometryAllocInfo info;
|
||||
info.VertexStart = Mesh.Vertices.Size();
|
||||
info.VertexStart = RemoveRange(FreeLists.Vertex, vertexCount);
|
||||
info.VertexCount = vertexCount;
|
||||
info.IndexStart = Mesh.Indexes.Size();
|
||||
info.IndexStart = RemoveRange(FreeLists.Index, indexCount);
|
||||
info.IndexCount = indexCount;
|
||||
Mesh.Vertices.Resize(info.VertexStart + vertexCount);
|
||||
Mesh.UniformIndexes.Resize(info.VertexStart + vertexCount);
|
||||
Mesh.Indexes.Resize(info.IndexStart + indexCount);
|
||||
info.Vertices = &Mesh.Vertices[info.VertexStart];
|
||||
info.UniformIndexes = &Mesh.UniformIndexes[info.VertexStart];
|
||||
info.Indexes = &Mesh.Indexes[info.IndexStart];
|
||||
|
||||
AddRange(UploadRanges.Vertex, { info.VertexStart, info.VertexCount });
|
||||
AddRange(UploadRanges.UniformIndexes, { info.VertexStart, info.VertexCount });
|
||||
AddRange(UploadRanges.Index, { info.IndexStart, info.IndexCount });
|
||||
AddRange(UploadRanges.Vertex, { info.VertexStart, info.VertexStart + info.VertexCount });
|
||||
AddRange(UploadRanges.UniformIndexes, { info.VertexStart, info.VertexStart + info.VertexCount });
|
||||
AddRange(UploadRanges.Index, { info.IndexStart, info.IndexStart + info.IndexCount });
|
||||
AddRange(UploadRanges.SurfaceIndex, { info.IndexStart / 3, (info.IndexStart + info.IndexCount) / 3 + 1 });
|
||||
|
||||
return info;
|
||||
}
|
||||
|
|
@ -92,14 +111,23 @@ public:
|
|||
UniformsAllocInfo AllocUniforms(int count)
|
||||
{
|
||||
UniformsAllocInfo info;
|
||||
info.Start = Mesh.Uniforms.Size();
|
||||
info.Start = RemoveRange(FreeLists.Uniforms, count);
|
||||
info.Count = count;
|
||||
Mesh.Uniforms.Resize(info.Start + count);
|
||||
Mesh.Materials.Resize(info.Start + count);
|
||||
info.Uniforms = &Mesh.Uniforms[info.Start];
|
||||
info.Materials = &Mesh.Materials[info.Start];
|
||||
|
||||
AddRange(UploadRanges.Uniforms, { info.Start, info.Count });
|
||||
AddRange(UploadRanges.Uniforms, { info.Start, info.Start + info.Count });
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
SurfaceAllocInfo AllocSurface()
|
||||
{
|
||||
SurfaceAllocInfo info;
|
||||
info.Index = RemoveRange(FreeLists.Surface, 1);
|
||||
info.Surface = &Mesh.Surfaces[info.Index];
|
||||
|
||||
AddRange(UploadRanges.Surface, { info.Index, info.Index + 1 });
|
||||
|
||||
return info;
|
||||
}
|
||||
|
|
@ -109,10 +137,10 @@ public:
|
|||
// Convert triangles to degenerates
|
||||
for (int i = 0; i < indexCount; i++)
|
||||
Mesh.Indexes[indexStart + i] = 0;
|
||||
AddRange(UploadRanges.Index, { indexStart, indexCount });
|
||||
AddRange(UploadRanges.Index, { indexStart, indexStart + indexCount });
|
||||
|
||||
AddRange(FreeLists.Vertex, { vertexStart, vertexCount });
|
||||
AddRange(FreeLists.Index, { indexStart, indexCount });
|
||||
AddRange(FreeLists.Vertex, { vertexStart, vertexStart + vertexCount });
|
||||
AddRange(FreeLists.Index, { indexStart, indexStart + indexCount });
|
||||
}
|
||||
|
||||
void FreeUniforms(int start, int count)
|
||||
|
|
@ -127,6 +155,28 @@ public:
|
|||
AddRange(FreeLists.Surface, { (int)surfaceIndex, 1 });
|
||||
}
|
||||
|
||||
// Sets the sizes of all the GPU buffers and empties the mesh
|
||||
virtual void Reset(const LevelMeshLimits& limits)
|
||||
{
|
||||
Mesh.Vertices.Resize(limits.MaxVertices);
|
||||
Mesh.UniformIndexes.Resize(limits.MaxVertices);
|
||||
|
||||
Mesh.Surfaces.Resize(limits.MaxSurfaces);
|
||||
Mesh.Uniforms.Resize(limits.MaxUniforms);
|
||||
Mesh.Materials.Resize(limits.MaxUniforms);
|
||||
|
||||
Mesh.Lights.Resize(16);
|
||||
Mesh.LightIndexes.Resize(16);
|
||||
|
||||
Mesh.Indexes.Resize(limits.MaxIndexes);
|
||||
Mesh.SurfaceIndexes.Resize(limits.MaxIndexes / 3 + 1);
|
||||
|
||||
FreeLists.Vertex.Clear(); FreeLists.Vertex.Push({ 0, limits.MaxVertices });
|
||||
FreeLists.Index.Clear(); FreeLists.Index.Push({ 0, limits.MaxIndexes });
|
||||
FreeLists.Uniforms.Clear(); FreeLists.Uniforms.Push({ 0, limits.MaxUniforms });
|
||||
FreeLists.Surface.Clear(); FreeLists.Surface.Push({ 0, limits.MaxSurfaces });
|
||||
}
|
||||
|
||||
// Data placed in GPU buffers
|
||||
struct
|
||||
{
|
||||
|
|
@ -146,16 +196,10 @@ public:
|
|||
// Index data
|
||||
TArray<uint32_t> Indexes;
|
||||
TArray<int> SurfaceIndexes;
|
||||
int IndexCount = 0; // Index range filled with data
|
||||
|
||||
// Above data must not be resized beyond these limits as that's the size of the GPU buffers
|
||||
int MaxVertices = 0;
|
||||
int MaxIndexes = 0;
|
||||
int MaxSurfaces = 0;
|
||||
int MaxUniforms = 0;
|
||||
int MaxSurfaceIndexes = 0;
|
||||
// GPU buffer size for collision nodes
|
||||
int MaxNodes = 0;
|
||||
int MaxLights = 0;
|
||||
int MaxLightIndexes = 0;
|
||||
} Mesh;
|
||||
|
||||
// Ranges in mesh that have changed since last upload
|
||||
|
|
@ -207,26 +251,10 @@ public:
|
|||
|
||||
void AddEmptyMesh();
|
||||
|
||||
void UploadAll()
|
||||
void UploadPortals()
|
||||
{
|
||||
ClearRanges(UploadRanges.Vertex);
|
||||
AddRange(UploadRanges.Vertex, { 0, (int)Mesh.Vertices.Size() });
|
||||
ClearRanges(UploadRanges.Index);
|
||||
AddRange(UploadRanges.Index, { 0, (int)Mesh.Indexes.Size() });
|
||||
ClearRanges(UploadRanges.SurfaceIndex);
|
||||
AddRange(UploadRanges.SurfaceIndex, { 0, (int)Mesh.SurfaceIndexes.Size() });
|
||||
ClearRanges(UploadRanges.Surface);
|
||||
AddRange(UploadRanges.Surface, { 0, (int)Mesh.Surfaces.Size() });
|
||||
ClearRanges(UploadRanges.UniformIndexes);
|
||||
AddRange(UploadRanges.UniformIndexes, { 0, (int)Mesh.UniformIndexes.Size() });
|
||||
ClearRanges(UploadRanges.Uniforms);
|
||||
AddRange(UploadRanges.Uniforms, { 0, (int)Mesh.Uniforms.Size() });
|
||||
ClearRanges(UploadRanges.Portals);
|
||||
UploadRanges.Portals.Clear();
|
||||
AddRange(UploadRanges.Portals, { 0, (int)Portals.Size() });
|
||||
ClearRanges(UploadRanges.Light);
|
||||
AddRange(UploadRanges.Light, { 0, (int)Mesh.Lights.Size() });
|
||||
ClearRanges(UploadRanges.LightIndex);
|
||||
AddRange(UploadRanges.LightIndex, { 0, (int)Mesh.LightIndexes.Size() });
|
||||
}
|
||||
|
||||
void UploadCollision()
|
||||
|
|
@ -236,42 +264,81 @@ public:
|
|||
UploadRanges.Node.Push({ 0, (int)Collision->get_nodes().size() });
|
||||
}
|
||||
|
||||
void ClearRanges(TArray<MeshBufferRange>& ranges)
|
||||
int RemoveRange(TArray<MeshBufferRange>& ranges, int count)
|
||||
{
|
||||
ranges.Clear();
|
||||
for (unsigned int i = ranges.Size(); i > 0; i--)
|
||||
{
|
||||
auto& item = ranges[i - 1];
|
||||
if (item.End - item.Start >= count)
|
||||
{
|
||||
int pos = item.Start;
|
||||
item.Start += count;
|
||||
if (item.Start == item.End)
|
||||
{
|
||||
ranges.Delete(i - 1);
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
I_FatalError("Could not find space in level mesh buffer");
|
||||
}
|
||||
|
||||
void AddRange(TArray<MeshBufferRange>& ranges, MeshBufferRange range)
|
||||
{
|
||||
if (range.Size <= 0)
|
||||
// Empty range?
|
||||
if (range.Start == range.End)
|
||||
return;
|
||||
|
||||
auto right = std::lower_bound(ranges.begin(), ranges.end(), range);
|
||||
// First element?
|
||||
if (ranges.Size() == 0)
|
||||
{
|
||||
ranges.push_back(range);
|
||||
return;
|
||||
}
|
||||
|
||||
// Find start position in ranges
|
||||
auto right = std::lower_bound(ranges.begin(), ranges.end(), range, [](const auto& a, const auto& b) { return a.Start < b.Start; });
|
||||
bool leftExists = right != ranges.begin();
|
||||
bool rightExists = right != ranges.end();
|
||||
|
||||
auto left = right;
|
||||
if (leftExists)
|
||||
--left;
|
||||
|
||||
if (leftExists && rightExists && left->Offset + left->Size == range.Offset && right->Offset == range.Offset + range.Size) // ####[--]####
|
||||
{
|
||||
left->Size += range.Size + right->Size;
|
||||
ranges.Delete(right - ranges.begin());
|
||||
}
|
||||
else if (leftExists && left->Offset + left->Size == range.Offset) // ####[--] ####
|
||||
{
|
||||
left->Size += range.Size;
|
||||
}
|
||||
else if (rightExists && right->Offset == range.Offset + range.Size) // #### [--]####
|
||||
{
|
||||
right->Offset -= range.Size;
|
||||
}
|
||||
else // ##### [--] ####
|
||||
// Is this a gap between two ranges?
|
||||
if ((!leftExists || left->End < range.Start) && (!rightExists || right->Start > range.End))
|
||||
{
|
||||
ranges.Insert(right - ranges.begin(), range);
|
||||
return;
|
||||
}
|
||||
|
||||
// Are we extending the left or the right range?
|
||||
if (leftExists && range.Start <= left->End)
|
||||
{
|
||||
left->End = std::max(left->End, range.End);
|
||||
right = left;
|
||||
}
|
||||
else // if (rightExists && right->Start <= range.End)
|
||||
{
|
||||
right->Start = range.Start;
|
||||
right->End = std::max(right->End, range.End);
|
||||
left = right;
|
||||
}
|
||||
|
||||
// Merge overlaps to the right
|
||||
while (true)
|
||||
{
|
||||
++right;
|
||||
if (right == ranges.end() || right->Start > range.End)
|
||||
break;
|
||||
left->End = std::max(right->End, range.End);
|
||||
}
|
||||
|
||||
// Remove ranges now covered by the extended range
|
||||
//ranges.erase(++left, right);
|
||||
++left;
|
||||
auto leftPos = left - ranges.begin();
|
||||
auto rightPos = right - ranges.begin();
|
||||
ranges.Delete(leftPos, rightPos - leftPos);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ void VkLevelMesh::CreateVulkanObjects()
|
|||
.AddMemory(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_SHADER_READ_BIT)
|
||||
.Execute(fb->GetCommands()->GetTransferCommands(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||
|
||||
DynamicBLAS = CreateBLAS(true, 0, Mesh->Mesh.Indexes.Size());
|
||||
DynamicBLAS = CreateBLAS(true, 0, Mesh->Mesh.IndexCount);
|
||||
CreateTLASInstanceBuffer();
|
||||
|
||||
UploadTLASInstanceBuffer();
|
||||
|
|
@ -128,7 +128,7 @@ void VkLevelMesh::BeginFrame()
|
|||
deletelist->Add(std::move(DynamicBLAS.AccelStructBuffer));
|
||||
deletelist->Add(std::move(DynamicBLAS.AccelStruct));
|
||||
|
||||
DynamicBLAS = CreateBLAS(true, 0, Mesh->Mesh.Indexes.Size());
|
||||
DynamicBLAS = CreateBLAS(true, 0, Mesh->Mesh.IndexCount);
|
||||
|
||||
deletelist->Add(std::move(TopLevelAS.TransferBuffer));
|
||||
deletelist->Add(std::move(TopLevelAS.InstanceBuffer));
|
||||
|
|
@ -173,7 +173,7 @@ void VkLevelMesh::CreateBuffers()
|
|||
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT |
|
||||
VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR : 0) |
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)
|
||||
.Size(Mesh->Mesh.MaxVertices * sizeof(FFlatVertex))
|
||||
.Size(Mesh->Mesh.Vertices.Size() * sizeof(FFlatVertex))
|
||||
.DebugName("VertexBuffer")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
|
|
@ -181,7 +181,7 @@ void VkLevelMesh::CreateBuffers()
|
|||
.Usage(
|
||||
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
|
||||
VK_BUFFER_USAGE_TRANSFER_DST_BIT)
|
||||
.Size(Mesh->Mesh.MaxVertices * sizeof(int))
|
||||
.Size(Mesh->Mesh.UniformIndexes.size() * sizeof(int))
|
||||
.DebugName("UniformIndexes")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
|
|
@ -193,7 +193,7 @@ void VkLevelMesh::CreateBuffers()
|
|||
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT |
|
||||
VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR : 0) |
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)
|
||||
.Size((size_t)Mesh->Mesh.MaxIndexes * sizeof(uint32_t))
|
||||
.Size((size_t)Mesh->Mesh.Indexes.Size() * sizeof(uint32_t))
|
||||
.DebugName("IndexBuffer")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
|
|
@ -205,19 +205,19 @@ void VkLevelMesh::CreateBuffers()
|
|||
|
||||
SurfaceIndexBuffer = BufferBuilder()
|
||||
.Usage(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT)
|
||||
.Size(Mesh->Mesh.MaxSurfaceIndexes * sizeof(int))
|
||||
.Size(Mesh->Mesh.SurfaceIndexes.Size() * sizeof(int))
|
||||
.DebugName("SurfaceBuffer")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
SurfaceBuffer = BufferBuilder()
|
||||
.Usage(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT)
|
||||
.Size(Mesh->Mesh.MaxSurfaces * sizeof(SurfaceInfo))
|
||||
.Size(Mesh->Mesh.Surfaces.Size() * sizeof(SurfaceInfo))
|
||||
.DebugName("SurfaceBuffer")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
UniformsBuffer = BufferBuilder()
|
||||
.Usage(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT)
|
||||
.Size(Mesh->Mesh.MaxUniforms * sizeof(SurfaceUniforms))
|
||||
.Size(Mesh->Mesh.Uniforms.Size() * sizeof(SurfaceUniforms))
|
||||
.DebugName("SurfaceUniformsBuffer")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
|
|
@ -229,13 +229,13 @@ void VkLevelMesh::CreateBuffers()
|
|||
|
||||
LightBuffer = BufferBuilder()
|
||||
.Usage(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT)
|
||||
.Size(Mesh->Mesh.MaxLights * sizeof(LightInfo))
|
||||
.Size(Mesh->Mesh.Lights.Size() * sizeof(LightInfo))
|
||||
.DebugName("LightBuffer")
|
||||
.Create(fb->GetDevice());
|
||||
|
||||
LightIndexBuffer = BufferBuilder()
|
||||
.Usage(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT)
|
||||
.Size(Mesh->Mesh.MaxLightIndexes * sizeof(int32_t))
|
||||
.Size(Mesh->Mesh.LightIndexes.Size() * sizeof(int32_t))
|
||||
.DebugName("LightIndexBuffer")
|
||||
.Create(fb->GetDevice());
|
||||
}
|
||||
|
|
@ -518,9 +518,9 @@ void VkLevelMeshUploader::UploadNodes()
|
|||
{
|
||||
const auto& srcnodes = Mesh->Mesh->Collision->get_nodes();
|
||||
CollisionNode* nodes = (CollisionNode*)(data + datapos);
|
||||
for (int i = 0, count = range.Size; i < count; i++)
|
||||
for (int i = 0, count = range.Count(); i < count; i++)
|
||||
{
|
||||
const auto& node = srcnodes[range.Offset + i];
|
||||
const auto& node = srcnodes[range.Start + i];
|
||||
CollisionNode info;
|
||||
info.center = SwapYZ(node.aabb.Center);
|
||||
info.extents = SwapYZ(node.aabb.Extents);
|
||||
|
|
@ -530,9 +530,9 @@ void VkLevelMeshUploader::UploadNodes()
|
|||
*(nodes++) = info;
|
||||
}
|
||||
|
||||
size_t copysize = range.Size * sizeof(CollisionNode);
|
||||
size_t copysize = range.Count() * sizeof(CollisionNode);
|
||||
if (copysize > 0)
|
||||
copyCommands.emplace_back(transferBuffer.get(), Mesh->NodeBuffer.get(), datapos, sizeof(CollisionNodeBufferHeader) + range.Offset * sizeof(CollisionNode), copysize);
|
||||
copyCommands.emplace_back(transferBuffer.get(), Mesh->NodeBuffer.get(), datapos, sizeof(CollisionNodeBufferHeader) + range.Start * sizeof(CollisionNode), copysize);
|
||||
datapos += copysize;
|
||||
}
|
||||
}
|
||||
|
|
@ -542,10 +542,10 @@ void VkLevelMeshUploader::UploadRanges(const TArray<MeshBufferRange>& ranges, co
|
|||
{
|
||||
for (const MeshBufferRange& range : ranges)
|
||||
{
|
||||
size_t copysize = range.Size * sizeof(T);
|
||||
memcpy(data + datapos, srcbuffer + range.Offset, copysize);
|
||||
size_t copysize = range.Count() * sizeof(T);
|
||||
memcpy(data + datapos, srcbuffer + range.Start, copysize);
|
||||
if (copysize > 0)
|
||||
copyCommands.emplace_back(transferBuffer.get(), destbuffer, datapos, range.Offset * sizeof(T), copysize);
|
||||
copyCommands.emplace_back(transferBuffer.get(), destbuffer, datapos, range.Start * sizeof(T), copysize);
|
||||
datapos += copysize;
|
||||
}
|
||||
}
|
||||
|
|
@ -555,9 +555,9 @@ void VkLevelMeshUploader::UploadSurfaces()
|
|||
for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.Surface)
|
||||
{
|
||||
SurfaceInfo* surfaces = (SurfaceInfo*)(data + datapos);
|
||||
for (int j = 0, count = range.Size; j < count; j++)
|
||||
for (int j = 0, count = range.Count(); j < count; j++)
|
||||
{
|
||||
LevelMeshSurface* surface = &Mesh->Mesh->Mesh.Surfaces[range.Offset + j];
|
||||
LevelMeshSurface* surface = &Mesh->Mesh->Mesh.Surfaces[range.Start + j];
|
||||
|
||||
SurfaceInfo info;
|
||||
info.Normal = FVector3(surface->Plane.X, surface->Plane.Z, surface->Plane.Y);
|
||||
|
|
@ -579,9 +579,9 @@ void VkLevelMeshUploader::UploadSurfaces()
|
|||
*(surfaces++) = info;
|
||||
}
|
||||
|
||||
size_t copysize = range.Size * sizeof(SurfaceInfo);
|
||||
size_t copysize = range.Count() * sizeof(SurfaceInfo);
|
||||
if (copysize > 0)
|
||||
copyCommands.emplace_back(transferBuffer.get(), Mesh->SurfaceBuffer.get(), datapos, range.Offset * sizeof(SurfaceInfo), copysize);
|
||||
copyCommands.emplace_back(transferBuffer.get(), Mesh->SurfaceBuffer.get(), datapos, range.Start * sizeof(SurfaceInfo), copysize);
|
||||
datapos += copysize;
|
||||
}
|
||||
}
|
||||
|
|
@ -590,10 +590,10 @@ void VkLevelMeshUploader::UploadUniforms()
|
|||
{
|
||||
for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.Uniforms)
|
||||
{
|
||||
for (int j = 0, count = range.Size; j < count; j++)
|
||||
for (int j = 0, count = range.Count(); j < count; j++)
|
||||
{
|
||||
auto& surfaceUniforms = Mesh->Mesh->Mesh.Uniforms[range.Offset + j];
|
||||
auto& material = Mesh->Mesh->Mesh.Materials[range.Offset + j];
|
||||
auto& surfaceUniforms = Mesh->Mesh->Mesh.Uniforms[range.Start + j];
|
||||
auto& material = Mesh->Mesh->Mesh.Materials[range.Start + j];
|
||||
if (material.mMaterial)
|
||||
{
|
||||
auto source = material.mMaterial->Source();
|
||||
|
|
@ -607,10 +607,10 @@ void VkLevelMeshUploader::UploadUniforms()
|
|||
}
|
||||
|
||||
SurfaceUniforms* uniforms = (SurfaceUniforms*)(data + datapos);
|
||||
size_t copysize = range.Size * sizeof(SurfaceUniforms);
|
||||
size_t copysize = range.Count() * sizeof(SurfaceUniforms);
|
||||
memcpy(uniforms, Mesh->Mesh->Mesh.Uniforms.Data(), copysize);
|
||||
if (copysize > 0)
|
||||
copyCommands.emplace_back(transferBuffer.get(), Mesh->UniformsBuffer.get(), datapos, range.Offset * sizeof(SurfaceUniforms), copysize);
|
||||
copyCommands.emplace_back(transferBuffer.get(), Mesh->UniformsBuffer.get(), datapos, range.Start * sizeof(SurfaceUniforms), copysize);
|
||||
datapos += copysize;
|
||||
}
|
||||
}
|
||||
|
|
@ -620,17 +620,17 @@ void VkLevelMeshUploader::UploadPortals()
|
|||
for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.Portals)
|
||||
{
|
||||
PortalInfo* portals = (PortalInfo*)(data + datapos);
|
||||
for (int i = 0, count = range.Size; i < count; i++)
|
||||
for (int i = 0, count = range.Count(); i < count; i++)
|
||||
{
|
||||
const auto& portal = Mesh->Mesh->Portals[range.Offset + i];
|
||||
const auto& portal = Mesh->Mesh->Portals[range.Start + i];
|
||||
PortalInfo info;
|
||||
info.transformation = portal.transformation;
|
||||
*(portals++) = info;
|
||||
}
|
||||
|
||||
size_t copysize = range.Size * sizeof(PortalInfo);
|
||||
size_t copysize = range.Count() * sizeof(PortalInfo);
|
||||
if (copysize > 0)
|
||||
copyCommands.emplace_back(transferBuffer.get(), Mesh->PortalBuffer.get(), datapos, range.Offset * sizeof(PortalInfo), copysize);
|
||||
copyCommands.emplace_back(transferBuffer.get(), Mesh->PortalBuffer.get(), datapos, range.Start * sizeof(PortalInfo), copysize);
|
||||
datapos += copysize;
|
||||
}
|
||||
}
|
||||
|
|
@ -640,9 +640,9 @@ void VkLevelMeshUploader::UploadLights()
|
|||
for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.Light)
|
||||
{
|
||||
LightInfo* lights = (LightInfo*)(data + datapos);
|
||||
for (int i = 0, count = range.Size; i < count; i++)
|
||||
for (int i = 0, count = range.Count(); i < count; i++)
|
||||
{
|
||||
const auto& light = Mesh->Mesh->Mesh.Lights[range.Offset + i];
|
||||
const auto& light = Mesh->Mesh->Mesh.Lights[range.Start + i];
|
||||
LightInfo info;
|
||||
info.Origin = SwapYZ(light.Origin);
|
||||
info.RelativeOrigin = SwapYZ(light.RelativeOrigin);
|
||||
|
|
@ -656,9 +656,9 @@ void VkLevelMeshUploader::UploadLights()
|
|||
*(lights++) = info;
|
||||
}
|
||||
|
||||
size_t copysize = range.Size * sizeof(LightInfo);
|
||||
size_t copysize = range.Count() * sizeof(LightInfo);
|
||||
if (copysize > 0)
|
||||
copyCommands.emplace_back(transferBuffer.get(), Mesh->LightBuffer.get(), datapos, range.Offset * sizeof(LightInfo), copysize);
|
||||
copyCommands.emplace_back(transferBuffer.get(), Mesh->LightBuffer.get(), datapos, range.Start * sizeof(LightInfo), copysize);
|
||||
datapos += copysize;
|
||||
}
|
||||
}
|
||||
|
|
@ -670,16 +670,16 @@ size_t VkLevelMeshUploader::GetTransferSize()
|
|||
if (!Mesh->useRayQuery)
|
||||
{
|
||||
if (Mesh->Mesh->UploadRanges.Node.Size() > 0) transferBufferSize += sizeof(CollisionNodeBufferHeader) + sizeof(CollisionNode);
|
||||
for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.Node) transferBufferSize += range.Size * sizeof(CollisionNode);
|
||||
for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.Node) transferBufferSize += range.Count() * sizeof(CollisionNode);
|
||||
}
|
||||
for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.Vertex) transferBufferSize += range.Size * sizeof(FFlatVertex);
|
||||
for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.UniformIndexes) transferBufferSize += range.Size * sizeof(int);
|
||||
for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.Index) transferBufferSize += range.Size * sizeof(uint32_t);
|
||||
for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.SurfaceIndex) transferBufferSize += range.Size * sizeof(int);
|
||||
for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.Surface) transferBufferSize += range.Size * sizeof(SurfaceInfo);
|
||||
for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.Uniforms) transferBufferSize += range.Size * sizeof(SurfaceUniforms);
|
||||
for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.Portals) transferBufferSize += range.Size * sizeof(PortalInfo);
|
||||
for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.LightIndex) transferBufferSize += range.Size * sizeof(int32_t);
|
||||
for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.Light) transferBufferSize += range.Size * sizeof(LightInfo);
|
||||
for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.Vertex) transferBufferSize += range.Count() * sizeof(FFlatVertex);
|
||||
for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.UniformIndexes) transferBufferSize += range.Count() * sizeof(int);
|
||||
for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.Index) transferBufferSize += range.Count() * sizeof(uint32_t);
|
||||
for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.SurfaceIndex) transferBufferSize += range.Count() * sizeof(int);
|
||||
for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.Surface) transferBufferSize += range.Count() * sizeof(SurfaceInfo);
|
||||
for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.Uniforms) transferBufferSize += range.Count() * sizeof(SurfaceUniforms);
|
||||
for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.Portals) transferBufferSize += range.Count() * sizeof(PortalInfo);
|
||||
for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.LightIndex) transferBufferSize += range.Count() * sizeof(int32_t);
|
||||
for (const MeshBufferRange& range : Mesh->Mesh->UploadRanges.Light) transferBufferSize += range.Count() * sizeof(LightInfo);
|
||||
return transferBufferSize;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue