BufferTests.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  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/RPI.Reflect/Buffer/BufferAssetCreator.h>
  9. #include <Atom/RPI.Reflect/ResourcePoolAssetCreator.h>
  10. #include <AzTest/AzTest.h>
  11. #include <Common/RHI/Factory.h>
  12. #include <Common/RPITestFixture.h>
  13. #include <Common/SerializeTester.h>
  14. #include <Common/ErrorMessageFinder.h>
  15. #include <Atom/RPI.Public/Buffer/Buffer.h>
  16. #include <Atom/RPI.Public/Buffer/BufferSystemInterface.h>
  17. namespace UnitTest
  18. {
  19. class BufferTests
  20. : public RPITestFixture
  21. {
  22. protected:
  23. struct ExpectedBuffer
  24. {
  25. AZStd::vector<uint8_t> m_data;
  26. AZ::RHI::BufferDescriptor m_bufferDescriptor;
  27. AZ::RHI::BufferViewDescriptor m_viewDescriptor;
  28. };
  29. AZ::Data::Asset<AZ::RPI::ResourcePoolAsset> CreateTestBufferPoolAsset()
  30. {
  31. using namespace AZ;
  32. using namespace RPI;
  33. Data::Asset<ResourcePoolAsset> asset;
  34. auto bufferPoolDesc = AZStd::make_unique<RHI::BufferPoolDescriptor>();
  35. bufferPoolDesc->m_bindFlags = RHI::BufferBindFlags::ShaderRead;
  36. bufferPoolDesc->m_heapMemoryLevel = RHI::HeapMemoryLevel::Host;
  37. ResourcePoolAssetCreator creator;
  38. creator.Begin(Uuid::CreateRandom());
  39. creator.SetPoolDescriptor(AZStd::move(bufferPoolDesc));
  40. creator.SetPoolName("TestPool");
  41. creator.End(asset);
  42. return asset;
  43. }
  44. ExpectedBuffer CreateValidBuffer()
  45. {
  46. using namespace AZ;
  47. // Build a simple buffer with 100 elements where
  48. // each element is 3 floats in size
  49. const uint32_t elementSize = sizeof(float) * 3;
  50. const uint32_t elementCount = 100;
  51. const size_t bufferSize = elementSize * elementCount;
  52. AZStd::vector<uint8_t> bufferData;
  53. bufferData.resize(bufferSize);
  54. // The actual data doesn't matter
  55. const uint8_t bufferDataSize = static_cast<uint8_t>(bufferData.size());
  56. for (uint8_t i = 0; i < bufferDataSize; ++i)
  57. {
  58. bufferData[i] = i;
  59. }
  60. RHI::BufferDescriptor bufferDescriptor;
  61. bufferDescriptor.m_bindFlags = RHI::BufferBindFlags::ShaderRead;
  62. bufferDescriptor.m_byteCount = bufferSize;
  63. RHI::BufferViewDescriptor viewDescriptor = RHI::BufferViewDescriptor::CreateStructured(0, elementCount, elementSize);
  64. ExpectedBuffer validBuffer;
  65. validBuffer.m_data = bufferData;
  66. validBuffer.m_bufferDescriptor = bufferDescriptor;
  67. validBuffer.m_viewDescriptor = viewDescriptor;
  68. return validBuffer;
  69. }
  70. AZ::Data::Asset<AZ::RPI::BufferAsset> BuildTestBuffer(ExpectedBuffer& expectedBuffer)
  71. {
  72. using namespace AZ;
  73. // Copy valid buffer to output buffer
  74. expectedBuffer = CreateValidBuffer();
  75. const size_t bufferSize = expectedBuffer.m_bufferDescriptor.m_byteCount;
  76. RPI::BufferAssetCreator creator;
  77. creator.Begin(Data::AssetId(AZ::Uuid::CreateRandom()));
  78. creator.SetBuffer(expectedBuffer.m_data.data(), bufferSize, expectedBuffer.m_bufferDescriptor);
  79. creator.SetBufferViewDescriptor(expectedBuffer.m_viewDescriptor);
  80. creator.SetPoolAsset(CreateTestBufferPoolAsset());
  81. Data::Asset<RPI::BufferAsset> asset;
  82. EXPECT_TRUE(creator.End(asset));
  83. EXPECT_TRUE(asset.IsReady());
  84. EXPECT_NE(asset.Get(), nullptr);
  85. return asset;
  86. }
  87. void ValidateBufferAsset(AZ::RPI::BufferAsset* bufferAsset, const ExpectedBuffer& expectedBuffer)
  88. {
  89. using namespace AZ;
  90. EXPECT_NE(bufferAsset, nullptr);
  91. EXPECT_TRUE(bufferAsset->GetBuffer().size() == expectedBuffer.m_data.size());
  92. const bool sameBuffer = memcmp(&bufferAsset->GetBuffer()[0], expectedBuffer.m_data.data(), bufferAsset->GetBuffer().size()) == 0;
  93. EXPECT_TRUE(sameBuffer);
  94. const RHI::BufferDescriptor& assetBufferDescriptor = bufferAsset->GetBufferDescriptor();
  95. const RHI::BufferDescriptor& expectedBufferDescriptor = expectedBuffer.m_bufferDescriptor;
  96. EXPECT_TRUE(assetBufferDescriptor.GetHash() == expectedBufferDescriptor.GetHash());
  97. EXPECT_TRUE(assetBufferDescriptor.m_bindFlags == expectedBufferDescriptor.m_bindFlags);
  98. EXPECT_TRUE(assetBufferDescriptor.m_byteCount == expectedBufferDescriptor.m_byteCount);
  99. EXPECT_TRUE(assetBufferDescriptor.m_sharedQueueMask == expectedBufferDescriptor.m_sharedQueueMask);
  100. const RHI::BufferViewDescriptor& assetViewDescriptor = bufferAsset->GetBufferViewDescriptor();
  101. const RHI::BufferViewDescriptor& expectedViewDescriptor = expectedBuffer.m_viewDescriptor;
  102. EXPECT_TRUE(assetViewDescriptor.GetHash() == expectedViewDescriptor.GetHash());
  103. EXPECT_TRUE(assetViewDescriptor.m_elementCount == expectedViewDescriptor.m_elementCount);
  104. EXPECT_TRUE(assetViewDescriptor.m_elementFormat == expectedViewDescriptor.m_elementFormat);
  105. EXPECT_TRUE(assetViewDescriptor.m_elementOffset == expectedViewDescriptor.m_elementOffset);
  106. EXPECT_TRUE(assetViewDescriptor.m_elementSize == expectedViewDescriptor.m_elementSize);
  107. }
  108. AZStd::unique_ptr<AZ::RPI::BufferAssetHandler> m_bufferAssetHandler;
  109. };
  110. // Test that a buffer can be created and that the contents match
  111. // what we expect.
  112. TEST_F(BufferTests, Creation)
  113. {
  114. using namespace AZ;
  115. ExpectedBuffer expectedBuffer;
  116. Data::Asset<RPI::BufferAsset> bufferAsset = BuildTestBuffer(expectedBuffer);
  117. ValidateBufferAsset(bufferAsset.Get(), expectedBuffer);
  118. }
  119. // Test that a buffer can be created, serialized and de-serialized
  120. // without losing any data.
  121. TEST_F(BufferTests, SerializeDeserialize)
  122. {
  123. using namespace AZ;
  124. ExpectedBuffer expectedBuffer;
  125. Data::Asset<RPI::BufferAsset> bufferAsset = BuildTestBuffer(expectedBuffer);
  126. SerializeTester<RPI::BufferAsset> tester(GetSerializeContext());
  127. tester.SerializeOut(bufferAsset.Get());
  128. Data::Asset<RPI::BufferAsset> serializedBufferAsset = tester.SerializeIn(Data::AssetId(Uuid::CreateRandom()));
  129. ValidateBufferAsset(serializedBufferAsset.Get(), expectedBuffer);
  130. }
  131. // Test that if we try to set data on the BufferAssetCreator
  132. // before Begin has been called that it fails
  133. TEST_F(BufferTests, SetBufferNoBegin)
  134. {
  135. using namespace AZ;
  136. ExpectedBuffer validBuffer = CreateValidBuffer();
  137. const size_t bufferSize = validBuffer.m_bufferDescriptor.m_byteCount;
  138. RPI::BufferAssetCreator creator;
  139. ErrorMessageFinder messageFinder("Begin() was not called", 2);
  140. creator.SetBuffer(validBuffer.m_data.data(), bufferSize, validBuffer.m_bufferDescriptor);
  141. //Ending the buffer here should also result in failure
  142. Data::Asset<RPI::BufferAsset> asset;
  143. ASSERT_FALSE(creator.End(asset));
  144. ASSERT_FALSE(asset.IsReady());
  145. ASSERT_EQ(asset.Get(), nullptr);
  146. }
  147. // Test that if we try to set empty data on the BufferAssetCreator
  148. // that it works as intended
  149. TEST_F(BufferTests, SetEmptyBuffer)
  150. {
  151. using namespace AZ;
  152. //Use a valid buffer for the buffer descriptor
  153. ExpectedBuffer validBuffer = CreateValidBuffer();
  154. RPI::BufferAssetCreator creator;
  155. creator.Begin(Data::AssetId(AZ::Uuid::CreateRandom()));
  156. // Setting nullptr should succeed if the buffer descriptor is valid
  157. // as the BufferAsset should be usable for R/W buffers
  158. creator.SetBuffer(nullptr, 0, validBuffer.m_bufferDescriptor);
  159. ASSERT_EQ(0, creator.GetErrorCount());
  160. ASSERT_EQ(0, creator.GetWarningCount());
  161. }
  162. // Test that if we try to set an invalid BufferDescriptor
  163. // on the BufferAssetCreator that it fails
  164. TEST_F(BufferTests, SetInvalidBufferDescriptor)
  165. {
  166. using namespace AZ;
  167. //Use a valid buffer for the buffer data
  168. ExpectedBuffer validBuffer = CreateValidBuffer();
  169. const size_t bufferSize = validBuffer.m_bufferDescriptor.m_byteCount;
  170. RHI::BufferDescriptor invalidBufferDescriptor;
  171. invalidBufferDescriptor.m_byteCount = 0;
  172. RPI::BufferAssetCreator creator;
  173. creator.Begin(Data::AssetId(AZ::Uuid::CreateRandom()));
  174. creator.SetPoolAsset(CreateTestBufferPoolAsset());
  175. ErrorMessageFinder messageFinder("Size of the buffer in the descriptor was 0");
  176. messageFinder.AddIgnoredErrorMessage("Cannot continue building BufferAsset", true);
  177. creator.SetBuffer(validBuffer.m_data.data(), bufferSize, invalidBufferDescriptor);
  178. // Ending the buffer here should also result in failure
  179. Data::Asset<RPI::BufferAsset> asset;
  180. ASSERT_FALSE(creator.End(asset));
  181. ASSERT_FALSE(asset.IsReady());
  182. ASSERT_EQ(asset.Get(), nullptr);
  183. }
  184. // Test that if we try to set initial buffer data that's more than
  185. // we describe in the buffer descriptor that the creator fails as expected.
  186. TEST_F(BufferTests, SetBufferTooMuchInitialData)
  187. {
  188. using namespace AZ;
  189. //Use a valid buffer for the buffer data
  190. ExpectedBuffer validBuffer = CreateValidBuffer();
  191. const size_t invalidInitialDataSize = validBuffer.m_bufferDescriptor.m_byteCount + 1;
  192. RPI::BufferAssetCreator creator;
  193. creator.Begin(Data::AssetId(AZ::Uuid::CreateRandom()));
  194. creator.SetPoolAsset(CreateTestBufferPoolAsset());
  195. ErrorMessageFinder messageFinder("initialSize is larger than the total size in the descriptor.");
  196. messageFinder.AddIgnoredErrorMessage("Cannot continue building BufferAsset", true);
  197. creator.SetBuffer(validBuffer.m_data.data(), invalidInitialDataSize, validBuffer.m_bufferDescriptor);
  198. // Ending the buffer here should also result in failure
  199. Data::Asset<RPI::BufferAsset> asset;
  200. ASSERT_FALSE(creator.End(asset));
  201. ASSERT_FALSE(asset.IsReady());
  202. ASSERT_EQ(asset.Get(), nullptr);
  203. }
  204. // Test that if we try to set an empty buffer with a non-zero
  205. // initial size that the creator fails as expected.
  206. TEST_F(BufferTests, SetEmptyBufferWithNonZeroSize)
  207. {
  208. using namespace AZ;
  209. //Use a valid buffer for the bufferDescriptor
  210. ExpectedBuffer validBuffer = CreateValidBuffer();
  211. RPI::BufferAssetCreator creator;
  212. creator.Begin(Data::AssetId(AZ::Uuid::CreateRandom()));
  213. creator.SetPoolAsset(CreateTestBufferPoolAsset());
  214. ErrorMessageFinder messageFinder("Initial buffer data was not provided but the initial size was non-zero.");
  215. messageFinder.AddIgnoredErrorMessage("Cannot continue building BufferAsset", true);
  216. creator.SetBuffer(nullptr, 1, validBuffer.m_bufferDescriptor);
  217. // Ending the buffer here should also result in failure
  218. Data::Asset<RPI::BufferAsset> asset;
  219. ASSERT_FALSE(creator.End(asset));
  220. ASSERT_FALSE(asset.IsReady());
  221. ASSERT_EQ(asset.Get(), nullptr);
  222. }
  223. // Test that if we try to set a buffer with an initial size of 0
  224. // that the creator fails as expected.
  225. TEST_F(BufferTests, SetBufferWithZeroSize)
  226. {
  227. using namespace AZ;
  228. //Use a valid buffer for the bufferDescriptor
  229. ExpectedBuffer validBuffer = CreateValidBuffer();
  230. RPI::BufferAssetCreator creator;
  231. creator.Begin(Data::AssetId(AZ::Uuid::CreateRandom()));
  232. creator.SetPoolAsset(CreateTestBufferPoolAsset());
  233. ErrorMessageFinder messageFinder("Initial buffer data was not null but the initial size was zero.");
  234. messageFinder.AddIgnoredErrorMessage("Cannot continue building BufferAsset", true);
  235. creator.SetBuffer(validBuffer.m_data.data(), 0, validBuffer.m_bufferDescriptor);
  236. // Ending the buffer here should also result in failure
  237. Data::Asset<RPI::BufferAsset> asset;
  238. ASSERT_FALSE(creator.End(asset));
  239. ASSERT_FALSE(asset.IsReady());
  240. ASSERT_EQ(asset.Get(), nullptr);
  241. }
  242. // Tests that if we try to set the view descriptor on the
  243. // BufferAssetCreator before Begin has been called that it fails
  244. TEST_F(BufferTests, SetViewDescriptorNoBegin)
  245. {
  246. using namespace AZ;
  247. ExpectedBuffer validBuffer = CreateValidBuffer();
  248. RPI::BufferAssetCreator creator;
  249. ErrorMessageFinder messageFinder("Begin() was not called", 2);
  250. creator.SetBufferViewDescriptor(validBuffer.m_viewDescriptor);
  251. //Ending the buffer here should also result in failure
  252. Data::Asset<RPI::BufferAsset> asset;
  253. ASSERT_FALSE(creator.End(asset));
  254. ASSERT_FALSE(asset.IsReady());
  255. ASSERT_EQ(asset.Get(), nullptr);
  256. }
  257. TEST_F(BufferTests, SetInvalidViewDescriptor)
  258. {
  259. using namespace AZ;
  260. ExpectedBuffer validBuffer = CreateValidBuffer();
  261. RHI::BufferViewDescriptor invalidViewDescriptor;
  262. RPI::BufferAssetCreator creator;
  263. creator.Begin(Data::AssetId(AZ::Uuid::CreateRandom()));
  264. creator.SetPoolAsset(CreateTestBufferPoolAsset());
  265. ErrorMessageFinder messageFinder("BufferAssetCreator::SetBufferViewDescriptor was given a view descriptor with an element count of 0.");
  266. messageFinder.AddIgnoredErrorMessage("Cannot continue building BufferAsset", true);
  267. creator.SetBufferViewDescriptor(invalidViewDescriptor);
  268. //Ending the buffer here should also result in failure
  269. Data::Asset<RPI::BufferAsset> asset;
  270. ASSERT_FALSE(creator.End(asset));
  271. ASSERT_FALSE(asset.IsReady());
  272. ASSERT_EQ(asset.Get(), nullptr);
  273. }
  274. // Buffer Asset tests
  275. // Buffer asset without initial data
  276. TEST_F(BufferTests, BufferAssetCreation_NoInitialData_Success)
  277. {
  278. using namespace AZ;
  279. ExpectedBuffer bufferInfo = CreateValidBuffer();
  280. RPI::BufferAssetCreator creator;
  281. creator.Begin(Data::AssetId(AZ::Uuid::CreateRandom()));
  282. creator.SetPoolAsset(CreateTestBufferPoolAsset());
  283. creator.SetBufferViewDescriptor(bufferInfo.m_viewDescriptor);
  284. // empty initial data
  285. creator.SetBuffer(nullptr, 0, bufferInfo.m_bufferDescriptor);
  286. Data::Asset<RPI::BufferAsset> asset;
  287. EXPECT_TRUE(creator.End(asset));
  288. EXPECT_TRUE(asset.IsReady());
  289. EXPECT_NE(asset.Get(), nullptr);
  290. }
  291. // Neither pool asset specified nor common pool type specified
  292. TEST_F(BufferTests, BufferAssetCreation_NoPoolSpecified_Fail)
  293. {
  294. using namespace AZ;
  295. ExpectedBuffer bufferInfo = CreateValidBuffer();
  296. RPI::BufferAssetCreator creator;
  297. creator.Begin(Data::AssetId(AZ::Uuid::CreateRandom()));
  298. creator.SetBufferViewDescriptor(bufferInfo.m_viewDescriptor);
  299. creator.SetBuffer(nullptr, 0, bufferInfo.m_bufferDescriptor);
  300. Data::Asset<RPI::BufferAsset> asset;
  301. // Failed
  302. ErrorMessageFinder messageFinder("BufferAssetCreator::ValidateBuffer Failed; need valid pool asset or select a valid common pool.", 1);
  303. ASSERT_FALSE(creator.End(asset));
  304. EXPECT_FALSE(asset.IsReady());
  305. EXPECT_EQ(asset.Get(), nullptr);
  306. }
  307. // Buffer system interface unit tests
  308. // Get buffer pools by type
  309. TEST_F(BufferTests, BufferSystem_GetCommonPools_Success)
  310. {
  311. using namespace AZ;
  312. for (uint32_t type = 0; type < static_cast<uint32_t>(RPI::CommonBufferPoolType::Count); type++)
  313. {
  314. ASSERT_NE(RPI::BufferSystemInterface::Get()->GetCommonBufferPool((RPI::CommonBufferPoolType)type).get(), nullptr);
  315. }
  316. }
  317. TEST_F(BufferTests, BufferSystem_CreateCommonBuffer_Success)
  318. {
  319. using namespace AZ;
  320. ExpectedBuffer bufferInfo = CreateValidBuffer();
  321. RPI::CommonBufferDescriptor desc;
  322. desc.m_poolType = RPI::CommonBufferPoolType::ReadOnly;
  323. desc.m_bufferName = "Buffer1";
  324. desc.m_byteCount = bufferInfo.m_bufferDescriptor.m_byteCount;
  325. desc.m_elementSize = bufferInfo.m_viewDescriptor.m_elementSize;
  326. desc.m_bufferData = bufferInfo.m_data.data();
  327. // with data
  328. Data::Instance<RPI::Buffer> bufferInst = RPI::BufferSystemInterface::Get()->CreateBufferFromCommonPool(desc);
  329. // buffer created
  330. ASSERT_NE(bufferInst.get(), nullptr);
  331. // buffer has same size as creation size
  332. EXPECT_EQ(bufferInst->GetBufferSize(), bufferInfo.m_bufferDescriptor.m_byteCount);
  333. // buffer has same buffer view descriptor as expected
  334. EXPECT_EQ(bufferInst->GetBufferViewDescriptor().m_elementCount, bufferInfo.m_viewDescriptor.m_elementCount);
  335. EXPECT_EQ(bufferInst->GetBufferViewDescriptor().m_elementSize, bufferInfo.m_viewDescriptor.m_elementSize);
  336. // without initial data
  337. RPI::CommonBufferDescriptor desc2;
  338. desc.m_poolType = RPI::CommonBufferPoolType::ReadOnly;
  339. desc.m_bufferName = "Buffer2";
  340. desc.m_byteCount = bufferInfo.m_bufferDescriptor.m_byteCount;
  341. Data::Instance<RPI::Buffer> bufferInst2 = RPI::BufferSystemInterface::Get()->CreateBufferFromCommonPool(desc);
  342. // buffer created
  343. EXPECT_NE(bufferInst2.get(), nullptr);
  344. }
  345. TEST_F(BufferTests, BufferSystem_FindCommonBuffer_Success_Fail)
  346. {
  347. using namespace AZ;
  348. ExpectedBuffer bufferInfo = CreateValidBuffer();
  349. RPI::CommonBufferDescriptor desc;
  350. desc.m_poolType = RPI::CommonBufferPoolType::ReadOnly;
  351. desc.m_bufferName = "Buffer1";
  352. desc.m_byteCount = bufferInfo.m_bufferDescriptor.m_byteCount;
  353. desc.m_isUniqueName = true;
  354. Data::Instance<RPI::Buffer> bufferInst = RPI::BufferSystemInterface::Get()->CreateBufferFromCommonPool(desc);
  355. // buffer created
  356. ASSERT_NE(bufferInst.get(), nullptr);
  357. // found
  358. Data::Instance<RPI::Buffer> bufferFound = RPI::BufferSystemInterface::Get()->FindCommonBuffer("Buffer1");
  359. EXPECT_EQ(bufferInst, bufferFound);
  360. // not found
  361. Data::Instance<RPI::Buffer> bufferFound2 = RPI::BufferSystemInterface::Get()->FindCommonBuffer("Buffer2");
  362. EXPECT_EQ(bufferFound2.get(), nullptr);
  363. }
  364. // Failed if creates a buffe which has a same name with existing buffer
  365. // and has m_isUniqueName is enabled
  366. TEST_F(BufferTests, BufferSystem_CreateDuplicatedNamedBufferEnableUniqueName_Fail)
  367. {
  368. using namespace AZ;
  369. ExpectedBuffer bufferInfo = CreateValidBuffer();
  370. RPI::CommonBufferDescriptor desc;
  371. desc.m_poolType = RPI::CommonBufferPoolType::ReadOnly;
  372. desc.m_bufferName = "Buffer1";
  373. desc.m_byteCount = bufferInfo.m_bufferDescriptor.m_byteCount;
  374. desc.m_isUniqueName = true;
  375. Data::Instance<RPI::Buffer> bufferInst = RPI::BufferSystemInterface::Get()->CreateBufferFromCommonPool(desc);
  376. // buffer created
  377. EXPECT_NE(bufferInst.get(), nullptr);
  378. AZ_TEST_START_ASSERTTEST;
  379. Data::Instance<RPI::Buffer> bufferInst2 = RPI::BufferSystemInterface::Get()->CreateBufferFromCommonPool(desc);
  380. AZ_TEST_STOP_ASSERTTEST(1);
  381. // buffer NOT created
  382. EXPECT_EQ(bufferInst2.get(), nullptr);
  383. }
  384. // create a buffer which has a same name with existing buffer
  385. TEST_F(BufferTests, BufferSystem_CreateDuplicatedNamedBuffers_Success)
  386. {
  387. using namespace AZ;
  388. ExpectedBuffer bufferInfo = CreateValidBuffer();
  389. RPI::CommonBufferDescriptor desc;
  390. desc.m_poolType = RPI::CommonBufferPoolType::ReadOnly;
  391. desc.m_bufferName = "Buffer1";
  392. desc.m_byteCount = bufferInfo.m_bufferDescriptor.m_byteCount;
  393. Data::Instance<RPI::Buffer> bufferInst = RPI::BufferSystemInterface::Get()->CreateBufferFromCommonPool(desc);
  394. // buffer created
  395. EXPECT_NE(bufferInst.get(), nullptr);
  396. Data::Instance<RPI::Buffer> bufferInst2 = RPI::BufferSystemInterface::Get()->CreateBufferFromCommonPool(desc);
  397. // buffer created
  398. EXPECT_NE(bufferInst2.get(), nullptr);
  399. }
  400. // Buffer instance creation unit tests
  401. TEST_F(BufferTests, Buffer_CreationUsingPoolAsset_Success)
  402. {
  403. using namespace AZ;
  404. ExpectedBuffer expectedBuffer;
  405. Data::Asset<RPI::BufferAsset> bufferAsset = BuildTestBuffer(expectedBuffer);
  406. Data::Instance<RPI::Buffer> bufferInst = RPI::Buffer::FindOrCreate(bufferAsset);
  407. ASSERT_NE(bufferInst.get(), nullptr);
  408. }
  409. TEST_F(BufferTests, Buffer_CreationUsingCommonPool_Success)
  410. {
  411. using namespace AZ;
  412. ExpectedBuffer bufferInfo = CreateValidBuffer();
  413. RPI::BufferAssetCreator creator;
  414. creator.Begin(Data::AssetId(AZ::Uuid::CreateRandom()));
  415. creator.SetBufferViewDescriptor(bufferInfo.m_viewDescriptor);
  416. creator.SetBuffer(nullptr, 0, bufferInfo.m_bufferDescriptor);
  417. creator.SetUseCommonPool(RPI::CommonBufferPoolType::ReadOnly);
  418. Data::Asset<RPI::BufferAsset> asset;
  419. creator.End(asset);
  420. Data::Instance<RPI::Buffer> bufferInst = RPI::Buffer::FindOrCreate(asset);
  421. ASSERT_NE(bufferInst.get(), nullptr);
  422. }
  423. // Resize buffer function: validate new size and buffer view descriptor
  424. TEST_F(BufferTests, Buffer_Resize_Success)
  425. {
  426. using namespace AZ;
  427. ExpectedBuffer bufferInfo = CreateValidBuffer();
  428. RPI::BufferAssetCreator creator;
  429. creator.Begin(Data::AssetId(AZ::Uuid::CreateRandom()));
  430. creator.SetBufferViewDescriptor(bufferInfo.m_viewDescriptor);
  431. creator.SetBuffer(nullptr, 0, bufferInfo.m_bufferDescriptor);
  432. creator.SetUseCommonPool(RPI::CommonBufferPoolType::ReadOnly);
  433. Data::Asset<RPI::BufferAsset> asset;
  434. creator.End(asset);
  435. uint64_t initialSize = bufferInfo.m_bufferDescriptor.m_byteCount;
  436. Data::Instance<RPI::Buffer> bufferInst = RPI::Buffer::FindOrCreate(asset);
  437. ASSERT_NE(bufferInst.get(), nullptr);
  438. EXPECT_EQ(bufferInst->GetBufferSize(), initialSize);
  439. // size up
  440. uint64_t newSize = 2 * initialSize;
  441. bufferInst->Resize(newSize);
  442. ASSERT_NE(bufferInst.get(), nullptr);
  443. EXPECT_EQ(bufferInst->GetBufferSize(), newSize);
  444. EXPECT_EQ(bufferInst->GetBufferViewDescriptor().m_elementCount*bufferInst->GetBufferViewDescriptor().m_elementSize, newSize);
  445. // size down
  446. newSize = initialSize/2;
  447. bufferInst->Resize(newSize);
  448. ASSERT_NE(bufferInst.get(), nullptr);
  449. EXPECT_EQ(bufferInst->GetBufferSize(), newSize);
  450. EXPECT_EQ(bufferInst->GetBufferViewDescriptor().m_elementCount*bufferInst->GetBufferViewDescriptor().m_elementSize, newSize);
  451. }
  452. TEST_F(BufferTests, Buffer_SetAsStructured_Success)
  453. {
  454. using namespace AZ;
  455. ExpectedBuffer bufferInfo = CreateValidBuffer();
  456. RPI::BufferAssetCreator creator;
  457. creator.Begin(Data::AssetId(AZ::Uuid::CreateRandom()));
  458. creator.SetBufferViewDescriptor(bufferInfo.m_viewDescriptor);
  459. creator.SetBuffer(nullptr, 0, bufferInfo.m_bufferDescriptor);
  460. creator.SetUseCommonPool(RPI::CommonBufferPoolType::ReadOnly);
  461. Data::Asset<RPI::BufferAsset> asset;
  462. creator.End(asset);
  463. Data::Instance<RPI::Buffer> bufferInst = RPI::Buffer::FindOrCreate(asset);
  464. ASSERT_NE(bufferInst.get(), nullptr);
  465. bufferInst->SetAsStructured<uint16_t>();
  466. EXPECT_EQ(bufferInst->GetBufferViewDescriptor().m_elementSize, 2);
  467. EXPECT_EQ(bufferInst->GetBufferView()->GetDescriptor().m_elementCount, bufferInst->GetBufferViewDescriptor().m_elementCount);
  468. EXPECT_EQ(bufferInst->GetBufferView()->GetDescriptor().m_elementSize, bufferInst->GetBufferViewDescriptor().m_elementSize);
  469. bufferInst->SetAsStructured<uint64_t>();
  470. EXPECT_EQ(bufferInst->GetBufferViewDescriptor().m_elementSize, 8);
  471. EXPECT_EQ(bufferInst->GetBufferView()->GetDescriptor().m_elementCount, bufferInst->GetBufferViewDescriptor().m_elementCount);
  472. EXPECT_EQ(bufferInst->GetBufferView()->GetDescriptor().m_elementSize, bufferInst->GetBufferViewDescriptor().m_elementSize);
  473. }
  474. } // namespace UnitTest