From 5a1c8131c51230fcfce12a57fd1e68aaa757c45e Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sat, 7 Sep 2024 00:42:49 +0200 Subject: [PATCH] Move inlined functions out of the class definition for better readability --- .../hwrenderer/data/hw_levelmesh.cpp | 24 ++ .../rendering/hwrenderer/data/hw_levelmesh.h | 403 +++++++++--------- 2 files changed, 222 insertions(+), 205 deletions(-) diff --git a/src/common/rendering/hwrenderer/data/hw_levelmesh.cpp b/src/common/rendering/hwrenderer/data/hw_levelmesh.cpp index 5f9fb459c..78ca51cc8 100644 --- a/src/common/rendering/hwrenderer/data/hw_levelmesh.cpp +++ b/src/common/rendering/hwrenderer/data/hw_levelmesh.cpp @@ -21,6 +21,30 @@ LevelMesh::LevelMesh() Mesh.MaxNodes = (int)std::max(Collision->get_nodes().size() * 2, (size_t)10000); } +void LevelMesh::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); + + Mesh.DrawIndexes.Resize(limits.MaxIndexes); + + 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 }); + FreeLists.DrawIndex.Clear(); FreeLists.DrawIndex.Push({ 0, limits.MaxIndexes }); +} + void LevelMesh::AddEmptyMesh() { GeometryAllocInfo ginfo = AllocGeometry(12, 3 * 4); diff --git a/src/common/rendering/hwrenderer/data/hw_levelmesh.h b/src/common/rendering/hwrenderer/data/hw_levelmesh.h index 1af04da67..b9cba5d75 100644 --- a/src/common/rendering/hwrenderer/data/hw_levelmesh.h +++ b/src/common/rendering/hwrenderer/data/hw_levelmesh.h @@ -92,98 +92,16 @@ public: TArray Portals; - GeometryAllocInfo AllocGeometry(int vertexCount, int indexCount) - { - GeometryAllocInfo info; - info.VertexStart = RemoveRange(FreeLists.Vertex, vertexCount); - info.VertexCount = vertexCount; - info.IndexStart = RemoveRange(FreeLists.Index, indexCount); - info.IndexCount = indexCount; - info.Vertices = &Mesh.Vertices[info.VertexStart]; - info.UniformIndexes = &Mesh.UniformIndexes[info.VertexStart]; - info.Indexes = &Mesh.Indexes[info.IndexStart]; + GeometryAllocInfo AllocGeometry(int vertexCount, int indexCount); + UniformsAllocInfo AllocUniforms(int count); + SurfaceAllocInfo AllocSurface(); - 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 }); - - Mesh.IndexCount = std::max(Mesh.IndexCount, info.IndexStart + info.IndexCount); - - return info; - } - - UniformsAllocInfo AllocUniforms(int count) - { - UniformsAllocInfo info; - info.Start = RemoveRange(FreeLists.Uniforms, count); - info.Count = count; - info.Uniforms = &Mesh.Uniforms[info.Start]; - info.Materials = &Mesh.Materials[info.Start]; - - 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; - } - - void FreeGeometry(int vertexStart, int vertexCount, int indexStart, int indexCount) - { - // Convert triangles to degenerates - for (int i = 0; i < indexCount; i++) - Mesh.Indexes[indexStart + i] = 0; - AddRange(UploadRanges.Index, { indexStart, indexStart + indexCount }); - - AddRange(FreeLists.Vertex, { vertexStart, vertexStart + vertexCount }); - AddRange(FreeLists.Index, { indexStart, indexStart + indexCount }); - } - - void FreeUniforms(int start, int count) - { - AddRange(FreeLists.Uniforms, { start, start + count }); - } - - void FreeSurface(unsigned int surfaceIndex) - { - // To do: remove the surface from the surface tile, if attached - - AddRange(FreeLists.Surface, { (int)surfaceIndex, (int)surfaceIndex + 1 }); - } + void FreeGeometry(int vertexStart, int vertexCount, int indexStart, int indexCount); + void FreeUniforms(int start, int count); + void FreeSurface(unsigned int surfaceIndex); // 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); - - Mesh.DrawIndexes.Resize(limits.MaxIndexes); - - 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 }); - FreeLists.DrawIndex.Clear(); FreeLists.DrawIndex.Push({ 0, limits.MaxIndexes }); - } + virtual void Reset(const LevelMeshLimits& limits); // Data placed in GPU buffers struct @@ -263,123 +181,12 @@ public: void AddEmptyMesh(); - void UploadPortals() - { - UploadRanges.Portals.Clear(); - AddRange(UploadRanges.Portals, { 0, (int)Portals.Size() }); - } + void UploadPortals(); + void UploadCollision(); - void UploadCollision() - { - UploadRanges.Node.Clear(); - if (Collision) - UploadRanges.Node.Push({ 0, (int)Collision->get_nodes().size() }); - } - - int RemoveRange(TArray& ranges, int count) - { - 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 RemoveRange(TArray& ranges, MeshBufferRange range) - { - if (range.Start == range.End) - return; - - auto entry = std::lower_bound(ranges.begin(), ranges.end(), range, [](const auto& a, const auto& b) { return a.End < b.End; }); - if (entry->Start == range.Start && entry->End == range.End) - { - ranges.Delete(entry - ranges.begin()); - } - else if (entry->Start == range.Start) - { - entry->Start = range.End; - } - else if (entry->End == range.End) - { - entry->End = range.Start; - } - else - { - MeshBufferRange split; - split.Start = entry->Start; - split.End = range.Start; - entry->Start = range.End; - ranges.Insert(entry - ranges.begin(), split); - } - } - - void AddRange(TArray& ranges, MeshBufferRange range) - { - // Empty range? - if (range.Start == range.End) - return; - - // 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; - - // 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); - } + void AddRange(TArray& ranges, MeshBufferRange range); + void RemoveRange(TArray& ranges, MeshBufferRange range); + int RemoveRange(TArray& ranges, int count); }; struct LevelMeshTileStats @@ -391,3 +198,189 @@ struct LevelMeshTileStats Stats tiles, pixels; }; + +inline GeometryAllocInfo LevelMesh::AllocGeometry(int vertexCount, int indexCount) +{ + GeometryAllocInfo info; + info.VertexStart = RemoveRange(FreeLists.Vertex, vertexCount); + info.VertexCount = vertexCount; + info.IndexStart = RemoveRange(FreeLists.Index, indexCount); + info.IndexCount = 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.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 }); + + Mesh.IndexCount = std::max(Mesh.IndexCount, info.IndexStart + info.IndexCount); + + return info; +} + +inline UniformsAllocInfo LevelMesh::AllocUniforms(int count) +{ + UniformsAllocInfo info; + info.Start = RemoveRange(FreeLists.Uniforms, count); + info.Count = count; + info.Uniforms = &Mesh.Uniforms[info.Start]; + info.Materials = &Mesh.Materials[info.Start]; + + AddRange(UploadRanges.Uniforms, { info.Start, info.Start + info.Count }); + + return info; +} + +inline SurfaceAllocInfo LevelMesh::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; +} + +inline void LevelMesh::FreeGeometry(int vertexStart, int vertexCount, int indexStart, int indexCount) +{ + // Convert triangles to degenerates + for (int i = 0; i < indexCount; i++) + Mesh.Indexes[indexStart + i] = 0; + AddRange(UploadRanges.Index, { indexStart, indexStart + indexCount }); + + AddRange(FreeLists.Vertex, { vertexStart, vertexStart + vertexCount }); + AddRange(FreeLists.Index, { indexStart, indexStart + indexCount }); +} + +inline void LevelMesh::FreeUniforms(int start, int count) +{ + AddRange(FreeLists.Uniforms, { start, start + count }); +} + +inline void LevelMesh::FreeSurface(unsigned int surfaceIndex) +{ + // To do: remove the surface from the surface tile, if attached + + AddRange(FreeLists.Surface, { (int)surfaceIndex, (int)surfaceIndex + 1 }); +} + +inline void LevelMesh::UploadPortals() +{ + UploadRanges.Portals.Clear(); + AddRange(UploadRanges.Portals, { 0, (int)Portals.Size() }); +} + +inline void LevelMesh::UploadCollision() +{ + UploadRanges.Node.Clear(); + if (Collision) + UploadRanges.Node.Push({ 0, (int)Collision->get_nodes().size() }); +} + +inline void LevelMesh::AddRange(TArray& ranges, MeshBufferRange range) +{ + // Empty range? + if (range.Start == range.End) + return; + + // 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; + + // 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); +} + +inline void LevelMesh::RemoveRange(TArray& ranges, MeshBufferRange range) +{ + if (range.Start == range.End) + return; + + auto entry = std::lower_bound(ranges.begin(), ranges.end(), range, [](const auto& a, const auto& b) { return a.End < b.End; }); + if (entry->Start == range.Start && entry->End == range.End) + { + ranges.Delete(entry - ranges.begin()); + } + else if (entry->Start == range.Start) + { + entry->Start = range.End; + } + else if (entry->End == range.End) + { + entry->End = range.Start; + } + else + { + MeshBufferRange split; + split.Start = entry->Start; + split.End = range.Start; + entry->Start = range.End; + ranges.Insert(entry - ranges.begin(), split); + } +} + +inline int LevelMesh::RemoveRange(TArray& ranges, int count) +{ + 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"); +}