summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngine
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2020-11-06 04:22:40 +0000
committerassiduous <assiduous@diligentgraphics.com>2020-11-06 04:22:40 +0000
commit01efea6331ae92a2cda01e41610e61bc6384b5ba (patch)
tree39e3ab68ec3dd4668a15615c9dc84fcacbd693e9 /Graphics/GraphicsEngine
parentFixed gcc/clang compiler issue (diff)
downloadDiligentCore-01efea6331ae92a2cda01e41610e61bc6384b5ba.tar.gz
DiligentCore-01efea6331ae92a2cda01e41610e61bc6384b5ba.zip
Refactored BottomLevelASBase
Diffstat (limited to 'Graphics/GraphicsEngine')
-rw-r--r--Graphics/GraphicsEngine/CMakeLists.txt1
-rw-r--r--Graphics/GraphicsEngine/include/BottomLevelASBase.hpp206
-rw-r--r--Graphics/GraphicsEngine/src/BottomLevelASBase.cpp170
3 files changed, 215 insertions, 162 deletions
diff --git a/Graphics/GraphicsEngine/CMakeLists.txt b/Graphics/GraphicsEngine/CMakeLists.txt
index 47692deb..db339e11 100644
--- a/Graphics/GraphicsEngine/CMakeLists.txt
+++ b/Graphics/GraphicsEngine/CMakeLists.txt
@@ -68,6 +68,7 @@ set(INTERFACE
set(SOURCE
src/APIInfo.cpp
+ src/BottomLevelASBase.cpp
src/BufferBase.cpp
src/DefaultShaderSourceStreamFactory.cpp
src/EngineMemory.cpp
diff --git a/Graphics/GraphicsEngine/include/BottomLevelASBase.hpp b/Graphics/GraphicsEngine/include/BottomLevelASBase.hpp
index 08fc4243..ddb5dd22 100644
--- a/Graphics/GraphicsEngine/include/BottomLevelASBase.hpp
+++ b/Graphics/GraphicsEngine/include/BottomLevelASBase.hpp
@@ -31,7 +31,7 @@
/// Implementation of the Diligent::BottomLevelASBase template class
#include <unordered_map>
-#include <memory>
+#include <atomic>
#include "BottomLevelAS.h"
#include "DeviceObjectBase.hpp"
@@ -42,6 +42,16 @@
namespace Diligent
{
+/// Validates bottom-level AS description and throws and exception in case of an error.
+void ValidateBottomLevelASDesc(const BottomLevelASDesc& Desc) noexcept(false);
+
+/// Copies bottom-level AS description (except for the Name) using MemPool to allocate required dynamic space.
+void CopyBottomLevelASDesc(const BottomLevelASDesc& SrcDesc,
+ BottomLevelASDesc& DstDesc,
+ LinearAllocator& MemPool,
+ std::unordered_map<HashMapStringKey, Uint32, HashMapStringKey::Hasher>& NameToIndex) noexcept(false);
+
+
/// Template class implementing base functionality for a bottom-level acceleration structure object.
/// \tparam BaseInterface - base interface that this class will inheret
@@ -65,26 +75,24 @@ public:
bool bIsDeviceInternal = false) :
TDeviceObjectBase{pRefCounters, pDevice, Desc, bIsDeviceInternal}
{
- ValidateBottomLevelASDesc(Desc);
+ ValidateBottomLevelASDesc(this->m_Desc);
if (Desc.CompactedSize > 0)
- {}
+ {
+ }
else
{
- LinearAllocator MemPool{GetRawAllocator()};
- CopyDescription(Desc, this->m_Desc, MemPool, m_NameToIndex);
- this->m_pRawPtr = MemPool.ReleaseOwnership();
+ CopyDescriptionUnsafe(Desc);
}
}
~BottomLevelASBase()
{
- if (this->m_pRawPtr)
- {
- GetRawAllocator().Free(this->m_pRawPtr);
- }
+ Clear();
}
+ IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_BottomLevelAS, TDeviceObjectBase)
+
static constexpr Uint32 InvalidGeometryIndex = ~0u;
virtual Uint32 DILIGENT_CALL_TYPE GetGeometryIndex(const char* Name) const override final
@@ -95,14 +103,14 @@ public:
if (iter != m_NameToIndex.end())
return iter->second;
- UNEXPECTED("Can't find geometry with specified name");
+ LOG_ERROR_MESSAGE("Can't find geometry with name '", Name, '\'');
return InvalidGeometryIndex;
}
virtual void DILIGENT_CALL_TYPE SetState(RESOURCE_STATE State) override final
{
VERIFY(State == RESOURCE_STATE_BUILD_AS_READ || State == RESOURCE_STATE_BUILD_AS_WRITE,
- "Unsupported state for bottom-level acceleration structure");
+ "Unsupported state for a bottom-level acceleration structure");
this->m_State = State;
}
@@ -123,36 +131,6 @@ public:
return (this->m_State & State) == State;
}
- void CopyDescription(const BottomLevelASBase& Src)
- {
- const auto& SrcDesc = Src.GetDesc();
- auto& DstDesc = this->m_Desc;
-
- try
- {
- if (this->m_pRawPtr)
- {
- GetRawAllocator().Free(this->m_pRawPtr);
- this->m_pRawPtr = nullptr;
- }
- m_NameToIndex.clear();
-
- DstDesc.TriangleCount = SrcDesc.TriangleCount;
- DstDesc.BoxCount = SrcDesc.BoxCount;
-
- LinearAllocator MemPool{GetRawAllocator()};
- CopyDescription(SrcDesc, DstDesc, MemPool, m_NameToIndex);
- this->m_pRawPtr = MemPool.ReleaseOwnership();
- }
- catch (...)
- {
- // memory for arrays is not allocated or have been freed
- DstDesc.pTriangles = nullptr;
- DstDesc.pBoxes = nullptr;
- m_NameToIndex.clear();
- }
- }
-
#ifdef DILIGENT_DEVELOPMENT
void UpdateVersion()
{
@@ -171,139 +149,43 @@ public:
}
#endif // DILIGENT_DEVELOPMENT
-protected:
- static void ValidateBottomLevelASDesc(const BottomLevelASDesc& Desc)
+ void CopyDescription(const BottomLevelASBase& SrcBLAS) noexcept
{
-#define LOG_BLAS_ERROR_AND_THROW(...) LOG_ERROR_AND_THROW("Description of Bottom-level AS '", (Desc.Name ? Desc.Name : ""), "' is invalid: ", ##__VA_ARGS__)
+ Clear();
- if (Desc.CompactedSize > 0)
+ try
{
- if (Desc.pTriangles != nullptr || Desc.pBoxes != nullptr)
- LOG_BLAS_ERROR_AND_THROW("If CompactedSize is specified then pTriangles and pBoxes must be null");
-
- if (Desc.Flags != RAYTRACING_BUILD_AS_NONE)
- LOG_BLAS_ERROR_AND_THROW("If CompactedSize is specified then Flags must be RAYTRACING_BUILD_AS_NONE");
+ CopyDescriptionUnsafe(SrcBLAS.GetDesc());
}
- else
+ catch (...)
{
- if (!((Desc.pBoxes != nullptr) ^ (Desc.pTriangles != nullptr)))
- LOG_BLAS_ERROR_AND_THROW("Exactly one of pTriangles and pBoxes must be defined");
-
- if (Desc.pBoxes == nullptr && Desc.BoxCount > 0)
- LOG_BLAS_ERROR_AND_THROW("pBoxes is null but BoxCount is not 0");
-
- if (Desc.pTriangles == nullptr && Desc.TriangleCount > 0)
- LOG_BLAS_ERROR_AND_THROW("pTriangles is null but TriangleCount is not 0");
-
- if ((Desc.Flags & RAYTRACING_BUILD_AS_PREFER_FAST_TRACE) && (Desc.Flags & RAYTRACING_BUILD_AS_PREFER_FAST_BUILD))
- LOG_BLAS_ERROR_AND_THROW("can not set both flags RAYTRACING_BUILD_AS_PREFER_FAST_TRACE and RAYTRACING_BUILD_AS_PREFER_FAST_BUILD");
-
-#ifdef DILIGENT_DEVELOPMENT
- for (Uint32 i = 0; i < Desc.TriangleCount; ++i)
- {
- const auto& tri = Desc.pTriangles[i];
-
- if (tri.GeometryName == nullptr)
- LOG_BLAS_ERROR_AND_THROW("pTriangles[", i, "].GeometryName must not be null");
-
- if (tri.VertexValueType >= VT_NUM_TYPES)
- LOG_BLAS_ERROR_AND_THROW("pTriangles[", i, "].VertexValueType must be valid type");
-
- if (tri.VertexComponentCount != 2 && tri.VertexComponentCount != 3)
- LOG_BLAS_ERROR_AND_THROW("pTriangles[", i, "].VertexComponentCount must be 2 or 3");
-
- if (tri.MaxVertexCount == 0)
- LOG_BLAS_ERROR_AND_THROW("pTriangles[", i, "].MaxVertexCount must be greater then 0");
-
- if (tri.MaxPrimitiveCount == 0)
- LOG_BLAS_ERROR_AND_THROW("pTriangles[", i, "].MaxPrimitiveCount must be greater then 0");
-
- if (tri.IndexType == VT_UNDEFINED)
- {
- if (tri.MaxVertexCount != tri.MaxPrimitiveCount * 3)
- LOG_BLAS_ERROR_AND_THROW("pTriangles[", i, "].MaxVertexCount must equal to (MaxPrimitiveCount * 3)");
- }
- else
- {
- if (tri.IndexType != VT_UINT32 && tri.IndexType != VT_UINT16)
- LOG_BLAS_ERROR_AND_THROW("pTriangles[", i, "].IndexType must be VT_UINT16 or VT_UINT32");
- }
- }
-
- for (Uint32 i = 0; i < Desc.BoxCount; ++i)
- {
- const auto& box = Desc.pBoxes[i];
-
- if (box.GeometryName == nullptr)
- LOG_BLAS_ERROR_AND_THROW("pBoxes[", i, "].GeometryName must not be null");
-
- if (box.MaxBoxCount == 0)
- LOG_BLAS_ERROR_AND_THROW("pBoxes[", i, "].MaxBoxCount must be greater then 0");
- }
-#endif // DILIGENT_DEVELOPMENT
+ Clear();
}
+ }
-#undef LOG_BLAS_ERROR_AND_THROW
+private:
+ void CopyDescriptionUnsafe(const BottomLevelASDesc& SrcDesc) noexcept(false)
+ {
+ LinearAllocator MemPool{GetRawAllocator()};
+ CopyBottomLevelASDesc(SrcDesc, this->m_Desc, MemPool, m_NameToIndex);
+ this->m_pRawPtr = MemPool.Release();
}
- static void CopyDescription(const BottomLevelASDesc& SrcDesc,
- BottomLevelASDesc& DstDesc,
- LinearAllocator& MemPool,
- std::unordered_map<HashMapStringKey, Uint32, HashMapStringKey::Hasher>& NameToIndex)
+ void Clear() noexcept
{
- if (SrcDesc.pTriangles != nullptr)
- {
- MemPool.AddSpace<decltype(*SrcDesc.pTriangles)>(SrcDesc.TriangleCount);
-
- for (Uint32 i = 0; i < SrcDesc.TriangleCount; ++i)
- MemPool.AddSpaceForString(SrcDesc.pTriangles[i].GeometryName);
-
- MemPool.Reserve();
-
- auto* pTriangles = MemPool.CopyArray(SrcDesc.pTriangles, SrcDesc.TriangleCount);
-
- // copy strings
- for (Uint32 i = 0; i < SrcDesc.TriangleCount; ++i)
- {
- pTriangles[i].GeometryName = MemPool.CopyString(SrcDesc.pTriangles[i].GeometryName);
- bool IsUniqueName = NameToIndex.emplace(SrcDesc.pTriangles[i].GeometryName, i).second;
- if (!IsUniqueName)
- LOG_ERROR_AND_THROW("Geometry name must be unique!");
- }
- DstDesc.pTriangles = pTriangles;
- DstDesc.pBoxes = nullptr;
- DstDesc.BoxCount = 0;
- }
- else if (SrcDesc.pBoxes != nullptr)
- {
- MemPool.AddSpace<decltype(*SrcDesc.pBoxes)>(SrcDesc.BoxCount);
-
- for (Uint32 i = 0; i < SrcDesc.BoxCount; ++i)
- MemPool.AddSpaceForString(SrcDesc.pBoxes[i].GeometryName);
-
- MemPool.Reserve();
-
- auto* pBoxes = MemPool.CopyArray(SrcDesc.pBoxes, SrcDesc.BoxCount);
-
- // copy strings
- for (Uint32 i = 0; i < SrcDesc.BoxCount; ++i)
- {
- pBoxes[i].GeometryName = MemPool.CopyString(SrcDesc.pBoxes[i].GeometryName);
- bool IsUniqueName = NameToIndex.emplace(SrcDesc.pBoxes[i].GeometryName, i).second;
- if (!IsUniqueName)
- LOG_ERROR_AND_THROW("Geometry name must be unique!");
- }
- DstDesc.pBoxes = pBoxes;
- DstDesc.pTriangles = nullptr;
- DstDesc.TriangleCount = 0;
- }
- else
+ if (this->m_pRawPtr != nullptr)
{
- LOG_ERROR_AND_THROW("Either pTriangles or pBoxes must not be null");
+ GetRawAllocator().Free(this->m_pRawPtr);
+ this->m_pRawPtr = nullptr;
}
- }
- IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_BottomLevelAS, TDeviceObjectBase)
+ // Preserve original name - it was allocated by DeviceObjectBase
+ auto* Name = this->m_Desc.Name;
+ this->m_Desc = BottomLevelASDesc{};
+ this->m_Desc.Name = Name;
+
+ m_NameToIndex.clear();
+ }
protected:
RESOURCE_STATE m_State = RESOURCE_STATE_UNKNOWN;
diff --git a/Graphics/GraphicsEngine/src/BottomLevelASBase.cpp b/Graphics/GraphicsEngine/src/BottomLevelASBase.cpp
new file mode 100644
index 00000000..fec51592
--- /dev/null
+++ b/Graphics/GraphicsEngine/src/BottomLevelASBase.cpp
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2019-2020 Diligent Graphics LLC
+ * Copyright 2015-2019 Egor Yusov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * In no event and under no legal theory, whether in tort (including negligence),
+ * contract, or otherwise, unless required by applicable law (such as deliberate
+ * and grossly negligent acts) or agreed to in writing, shall any Contributor be
+ * liable for any damages, including any direct, indirect, special, incidental,
+ * or consequential damages of any character arising as a result of this License or
+ * out of the use or inability to use the software (including but not limited to damages
+ * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
+ * all other commercial damages or losses), even if such Contributor has been advised
+ * of the possibility of such damages.
+ */
+
+#include "pch.h"
+#include "BottomLevelASBase.hpp"
+
+namespace Diligent
+{
+
+void ValidateBottomLevelASDesc(const BottomLevelASDesc& Desc) noexcept(false)
+{
+#define LOG_BLAS_ERROR_AND_THROW(...) LOG_ERROR_AND_THROW("Description of a bottom-level AS '", (Desc.Name ? Desc.Name : ""), "' is invalid: ", ##__VA_ARGS__)
+
+ if (Desc.CompactedSize > 0)
+ {
+ if (Desc.pTriangles != nullptr || Desc.pBoxes != nullptr)
+ LOG_BLAS_ERROR_AND_THROW("If non-zero CompactedSize is specified, pTriangles and pBoxes must both be null");
+
+ if (Desc.Flags != RAYTRACING_BUILD_AS_NONE)
+ LOG_BLAS_ERROR_AND_THROW("If non-zero CompactedSize is specified, Flags must be RAYTRACING_BUILD_AS_NONE");
+ }
+ else
+ {
+ if (!((Desc.pBoxes != nullptr) ^ (Desc.pTriangles != nullptr)))
+ LOG_BLAS_ERROR_AND_THROW("Exactly one of pTriangles and pBoxes must be defined");
+
+ if (Desc.pBoxes == nullptr && Desc.BoxCount > 0)
+ LOG_BLAS_ERROR_AND_THROW("pBoxes is null, but BoxCount is not 0");
+
+ if (Desc.pTriangles == nullptr && Desc.TriangleCount > 0)
+ LOG_BLAS_ERROR_AND_THROW("pTriangles is null, but TriangleCount is not 0");
+
+ if ((Desc.Flags & RAYTRACING_BUILD_AS_PREFER_FAST_TRACE) && (Desc.Flags & RAYTRACING_BUILD_AS_PREFER_FAST_BUILD))
+ LOG_BLAS_ERROR_AND_THROW("RAYTRACING_BUILD_AS_PREFER_FAST_TRACE and RAYTRACING_BUILD_AS_PREFER_FAST_BUILD flags are mutually exclusive");
+
+ for (Uint32 i = 0; i < Desc.TriangleCount; ++i)
+ {
+ const auto& tri = Desc.pTriangles[i];
+
+ if (tri.GeometryName == nullptr)
+ LOG_BLAS_ERROR_AND_THROW("pTriangles[", i, "].GeometryName must not be null");
+
+ if (tri.VertexValueType >= VT_NUM_TYPES)
+ LOG_BLAS_ERROR_AND_THROW("pTriangles[", i, "].VertexValueType must be a valid type");
+
+ if (tri.VertexComponentCount != 2 && tri.VertexComponentCount != 3)
+ LOG_BLAS_ERROR_AND_THROW("pTriangles[", i, "].VertexComponentCount must be 2 or 3");
+
+ if (tri.MaxVertexCount == 0)
+ LOG_BLAS_ERROR_AND_THROW("pTriangles[", i, "].MaxVertexCount must be greater than 0");
+
+ if (tri.MaxPrimitiveCount == 0)
+ LOG_BLAS_ERROR_AND_THROW("pTriangles[", i, "].MaxPrimitiveCount must be greater than 0");
+
+ if (tri.IndexType == VT_UNDEFINED)
+ {
+ if (tri.MaxVertexCount != tri.MaxPrimitiveCount * 3)
+ LOG_BLAS_ERROR_AND_THROW("pTriangles[", i, "].MaxVertexCount must equal to (MaxPrimitiveCount * 3)");
+ }
+ else
+ {
+ if (tri.IndexType != VT_UINT32 && tri.IndexType != VT_UINT16)
+ LOG_BLAS_ERROR_AND_THROW("pTriangles[", i, "].IndexType must be VT_UINT16 or VT_UINT32");
+ }
+ }
+
+ for (Uint32 i = 0; i < Desc.BoxCount; ++i)
+ {
+ const auto& box = Desc.pBoxes[i];
+
+ if (box.GeometryName == nullptr)
+ LOG_BLAS_ERROR_AND_THROW("pBoxes[", i, "].GeometryName must not be null");
+
+ if (box.MaxBoxCount == 0)
+ LOG_BLAS_ERROR_AND_THROW("pBoxes[", i, "].MaxBoxCount must be greater than 0");
+ }
+ }
+
+#undef LOG_BLAS_ERROR_AND_THROW
+}
+
+void CopyBottomLevelASDesc(const BottomLevelASDesc& SrcDesc,
+ BottomLevelASDesc& DstDesc,
+ LinearAllocator& MemPool,
+ std::unordered_map<HashMapStringKey, Uint32, HashMapStringKey::Hasher>& NameToIndex) noexcept(false)
+{
+ // Preserve original name
+ const auto* Name = DstDesc.Name;
+ DstDesc = SrcDesc;
+ DstDesc.Name = Name;
+
+ if (SrcDesc.pTriangles != nullptr)
+ {
+ MemPool.AddSpace<decltype(*SrcDesc.pTriangles)>(SrcDesc.TriangleCount);
+
+ for (Uint32 i = 0; i < SrcDesc.TriangleCount; ++i)
+ MemPool.AddSpaceForString(SrcDesc.pTriangles[i].GeometryName);
+
+ MemPool.Reserve();
+
+ auto* pTriangles = MemPool.CopyArray(SrcDesc.pTriangles, SrcDesc.TriangleCount);
+
+ // Copy strings
+ for (Uint32 i = 0; i < SrcDesc.TriangleCount; ++i)
+ {
+ const auto* SrcGeoName = SrcDesc.pTriangles[i].GeometryName;
+ pTriangles[i].GeometryName = MemPool.CopyString(SrcGeoName);
+ bool IsUniqueName = NameToIndex.emplace(SrcGeoName, i).second;
+ if (!IsUniqueName)
+ LOG_ERROR_AND_THROW("Geometry name '", SrcGeoName, "' is not unique");
+ }
+ DstDesc.pTriangles = pTriangles;
+ DstDesc.pBoxes = nullptr;
+ DstDesc.BoxCount = 0;
+ }
+ else if (SrcDesc.pBoxes != nullptr)
+ {
+ MemPool.AddSpace<decltype(*SrcDesc.pBoxes)>(SrcDesc.BoxCount);
+
+ for (Uint32 i = 0; i < SrcDesc.BoxCount; ++i)
+ MemPool.AddSpaceForString(SrcDesc.pBoxes[i].GeometryName);
+
+ MemPool.Reserve();
+
+ auto* pBoxes = MemPool.CopyArray(SrcDesc.pBoxes, SrcDesc.BoxCount);
+
+ // Copy strings
+ for (Uint32 i = 0; i < SrcDesc.BoxCount; ++i)
+ {
+ const auto* SrcGeoName = SrcDesc.pBoxes[i].GeometryName;
+ pBoxes[i].GeometryName = MemPool.CopyString(SrcGeoName);
+ bool IsUniqueName = NameToIndex.emplace(SrcGeoName, i).second;
+ if (!IsUniqueName)
+ LOG_ERROR_AND_THROW("Geometry name '", SrcGeoName, "' is not unique");
+ }
+ DstDesc.pBoxes = pBoxes;
+ DstDesc.pTriangles = nullptr;
+ DstDesc.TriangleCount = 0;
+ }
+ else
+ {
+ LOG_ERROR_AND_THROW("Either pTriangles or pBoxes must not be null");
+ }
+}
+
+} // namespace Diligent