FrameGraphTests.cpp 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686
  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 <Tests/FrameGraph.h>
  10. #include <Tests/Factory.h>
  11. #include <Tests/Device.h>
  12. #include <Atom/RHI/ImagePool.h>
  13. #include <Atom/RHI/BufferPool.h>
  14. #include <Atom/RHI/ImageFrameAttachment.h>
  15. #include <Atom/RHI/BufferFrameAttachment.h>
  16. #include <Atom/RHI/ImageScopeAttachment.h>
  17. #include <Atom/RHI/BufferScopeAttachment.h>
  18. #include <AzCore/Math/Random.h>
  19. namespace UnitTest
  20. {
  21. using namespace AZ;
  22. class FrameGraphTests
  23. : public RHITestFixture
  24. {
  25. public:
  26. FrameGraphTests()
  27. : RHITestFixture()
  28. {
  29. }
  30. void ValidateBinding(
  31. const RHI::Scope* scope,
  32. const RHI::BufferScopeAttachment* scopeAttachment,
  33. const RHI::Buffer* buffer)
  34. {
  35. ASSERT_TRUE(scopeAttachment->GetPrevious() == nullptr);
  36. ASSERT_TRUE(scopeAttachment->GetNext() == nullptr);
  37. ASSERT_TRUE(&scopeAttachment->GetScope() == scope);
  38. const RHI::BufferFrameAttachment& attachment = scopeAttachment->GetFrameAttachment();
  39. ASSERT_TRUE(attachment.GetFirstScope() == scope);
  40. ASSERT_TRUE(attachment.GetLastScope() == scope);
  41. ASSERT_TRUE(attachment.GetFirstScopeAttachment() == scopeAttachment);
  42. ASSERT_TRUE(attachment.GetLastScopeAttachment() == scopeAttachment);
  43. if (buffer)
  44. {
  45. ASSERT_TRUE(buffer == attachment.GetBuffer());
  46. }
  47. }
  48. void ValidateBinding(
  49. const RHI::Scope* scope,
  50. const RHI::ImageScopeAttachment* scopeAttachment,
  51. const RHI::Image* image)
  52. {
  53. ASSERT_TRUE(scopeAttachment->GetPrevious() == nullptr);
  54. ASSERT_TRUE(scopeAttachment->GetNext() == nullptr);
  55. ASSERT_TRUE(&scopeAttachment->GetScope() == scope);
  56. const RHI::ImageFrameAttachment& attachment = scopeAttachment->GetFrameAttachment();
  57. ASSERT_TRUE(attachment.GetFirstScope() == scope);
  58. ASSERT_TRUE(attachment.GetLastScope() == scope);
  59. ASSERT_TRUE(attachment.GetFirstScopeAttachment() == scopeAttachment);
  60. ASSERT_TRUE(attachment.GetLastScopeAttachment() == scopeAttachment);
  61. if (image)
  62. {
  63. ASSERT_TRUE(image == attachment.GetImage());
  64. }
  65. }
  66. void SetUp() override
  67. {
  68. RHITestFixture::SetUp();
  69. m_rootFactory.reset(aznew Factory());
  70. m_rhiSystem.reset(aznew AZ::RHI::RHISystem);
  71. m_rhiSystem->InitDevices();
  72. m_rhiSystem->Init();
  73. m_state.reset(new State);
  74. {
  75. m_state->m_bufferPool = aznew RHI::BufferPool;
  76. RHI::BufferPoolDescriptor desc;
  77. desc.m_bindFlags = RHI::BufferBindFlags::ShaderReadWrite;
  78. m_state->m_bufferPool->Init(RHI::MultiDevice::DefaultDevice, desc);
  79. }
  80. for (uint32_t i = 0; i < BufferCount; ++i)
  81. {
  82. RHI::Ptr<RHI::Buffer> buffer;
  83. buffer = aznew RHI::Buffer;
  84. RHI::BufferDescriptor desc;
  85. desc.m_bindFlags = RHI::BufferBindFlags::ShaderReadWrite;
  86. desc.m_byteCount = BufferSize;
  87. RHI::BufferInitRequest request;
  88. request.m_descriptor = desc;
  89. request.m_buffer = buffer.get();
  90. m_state->m_bufferPool->InitBuffer(request);
  91. AZStd::string name = AZStd::string::format("B%d", i);
  92. m_state->m_bufferAttachments[i].m_id = RHI::AttachmentId(name);
  93. m_state->m_bufferAttachments[i].m_buffer = AZStd::move(buffer);
  94. }
  95. {
  96. m_state->m_imagePool = aznew RHI::ImagePool;
  97. RHI::ImagePoolDescriptor desc;
  98. desc.m_bindFlags = RHI::ImageBindFlags::ShaderReadWrite;
  99. m_state->m_imagePool->Init(RHI::MultiDevice::DefaultDevice, desc);
  100. }
  101. for (uint32_t i = 0; i < ImageCount; ++i)
  102. {
  103. RHI::Ptr<RHI::Image> image;
  104. image = aznew RHI::Image;
  105. RHI::ImageDescriptor desc = RHI::ImageDescriptor::Create2D(
  106. RHI::ImageBindFlags::ShaderReadWrite,
  107. ImageSize,
  108. ImageSize,
  109. RHI::Format::R8G8B8A8_UNORM);
  110. desc.m_mipLevels = ImageMipCount;
  111. desc.m_arraySize = ImageArrayCount;
  112. RHI::ImageInitRequest request;
  113. request.m_descriptor = desc;
  114. request.m_image = image.get();
  115. m_state->m_imagePool->InitImage(request);
  116. m_state->m_imageAttachments[i].m_id = RHI::AttachmentId(AZStd::string::format("I%d", i));
  117. m_state->m_imageAttachments[i].m_image = AZStd::move(image);
  118. }
  119. for (uint32_t i = 0; i < ScopeCount; ++i)
  120. {
  121. RHI::Ptr<RHI::Scope> scope;
  122. scope = RHI::Factory::Get().CreateScope();
  123. scope->Init(RHI::ScopeId{AZStd::string::format("S%d", i)});
  124. m_state->m_scopes[i] = AZStd::move(scope);
  125. }
  126. m_state->m_frameGraphCompiler = RHI::Factory::Get().CreateFrameGraphCompiler();
  127. m_state->m_frameGraphCompiler->Init();
  128. }
  129. void TearDown() override
  130. {
  131. m_state.reset();
  132. m_rhiSystem->Shutdown();
  133. m_rhiSystem.reset();
  134. m_rootFactory.reset();
  135. RHITestFixture::TearDown();
  136. }
  137. void TestEmptyGraph()
  138. {
  139. RHI::FrameGraph frameGraph;
  140. for (uint32_t frameIdx = 0; frameIdx < FrameIterationCount; ++frameIdx)
  141. {
  142. /// Test an empty graph.
  143. frameGraph.Begin();
  144. frameGraph.End();
  145. {
  146. RHI::FrameGraphCompileRequest request;
  147. request.m_frameGraph = &frameGraph;
  148. m_state->m_frameGraphCompiler->Compile(request);
  149. }
  150. ASSERT_TRUE(frameGraph.GetScopes().empty());
  151. }
  152. }
  153. void TestSingleEmptyScope()
  154. {
  155. RHI::FrameGraph frameGraph;
  156. for (uint32_t frameIdx = 0; frameIdx < FrameIterationCount; ++frameIdx)
  157. {
  158. frameGraph.Begin();
  159. frameGraph.BeginScope(*m_state->m_scopes[0]);
  160. frameGraph.EndScope();
  161. frameGraph.End();
  162. {
  163. RHI::FrameGraphCompileRequest request;
  164. request.m_frameGraph = &frameGraph;
  165. m_state->m_frameGraphCompiler->Compile(request);
  166. }
  167. ASSERT_TRUE(frameGraph.GetScopes().size() == 1);
  168. ASSERT_TRUE(frameGraph.GetScopes()[0] == m_state->m_scopes[0]);
  169. }
  170. }
  171. void TestSingleScope()
  172. {
  173. RHI::FrameGraph frameGraph;
  174. for (uint32_t frameIdx = 0; frameIdx < FrameIterationCount; ++frameIdx)
  175. {
  176. frameGraph.Begin();
  177. frameGraph.BeginScope(*m_state->m_scopes[0]);
  178. frameGraph.SetHardwareQueueClass(RHI::HardwareQueueClass::Graphics);
  179. frameGraph.GetAttachmentDatabase().ImportBuffer(m_state->m_bufferAttachments[0].m_id, m_state->m_bufferAttachments[0].m_buffer);
  180. frameGraph.GetAttachmentDatabase().ImportBuffer(m_state->m_bufferAttachments[1].m_id, m_state->m_bufferAttachments[1].m_buffer);
  181. {
  182. RHI::BufferScopeAttachmentDescriptor desc;
  183. desc.m_attachmentId = m_state->m_bufferAttachments[0].m_id;
  184. desc.m_bufferViewDescriptor = RHI::BufferViewDescriptor::CreateRaw(0, BufferSize);
  185. desc.m_loadStoreAction.m_loadAction = RHI::AttachmentLoadAction::Clear;
  186. desc.m_loadStoreAction.m_clearValue = RHI::ClearValue::CreateVector4Float(1.0f, 0.0, 0.0, 0.0);
  187. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite, RHI::ScopeAttachmentStage::AnyGraphics);
  188. desc.m_attachmentId = m_state->m_bufferAttachments[1].m_id;
  189. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite, RHI::ScopeAttachmentStage::AnyGraphics);
  190. }
  191. frameGraph.GetAttachmentDatabase().ImportImage(m_state->m_imageAttachments[0].m_id, m_state->m_imageAttachments[0].m_image);
  192. frameGraph.GetAttachmentDatabase().ImportImage(m_state->m_imageAttachments[1].m_id, m_state->m_imageAttachments[1].m_image);
  193. frameGraph.GetAttachmentDatabase().ImportImage(m_state->m_imageAttachments[2].m_id, m_state->m_imageAttachments[2].m_image);
  194. {
  195. RHI::ImageScopeAttachmentDescriptor desc;
  196. desc.m_attachmentId = m_state->m_imageAttachments[0].m_id;
  197. desc.m_loadStoreAction.m_clearValue = RHI::ClearValue::CreateVector4Float(0.0f, 1.0f, 0.0f, 1.0f);
  198. desc.m_loadStoreAction.m_loadAction = RHI::AttachmentLoadAction::Clear;
  199. desc.m_imageViewDescriptor = RHI::ImageViewDescriptor();
  200. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite, RHI::ScopeAttachmentStage::AnyGraphics);
  201. desc.m_attachmentId = m_state->m_imageAttachments[1].m_id;
  202. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite, RHI::ScopeAttachmentStage::AnyGraphics);
  203. desc.m_attachmentId = m_state->m_imageAttachments[2].m_id;
  204. AZ_TEST_START_TRACE_SUPPRESSION;
  205. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite, RHI::ScopeAttachmentStage::Uninitialized);
  206. AZ_TEST_STOP_TRACE_SUPPRESSION(1);
  207. }
  208. const RHI::FrameGraphAttachmentDatabase& attachmentDatabase = frameGraph.GetAttachmentDatabase();
  209. ASSERT_TRUE(attachmentDatabase.GetAttachments().size() == 5);
  210. ASSERT_TRUE(attachmentDatabase.GetBufferDescriptor(m_state->m_bufferAttachments[0].m_id).GetHash() == m_state->m_bufferAttachments[0].m_buffer->GetDescriptor().GetHash());
  211. ASSERT_TRUE(attachmentDatabase.GetBufferDescriptor(m_state->m_bufferAttachments[1].m_id).GetHash() == m_state->m_bufferAttachments[1].m_buffer->GetDescriptor().GetHash());
  212. ASSERT_TRUE(attachmentDatabase.GetImageDescriptor(m_state->m_imageAttachments[0].m_id).GetHash() == m_state->m_imageAttachments[0].m_image->GetDescriptor().GetHash());
  213. ASSERT_TRUE(attachmentDatabase.GetImageDescriptor(m_state->m_imageAttachments[1].m_id).GetHash() == m_state->m_imageAttachments[1].m_image->GetDescriptor().GetHash());
  214. frameGraph.EndScope();
  215. frameGraph.End();
  216. {
  217. RHI::FrameGraphCompileRequest request;
  218. request.m_frameGraph = &frameGraph;
  219. m_state->m_frameGraphCompiler->Compile(request);
  220. }
  221. ASSERT_TRUE(frameGraph.GetScopes().size() == 1);
  222. ASSERT_TRUE(frameGraph.GetScopes()[0] == m_state->m_scopes[0]);
  223. const RHI::Scope* scope = frameGraph.FindScope(m_state->m_scopes[0]->GetId());
  224. ASSERT_TRUE(scope == m_state->m_scopes[0].get());
  225. ASSERT_TRUE(scope->GetIndex() == 0);
  226. ASSERT_TRUE(scope->GetBufferAttachments().size() == 2);
  227. for (uint32_t i = 0; i < 2; ++i)
  228. {
  229. ValidateBinding(scope, scope->GetBufferAttachments()[i], m_state->m_bufferAttachments[i].m_buffer.get());
  230. }
  231. ASSERT_TRUE(scope->GetImageAttachments().size() == 3);
  232. ASSERT_TRUE(scope->GetAttachments().size() == 5);
  233. for (uint32_t i = 0; i < 2; ++i)
  234. {
  235. ValidateBinding(scope, scope->GetImageAttachments()[i], m_state->m_imageAttachments[i].m_image.get());
  236. }
  237. }
  238. }
  239. void TestScopeGraph()
  240. {
  241. RHI::FrameGraph frameGraph;
  242. RHI::ImageScopeAttachmentDescriptor imageBindingDescs[2];
  243. imageBindingDescs[0].m_imageViewDescriptor = RHI::ImageViewDescriptor();
  244. imageBindingDescs[0].m_loadStoreAction.m_loadAction = RHI::AttachmentLoadAction::Clear;
  245. imageBindingDescs[0].m_loadStoreAction.m_clearValue = RHI::ClearValue::CreateVector4Float(1.0f, 0.0, 0.0, 0.0);
  246. imageBindingDescs[1] = imageBindingDescs[0];
  247. imageBindingDescs[1].m_loadStoreAction.m_loadAction = RHI::AttachmentLoadAction::Load;
  248. RHI::BufferScopeAttachmentDescriptor bufferBindingDescs[2];
  249. bufferBindingDescs[0].m_bufferViewDescriptor = RHI::BufferViewDescriptor::CreateRaw(0, BufferSize);
  250. bufferBindingDescs[0].m_loadStoreAction.m_loadAction = RHI::AttachmentLoadAction::Clear;
  251. bufferBindingDescs[0].m_loadStoreAction.m_clearValue = RHI::ClearValue::CreateVector4Float(1.0f, 0.0, 0.0, 0.0);
  252. bufferBindingDescs[1] = bufferBindingDescs[0];
  253. bufferBindingDescs[1].m_loadStoreAction.m_loadAction = RHI::AttachmentLoadAction::Load;
  254. AZ::SimpleLcgRandom random;
  255. struct Interval
  256. {
  257. uint32_t m_begin;
  258. uint32_t m_end;
  259. };
  260. for (uint32_t frameIdx = 0; frameIdx < FrameIterationCount; ++frameIdx)
  261. {
  262. frameGraph.Begin();
  263. Interval bufferScopeIntervals[BufferCount];
  264. for (uint32_t i = 0; i < BufferCount; ++i)
  265. {
  266. uint32_t b = random.GetRandom() % ScopeCount;
  267. uint32_t e = random.GetRandom() % ScopeCount;
  268. if (b > e)
  269. {
  270. AZStd::swap(b, e);
  271. }
  272. bufferScopeIntervals[i].m_begin = b;
  273. bufferScopeIntervals[i].m_end = e;
  274. }
  275. Interval imageScopeIntervals[ImageCount];
  276. for (uint32_t i = 0; i < ImageCount; ++i)
  277. {
  278. uint32_t b = random.GetRandom() % ScopeCount;
  279. uint32_t e = random.GetRandom() % ScopeCount;
  280. if (b > e)
  281. {
  282. AZStd::swap(b, e);
  283. }
  284. imageScopeIntervals[i].m_begin = b;
  285. imageScopeIntervals[i].m_end = e;
  286. }
  287. for (uint32_t scopeIdx = 0; scopeIdx < ScopeCount; ++scopeIdx)
  288. {
  289. if (scopeIdx == 0)
  290. {
  291. for (uint32_t i = 0; i < BufferCount; ++i)
  292. {
  293. frameGraph.GetAttachmentDatabase().ImportBuffer(m_state->m_bufferAttachments[i].m_id, m_state->m_bufferAttachments[i].m_buffer);
  294. }
  295. for (uint32_t i = 0; i < ImageCount; ++i)
  296. {
  297. frameGraph.GetAttachmentDatabase().ImportImage(m_state->m_imageAttachments[i].m_id, m_state->m_imageAttachments[i].m_image);
  298. }
  299. }
  300. frameGraph.BeginScope(*m_state->m_scopes[scopeIdx]);
  301. for (uint32_t i = 0; i < BufferCount; ++i)
  302. {
  303. if (scopeIdx == bufferScopeIntervals[i].m_begin)
  304. {
  305. bufferBindingDescs[0].m_attachmentId = m_state->m_bufferAttachments[i].m_id;
  306. frameGraph.UseShaderAttachment(
  307. bufferBindingDescs[0], RHI::ScopeAttachmentAccess::ReadWrite, RHI::ScopeAttachmentStage::AnyGraphics);
  308. }
  309. else if (scopeIdx == bufferScopeIntervals[i].m_end)
  310. {
  311. bufferBindingDescs[1].m_attachmentId = m_state->m_bufferAttachments[i].m_id;
  312. frameGraph.UseShaderAttachment(
  313. bufferBindingDescs[1], RHI::ScopeAttachmentAccess::Read, RHI::ScopeAttachmentStage::AnyGraphics);
  314. }
  315. }
  316. for (uint32_t i = 0; i < ImageCount; ++i)
  317. {
  318. if (scopeIdx == imageScopeIntervals[i].m_begin)
  319. {
  320. imageBindingDescs[0].m_attachmentId = m_state->m_imageAttachments[i].m_id;
  321. frameGraph.UseShaderAttachment(
  322. imageBindingDescs[0], RHI::ScopeAttachmentAccess::ReadWrite, RHI::ScopeAttachmentStage::AnyGraphics);
  323. }
  324. else if (scopeIdx == imageScopeIntervals[i].m_end)
  325. {
  326. imageBindingDescs[1].m_attachmentId = m_state->m_imageAttachments[i].m_id;
  327. frameGraph.UseShaderAttachment(
  328. imageBindingDescs[1], RHI::ScopeAttachmentAccess::Read, RHI::ScopeAttachmentStage::AnyGraphics);
  329. }
  330. }
  331. frameGraph.EndScope();
  332. }
  333. frameGraph.End();
  334. {
  335. RHI::FrameGraphCompileRequest request;
  336. request.m_frameGraph = &frameGraph;
  337. m_state->m_frameGraphCompiler->Compile(request);
  338. }
  339. const RHI::FrameGraphAttachmentDatabase& attachmentDatabase = frameGraph.GetAttachmentDatabase();
  340. ASSERT_TRUE(frameGraph.GetScopes().size() == ScopeCount);
  341. ASSERT_TRUE(attachmentDatabase.GetAttachments().size() == BufferCount + ImageCount);
  342. ASSERT_TRUE(attachmentDatabase.GetBufferAttachments().size() == BufferCount);
  343. ASSERT_TRUE(attachmentDatabase.GetImageAttachments().size() == ImageCount);
  344. ASSERT_TRUE(attachmentDatabase.GetImportedImageAttachments().size() == ImageCount);
  345. ASSERT_TRUE(attachmentDatabase.GetImportedBufferAttachments().size() == BufferCount);
  346. for (uint32_t i = 0; i < ImageCount; ++i)
  347. {
  348. ASSERT_TRUE(attachmentDatabase.FindAttachment(m_state->m_imageAttachments[i].m_id) != nullptr);
  349. }
  350. for (uint32_t i = 0; i < BufferCount; ++i)
  351. {
  352. ASSERT_TRUE(attachmentDatabase.FindAttachment(m_state->m_bufferAttachments[i].m_id) != nullptr);
  353. }
  354. for (const RHI::FrameAttachment* attachment : attachmentDatabase.GetAttachments())
  355. {
  356. const RHI::ScopeAttachment* scopeAttachmentPrev = nullptr;
  357. for (const RHI::ScopeAttachment* scopeAttachment = attachment->GetFirstScopeAttachment();
  358. scopeAttachment;
  359. scopeAttachment = scopeAttachment->GetNext())
  360. {
  361. ASSERT_TRUE(&scopeAttachment->GetFrameAttachment() == attachment);
  362. ASSERT_TRUE(scopeAttachment->GetPrevious() == scopeAttachmentPrev);
  363. if (scopeAttachmentPrev)
  364. {
  365. ASSERT_TRUE(scopeAttachmentPrev->GetScope().GetIndex() < scopeAttachment->GetScope().GetIndex());
  366. }
  367. scopeAttachmentPrev = scopeAttachment;
  368. }
  369. }
  370. }
  371. }
  372. void TestOverlappingAttachments()
  373. {
  374. RHI::FrameGraph frameGraph;
  375. for (uint32_t frameIdx = 0; frameIdx < FrameIterationCount; ++frameIdx)
  376. {
  377. frameGraph.Begin();
  378. frameGraph.BeginScope(*m_state->m_scopes[0]);
  379. frameGraph.SetHardwareQueueClass(RHI::HardwareQueueClass::Graphics);
  380. constexpr uint32_t numImports = 10;
  381. for (uint32_t i = 0; i < numImports; ++i)
  382. {
  383. frameGraph.GetAttachmentDatabase().ImportBuffer(
  384. m_state->m_bufferAttachments[i].m_id, m_state->m_bufferAttachments[i].m_buffer);
  385. }
  386. {
  387. // Same attachment added twice
  388. RHI::BufferScopeAttachmentDescriptor desc;
  389. desc.m_attachmentId = m_state->m_bufferAttachments[0].m_id;
  390. desc.m_bufferViewDescriptor = RHI::BufferViewDescriptor::CreateRaw(0, BufferSize);
  391. desc.m_loadStoreAction.m_loadAction = RHI::AttachmentLoadAction::DontCare;
  392. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite, RHI::ScopeAttachmentStage::AnyGraphics);
  393. AZ_TEST_START_TRACE_SUPPRESSION;
  394. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite, RHI::ScopeAttachmentStage::AnyGraphics);
  395. AZ_TEST_STOP_ASSERTTEST(1);
  396. // Partial overlap
  397. desc.m_attachmentId = m_state->m_bufferAttachments[1].m_id;
  398. desc.m_bufferViewDescriptor = RHI::BufferViewDescriptor::CreateRaw(0, BufferSize);
  399. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite, RHI::ScopeAttachmentStage::AnyGraphics);
  400. desc.m_bufferViewDescriptor.m_elementOffset = 0;
  401. desc.m_bufferViewDescriptor.m_elementCount = 1;
  402. AZ_TEST_START_TRACE_SUPPRESSION;
  403. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite, RHI::ScopeAttachmentStage::AnyGraphics);
  404. AZ_TEST_STOP_ASSERTTEST(1);
  405. // Edge overlap
  406. desc.m_attachmentId = m_state->m_bufferAttachments[2].m_id;
  407. desc.m_bufferViewDescriptor = RHI::BufferViewDescriptor::CreateRaw(0, BufferSize/2);
  408. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite, RHI::ScopeAttachmentStage::AnyGraphics);
  409. desc.m_bufferViewDescriptor = RHI::BufferViewDescriptor::CreateRaw((BufferSize / 2) - 1, BufferSize);
  410. AZ_TEST_START_TRACE_SUPPRESSION;
  411. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite, RHI::ScopeAttachmentStage::AnyGraphics);
  412. AZ_TEST_STOP_ASSERTTEST(1);
  413. // No overlap
  414. desc.m_attachmentId = m_state->m_bufferAttachments[3].m_id;
  415. desc.m_bufferViewDescriptor = RHI::BufferViewDescriptor::CreateRaw(0, BufferSize/2);
  416. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite, RHI::ScopeAttachmentStage::AnyGraphics);
  417. desc.m_bufferViewDescriptor = RHI::BufferViewDescriptor::CreateRaw((BufferSize / 2) + 1, BufferSize);
  418. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite, RHI::ScopeAttachmentStage::AnyGraphics);
  419. // Overlap read only
  420. desc.m_attachmentId = m_state->m_bufferAttachments[4].m_id;
  421. desc.m_bufferViewDescriptor = RHI::BufferViewDescriptor::CreateRaw(0, BufferSize / 2);
  422. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::Read, RHI::ScopeAttachmentStage::AnyGraphics);
  423. desc.m_bufferViewDescriptor = RHI::BufferViewDescriptor::CreateRaw((BufferSize / 2) - 1, BufferSize);
  424. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::Read, RHI::ScopeAttachmentStage::AnyGraphics);
  425. // Overlap with invalid usage
  426. desc.m_attachmentId = m_state->m_bufferAttachments[5].m_id;
  427. desc.m_bufferViewDescriptor = RHI::BufferViewDescriptor::CreateRaw(0, BufferSize);
  428. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::Read, RHI::ScopeAttachmentStage::AnyGraphics);
  429. desc.m_bufferViewDescriptor = RHI::BufferViewDescriptor::CreateRaw(0, BufferSize);
  430. AZ_TEST_START_TRACE_SUPPRESSION;
  431. frameGraph.UseAttachment(
  432. desc,
  433. RHI::ScopeAttachmentAccess::Read,
  434. RHI::ScopeAttachmentUsage::InputAssembly,
  435. RHI::ScopeAttachmentStage::VertexInput);
  436. AZ_TEST_STOP_ASSERTTEST(1);
  437. }
  438. for (uint32_t i = 0; i < numImports; ++i)
  439. {
  440. frameGraph.GetAttachmentDatabase().ImportImage(
  441. m_state->m_imageAttachments[i].m_id, m_state->m_imageAttachments[i].m_image);
  442. }
  443. {
  444. // Same attachment twice
  445. RHI::ImageScopeAttachmentDescriptor desc;
  446. desc.m_attachmentId = m_state->m_imageAttachments[0].m_id;
  447. desc.m_loadStoreAction.m_loadAction = RHI::AttachmentLoadAction::DontCare;
  448. desc.m_imageViewDescriptor = RHI::ImageViewDescriptor();
  449. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite, RHI::ScopeAttachmentStage::AnyGraphics);
  450. AZ_TEST_START_TRACE_SUPPRESSION;
  451. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite, RHI::ScopeAttachmentStage::AnyGraphics);
  452. AZ_TEST_STOP_ASSERTTEST(1);
  453. // Mipmap overlap
  454. desc.m_attachmentId = m_state->m_imageAttachments[1].m_id;
  455. desc.m_imageViewDescriptor = RHI::ImageViewDescriptor::Create(RHI::Format::Unknown, 0, 1);
  456. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite, RHI::ScopeAttachmentStage::AnyGraphics);
  457. desc.m_imageViewDescriptor = RHI::ImageViewDescriptor::Create(RHI::Format::Unknown, 1, 2);
  458. AZ_TEST_START_TRACE_SUPPRESSION;
  459. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite, RHI::ScopeAttachmentStage::AnyGraphics);
  460. AZ_TEST_STOP_ASSERTTEST(1);
  461. // Mipmap overlap, Slice Overlap
  462. desc.m_attachmentId = m_state->m_imageAttachments[3].m_id;
  463. desc.m_imageViewDescriptor = RHI::ImageViewDescriptor::Create(RHI::Format::Unknown, 0, 1, 0, 1);
  464. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite, RHI::ScopeAttachmentStage::AnyGraphics);
  465. desc.m_imageViewDescriptor = RHI::ImageViewDescriptor::Create(RHI::Format::Unknown, 1, 2, 1, 2);
  466. AZ_TEST_START_TRACE_SUPPRESSION;
  467. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite, RHI::ScopeAttachmentStage::AnyGraphics);
  468. AZ_TEST_STOP_ASSERTTEST(1);
  469. // No overlap, different aspect mask
  470. desc.m_attachmentId = m_state->m_imageAttachments[4].m_id;
  471. desc.m_imageViewDescriptor = RHI::ImageViewDescriptor();
  472. desc.m_imageViewDescriptor.m_aspectFlags = RHI::ImageAspectFlags::Depth;
  473. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite, RHI::ScopeAttachmentStage::AnyGraphics);
  474. desc.m_imageViewDescriptor.m_aspectFlags = RHI::ImageAspectFlags::Stencil;
  475. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite, RHI::ScopeAttachmentStage::AnyGraphics);
  476. // No overlap on mimap
  477. desc.m_attachmentId = m_state->m_imageAttachments[5].m_id;
  478. desc.m_imageViewDescriptor = RHI::ImageViewDescriptor::Create(RHI::Format::Unknown, 0, 1, 0, 1);
  479. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite, RHI::ScopeAttachmentStage::AnyGraphics);
  480. desc.m_imageViewDescriptor = RHI::ImageViewDescriptor::Create(RHI::Format::Unknown, 2, 3, 0, 1);
  481. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite, RHI::ScopeAttachmentStage::AnyGraphics);
  482. // No overlap on slice
  483. desc.m_attachmentId = m_state->m_imageAttachments[6].m_id;
  484. desc.m_imageViewDescriptor = RHI::ImageViewDescriptor::Create(RHI::Format::Unknown, 0, 1, 0, 1);
  485. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite, RHI::ScopeAttachmentStage::AnyGraphics);
  486. desc.m_imageViewDescriptor = RHI::ImageViewDescriptor::Create(RHI::Format::Unknown, 0, 1, 2, 3);
  487. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite, RHI::ScopeAttachmentStage::AnyGraphics);
  488. // No overlap on mipmap and slice
  489. desc.m_attachmentId = m_state->m_imageAttachments[7].m_id;
  490. desc.m_imageViewDescriptor = RHI::ImageViewDescriptor::Create(RHI::Format::Unknown, 0, 1, 1, 2);
  491. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite, RHI::ScopeAttachmentStage::AnyGraphics);
  492. desc.m_imageViewDescriptor = RHI::ImageViewDescriptor::Create(RHI::Format::Unknown, 2, 3, 3, 4);
  493. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::ReadWrite, RHI::ScopeAttachmentStage::AnyGraphics);
  494. // Overlap read only
  495. desc.m_attachmentId = m_state->m_imageAttachments[8].m_id;
  496. desc.m_imageViewDescriptor = RHI::ImageViewDescriptor();
  497. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::Read, RHI::ScopeAttachmentStage::AnyGraphics);
  498. frameGraph.UseShaderAttachment(desc, RHI::ScopeAttachmentAccess::Read, RHI::ScopeAttachmentStage::AnyGraphics);
  499. // Overlap invalid usage
  500. desc.m_attachmentId = m_state->m_imageAttachments[9].m_id;
  501. desc.m_imageViewDescriptor = RHI::ImageViewDescriptor();
  502. frameGraph.UseDepthStencilAttachment(
  503. desc, RHI::ScopeAttachmentAccess::Read, RHI::ScopeAttachmentStage::EarlyFragmentTest);
  504. AZ_TEST_START_TRACE_SUPPRESSION;
  505. frameGraph.UseDepthStencilAttachment(
  506. desc, RHI::ScopeAttachmentAccess::Read, RHI::ScopeAttachmentStage::EarlyFragmentTest);
  507. AZ_TEST_STOP_ASSERTTEST(1);
  508. }
  509. frameGraph.EndScope();
  510. frameGraph.End();
  511. }
  512. }
  513. private:
  514. static const uint32_t FrameIterationCount = 32;
  515. static const uint32_t ImageCount = 256;
  516. static const uint32_t BufferCount = 256;
  517. static const uint32_t BufferSize = 64;
  518. static const uint32_t ImageSize = 16;
  519. static const uint32_t ImageMipCount = 5;
  520. static const uint32_t ImageArrayCount = 3;
  521. static const uint32_t ScopeCount = 128;
  522. AZStd::unique_ptr<AZ::RHI::RHISystem> m_rhiSystem;
  523. AZStd::unique_ptr<Factory> m_rootFactory;
  524. struct ImageAttachment
  525. {
  526. RHI::Ptr<RHI::Image> m_image;
  527. RHI::AttachmentId m_id;
  528. };
  529. struct BufferAttachment
  530. {
  531. RHI::Ptr<RHI::Buffer> m_buffer;
  532. RHI::AttachmentId m_id;
  533. };
  534. struct State
  535. {
  536. RHI::Ptr<RHI::BufferPool> m_bufferPool;
  537. RHI::Ptr<RHI::ImagePool> m_imagePool;
  538. RHI::Ptr<RHI::FrameGraphCompiler> m_frameGraphCompiler;
  539. ImageAttachment m_imageAttachments[ImageCount];
  540. BufferAttachment m_bufferAttachments[BufferCount];
  541. RHI::Ptr<RHI::Scope> m_scopes[ScopeCount];
  542. };
  543. AZStd::unique_ptr<State> m_state;
  544. };
  545. TEST_F(FrameGraphTests, TestEmptyGraph)
  546. {
  547. TestEmptyGraph();
  548. }
  549. TEST_F(FrameGraphTests, TestSingleEmptyScope)
  550. {
  551. TestSingleEmptyScope();
  552. }
  553. TEST_F(FrameGraphTests, TestSingleScope)
  554. {
  555. TestSingleScope();
  556. }
  557. TEST_F(FrameGraphTests, TestScopeGraph)
  558. {
  559. TestScopeGraph();
  560. }
  561. TEST_F(FrameGraphTests, TestOverlappingAttachments)
  562. {
  563. TestOverlappingAttachments();
  564. }
  565. }