Skip to content

Commit b280766

Browse files
DeviceObjectArchive: reworked Deserialize method to return error instead of throwing exception
1 parent 5d58381 commit b280766

File tree

3 files changed

+85
-73
lines changed

3 files changed

+85
-73
lines changed

Graphics/GraphicsEngine/include/DeviceObjectArchive.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ class DeviceObjectArchive
242242
void AppendDeviceData(const DeviceObjectArchive& Src, DeviceType Dev) noexcept(false);
243243
void Merge(const DeviceObjectArchive& Src) noexcept(false);
244244

245-
void Deserialize(const CreateInfo& CI) noexcept(false);
245+
bool Deserialize(const CreateInfo& CI) noexcept;
246246
void Serialize(IFileStream* pStream) const;
247247
void Serialize(IDataBlob** ppDataBlob) const;
248248

@@ -300,6 +300,8 @@ class DeviceObjectArchive
300300
return m_NamedResources;
301301
}
302302

303+
void Clear() noexcept;
304+
303305
private:
304306
// Named resources
305307
std::unordered_map<NamedResourceKey, ResourceData, NamedResourceKey::Hasher> m_NamedResources;

Graphics/GraphicsEngine/src/DearchiverBase.cpp

Lines changed: 29 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -653,52 +653,47 @@ bool DearchiverBase::LoadArchive(const IDataBlob* pArchiveData, Uint32 ContentVe
653653
if (pArchiveData == nullptr)
654654
return false;
655655

656-
try
656+
for (const ArchiveData& Archive : m_Archives)
657657
{
658-
for (const auto& Archive : m_Archives)
658+
if (Archive.pObjArchive->GetData() == pArchiveData)
659659
{
660-
if (Archive.pObjArchive->GetData() == pArchiveData)
661-
{
662-
// The archive is already loaded
663-
return true;
664-
}
660+
// The archive is already loaded
661+
return true;
665662
}
663+
}
666664

667-
auto pObjArchive = std::make_unique<DeviceObjectArchive>(DeviceObjectArchive::CreateInfo{pArchiveData, ContentVersion, MakeCopy});
668-
const auto ArchiveIdx = m_Archives.size();
665+
std::unique_ptr<DeviceObjectArchive> pObjArchive = std::make_unique<DeviceObjectArchive>();
666+
if (!pObjArchive->Deserialize(DeviceObjectArchive::CreateInfo{pArchiveData, ContentVersion, MakeCopy}))
667+
return false;
668+
669+
const size_t ArchiveIdx = m_Archives.size();
669670

670-
const auto& ArchiveResources = pObjArchive->GetNamedResources();
671-
for (const auto& it : ArchiveResources)
671+
const auto& ArchiveResources = pObjArchive->GetNamedResources();
672+
for (const auto& it : ArchiveResources)
673+
{
674+
const ResourceType ResType = it.first.GetType();
675+
const char* ResName = it.first.GetName();
676+
constexpr bool MakeNameCopy = true;
677+
678+
const auto it_inserted = m_ResNameToArchiveIdx.emplace(NamedResourceKey{ResType, ResName, MakeNameCopy}, ArchiveIdx);
679+
if (!it_inserted.second)
672680
{
673-
const auto ResType = it.first.GetType();
674-
const auto* ResName = it.first.GetName();
675-
constexpr auto MakeNameCopy = true;
681+
const auto& OtherArchiveResources = m_Archives[it_inserted.first->second].pObjArchive->GetNamedResources();
682+
const auto it_other = OtherArchiveResources.find(NamedResourceKey{ResType, ResName});
676683

677-
const auto it_inserted = m_ResNameToArchiveIdx.emplace(NamedResourceKey{ResType, ResName, MakeNameCopy}, ArchiveIdx);
678-
if (!it_inserted.second)
684+
const bool IsDuplicate =
685+
(it_other != OtherArchiveResources.end()) &&
686+
(it.second == it_other->second);
687+
if (!IsDuplicate)
679688
{
680-
const auto& OtherArchiveResources = m_Archives[it_inserted.first->second].pObjArchive->GetNamedResources();
681-
const auto it_other = OtherArchiveResources.find(NamedResourceKey{ResType, ResName});
682-
683-
const auto IsDuplicate =
684-
(it_other != OtherArchiveResources.end()) &&
685-
(it.second == it_other->second);
686-
if (!IsDuplicate)
687-
{
688-
LOG_ERROR_MESSAGE("Resource with name '", ResName, "' already exists in the archive.");
689-
}
689+
LOG_ERROR_MESSAGE("Resource with name '", ResName, "' already exists in the archive.");
690690
}
691691
}
692+
}
692693

693-
m_Archives.emplace_back(std::move(pObjArchive));
694+
m_Archives.emplace_back(std::move(pObjArchive));
694695

695-
return true;
696-
}
697-
catch (...)
698-
{
699-
LOG_ERROR("Failed to create the device object archive");
700-
return false;
701-
}
696+
return true;
702697
}
703698

704699
void DearchiverBase::UnpackPipelineState(const PipelineStateUnpackInfo& UnpackInfo, IPipelineState** ppPSO)

Graphics/GraphicsEngine/src/DeviceObjectArchive.cpp

Lines changed: 53 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,36 @@ DeviceObjectArchive::DeviceObjectArchive(Uint32 ContentVersion) noexcept :
151151
{
152152
}
153153

154-
void DeviceObjectArchive::Deserialize(const CreateInfo& CI) noexcept(false)
154+
void DeviceObjectArchive::Clear() noexcept
155155
{
156+
m_NamedResources.clear();
157+
m_DeviceShaders = {};
158+
m_pArchiveData.Release();
159+
m_ContentVersion = 0;
160+
}
161+
162+
163+
bool DeviceObjectArchive::Deserialize(const CreateInfo& CI) noexcept
164+
{
165+
Clear();
166+
167+
#define CHECK_ARCHIVE(Expr, ...) \
168+
do \
169+
{ \
170+
if (!(Expr)) \
171+
{ \
172+
LOG_ERROR_MESSAGE(__VA_ARGS__); \
173+
Clear(); \
174+
return false; \
175+
} \
176+
} while (false)
177+
178+
CHECK_ARCHIVE(CI.pData != nullptr, "pData must not be null");
179+
180+
m_pArchiveData = CI.MakeCopy ?
181+
DataBlobImpl::MakeCopy(CI.pData) :
182+
const_cast<IDataBlob*>(CI.pData); // Need to remove const for AddRef/Release
183+
156184
Serializer<SerializerMode::Read> Reader{
157185
SerializedData{
158186
const_cast<void*>(CI.pData->GetConstDataPtr()),
@@ -164,56 +192,48 @@ void DeviceObjectArchive::Deserialize(const CreateInfo& CI) noexcept(false)
164192
// NB: this must match header serialization in DeviceObjectArchive::SerializeHeader
165193
ArchiveHeader Header;
166194
ASSERT_SIZEOF64(Header, 24, "Please handle new members here");
167-
if (!ArchiveReader.Ser(Header.MagicNumber))
168-
LOG_ERROR_AND_THROW("Failed to read device object archive header magic number.");
195+
CHECK_ARCHIVE(ArchiveReader.Ser(Header.MagicNumber), "Failed to read device object archive header magic number.");
169196

170-
if (Header.MagicNumber != HeaderMagicNumber)
171-
LOG_ERROR_AND_THROW("Invalid device object archive header.");
197+
CHECK_ARCHIVE(Header.MagicNumber == HeaderMagicNumber, "Invalid device object archive header.");
172198

173-
if (!ArchiveReader.Ser(Header.Version))
174-
LOG_ERROR_AND_THROW("Failed to read device object archive version.");
199+
CHECK_ARCHIVE(ArchiveReader.Ser(Header.Version), "Failed to read device object archive version.");
175200

176-
if (Header.Version != ArchiveVersion)
177-
LOG_ERROR_AND_THROW("Unsupported device object archive version: ", Header.Version, ". Expected version: ", Uint32{ArchiveVersion});
201+
CHECK_ARCHIVE(Header.Version == ArchiveVersion, "Unsupported device object archive version: ", Header.Version, ". Expected version: ", Uint32{ArchiveVersion});
178202

179-
if (!ArchiveReader.Ser(Header.APIVersion))
180-
LOG_ERROR_AND_THROW("Failed to read Diligent API version.");
203+
CHECK_ARCHIVE(ArchiveReader.Ser(Header.APIVersion), "Failed to read Diligent API version.");
181204

182-
if (!ArchiveReader.Ser(Header.ContentVersion))
183-
LOG_ERROR_AND_THROW("Failed to read device object archive content version.");
205+
CHECK_ARCHIVE(ArchiveReader.Ser(Header.ContentVersion), "Failed to read device object archive content version.");
184206

185-
if (CI.ContentVersion != CreateInfo{}.ContentVersion && Header.ContentVersion != CI.ContentVersion)
186-
LOG_ERROR_AND_THROW("Invalid archive content version: ", Header.ContentVersion, ". Expected version: ", CI.ContentVersion);
207+
CHECK_ARCHIVE(CI.ContentVersion == CreateInfo{}.ContentVersion || Header.ContentVersion == CI.ContentVersion,
208+
"Invalid archive content version: ", Header.ContentVersion, ". Expected version: ", CI.ContentVersion);
187209
m_ContentVersion = Header.ContentVersion;
188210

189-
if (!ArchiveReader.Ser(Header.GitHash))
190-
LOG_ERROR_AND_THROW("Failed to read Git Hash.");
211+
CHECK_ARCHIVE(ArchiveReader.Ser(Header.GitHash), "Failed to read Git Hash.");
191212

192213
Uint32 NumResources = 0;
193-
if (!Reader(NumResources))
194-
LOG_ERROR_AND_THROW("Failed to read the number of named resources in the device object archive.");
214+
CHECK_ARCHIVE(Reader(NumResources), "Failed to read the number of named resources in the device object archive.");
195215

196216
for (Uint32 res = 0; res < NumResources; ++res)
197217
{
198218
const char* Name = nullptr;
199219
ResourceType ResType = ResourceType::Undefined;
200-
if (!Reader(ResType, Name))
201-
LOG_ERROR_AND_THROW("Failed to read the type and name of resource ", res, "/", NumResources, '.');
220+
CHECK_ARCHIVE(Reader(ResType, Name), "Failed to read the type and name of resource ", res, "/", NumResources, '.');
202221
VERIFY_EXPR(Name != nullptr);
203222

204223
// No need to make the name copy as we keep the source data blob alive.
205-
constexpr auto MakeNameCopy = false;
206-
auto& ResData = m_NamedResources[NamedResourceKey{ResType, Name, MakeNameCopy}];
224+
constexpr bool MakeNameCopy = false;
225+
ResourceData& ResData = m_NamedResources[NamedResourceKey{ResType, Name, MakeNameCopy}];
207226

208-
if (!ArchiveReader.SerializeResourceData(ResData))
209-
LOG_ERROR_AND_THROW("Failed to read data of resource '", Name, "'.");
227+
CHECK_ARCHIVE(ArchiveReader.SerializeResourceData(ResData), "Failed to read data of resource '", Name, "'.");
210228
}
211229

212-
for (auto& Shaders : m_DeviceShaders)
230+
for (std::vector<SerializedData>& Shaders : m_DeviceShaders)
213231
{
214-
if (!ArchiveReader.SerializeShaders(Shaders))
215-
LOG_ERROR_AND_THROW("Failed to read shader data from the device object archive.");
232+
CHECK_ARCHIVE(ArchiveReader.SerializeShaders(Shaders), "Failed to read shader data from the device object archive.");
216233
}
234+
#undef CHECK_ARCHIVE
235+
236+
return true;
217237
}
218238

219239
void DeviceObjectArchive::Serialize(IDataBlob** ppDataBlob) const
@@ -320,17 +340,12 @@ const char* ResourceTypeToString(DeviceObjectArchive::ResourceType Type)
320340
} // namespace
321341

322342

323-
DeviceObjectArchive::DeviceObjectArchive(const CreateInfo& CI) noexcept(false) :
324-
m_pArchiveData{
325-
CI.MakeCopy ?
326-
DataBlobImpl::MakeCopy(CI.pData) :
327-
const_cast<IDataBlob*>(CI.pData) // Need to remove const for AddRef/Release
328-
}
343+
DeviceObjectArchive::DeviceObjectArchive(const CreateInfo& CI) noexcept(false)
329344
{
330-
if (!m_pArchiveData)
331-
LOG_ERROR_AND_THROW("pData must not be null");
332-
333-
Deserialize(CI);
345+
if (!Deserialize(CI))
346+
{
347+
LOG_ERROR_AND_THROW("Failed to deserialize device object archive");
348+
}
334349
}
335350

336351
const SerializedData& DeviceObjectArchive::GetDeviceSpecificData(ResourceType Type,

0 commit comments

Comments
 (0)