DrawPacketTests.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  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 "RHITestFixture.h"
  9. #include <Atom/RHI/DeviceDrawPacket.h>
  10. #include <Atom/RHI/DeviceDrawPacketBuilder.h>
  11. #include <Atom/RHI/DevicePipelineState.h>
  12. #include <Atom/RHI/DrawListContext.h>
  13. #include <Atom/RHI/DrawListTagRegistry.h>
  14. #include <Atom/RHI/GeometryView.h>
  15. #include <AzCore/Math/Random.h>
  16. #include <AzCore/std/sort.h>
  17. #include <Tests/Factory.h>
  18. namespace UnitTest
  19. {
  20. using namespace AZ;
  21. struct DrawItemData
  22. {
  23. DrawItemData(SimpleLcgRandom& random, const RHI::DevicePipelineState* psoEmpty, const RHI::DeviceGeometryView& geometryView)
  24. {
  25. m_pipelineState = psoEmpty;
  26. m_geometryView = &geometryView;
  27. m_streamIndices = geometryView.GetFullStreamBufferIndices(); // Ordered Stream Indices
  28. m_tag = RHI::DrawListTag(random.GetRandom() % RHI::Limits::Pipeline::DrawListTagCountMax);
  29. m_stencilRef = static_cast<uint8_t>(random.GetRandom());
  30. m_sortKey = random.GetRandom();
  31. }
  32. const RHI::DeviceGeometryView* m_geometryView = nullptr;
  33. RHI::StreamBufferIndices m_streamIndices;
  34. const RHI::DevicePipelineState* m_pipelineState;
  35. RHI::DrawListTag m_tag;
  36. RHI::DrawItemSortKey m_sortKey;
  37. uint8_t m_stencilRef;
  38. };
  39. struct DrawPacketData
  40. {
  41. const size_t DrawItemCountMax = 8;
  42. DrawPacketData(SimpleLcgRandom& random)
  43. {
  44. m_bufferEmpty = RHI::Factory::Get().CreateBuffer();
  45. m_psoEmpty = RHI::Factory::Get().CreatePipelineState();
  46. for (auto& srg : m_srgs)
  47. {
  48. srg = RHI::Factory::Get().CreateShaderResourceGroup();
  49. }
  50. unsigned int* data = reinterpret_cast<unsigned int*>(m_rootConstants.data());
  51. for (uint32_t i = 0; i < m_rootConstants.size()/sizeof(unsigned int); ++i)
  52. {
  53. data[i] = random.GetRandom();
  54. }
  55. m_geometryView.SetDrawArguments( RHI::DrawIndexed{} );
  56. m_geometryView.SetIndexBufferView({ *m_bufferEmpty, random.GetRandom(), random.GetRandom(), RHI::IndexFormat::Uint16 });
  57. for (u32 i = 0; i < RHI::Limits::Pipeline::StreamCountMax; ++i)
  58. {
  59. m_geometryView.AddStreamBufferView({ *m_bufferEmpty, random.GetRandom(), random.GetRandom(), random.GetRandom() });
  60. }
  61. for (size_t i = 0; i < DrawItemCountMax; ++i)
  62. {
  63. m_drawItemDatas.emplace_back(random, m_psoEmpty.get(), m_geometryView);
  64. }
  65. }
  66. void ValidateDrawItem(const DrawItemData& drawItemData, RHI::DeviceDrawItemProperties itemProperties) const
  67. {
  68. const RHI::DeviceDrawItem* drawItem = itemProperties.m_item;
  69. EXPECT_EQ(itemProperties.m_sortKey, drawItemData.m_sortKey);
  70. EXPECT_EQ(drawItem->m_stencilRef, drawItemData.m_stencilRef);
  71. EXPECT_EQ(drawItem->m_pipelineState, drawItemData.m_pipelineState);
  72. EXPECT_EQ(drawItem->m_geometryView, drawItemData.m_geometryView);
  73. // Ordered Stream Indices (see matching comment in DrawItemData constructor)
  74. auto streamIter = drawItem->m_geometryView->CreateStreamIterator(drawItem->m_streamIndices);
  75. for (u8 i = 0; !streamIter.HasEnded(); ++i, ++streamIter)
  76. {
  77. EXPECT_EQ(drawItem->m_geometryView->GetStreamBufferView(i), *streamIter);
  78. }
  79. EXPECT_EQ(static_cast<size_t>(drawItem->m_shaderResourceGroupCount), m_srgs.size());
  80. for (size_t i = 0; i < m_srgs.size(); ++i)
  81. {
  82. EXPECT_EQ(m_srgs[i], drawItem->m_shaderResourceGroups[i]);
  83. }
  84. EXPECT_EQ(static_cast<size_t>(drawItem->m_rootConstantSize), m_rootConstants.size());
  85. for (size_t i = 0; i < m_rootConstants.size(); ++i)
  86. {
  87. EXPECT_EQ(m_rootConstants[i], drawItem->m_rootConstants[i]);
  88. }
  89. }
  90. const RHI::DeviceDrawPacket* Build(RHI::DeviceDrawPacketBuilder& builder)
  91. {
  92. builder.Begin(nullptr);
  93. for (auto& srgPtr : m_srgs)
  94. {
  95. builder.AddShaderResourceGroup(srgPtr.get());
  96. }
  97. builder.SetRootConstants(m_rootConstants);
  98. builder.SetGeometryView(&m_geometryView);
  99. RHI::DrawListMask drawListMask;
  100. for (size_t i = 0; i < DrawItemCountMax; ++i)
  101. {
  102. const DrawItemData& drawItemData = m_drawItemDatas[i];
  103. drawListMask[drawItemData.m_tag.GetIndex()] = true;
  104. RHI::DeviceDrawPacketBuilder::DeviceDrawRequest drawRequest;
  105. drawRequest.m_streamIndices = drawItemData.m_streamIndices;
  106. drawRequest.m_listTag = drawItemData.m_tag;
  107. drawRequest.m_sortKey = drawItemData.m_sortKey;
  108. drawRequest.m_stencilRef = drawItemData.m_stencilRef;
  109. drawRequest.m_pipelineState = drawItemData.m_pipelineState;
  110. builder.AddDrawItem(drawRequest);
  111. }
  112. const RHI::DeviceDrawPacket* drawPacket = builder.End();
  113. EXPECT_NE(drawPacket, nullptr);
  114. EXPECT_EQ(drawPacket->GetDrawListMask(), drawListMask);
  115. EXPECT_EQ(drawPacket->GetDrawItemCount(), m_drawItemDatas.size());
  116. for (size_t i = 0; i < m_drawItemDatas.size(); ++i)
  117. {
  118. ValidateDrawItem(m_drawItemDatas[i], drawPacket->GetDrawItemProperties(i));
  119. }
  120. return drawPacket;
  121. }
  122. RHI::Ptr<RHI::DeviceBuffer> m_bufferEmpty;
  123. RHI::ConstPtr<RHI::DevicePipelineState> m_psoEmpty;
  124. AZStd::array<RHI::Ptr<RHI::DeviceShaderResourceGroup>, RHI::Limits::Pipeline::ShaderResourceGroupCountMax> m_srgs;
  125. AZStd::array<uint8_t, sizeof(unsigned int) * 4> m_rootConstants;
  126. RHI::DeviceGeometryView m_geometryView;
  127. AZStd::vector<DrawItemData> m_drawItemDatas;
  128. };
  129. class DrawPacketTest
  130. : public RHITestFixture
  131. {
  132. protected:
  133. static const uint32_t s_randomSeed = 1234;
  134. RHI::Ptr<RHI::DrawListTagRegistry> m_drawListTagRegistry;
  135. RHI::DrawListContext m_drawListContext;
  136. AZStd::unique_ptr<AZ::RHI::RHISystem> m_rhiSystem;
  137. AZStd::unique_ptr<Factory> m_factory;
  138. public:
  139. void SetUp() override
  140. {
  141. RHITestFixture::SetUp();
  142. m_factory.reset(aznew Factory());
  143. m_drawListTagRegistry = RHI::DrawListTagRegistry::Create();
  144. m_rhiSystem.reset(aznew AZ::RHI::RHISystem);
  145. m_rhiSystem->InitDevices();
  146. m_rhiSystem->Init();
  147. }
  148. void TearDown() override
  149. {
  150. m_rhiSystem->Shutdown();
  151. m_rhiSystem.reset();
  152. m_drawListTagRegistry = nullptr;
  153. m_factory.reset();
  154. RHITestFixture::TearDown();
  155. }
  156. void TestDrawListTagRegistryNullCase()
  157. {
  158. RHI::DrawListTag nullTag = m_drawListTagRegistry->AcquireTag(Name());
  159. EXPECT_TRUE(nullTag.IsNull());
  160. EXPECT_EQ(m_drawListTagRegistry->GetAllocatedTagCount(), 0);
  161. m_drawListTagRegistry->ReleaseTag(nullTag);
  162. EXPECT_EQ(m_drawListTagRegistry->GetAllocatedTagCount(), 0);
  163. }
  164. void TestDrawListTagRegistrySimple()
  165. {
  166. const Name forwardName1("Forward");
  167. const Name forwardName2("forward");
  168. RHI::DrawListTag forwardTag1 = m_drawListTagRegistry->AcquireTag(forwardName1);
  169. RHI::DrawListTag forwardTag2 = m_drawListTagRegistry->AcquireTag(forwardName2);
  170. EXPECT_FALSE(forwardTag1.IsNull());
  171. EXPECT_FALSE(forwardTag2.IsNull());
  172. EXPECT_NE(forwardTag1, forwardTag2);
  173. RHI::DrawListTag forwardTag3 = m_drawListTagRegistry->AcquireTag(forwardName1);
  174. EXPECT_EQ(forwardTag1, forwardTag3);
  175. m_drawListTagRegistry->ReleaseTag(forwardTag1);
  176. m_drawListTagRegistry->ReleaseTag(forwardTag2);
  177. m_drawListTagRegistry->ReleaseTag(forwardTag3);
  178. EXPECT_EQ(m_drawListTagRegistry->GetAllocatedTagCount(), 0);
  179. }
  180. void TestDrawListTagRegistryDeAllocateAssert()
  181. {
  182. AZ_TEST_START_ASSERTTEST;
  183. EXPECT_EQ(m_drawListTagRegistry->GetAllocatedTagCount(), 0);
  184. const Name tagName{ "Test" };
  185. RHI::DrawListTag tag = m_drawListTagRegistry->AcquireTag(tagName);
  186. m_drawListTagRegistry->AcquireTag(tagName);
  187. m_drawListTagRegistry->AcquireTag(tagName);
  188. m_drawListTagRegistry->ReleaseTag(tag);
  189. m_drawListTagRegistry->ReleaseTag(tag);
  190. m_drawListTagRegistry->ReleaseTag(tag);
  191. // One additional forfeit should assert.
  192. m_drawListTagRegistry->ReleaseTag(tag);
  193. AZ_TEST_STOP_ASSERTTEST(1);
  194. }
  195. void TestDrawListTagRegistryRandomAllocations()
  196. {
  197. AZ::SimpleLcgRandom random(s_randomSeed);
  198. AZStd::vector<RHI::DrawListTag> acquiredTags;
  199. const uint32_t IterationCount = 1000;
  200. for (uint32_t iter = 0; iter < IterationCount; ++iter)
  201. {
  202. Name tagNameUnique = Name(AZStd::string::format("Tag_%d", iter));
  203. // Acquire
  204. if (random.GetRandom() % 2)
  205. {
  206. RHI::DrawListTag tag = m_drawListTagRegistry->AcquireTag(tagNameUnique);
  207. if (tag.IsNull())
  208. {
  209. EXPECT_EQ(m_drawListTagRegistry->GetAllocatedTagCount(), RHI::Limits::Pipeline::DrawListTagCountMax);
  210. }
  211. else
  212. {
  213. EXPECT_LT(m_drawListTagRegistry->GetAllocatedTagCount(), RHI::Limits::Pipeline::DrawListTagCountMax);
  214. acquiredTags.emplace_back(tag);
  215. }
  216. }
  217. // Forfeit
  218. else if (!acquiredTags.empty())
  219. {
  220. size_t tagIndex = random.GetRandom() % static_cast<uint32_t>(acquiredTags.size());
  221. RHI::DrawListTag tag = acquiredTags[tagIndex];
  222. size_t allocationCountBefore = m_drawListTagRegistry->GetAllocatedTagCount();
  223. m_drawListTagRegistry->ReleaseTag(tag);
  224. size_t allocationCountAfter = m_drawListTagRegistry->GetAllocatedTagCount();
  225. EXPECT_EQ(allocationCountBefore - allocationCountAfter, 1);
  226. acquiredTags.erase(acquiredTags.begin() + tagIndex);
  227. }
  228. EXPECT_EQ(acquiredTags.size(), m_drawListTagRegistry->GetAllocatedTagCount());
  229. }
  230. // Erase all references, make sure the registry is empty again.
  231. for (RHI::DrawListTag tag : acquiredTags)
  232. {
  233. m_drawListTagRegistry->ReleaseTag(tag);
  234. }
  235. acquiredTags.clear();
  236. EXPECT_EQ(m_drawListTagRegistry->GetAllocatedTagCount(), 0);
  237. }
  238. void DrawPacketEmpty()
  239. {
  240. RHI::DeviceDrawPacketBuilder builder;
  241. builder.Begin(nullptr);
  242. const RHI::DeviceDrawPacket* drawPacket = builder.End();
  243. EXPECT_EQ(drawPacket, nullptr);
  244. }
  245. void DrawPacketNullItem()
  246. {
  247. RHI::DeviceDrawPacketBuilder builder;
  248. builder.Begin(nullptr);
  249. RHI::DeviceDrawPacketBuilder::DeviceDrawRequest drawRequest;
  250. builder.AddDrawItem(drawRequest);
  251. const RHI::DeviceDrawPacket* drawPacket = builder.End();
  252. EXPECT_EQ(drawPacket, nullptr);
  253. }
  254. void DrawPacketBuild()
  255. {
  256. AZ::SimpleLcgRandom random(s_randomSeed);
  257. DrawPacketData drawPacketData(random);
  258. RHI::DeviceDrawPacketBuilder builder;
  259. const RHI::DeviceDrawPacket* drawPacket = drawPacketData.Build(builder);
  260. delete drawPacket;
  261. }
  262. void DrawPacketBuildClearBuildNull()
  263. {
  264. AZ::SimpleLcgRandom random(s_randomSeed);
  265. DrawPacketData drawPacketData(random);
  266. RHI::DeviceDrawPacketBuilder builder;
  267. const RHI::DeviceDrawPacket* drawPacket = drawPacketData.Build(builder);
  268. delete drawPacket;
  269. // Try to build a 'null' packet. This should result in a null pointer.
  270. builder.Begin(nullptr);
  271. drawPacket = builder.End();
  272. EXPECT_EQ(drawPacket, nullptr);
  273. }
  274. void DrawPacketClone()
  275. {
  276. AZ::SimpleLcgRandom random(s_randomSeed);
  277. DrawPacketData drawPacketData(random);
  278. RHI::DeviceDrawPacketBuilder builder;
  279. const RHI::DeviceDrawPacket* drawPacket = drawPacketData.Build(builder);
  280. RHI::DeviceDrawPacketBuilder builder2;
  281. const RHI::DeviceDrawPacket* drawPacketClone = builder2.Clone(drawPacket);
  282. EXPECT_EQ(drawPacket->m_drawItemCount, drawPacketClone->m_drawItemCount);
  283. EXPECT_EQ(drawPacket->m_geometryView, drawPacketClone->m_geometryView);
  284. EXPECT_EQ(drawPacket->m_shaderResourceGroupCount, drawPacketClone->m_shaderResourceGroupCount);
  285. EXPECT_EQ(drawPacket->m_uniqueShaderResourceGroupCount, drawPacketClone->m_uniqueShaderResourceGroupCount);
  286. EXPECT_EQ(drawPacket->m_rootConstantSize, drawPacketClone->m_rootConstantSize);
  287. EXPECT_EQ(drawPacket->m_scissorsCount, drawPacketClone->m_scissorsCount);
  288. EXPECT_EQ(drawPacket->m_viewportsCount, drawPacketClone->m_viewportsCount);
  289. uint8_t drawItemCount = drawPacket->m_drawItemCount;
  290. for (uint8_t i = 0; i < drawItemCount; ++i)
  291. {
  292. EXPECT_EQ(drawPacket->GetDrawListTag(i), drawPacketClone->GetDrawListTag(i));
  293. EXPECT_EQ(drawPacket->GetDrawFilterMask(i), drawPacketClone->GetDrawFilterMask(i));
  294. EXPECT_EQ(*(drawPacket->m_drawItemSortKeys + i), *(drawPacketClone->m_drawItemSortKeys + i));
  295. const RHI::DeviceDrawItem* drawItem = drawPacket->m_drawItems + i;
  296. const RHI::DeviceDrawItem* drawItemClone = drawPacketClone->m_drawItems + i;
  297. // Check the clone is an actual copy not an identical pointer.
  298. EXPECT_NE(drawItem, drawItemClone);
  299. EXPECT_EQ(drawItem->m_pipelineState->GetType(), drawItemClone->m_pipelineState->GetType());
  300. EXPECT_EQ(drawItem->m_stencilRef, drawItemClone->m_stencilRef);
  301. EXPECT_EQ(drawItem->m_geometryView, drawItemClone->m_geometryView);
  302. EXPECT_EQ(drawItem->m_streamIndices, drawItemClone->m_streamIndices);
  303. EXPECT_EQ(drawItem->m_shaderResourceGroupCount, drawItemClone->m_shaderResourceGroupCount);
  304. EXPECT_EQ(drawItem->m_rootConstantSize, drawItemClone->m_rootConstantSize);
  305. EXPECT_EQ(drawItem->m_scissorsCount, drawItemClone->m_scissorsCount);
  306. EXPECT_EQ(drawItem->m_viewportsCount, drawItemClone->m_viewportsCount);
  307. uint8_t shaderResourceGroupCount = drawItem->m_shaderResourceGroupCount;
  308. uint8_t rootConstantSize = drawItem->m_rootConstantSize;
  309. uint8_t scissorsCount = drawItem->m_scissorsCount;
  310. uint8_t viewportsCount = drawItem->m_viewportsCount;
  311. for (uint8_t j = 0; j < shaderResourceGroupCount; ++j)
  312. {
  313. EXPECT_EQ(*(drawItem->m_shaderResourceGroups + j), *(drawItemClone->m_shaderResourceGroups + j));
  314. }
  315. for (uint8_t j = 0; j < rootConstantSize; ++j)
  316. {
  317. EXPECT_EQ(*(drawItem->m_rootConstants + j), *(drawItemClone->m_rootConstants + j));
  318. }
  319. for (uint8_t j = 0; j < scissorsCount; ++j)
  320. {
  321. EXPECT_EQ(drawItem->m_scissors + j, drawItemClone->m_scissors + j);
  322. }
  323. for (uint8_t j = 0; j < viewportsCount; ++j)
  324. {
  325. EXPECT_EQ(drawItem->m_viewports + j, drawItemClone->m_viewports + j);
  326. }
  327. }
  328. uint8_t shaderResourceGroupCount = drawPacket->m_shaderResourceGroupCount;
  329. uint8_t uniqueShaderResourceGroupCount = drawPacket->m_uniqueShaderResourceGroupCount;
  330. uint8_t rootConstantSize = drawPacket->m_rootConstantSize;
  331. uint8_t scissorsCount = drawPacket->m_scissorsCount;
  332. uint8_t viewportsCount = drawPacket->m_viewportsCount;
  333. for (uint8_t i = 0; i < shaderResourceGroupCount; ++i)
  334. {
  335. EXPECT_EQ(*(drawPacket->m_shaderResourceGroups + i), *(drawPacketClone->m_shaderResourceGroups + i));
  336. }
  337. for (uint8_t i = 0; i < uniqueShaderResourceGroupCount; ++i)
  338. {
  339. EXPECT_EQ(*(drawPacket->m_uniqueShaderResourceGroups + i), *(drawPacketClone->m_uniqueShaderResourceGroups + i));
  340. }
  341. for (uint8_t i = 0; i < rootConstantSize; ++i)
  342. {
  343. EXPECT_EQ(*(drawPacket->m_rootConstants + i), *(drawPacketClone->m_rootConstants + i));
  344. }
  345. for (uint8_t i = 0; i < scissorsCount; ++i)
  346. {
  347. EXPECT_EQ(drawPacket->m_scissors + i, drawPacketClone->m_scissors + i);
  348. }
  349. for (uint8_t i = 0; i < viewportsCount; ++i)
  350. {
  351. EXPECT_EQ(drawPacket->m_viewports + i, drawPacketClone->m_viewports + i);
  352. }
  353. delete drawPacket;
  354. delete drawPacketClone;
  355. }
  356. void TestSetInstanceCount()
  357. {
  358. AZ::SimpleLcgRandom random(s_randomSeed);
  359. DrawPacketData drawPacketData(random);
  360. RHI::DeviceDrawPacketBuilder builder;
  361. const RHI::DeviceDrawPacket* drawPacket = drawPacketData.Build(builder);
  362. RHI::DeviceDrawPacketBuilder builder2;
  363. RHI::DeviceDrawPacket* drawPacketClone = const_cast<RHI::DeviceDrawPacket*>(builder2.Clone(drawPacket));
  364. uint8_t drawItemCount = drawPacketClone->m_drawItemCount;
  365. // Test default value
  366. EXPECT_EQ(drawPacketClone->m_geometryView->GetDrawArguments().m_type, RHI::DrawType::Indexed);
  367. for (uint8_t i = 0; i < drawItemCount; ++i)
  368. {
  369. const RHI::DeviceDrawItem* drawItemClone = drawPacketClone->m_drawItems + i;
  370. EXPECT_EQ(drawItemClone->m_drawInstanceArgs.m_instanceCount, 1);
  371. }
  372. drawPacketClone->SetInstanceCount(12);
  373. for (uint8_t i = 0; i < drawItemCount; ++i)
  374. {
  375. const RHI::DeviceDrawItem* drawItemClone = drawPacketClone->m_drawItems + i;
  376. EXPECT_EQ(drawItemClone->m_drawInstanceArgs.m_instanceCount, 12);
  377. // Check that the original draw packet is not affected
  378. const RHI::DeviceDrawItem* drawItem = drawPacket->m_drawItems + i;
  379. EXPECT_EQ(drawItem->m_drawInstanceArgs.m_instanceCount, 1);
  380. }
  381. delete drawPacket;
  382. delete drawPacketClone;
  383. }
  384. void TestSetRootConstants()
  385. {
  386. AZ::SimpleLcgRandom random(s_randomSeed);
  387. DrawPacketData drawPacketData(random);
  388. RHI::DeviceDrawPacketBuilder builder;
  389. const RHI::DeviceDrawPacket* drawPacket = drawPacketData.Build(builder);
  390. RHI::DeviceDrawPacketBuilder builder2;
  391. RHI::DeviceDrawPacket* drawPacketClone = const_cast<RHI::DeviceDrawPacket*>(builder2.Clone(drawPacket));
  392. AZStd::array<uint8_t, sizeof(unsigned int) * 4> rootConstantOld;
  393. EXPECT_EQ(sizeof(unsigned int) * 4, drawPacketClone->m_rootConstantSize);
  394. // Keep a copy of old root constant for later verification
  395. for (uint8_t i = 0; i < drawPacketClone->m_rootConstantSize; ++i)
  396. {
  397. rootConstantOld[i] = drawPacketClone->m_rootConstants[i];
  398. }
  399. // Root constant data to be set, partial size as of the full root constant size.
  400. AZStd::array<uint8_t, sizeof(unsigned int) * 2> rootConstantNew = { 1, 2, 3, 4, 5, 6, 7, 8 };
  401. // Attempt to set beyond the array
  402. AZ_TEST_START_TRACE_SUPPRESSION;
  403. drawPacketClone->SetRootConstant(9, rootConstantNew);
  404. AZ_TEST_STOP_TRACE_SUPPRESSION(1);
  405. // Nothing will be set if it triggers the assert
  406. for (uint8_t i = 0; i < drawPacketClone->m_rootConstantSize; ++i)
  407. {
  408. EXPECT_EQ(rootConstantOld[i], drawPacketClone->m_rootConstants[i]);
  409. }
  410. drawPacketClone->SetRootConstant(8, rootConstantNew);
  411. // Compare the part staying the same.
  412. for (uint8_t i = 0; i < drawPacketClone->m_rootConstantSize - 8; ++i)
  413. {
  414. EXPECT_EQ(rootConstantOld[i], drawPacketClone->m_rootConstants[i]);
  415. }
  416. // Compare the part being set
  417. for (uint8_t i = drawPacketClone->m_rootConstantSize - 8; i < drawPacketClone->m_rootConstantSize; ++i)
  418. {
  419. EXPECT_EQ(rootConstantNew[i - (drawPacketClone->m_rootConstantSize - 8)], drawPacketClone->m_rootConstants[i]);
  420. }
  421. // Compare the origin which shouldn't be affected.
  422. for (uint8_t i = 0; i < drawPacket->m_rootConstantSize; ++i)
  423. {
  424. EXPECT_EQ(rootConstantOld[i], drawPacket->m_rootConstants[i]);
  425. }
  426. delete drawPacket;
  427. delete drawPacketClone;
  428. }
  429. };
  430. TEST_F(DrawPacketTest, TestDrawListTagRegistryNullCase)
  431. {
  432. TestDrawListTagRegistryNullCase();
  433. }
  434. TEST_F(DrawPacketTest, TestDrawListTagRegistrySimple)
  435. {
  436. TestDrawListTagRegistrySimple();
  437. }
  438. TEST_F(DrawPacketTest, TestDrawListTagRegistryDeAllocateAssert)
  439. {
  440. TestDrawListTagRegistryDeAllocateAssert();
  441. }
  442. TEST_F(DrawPacketTest, TestDrawListTagRegistryRandomAllocations)
  443. {
  444. TestDrawListTagRegistryRandomAllocations();
  445. }
  446. TEST_F(DrawPacketTest, DrawPacketEmpty)
  447. {
  448. DrawPacketEmpty();
  449. }
  450. TEST_F(DrawPacketTest, DrawPacketNullItem)
  451. {
  452. DrawPacketNullItem();
  453. }
  454. TEST_F(DrawPacketTest, DrawPacketBuild)
  455. {
  456. DrawPacketBuild();
  457. }
  458. TEST_F(DrawPacketTest, DrawPacketBuildClearBuildNull)
  459. {
  460. DrawPacketBuildClearBuildNull();
  461. }
  462. TEST_F(DrawPacketTest, DrawPacketClone)
  463. {
  464. DrawPacketClone();
  465. }
  466. TEST_F(DrawPacketTest, TestSetInstanceCount)
  467. {
  468. TestSetInstanceCount();
  469. }
  470. TEST_F(DrawPacketTest, TestSetRootConstants)
  471. {
  472. TestSetRootConstants();
  473. }
  474. }
  475. AZ_UNIT_TEST_HOOK(DEFAULT_UNIT_TEST_ENV);