PhysicalDeviceDriverInfoSerializer.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <Atom/RHI.Reflect/PhysicalDeviceDriverInfoSerializer.h>
  9. namespace AZ::RHI
  10. {
  11. AZ_CLASS_ALLOCATOR_IMPL(JsonPhysicalDeviceDriverInfoSerializer, SystemAllocator);
  12. namespace
  13. {
  14. static constexpr const char FieldVendor[] = "vendor";
  15. static constexpr const char FieldMinVersion[] = "minVersion";
  16. static constexpr const char FieldVersionsWithIssues[] = "versionsWithIssues";
  17. }
  18. uint32_t ConvertVersionNumber(VendorId vendor, const AZStd::string& versionStr)
  19. {
  20. AZStd::vector<uint32_t> versions;
  21. constexpr const char del = '.';
  22. size_t start = 0;
  23. size_t end = versionStr.find(del);
  24. while (end != AZStd::string::npos)
  25. {
  26. versions.push_back(aznumeric_cast<uint32_t>(atoi(versionStr.substr(start, end - start).c_str())));
  27. start = end + 1;
  28. end = versionStr.find(del, start);
  29. }
  30. versions.push_back(aznumeric_cast<uint32_t>(atoi(versionStr.substr(start, end).c_str())));
  31. uint32_t version = 0;
  32. // Version encoding using Vulkan format
  33. switch (vendor)
  34. {
  35. case VendorId::nVidia:
  36. // nVidia version format xx.xx.1x.xxxx
  37. // e.g. 27.21.14.5687
  38. if (versions.size() == 4)
  39. {
  40. version = (((versions[2] % 10) * 100 + versions[3] / 100) << 22) | ((versions[3] % 100) << 14);
  41. }
  42. // nVidia version format xxx.xx
  43. // e.g 456.87
  44. else if (versions.size() == 2)
  45. {
  46. version = (versions[0] << 22) | (versions[1] << 14);
  47. }
  48. else
  49. {
  50. AZ_Warning(
  51. "PhysicalDeviceDriverInfoSerializer", false, "Vendor %s version %s is using an unknown format.",
  52. ToString(vendor).data(), versionStr.c_str());
  53. }
  54. break;
  55. case VendorId::Intel:
  56. // Intel version format xx.xx.1xx.xxxx
  57. // e.g. 25.20.100.6793
  58. if (versions.size() == 4)
  59. {
  60. version = (versions[2] << 14) | versions[3];
  61. }
  62. // Intel version format 1xx.xxxx
  63. // e.g. 100.6793
  64. else if (versions.size() == 2)
  65. {
  66. version = (versions[0] << 14) | versions[1];
  67. }
  68. else
  69. {
  70. AZ_Warning(
  71. "PhysicalDeviceDriverInfoSerializer", false, "Vendor %s version %s is using an unknown format.",
  72. ToString(vendor).data(), versionStr.c_str());
  73. }
  74. break;
  75. default:
  76. // Default using Vulkan's standard
  77. // https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#extendingvulkan-coreversions-versionnumbers
  78. if (versions.size() == 3)
  79. {
  80. version = (versions[0] << 22) | (versions[1] << 12) | versions[2];
  81. }
  82. else
  83. {
  84. AZ_Warning(
  85. "PhysicalDeviceDriverInfoSerializer", false, "Vendor %s version %s is using an unknown format.",
  86. ToString(vendor).data(), versionStr.c_str());
  87. }
  88. }
  89. return version;
  90. }
  91. JsonSerializationResult::Result JsonPhysicalDeviceDriverInfoSerializer::Load(
  92. void* outputValue, [[maybe_unused]] const Uuid& outputValueTypeId, const rapidjson::Value& inputValue,
  93. JsonDeserializerContext& context)
  94. {
  95. AZ_Assert(azrtti_typeid<PhysicalDeviceDriverInfo>() == outputValueTypeId,
  96. "Unable to deserialize PhysicalDeviceDriverInfo to json because the provided type is %s",
  97. outputValueTypeId.ToString<AZStd::string>().c_str());
  98. PhysicalDeviceDriverInfo* driverInfo = reinterpret_cast<PhysicalDeviceDriverInfo*>(outputValue);
  99. JsonSerializationResult::ResultCode result(JsonSerializationResult::Tasks::ReadField);
  100. driverInfo->m_vendorId = VendorId::Unknown;
  101. AZStd::vector<AZStd::string> badVersions;
  102. result.Combine(ContinueLoadingFromJsonObjectField(&driverInfo->m_vendorId, azrtti_typeid(driverInfo->m_vendorId), inputValue, FieldVendor, context));
  103. result.Combine(ContinueLoadingFromJsonObjectField(&driverInfo->m_minVersion.m_readableVersion, azrtti_typeid(driverInfo->m_minVersion.m_readableVersion), inputValue, FieldMinVersion, context));
  104. result.Combine(ContinueLoadingFromJsonObjectField(&badVersions, azrtti_typeid(badVersions), inputValue, FieldVersionsWithIssues, context));
  105. driverInfo->m_minVersion.m_encodedVersion = ConvertVersionNumber(driverInfo->m_vendorId, driverInfo->m_minVersion.m_readableVersion);
  106. driverInfo->m_versionsWithIssues.reserve(driverInfo->m_versionsWithIssues.size());
  107. for (const AZStd::string& badVersion : badVersions)
  108. {
  109. driverInfo->m_versionsWithIssues.push_back(
  110. PhysicalDeviceDriverInfo::Version{ConvertVersionNumber(driverInfo->m_vendorId, badVersion), badVersion}
  111. );
  112. }
  113. if (result.GetProcessing() == JsonSerializationResult::Processing::Completed)
  114. {
  115. return context.Report(result, "Successfully loaded physical device driver Info.");
  116. }
  117. else
  118. {
  119. return context.Report(result, "Partially loaded physical device driver Info.");
  120. }
  121. }
  122. JsonSerializationResult::Result JsonPhysicalDeviceDriverInfoSerializer::Store(
  123. rapidjson::Value& outputValue, const void* inputValue, [[maybe_unused]] const void* defaultValue,
  124. [[maybe_unused]] const Uuid& valueTypeId, JsonSerializerContext& context)
  125. {
  126. AZ_Assert(azrtti_typeid<PhysicalDeviceDriverInfo>() == valueTypeId,
  127. "Unable to serialize PhysicalDeviceDriverInfo to json because the provided type is %s",
  128. valueTypeId.ToString<AZStd::string>().c_str());
  129. namespace JSR = JsonSerializationResult;
  130. JsonSerializationResult::ResultCode result(JSR::Tasks::WriteValue);
  131. const PhysicalDeviceDriverInfo* driverInfo = reinterpret_cast<const PhysicalDeviceDriverInfo*>(inputValue);
  132. AZStd::vector<AZStd::string> badVersions;
  133. badVersions.reserve(driverInfo->m_versionsWithIssues.size());
  134. for (const auto& badVersion : driverInfo->m_versionsWithIssues)
  135. {
  136. badVersions.push_back(badVersion.m_readableVersion);
  137. }
  138. VendorId defaultVendorId = VendorId::Unknown;
  139. result.Combine(ContinueStoringToJsonObjectField(outputValue, FieldVendor, &driverInfo->m_vendorId, &defaultVendorId, azrtti_typeid(driverInfo->m_vendorId), context));
  140. result.Combine(ContinueStoringToJsonObjectField(outputValue, FieldMinVersion, &driverInfo->m_minVersion.m_readableVersion, nullptr, azrtti_typeid(driverInfo->m_minVersion.m_readableVersion), context));
  141. result.Combine(ContinueStoringToJsonObjectField(outputValue, FieldVersionsWithIssues, &badVersions, nullptr, azrtti_typeid(badVersions), context));
  142. if (result.GetProcessing() == JsonSerializationResult::Processing::Completed)
  143. {
  144. return context.Report(result, "Successfully stored physical device driver Info.");
  145. }
  146. else
  147. {
  148. return context.Report(result, "Partially stored physical device driver Info.");
  149. }
  150. }
  151. }