Gr.cpp 98 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212
  1. // Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <Tests/Framework/Framework.h>
  6. #include <Tests/Gr/GrCommon.h>
  7. #include <AnKi/Gr.h>
  8. #include <AnKi/Window/NativeWindow.h>
  9. #include <AnKi/Window/Input.h>
  10. #include <AnKi/Core/CVarSet.h>
  11. #include <AnKi/Core/GpuMemory/RebarTransientMemoryPool.h>
  12. #include <AnKi/Util/HighRezTimer.h>
  13. #include <AnKi/Resource/TransferGpuAllocator.h>
  14. #include <AnKi/ShaderCompiler/ShaderProgramParser.h>
  15. #include <AnKi/Collision/Aabb.h>
  16. #include <AnKi/Util/WeakArray.h>
  17. #include <ctime>
  18. using namespace anki;
  19. const U kWidth = 1024;
  20. const U kHeight = 768;
  21. static void commonInit()
  22. {
  23. DefaultMemoryPool::allocateSingleton(allocAligned, nullptr);
  24. ShaderCompilerMemoryPool::allocateSingleton(allocAligned, nullptr);
  25. g_windowWidthCVar.set(kWidth);
  26. g_windowHeightCVar.set(kHeight);
  27. g_validationCVar.set(true);
  28. g_vsyncCVar.set(false);
  29. g_debugMarkersCVar.set(true);
  30. initWindow();
  31. ANKI_TEST_EXPECT_NO_ERR(Input::allocateSingleton().init());
  32. initGrManager();
  33. }
  34. static void commonDestroy()
  35. {
  36. GrManager::freeSingleton();
  37. Input::freeSingleton();
  38. NativeWindow::freeSingleton();
  39. ShaderCompilerMemoryPool::freeSingleton();
  40. DefaultMemoryPool::freeSingleton();
  41. }
  42. ANKI_TEST(Gr, GrManager)
  43. {
  44. g_validationCVar.set(true);
  45. DefaultMemoryPool::allocateSingleton(allocAligned, nullptr);
  46. initWindow();
  47. ANKI_TEST_EXPECT_NO_ERR(Input::allocateSingleton().init());
  48. initGrManager();
  49. GrManager::freeSingleton();
  50. Input::freeSingleton();
  51. NativeWindow::freeSingleton();
  52. DefaultMemoryPool::freeSingleton();
  53. }
  54. ANKI_TEST(Gr, Shader)
  55. {
  56. #if 0
  57. COMMON_BEGIN()
  58. ShaderPtr shader = createShader(FRAG_MRT_SRC, ShaderType::kFragment, *g_gr);
  59. COMMON_END()
  60. #endif
  61. }
  62. ANKI_TEST(Gr, ShaderProgram)
  63. {
  64. #if 0
  65. COMMON_BEGIN()
  66. constexpr const char* kVertSrc = R"(
  67. out gl_PerVertex
  68. {
  69. vec4 gl_Position;
  70. };
  71. void main()
  72. {
  73. const vec2 POSITIONS[3] = vec2[](vec2(-1.0, 1.0), vec2(0.0, -1.0), vec2(1.0, 1.0));
  74. gl_Position = vec4(POSITIONS[gl_VertexID % 3], 0.0, 1.0);
  75. })";
  76. constexpr const char* kFragSrc = R"(layout (location = 0) out vec4 out_color;
  77. void main()
  78. {
  79. out_color = vec4(0.5);
  80. })";
  81. ShaderProgramPtr ppline = createProgram(kVertSrc, kFragSrc, *g_gr);
  82. COMMON_END()
  83. #endif
  84. }
  85. ANKI_TEST(Gr, ClearScreen)
  86. {
  87. commonInit();
  88. ANKI_TEST_LOGI("Expect to see a magenta background");
  89. constexpr U kIterations = 100;
  90. U iterations = kIterations;
  91. while(iterations--)
  92. {
  93. HighRezTimer timer;
  94. timer.start();
  95. TexturePtr presentTex = GrManager::getSingleton().acquireNextPresentableTexture();
  96. CommandBufferInitInfo cinit;
  97. cinit.m_flags = CommandBufferFlag::kGeneralWork | CommandBufferFlag::kSmallBatch;
  98. CommandBufferPtr cmdb = GrManager::getSingleton().newCommandBuffer(cinit);
  99. const TextureBarrierInfo barrier = {TextureView(presentTex.get(), TextureSubresourceDescriptor::all()), TextureUsageBit::kNone,
  100. TextureUsageBit::kFramebufferWrite};
  101. cmdb->setPipelineBarrier({&barrier, 1}, {}, {});
  102. RenderTarget rt;
  103. rt.m_textureView = TextureView(presentTex.get(), TextureSubresourceDescriptor::all());
  104. const F32 col = 1.0f - F32(iterations) / F32(kIterations);
  105. rt.m_clearValue.m_colorf = {col, 0.0f, col, 1.0f};
  106. cmdb->beginRenderPass({rt});
  107. cmdb->endRenderPass();
  108. const TextureBarrierInfo barrier2 = {TextureView(presentTex.get(), TextureSubresourceDescriptor::all()), TextureUsageBit::kFramebufferWrite,
  109. TextureUsageBit::kPresent};
  110. cmdb->setPipelineBarrier({&barrier2, 1}, {}, {});
  111. cmdb->endRecording();
  112. GrManager::getSingleton().submit(cmdb.get());
  113. GrManager::getSingleton().swapBuffers();
  114. timer.stop();
  115. const F32 TICK = 1.0f / 30.0f;
  116. if(timer.getElapsedTime() < TICK)
  117. {
  118. HighRezTimer::sleep(TICK - timer.getElapsedTime());
  119. }
  120. }
  121. commonDestroy();
  122. }
  123. ANKI_TEST(Gr, SimpleDrawcall)
  124. {
  125. #if 0
  126. COMMON_BEGIN()
  127. constexpr const char* kVertSrc = R"(
  128. out gl_PerVertex
  129. {
  130. vec4 gl_Position;
  131. };
  132. void main()
  133. {
  134. const vec2 POSITIONS[3] = vec2[](vec2(-1.0, 1.0), vec2(0.0, -1.0), vec2(1.0, 1.0));
  135. gl_Position = vec4(POSITIONS[gl_VertexID % 3], 0.0, 1.0);
  136. })";
  137. constexpr const char* kFragSrc = R"(layout (location = 0) out vec4 out_color;
  138. void main()
  139. {
  140. out_color = vec4(0.5);
  141. })";
  142. ANKI_TEST_LOGI("Expect to see a grey triangle");
  143. ShaderProgramPtr prog = createProgram(kVertSrc, kFragSrc, *g_gr);
  144. const U ITERATIONS = 200;
  145. for(U i = 0; i < ITERATIONS; ++i)
  146. {
  147. HighRezTimer timer;
  148. timer.start();
  149. TexturePtr presentTex = g_gr->acquireNextPresentableTexture();
  150. FramebufferPtr fb = createColorFb(*g_gr, presentTex);
  151. CommandBufferInitInfo cinit;
  152. cinit.m_flags = CommandBufferFlag::kGeneralWork;
  153. CommandBufferPtr cmdb = g_gr->newCommandBuffer(cinit);
  154. cmdb->setViewport(0, 0, g_win->getWidth(), g_win->getHeight());
  155. cmdb->bindShaderProgram(prog.get());
  156. presentBarrierA(cmdb, presentTex);
  157. TextureViewInitInfo init;
  158. init.m_texture = presentTex.get();
  159. TextureViewPtr view = g_gr->newTextureView(init);
  160. RenderTarget rt;
  161. rt.m_view = view.get();
  162. cmdb->beginRenderPass({rt});
  163. cmdb->draw(PrimitiveTopology::kTriangles, 3);
  164. cmdb->endRenderPass();
  165. presentBarrierB(cmdb, presentTex);
  166. cmdb->endRecording();
  167. GrManager::getSingleton().submit(cmdb.get());
  168. g_gr->swapBuffers();
  169. timer.stop();
  170. const F32 TICK = 1.0f / 30.0f;
  171. if(timer.getElapsedTime() < TICK)
  172. {
  173. HighRezTimer::sleep(TICK - timer.getElapsedTime());
  174. }
  175. }
  176. COMMON_END()
  177. #endif
  178. }
  179. ANKI_TEST(Gr, ViewportAndScissor)
  180. {
  181. #if 0
  182. COMMON_BEGIN()
  183. ANKI_TEST_LOGI("Expect to see a grey quad appearing in the 4 corners. The clear color will change and affect only"
  184. "the area around the quad");
  185. ShaderProgramPtr prog = createProgram(VERT_QUAD_STRIP_SRC, FRAG_SRC, *gr);
  186. srand(time(nullptr));
  187. Array<FramebufferPtr, 4> fb;
  188. for(FramebufferPtr& f : fb)
  189. {
  190. FramebufferInitInfo fbinit;
  191. fbinit.m_colorAttachmentCount = 1;
  192. fbinit.m_colorAttachments[0].m_clearValue.m_colorf = {{randFloat(1.0), randFloat(1.0), randFloat(1.0), 1.0}};
  193. f = gr->newFramebuffer(fbinit);
  194. }
  195. static const Array2d<U, 4, 4> VIEWPORTS = {{{{0, 0, WIDTH / 2, HEIGHT / 2}},
  196. {{WIDTH / 2, 0, WIDTH / 2, HEIGHT / 2}},
  197. {{WIDTH / 2, HEIGHT / 2, WIDTH / 2, HEIGHT / 2}},
  198. {{0, HEIGHT / 2, WIDTH / 2, HEIGHT / 2}}}};
  199. const U ITERATIONS = 400;
  200. const U SCISSOR_MARGIN = 20;
  201. const U RENDER_AREA_MARGIN = 10;
  202. for(U i = 0; i < ITERATIONS; ++i)
  203. {
  204. HighRezTimer timer;
  205. timer.start();
  206. gr->beginFrame();
  207. CommandBufferInitInfo cinit;
  208. cinit.m_flags = CommandBufferFlag::kGeneralWork | CommandBufferFlag::kSmallBatch;
  209. CommandBufferPtr cmdb = gr->newCommandBuffer(cinit);
  210. U idx = (i / 30) % 4;
  211. auto vp = VIEWPORTS[idx];
  212. cmdb->setViewport(vp[0], vp[1], vp[2], vp[3]);
  213. cmdb->setScissor(
  214. vp[0] + SCISSOR_MARGIN, vp[1] + SCISSOR_MARGIN, vp[2] - SCISSOR_MARGIN * 2, vp[3] - SCISSOR_MARGIN * 2);
  215. cmdb->bindShaderProgram(prog);
  216. cmdb->beginRenderPass(fb[i % 4],
  217. {},
  218. {},
  219. vp[0] + RENDER_AREA_MARGIN,
  220. vp[1] + RENDER_AREA_MARGIN,
  221. vp[2] - RENDER_AREA_MARGIN * 2,
  222. vp[3] - RENDER_AREA_MARGIN * 2);
  223. cmdb->draw(PrimitiveTopology::TRIANGLE_STRIP, 4);
  224. cmdb->endRenderPass();
  225. cmdb->flush();
  226. gr->swapBuffers();
  227. timer.stop();
  228. const F32 TICK = 1.0f / 30.0f;
  229. if(timer.getElapsedTime() < TICK)
  230. {
  231. HighRezTimer::sleep(TICK - timer.getElapsedTime());
  232. }
  233. }
  234. COMMON_END()
  235. #endif
  236. }
  237. ANKI_TEST(Gr, ViewportAndScissorOffscreen)
  238. {
  239. #if 0
  240. srand(U32(time(nullptr)));
  241. COMMON_BEGIN()
  242. constexpr const char* kFragSrc = R"(layout (location = 0) out vec4 out_color;
  243. void main()
  244. {
  245. out_color = vec4(0.5);
  246. })";
  247. ANKI_TEST_LOGI("Expect to see a grey quad appearing in the 4 corners. "
  248. "Around that quad is a border that changes color. "
  249. "The quads appear counter-clockwise");
  250. ShaderProgramPtr prog = createProgram(VERT_QUAD_STRIP_SRC, kFragSrc, *g_gr);
  251. ShaderProgramPtr blitProg = createProgram(VERT_QUAD_SRC, FRAG_TEX_SRC, *g_gr);
  252. const Format COL_FORMAT = Format::kR8G8B8A8_Unorm;
  253. const U RT_WIDTH = 32;
  254. const U RT_HEIGHT = 16;
  255. TextureInitInfo init;
  256. init.m_depth = 1;
  257. init.m_format = COL_FORMAT;
  258. init.m_usage = TextureUsageBit::kSampledFragment | TextureUsageBit::kAllFramebuffer;
  259. init.m_height = RT_HEIGHT;
  260. init.m_width = RT_WIDTH;
  261. init.m_mipmapCount = 1;
  262. init.m_depth = 1;
  263. init.m_layerCount = 1;
  264. init.m_samples = 1;
  265. init.m_type = TextureType::k2D;
  266. TexturePtr rt = g_gr->newTexture(init);
  267. TextureViewInitInfo viewInit(rt.get());
  268. TextureViewPtr texView = g_gr->newTextureView(viewInit);
  269. Array<FramebufferPtr, 4> fb;
  270. for(FramebufferPtr& f : fb)
  271. {
  272. TextureViewInitInfo viewInf(rt.get());
  273. TextureViewPtr view = g_gr->newTextureView(viewInf);
  274. FramebufferInitInfo fbinit;
  275. fbinit.m_colorAttachmentCount = 1;
  276. fbinit.m_colorAttachments[0].m_clearValue.m_colorf = {
  277. {getRandomRange(0.0f, 1.0f), getRandomRange(0.0f, 1.0f), getRandomRange(0.0f, 1.0f), 1.0}};
  278. fbinit.m_colorAttachments[0].m_textureView = view;
  279. f = g_gr->newFramebuffer(fbinit);
  280. }
  281. SamplerInitInfo samplerInit;
  282. samplerInit.m_minMagFilter = SamplingFilter::kNearest;
  283. samplerInit.m_mipmapFilter = SamplingFilter::kBase;
  284. SamplerPtr sampler = g_gr->newSampler(samplerInit);
  285. static const Array2d<U32, 4, 4> VIEWPORTS = {{{{0, 0, RT_WIDTH / 2, RT_HEIGHT / 2}},
  286. {{RT_WIDTH / 2, 0, RT_WIDTH / 2, RT_HEIGHT / 2}},
  287. {{RT_WIDTH / 2, RT_HEIGHT / 2, RT_WIDTH / 2, RT_HEIGHT / 2}},
  288. {{0, RT_HEIGHT / 2, RT_WIDTH / 2, RT_HEIGHT / 2}}}};
  289. const U32 ITERATIONS = 400;
  290. const U32 SCISSOR_MARGIN = 2;
  291. const U32 RENDER_AREA_MARGIN = 1;
  292. for(U32 i = 0; i < ITERATIONS; ++i)
  293. {
  294. HighRezTimer timer;
  295. timer.start();
  296. TexturePtr presentTex = g_gr->acquireNextPresentableTexture();
  297. FramebufferPtr dfb = createColorFb(*g_gr, presentTex);
  298. if(i == 0)
  299. {
  300. CommandBufferInitInfo cinit;
  301. cinit.m_flags = CommandBufferFlag::kGeneralWork | CommandBufferFlag::kSmallBatch;
  302. CommandBufferPtr cmdb = g_gr->newCommandBuffer(cinit);
  303. cmdb->setViewport(0, 0, RT_WIDTH, RT_HEIGHT);
  304. setTextureSurfaceBarrier(cmdb, rt, TextureUsageBit::kNone, TextureUsageBit::kFramebufferWrite, TextureSurfaceDescriptor(0, 0, 0, 0));
  305. cmdb->beginRenderPass(fb[0].get(), {{TextureUsageBit::kFramebufferWrite}}, {});
  306. cmdb->endRenderPass();
  307. setTextureSurfaceBarrier(cmdb, rt, TextureUsageBit::kFramebufferWrite, TextureUsageBit::kSampledFragment, TextureSurfaceDescriptor(0, 0, 0, 0));
  308. cmdb->endRecording();
  309. GrManager::getSingleton().submit(cmdb.get());
  310. }
  311. CommandBufferInitInfo cinit;
  312. cinit.m_flags = CommandBufferFlag::kGeneralWork | CommandBufferFlag::kSmallBatch;
  313. CommandBufferPtr cmdb = g_gr->newCommandBuffer(cinit);
  314. // Draw offscreen
  315. setTextureSurfaceBarrier(cmdb, rt, TextureUsageBit::kSampledFragment, TextureUsageBit::kFramebufferWrite, TextureSurfaceDescriptor(0, 0, 0, 0));
  316. auto vp = VIEWPORTS[(i / 30) % 4];
  317. cmdb->setViewport(vp[0], vp[1], vp[2], vp[3]);
  318. cmdb->setScissor(vp[0] + SCISSOR_MARGIN, vp[1] + SCISSOR_MARGIN, vp[2] - SCISSOR_MARGIN * 2, vp[3] - SCISSOR_MARGIN * 2);
  319. cmdb->bindShaderProgram(prog.get());
  320. cmdb->beginRenderPass(fb[i % 4].get(), {{TextureUsageBit::kFramebufferWrite}}, {}, vp[0] + RENDER_AREA_MARGIN, vp[1] + RENDER_AREA_MARGIN,
  321. vp[2] - RENDER_AREA_MARGIN * 2, vp[3] - RENDER_AREA_MARGIN * 2);
  322. cmdb->draw(PrimitiveTopology::kTriangleStrip, 4);
  323. cmdb->endRenderPass();
  324. // Draw onscreen
  325. cmdb->setViewport(0, 0, g_win->getWidth(), g_win->getHeight());
  326. cmdb->setScissor(0, 0, g_win->getWidth(), g_win->getHeight());
  327. cmdb->bindShaderProgram(blitProg.get());
  328. setTextureSurfaceBarrier(cmdb, rt, TextureUsageBit::kFramebufferWrite, TextureUsageBit::kSampledFragment, TextureSurfaceDescriptor(0, 0, 0, 0));
  329. // cmdb->bindTextureAndSampler(0, 0, texView.get(), sampler.get());
  330. presentBarrierA(cmdb, presentTex);
  331. cmdb->beginRenderPass(dfb.get(), {TextureUsageBit::kFramebufferWrite}, {});
  332. cmdb->draw(PrimitiveTopology::kTriangles, 6);
  333. cmdb->endRenderPass();
  334. presentBarrierB(cmdb, presentTex);
  335. cmdb->endRecording();
  336. GrManager::getSingleton().submit(cmdb.get());
  337. g_gr->swapBuffers();
  338. timer.stop();
  339. const F32 TICK = 1.0f / 30.0f;
  340. if(timer.getElapsedTime() < TICK)
  341. {
  342. HighRezTimer::sleep(TICK - timer.getElapsedTime());
  343. }
  344. }
  345. COMMON_END()
  346. #endif
  347. }
  348. ANKI_TEST(Gr, Buffer)
  349. {
  350. #if 0
  351. COMMON_BEGIN()
  352. BufferInitInfo buffInit("a");
  353. buffInit.m_size = 512;
  354. buffInit.m_usage = BufferUsageBit::kAllUniform;
  355. buffInit.m_mapAccess = BufferMapAccessBit::kNone;
  356. BufferPtr a = g_gr->newBuffer(buffInit);
  357. buffInit.setName("b");
  358. buffInit.m_size = 64;
  359. buffInit.m_usage = BufferUsageBit::kAllStorage;
  360. buffInit.m_mapAccess = BufferMapAccessBit::kWrite | BufferMapAccessBit::kRead;
  361. BufferPtr b = g_gr->newBuffer(buffInit);
  362. void* ptr = b->map(0, 64, BufferMapAccessBit::kWrite);
  363. ANKI_TEST_EXPECT_NEQ(ptr, nullptr);
  364. U8 ptr2[64];
  365. memset(ptr, 0xCC, 64);
  366. memset(ptr2, 0xCC, 64);
  367. b->unmap();
  368. ptr = b->map(0, 64, BufferMapAccessBit::kRead);
  369. ANKI_TEST_EXPECT_NEQ(ptr, nullptr);
  370. ANKI_TEST_EXPECT_EQ(memcmp(ptr, ptr2, 64), 0);
  371. b->unmap();
  372. COMMON_END()
  373. #endif
  374. }
  375. ANKI_TEST(Gr, DrawWithUniforms)
  376. {
  377. #if 0
  378. COMMON_BEGIN()
  379. // A non-uploaded buffer
  380. BufferPtr b = g_gr->newBuffer(BufferInitInfo(sizeof(Vec4) * 3, BufferUsageBit::kAllUniform, BufferMapAccessBit::kWrite));
  381. Vec4* ptr = static_cast<Vec4*>(b->map(0, sizeof(Vec4) * 3, BufferMapAccessBit::kWrite));
  382. ANKI_TEST_EXPECT_NEQ(ptr, nullptr);
  383. ptr[0] = Vec4(1.0, 0.0, 0.0, 0.0);
  384. ptr[1] = Vec4(0.0, 1.0, 0.0, 0.0);
  385. ptr[2] = Vec4(0.0, 0.0, 1.0, 0.0);
  386. b->unmap();
  387. // Prog
  388. constexpr const char* kUboVert = R"(
  389. struct A
  390. {
  391. float4 m_color[3];
  392. };
  393. [[vk::binding(0)]] ConstantBuffer<A> g_color;
  394. struct B
  395. {
  396. float4 m_rotation2d;
  397. };
  398. [[vk::binding(1)]] ConstantBuffer<B> g_rotation2d;
  399. struct VertOut
  400. {
  401. float4 m_svPosition : SV_POSITION;
  402. float3 m_color : COLOR;
  403. };
  404. VertOut main(uint svVertexId : SV_VERTEXID)
  405. {
  406. VertOut o;
  407. o.m_color = g_color.m_color[svVertexId].xyz;
  408. const float2 kPositions[3] = {float2(-1.0, 1.0), float2(0.0, -1.0), float2(1.0, 1.0)};
  409. float2x2 rot = float2x2(
  410. g_rotation2d.m_rotation2d.x, g_rotation2d.m_rotation2d.y, g_rotation2d.m_rotation2d.z, g_rotation2d.m_rotation2d.w);
  411. float2 pos = mul(rot, kPositions[svVertexId % 3]);
  412. o.m_svPosition = float4(pos, 0.0, 1.0);
  413. return o;
  414. })";
  415. constexpr const char* kUboFrag = R"(
  416. struct VertOut
  417. {
  418. float4 m_svPosition : SV_POSITION;
  419. float3 m_color : COLOR;
  420. };
  421. float4 main(VertOut i) : SV_TARGET0
  422. {
  423. return float4(i.m_color, 1.0);
  424. })";
  425. ShaderProgramPtr prog = createProgram(kUboVert, kUboFrag, *g_gr);
  426. const U ITERATION_COUNT = 100;
  427. U iterations = ITERATION_COUNT;
  428. while(iterations--)
  429. {
  430. HighRezTimer timer;
  431. timer.start();
  432. TexturePtr presentTex = g_gr->acquireNextPresentableTexture();
  433. FramebufferPtr fb = createColorFb(*g_gr, presentTex);
  434. CommandBufferInitInfo cinit;
  435. cinit.m_flags = CommandBufferFlag::kGeneralWork;
  436. CommandBufferPtr cmdb = g_gr->newCommandBuffer(cinit);
  437. cmdb->setViewport(0, 0, g_win->getWidth(), g_win->getHeight());
  438. cmdb->bindShaderProgram(prog.get());
  439. presentBarrierA(cmdb, presentTex);
  440. cmdb->beginRenderPass(fb.get(), {TextureUsageBit::kFramebufferWrite}, {});
  441. cmdb->bindUniformBuffer(0, 0, b.get(), 0, kMaxPtrSize);
  442. // Uploaded buffer
  443. Vec4* rotMat = SET_UNIFORMS(Vec4*, sizeof(Vec4), cmdb, 0, 1);
  444. F32 angle = toRad(360.0f / F32(ITERATION_COUNT) * F32(iterations));
  445. (*rotMat)[0] = cos(angle);
  446. (*rotMat)[1] = -sin(angle);
  447. (*rotMat)[2] = sin(angle);
  448. (*rotMat)[3] = cos(angle);
  449. cmdb->draw(PrimitiveTopology::kTriangles, 3);
  450. cmdb->endRenderPass();
  451. presentBarrierB(cmdb, presentTex);
  452. cmdb->endRecording();
  453. GrManager::getSingleton().submit(cmdb.get());
  454. g_gr->swapBuffers();
  455. timer.stop();
  456. const F32 TICK = 1.0f / 30.0f;
  457. if(timer.getElapsedTime() < TICK)
  458. {
  459. HighRezTimer::sleep(TICK - timer.getElapsedTime());
  460. }
  461. }
  462. COMMON_END()
  463. #endif
  464. }
  465. ANKI_TEST(Gr, DrawWithVertex)
  466. {
  467. #if 0
  468. COMMON_BEGIN()
  469. // The buffers
  470. struct Vert
  471. {
  472. Vec3 m_pos;
  473. Array<U8, 4> m_color;
  474. };
  475. static_assert(sizeof(Vert) == sizeof(Vec4), "See file");
  476. BufferPtr b = g_gr->newBuffer(BufferInitInfo(sizeof(Vert) * 3, BufferUsageBit::kVertex, BufferMapAccessBit::kWrite));
  477. Vert* ptr = static_cast<Vert*>(b->map(0, sizeof(Vert) * 3, BufferMapAccessBit::kWrite));
  478. ANKI_TEST_EXPECT_NEQ(ptr, nullptr);
  479. ptr[0].m_pos = Vec3(-1.0, 1.0, 0.0);
  480. ptr[1].m_pos = Vec3(0.0, -1.0, 0.0);
  481. ptr[2].m_pos = Vec3(1.0, 1.0, 0.0);
  482. ptr[0].m_color = {{255, 0, 0}};
  483. ptr[1].m_color = {{0, 255, 0}};
  484. ptr[2].m_color = {{0, 0, 255}};
  485. b->unmap();
  486. BufferPtr c = g_gr->newBuffer(BufferInitInfo(sizeof(Vec3) * 3, BufferUsageBit::kVertex, BufferMapAccessBit::kWrite));
  487. Vec3* otherColor = static_cast<Vec3*>(c->map(0, sizeof(Vec3) * 3, BufferMapAccessBit::kWrite));
  488. otherColor[0] = Vec3(0.0, 1.0, 1.0);
  489. otherColor[1] = Vec3(1.0, 0.0, 1.0);
  490. otherColor[2] = Vec3(1.0, 1.0, 0.0);
  491. c->unmap();
  492. // Prog
  493. ShaderProgramPtr prog = createProgram(VERT_INP_SRC, FRAG_INP_SRC, *g_gr);
  494. U iterations = 100;
  495. while(iterations--)
  496. {
  497. HighRezTimer timer;
  498. timer.start();
  499. TexturePtr presentTex = g_gr->acquireNextPresentableTexture();
  500. FramebufferPtr fb = createColorFb(*g_gr, presentTex);
  501. CommandBufferInitInfo cinit;
  502. cinit.m_flags = CommandBufferFlag::kGeneralWork;
  503. CommandBufferPtr cmdb = g_gr->newCommandBuffer(cinit);
  504. cmdb->bindVertexBuffer(0, b.get(), 0, sizeof(Vert));
  505. cmdb->bindVertexBuffer(1, c.get(), 0, sizeof(Vec3));
  506. cmdb->setVertexAttribute(VertexAttributeSemantic::kPosition, 0, Format::kR32G32B32_Sfloat, 0);
  507. cmdb->setVertexAttribute(VertexAttributeSemantic::kColor, 0, Format::kR8G8B8_Unorm, sizeof(Vec3));
  508. cmdb->setVertexAttribute(VertexAttributeSemantic::kMisc0, 1, Format::kR32G32B32_Sfloat, 0);
  509. cmdb->setViewport(0, 0, g_win->getWidth(), g_win->getHeight());
  510. cmdb->setPolygonOffset(0.0, 0.0);
  511. cmdb->bindShaderProgram(prog.get());
  512. presentBarrierA(cmdb, presentTex);
  513. cmdb->beginRenderPass(fb.get(), {TextureUsageBit::kFramebufferWrite}, {});
  514. cmdb->draw(PrimitiveTopology::kTriangles, 3);
  515. cmdb->endRenderPass();
  516. presentBarrierB(cmdb, presentTex);
  517. cmdb->endRecording();
  518. GrManager::getSingleton().submit(cmdb.get());
  519. g_gr->swapBuffers();
  520. timer.stop();
  521. const F32 TICK = 1.0f / 30.0f;
  522. if(timer.getElapsedTime() < TICK)
  523. {
  524. HighRezTimer::sleep(TICK - timer.getElapsedTime());
  525. }
  526. }
  527. COMMON_END()
  528. #endif
  529. }
  530. ANKI_TEST(Gr, Sampler)
  531. {
  532. #if 0
  533. COMMON_BEGIN()
  534. SamplerInitInfo init;
  535. SamplerPtr b = g_gr->newSampler(init);
  536. COMMON_END()
  537. #endif
  538. }
  539. ANKI_TEST(Gr, Texture)
  540. {
  541. #if 0
  542. COMMON_BEGIN()
  543. TextureInitInfo init;
  544. init.m_depth = 1;
  545. init.m_format = Format::kR8G8B8_Unorm;
  546. init.m_usage = TextureUsageBit::kSampledFragment;
  547. init.m_height = 4;
  548. init.m_width = 4;
  549. init.m_mipmapCount = 2;
  550. init.m_depth = 1;
  551. init.m_layerCount = 1;
  552. init.m_samples = 1;
  553. init.m_type = TextureType::k2D;
  554. TexturePtr b = g_gr->newTexture(init);
  555. COMMON_END()
  556. #endif
  557. }
  558. ANKI_TEST(Gr, DrawWithTexture)
  559. {
  560. #if 0
  561. COMMON_BEGIN()
  562. //
  563. // Create sampler
  564. //
  565. SamplerInitInfo samplerInit;
  566. samplerInit.m_minMagFilter = SamplingFilter::kNearest;
  567. samplerInit.m_mipmapFilter = SamplingFilter::kLinear;
  568. samplerInit.m_addressing = SamplingAddressing::kClamp;
  569. SamplerPtr sampler = g_gr->newSampler(samplerInit);
  570. //
  571. // Create texture A
  572. //
  573. TextureInitInfo init;
  574. init.m_depth = 1;
  575. init.m_format = Format::kR8G8B8_Unorm;
  576. init.m_usage = TextureUsageBit::kSampledFragment | TextureUsageBit::kTransferDestination;
  577. init.m_height = 2;
  578. init.m_width = 2;
  579. init.m_mipmapCount = 2;
  580. init.m_samples = 1;
  581. init.m_depth = 1;
  582. init.m_layerCount = 1;
  583. init.m_type = TextureType::k2D;
  584. TexturePtr a = g_gr->newTexture(init);
  585. TextureViewPtr aView = g_gr->newTextureView(TextureViewInitInfo(a.get()));
  586. //
  587. // Create texture B
  588. //
  589. init.m_width = 4;
  590. init.m_height = 4;
  591. init.m_mipmapCount = 3;
  592. init.m_usage = TextureUsageBit::kSampledFragment | TextureUsageBit::kTransferDestination | TextureUsageBit::kGenerateMipmaps;
  593. TexturePtr b = g_gr->newTexture(init);
  594. TextureViewPtr bView = g_gr->newTextureView(TextureViewInitInfo(b.get()));
  595. //
  596. // Upload all textures
  597. //
  598. Array<U8, 2 * 2 * 3> mip0 = {{255, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0, 255}};
  599. Array<U8, 3> mip1 = {{128, 128, 128}};
  600. Array<U8, 4 * 4 * 3> bmip0 = {{255, 0, 0, 0, 255, 0, 0, 0, 255, 255, 255, 0, 255, 0, 255, 0, 255, 255, 255, 255, 255, 128, 0, 0, 0,
  601. 128, 0, 0, 0, 128, 128, 128, 0, 128, 0, 128, 0, 128, 128, 128, 128, 128, 255, 128, 0, 0, 128, 255}};
  602. CommandBufferInitInfo cmdbinit;
  603. cmdbinit.m_flags = CommandBufferFlag::kGeneralWork;
  604. CommandBufferPtr cmdb = g_gr->newCommandBuffer(cmdbinit);
  605. // Set barriers
  606. setTextureSurfaceBarrier(cmdb, a, TextureUsageBit::kSampledFragment, TextureUsageBit::kTransferDestination, TextureSurfaceDescriptor(0, 0, 0, 0));
  607. setTextureSurfaceBarrier(cmdb, a, TextureUsageBit::kSampledFragment, TextureUsageBit::kTransferDestination, TextureSurfaceDescriptor(1, 0, 0, 0));
  608. setTextureSurfaceBarrier(cmdb, b, TextureUsageBit::kNone, TextureUsageBit::kTransferDestination, TextureSurfaceDescriptor(0, 0, 0, 0));
  609. TransferGpuAllocatorHandle handle0, handle1, handle2;
  610. UPLOAD_TEX_SURFACE(cmdb, a, TextureSurfaceDescriptor(0, 0, 0, 0), &mip0[0], sizeof(mip0), handle0);
  611. UPLOAD_TEX_SURFACE(cmdb, a, TextureSurfaceDescriptor(1, 0, 0, 0), &mip1[0], sizeof(mip1), handle1);
  612. UPLOAD_TEX_SURFACE(cmdb, b, TextureSurfaceDescriptor(0, 0, 0, 0), &bmip0[0], sizeof(bmip0), handle2);
  613. // Gen mips
  614. setTextureSurfaceBarrier(cmdb, b, TextureUsageBit::kTransferDestination, TextureUsageBit::kGenerateMipmaps, TextureSurfaceDescriptor(0, 0, 0, 0));
  615. cmdb->generateMipmaps2d(g_gr->newTextureView(TextureViewInitInfo(b.get())).get());
  616. // Set barriers
  617. setTextureSurfaceBarrier(cmdb, a, TextureUsageBit::kTransferDestination, TextureUsageBit::kSampledFragment, TextureSurfaceDescriptor(0, 0, 0, 0));
  618. setTextureSurfaceBarrier(cmdb, a, TextureUsageBit::kTransferDestination, TextureUsageBit::kSampledFragment, TextureSurfaceDescriptor(1, 0, 0, 0));
  619. for(U32 i = 0; i < 3; ++i)
  620. {
  621. setTextureSurfaceBarrier(cmdb, b, TextureUsageBit::kGenerateMipmaps, TextureUsageBit::kSampledFragment, TextureSurfaceDescriptor(i, 0, 0, 0));
  622. }
  623. FencePtr fence;
  624. cmdb->endRecording();
  625. GrManager::getSingleton().submit(cmdb.get(), {}, &fence);
  626. transfAlloc->release(handle0, fence);
  627. transfAlloc->release(handle1, fence);
  628. transfAlloc->release(handle2, fence);
  629. //
  630. // Create prog
  631. //
  632. static const char* FRAG_2TEX_SRC = R"(layout (location = 0) out vec4 out_color;
  633. layout(location = 0) in vec2 in_uv;
  634. layout(set = 0, binding = 0) uniform sampler2D u_tex0;
  635. layout(set = 0, binding = 1) uniform sampler2D u_tex1;
  636. layout(push_constant) uniform b_pc
  637. {
  638. Vec4 u_viewport;
  639. };
  640. void main()
  641. {
  642. if(gl_FragCoord.x < u_viewport.x / 2.0)
  643. {
  644. if(gl_FragCoord.y < u_viewport.y / 2.0)
  645. {
  646. vec2 uv = in_uv * 2.0;
  647. out_color = textureLod(u_tex0, uv, 0.0);
  648. }
  649. else
  650. {
  651. vec2 uv = in_uv * 2.0 - vec2(0.0, 1.0);
  652. out_color = textureLod(u_tex0, uv, 1.0);
  653. }
  654. }
  655. else
  656. {
  657. if(gl_FragCoord.y < u_viewport.y / 2.0)
  658. {
  659. vec2 uv = in_uv * 2.0 - vec2(1.0, 0.0);
  660. out_color = textureLod(u_tex1, uv, 0.0);
  661. }
  662. else
  663. {
  664. vec2 uv = in_uv * 2.0 - vec2(1.0, 1.0);
  665. out_color = textureLod(u_tex1, uv, 1.0);
  666. }
  667. }
  668. })";
  669. ShaderProgramPtr prog = createProgram(VERT_QUAD_SRC, FRAG_2TEX_SRC, *g_gr);
  670. //
  671. // Draw
  672. //
  673. const U ITERATION_COUNT = 200;
  674. U iterations = ITERATION_COUNT;
  675. while(iterations--)
  676. {
  677. HighRezTimer timer;
  678. timer.start();
  679. TexturePtr presentTex = g_gr->acquireNextPresentableTexture();
  680. FramebufferPtr fb = createColorFb(*g_gr, presentTex);
  681. CommandBufferInitInfo cinit;
  682. cinit.m_flags = CommandBufferFlag::kGeneralWork | CommandBufferFlag::kSmallBatch;
  683. CommandBufferPtr cmdb = g_gr->newCommandBuffer(cinit);
  684. cmdb->setViewport(0, 0, g_win->getWidth(), g_win->getHeight());
  685. cmdb->bindShaderProgram(prog.get());
  686. presentBarrierA(cmdb, presentTex);
  687. cmdb->beginRenderPass(fb.get(), {TextureUsageBit::kFramebufferWrite}, {});
  688. Vec4 pc(F32(g_win->getWidth()), F32(g_win->getHeight()), 0.0f, 0.0f);
  689. cmdb->setPushConstants(&pc, sizeof(pc));
  690. // cmdb->bindTextureAndSampler(0, 0, aView.get(), sampler.get());
  691. // cmdb->bindTextureAndSampler(0, 1, bView.get(), sampler.get());
  692. cmdb->draw(PrimitiveTopology::kTriangles, 6);
  693. cmdb->endRenderPass();
  694. presentBarrierB(cmdb, presentTex);
  695. cmdb->endRecording();
  696. GrManager::getSingleton().submit(cmdb.get());
  697. g_gr->swapBuffers();
  698. timer.stop();
  699. const F32 TICK = 1.0f / 30.0f;
  700. if(timer.getElapsedTime() < TICK)
  701. {
  702. HighRezTimer::sleep(TICK - timer.getElapsedTime());
  703. }
  704. }
  705. COMMON_END()
  706. #endif
  707. }
  708. #if 0
  709. static void drawOffscreenDrawcalls([[maybe_unused]] GrManager& gr, ShaderProgramPtr prog, CommandBufferPtr cmdb, U32 viewPortSize,
  710. BufferPtr indexBuff, BufferPtr vertBuff)
  711. {
  712. static F32 ang = -2.5f;
  713. ang += toRad(2.5f);
  714. Mat4 viewMat(Vec3(0.0, 0.0, 5.0), Mat3::getIdentity(), Vec3(1.0f));
  715. viewMat.invert();
  716. Mat4 projMat = Mat4::calculatePerspectiveProjectionMatrix(toRad(60.0f), toRad(60.0f), 0.1f, 100.0f);
  717. Mat4 modelMat(Vec3(-0.5, -0.5, 0.0), Mat3(Euler(ang, ang / 2.0f, ang / 3.0f)), Vec3(1.0f));
  718. Mat4* mvp = SET_UNIFORMS(Mat4*, sizeof(*mvp), cmdb, 0, 0);
  719. *mvp = projMat * viewMat * modelMat;
  720. Vec4* color = SET_UNIFORMS(Vec4*, sizeof(*color) * 2, cmdb, 0, 1);
  721. *color++ = Vec4(1.0, 0.0, 0.0, 0.0);
  722. *color = Vec4(0.0, 1.0, 0.0, 0.0);
  723. cmdb->bindVertexBuffer(0, BufferView(vertBuff.get()), sizeof(Vec3));
  724. cmdb->setVertexAttribute(VertexAttributeSemantic::kPosition, 0, Format::kR32G32B32_Sfloat, 0);
  725. cmdb->bindShaderProgram(prog.get());
  726. cmdb->bindIndexBuffer(BufferView(indexBuff.get()), IndexType::kU16);
  727. cmdb->setViewport(0, 0, viewPortSize, viewPortSize);
  728. cmdb->drawIndexed(PrimitiveTopology::kTriangles, 6 * 2 * 3);
  729. // 2nd draw
  730. modelMat = Mat4(Vec3(0.5, 0.5, 0.0), Mat3(Euler(ang * 2.0f, ang, ang / 3.0f * 2.0f)), Vec3(1.0f));
  731. mvp = SET_UNIFORMS(Mat4*, sizeof(*mvp), cmdb, 0, 0);
  732. *mvp = projMat * viewMat * modelMat;
  733. color = SET_UNIFORMS(Vec4*, sizeof(*color) * 2, cmdb, 0, 1);
  734. *color++ = Vec4(0.0, 0.0, 1.0, 0.0);
  735. *color = Vec4(0.0, 1.0, 1.0, 0.0);
  736. cmdb->drawIndexed(PrimitiveTopology::kTriangles, 6 * 2 * 3);
  737. }
  738. #endif
  739. static void drawOffscreen(GrManager& gr)
  740. {
  741. #if 0
  742. //
  743. // Create textures
  744. //
  745. SamplerInitInfo samplerInit;
  746. samplerInit.m_minMagFilter = SamplingFilter::kLinear;
  747. samplerInit.m_mipmapFilter = SamplingFilter::kLinear;
  748. SamplerPtr sampler = gr.newSampler(samplerInit);
  749. const Format COL_FORMAT = Format::kR8G8B8A8_Unorm;
  750. const U TEX_SIZE = 256;
  751. TextureInitInfo init;
  752. init.m_format = COL_FORMAT;
  753. init.m_usage = TextureUsageBit::kSampledFragment | TextureUsageBit::kAllFramebuffer;
  754. init.m_height = TEX_SIZE;
  755. init.m_width = TEX_SIZE;
  756. init.m_type = TextureType::k2D;
  757. TexturePtr col0 = gr.newTexture(init);
  758. TexturePtr col1 = gr.newTexture(init);
  759. TextureViewPtr col0View = gr.newTextureView(TextureViewInitInfo(col0.get()));
  760. TextureViewPtr col1View = gr.newTextureView(TextureViewInitInfo(col1.get()));
  761. init.m_format = kDsFormat;
  762. TexturePtr dp = gr.newTexture(init);
  763. //
  764. // Create FB
  765. //
  766. FramebufferInitInfo fbinit;
  767. fbinit.m_colorAttachmentCount = 2;
  768. fbinit.m_colorAttachments[0].m_textureView = gr.newTextureView(TextureViewInitInfo(col0.get()));
  769. fbinit.m_colorAttachments[0].m_clearValue.m_colorf = {{0.1f, 0.0f, 0.0f, 0.0f}};
  770. fbinit.m_colorAttachments[1].m_textureView = gr.newTextureView(TextureViewInitInfo(col1.get()));
  771. fbinit.m_colorAttachments[1].m_clearValue.m_colorf = {{0.0f, 0.1f, 0.0f, 0.0f}};
  772. TextureViewInitInfo viewInit(dp.get());
  773. viewInit.m_depthStencilAspect = DepthStencilAspectBit::kDepth;
  774. fbinit.m_depthStencilAttachment.m_textureView = gr.newTextureView(viewInit);
  775. fbinit.m_depthStencilAttachment.m_clearValue.m_depthStencil.m_depth = 1.0;
  776. FramebufferPtr fb = gr.newFramebuffer(fbinit);
  777. //
  778. // Create buffs
  779. //
  780. BufferPtr verts, indices;
  781. createCube(gr, verts, indices);
  782. //
  783. // Create progs
  784. //
  785. ShaderProgramPtr prog = createProgram(VERT_MRT_SRC, FRAG_MRT_SRC, gr);
  786. ShaderProgramPtr resolveProg = createProgram(VERT_QUAD_SRC, FRAG_MRT2_SRC, gr);
  787. //
  788. // Draw
  789. //
  790. const U ITERATION_COUNT = 200;
  791. U iterations = ITERATION_COUNT;
  792. while(iterations--)
  793. {
  794. HighRezTimer timer;
  795. timer.start();
  796. CommandBufferInitInfo cinit;
  797. cinit.m_flags = CommandBufferFlag::kGeneralWork;
  798. CommandBufferPtr cmdb = gr.newCommandBuffer(cinit);
  799. cmdb->setPolygonOffset(0.0, 0.0);
  800. setTextureSurfaceBarrier(cmdb, col0, TextureUsageBit::kNone, TextureUsageBit::kFramebufferWrite, TextureSurfaceDescriptor(0, 0, 0, 0));
  801. setTextureSurfaceBarrier(cmdb, col1, TextureUsageBit::kNone, TextureUsageBit::kFramebufferWrite, TextureSurfaceDescriptor(0, 0, 0, 0));
  802. setTextureSurfaceBarrier(cmdb, dp, TextureUsageBit::kNone, TextureUsageBit::kAllFramebuffer, TextureSurfaceDescriptor(0, 0, 0, 0));
  803. cmdb->beginRenderPass(fb.get(), {{TextureUsageBit::kFramebufferWrite, TextureUsageBit::kFramebufferWrite}}, TextureUsageBit::kAllFramebuffer);
  804. drawOffscreenDrawcalls(gr, prog, cmdb, TEX_SIZE, indices, verts);
  805. cmdb->endRenderPass();
  806. setTextureSurfaceBarrier(cmdb, col0, TextureUsageBit::kFramebufferWrite, TextureUsageBit::kSampledFragment, TextureSurfaceDescriptor(0, 0, 0, 0));
  807. setTextureSurfaceBarrier(cmdb, col1, TextureUsageBit::kFramebufferWrite, TextureUsageBit::kSampledFragment, TextureSurfaceDescriptor(0, 0, 0, 0));
  808. setTextureSurfaceBarrier(cmdb, dp, TextureUsageBit::kAllFramebuffer, TextureUsageBit::kSampledFragment, TextureSurfaceDescriptor(0, 0, 0, 0));
  809. // Draw quad
  810. TexturePtr presentTex = gr.acquireNextPresentableTexture();
  811. FramebufferPtr dfb = createColorFb(gr, presentTex);
  812. presentBarrierA(cmdb, presentTex);
  813. cmdb->beginRenderPass(dfb.get(), {TextureUsageBit::kFramebufferWrite}, {});
  814. cmdb->bindShaderProgram(resolveProg.get());
  815. cmdb->setViewport(0, 0, WIDTH, HEIGHT);
  816. // cmdb->bindTextureAndSampler(0, 0, col0View.get(), sampler.get());
  817. // cmdb->bindTextureAndSampler(0, 2, col1View.get(), sampler.get());
  818. cmdb->draw(PrimitiveTopology::kTriangles, 6);
  819. cmdb->endRenderPass();
  820. presentBarrierB(cmdb, presentTex);
  821. cmdb->endRecording();
  822. GrManager::getSingleton().submit(cmdb.get());
  823. // End
  824. gr.swapBuffers();
  825. timer.stop();
  826. const F32 TICK = 1.0f / 30.0f;
  827. if(timer.getElapsedTime() < TICK)
  828. {
  829. HighRezTimer::sleep(TICK - timer.getElapsedTime());
  830. }
  831. }
  832. #endif
  833. }
  834. ANKI_TEST(Gr, DrawOffscreen)
  835. {
  836. #if 0
  837. COMMON_BEGIN()
  838. drawOffscreen(*g_gr);
  839. COMMON_END();
  840. #endif
  841. }
  842. ANKI_TEST(Gr, ImageLoadStore)
  843. {
  844. #if 0
  845. COMMON_BEGIN()
  846. SamplerInitInfo samplerInit;
  847. samplerInit.m_minMagFilter = SamplingFilter::kNearest;
  848. samplerInit.m_mipmapFilter = SamplingFilter::kBase;
  849. SamplerPtr sampler = g_gr->newSampler(samplerInit);
  850. TextureInitInfo init;
  851. init.m_width = init.m_height = 4;
  852. init.m_mipmapCount = 2;
  853. init.m_usage = TextureUsageBit::kTransferDestination | TextureUsageBit::kAllSampled | TextureUsageBit::kStorageComputeWrite;
  854. init.m_type = TextureType::k2D;
  855. init.m_format = Format::kR8G8B8A8_Unorm;
  856. TexturePtr tex = g_gr->newTexture(init);
  857. TextureViewInitInfo viewInit(tex.get());
  858. viewInit.m_firstMipmap = 1;
  859. viewInit.m_mipmapCount = 1;
  860. TextureViewPtr view = g_gr->newTextureView(viewInit);
  861. // Prog
  862. ShaderProgramPtr prog = createProgram(VERT_QUAD_SRC, FRAG_SIMPLE_TEX_SRC, *g_gr);
  863. // Create shader & compute prog
  864. ShaderPtr shader = createShader(COMP_WRITE_IMAGE_SRC, ShaderType::kCompute, *g_gr);
  865. ShaderProgramInitInfo sprogInit;
  866. sprogInit.m_computeShader = shader.get();
  867. ShaderProgramPtr compProg = g_gr->newShaderProgram(sprogInit);
  868. // Write texture data
  869. CommandBufferInitInfo cmdbinit;
  870. CommandBufferPtr cmdb = g_gr->newCommandBuffer(cmdbinit);
  871. setTextureSurfaceBarrier(cmdb, tex, TextureUsageBit::kNone, TextureUsageBit::kTransferDestination, TextureSurfaceDescriptor(0, 0, 0, 0));
  872. ClearValue clear;
  873. clear.m_colorf = {{0.0, 1.0, 0.0, 1.0}};
  874. TextureViewInitInfo viewInit2(tex.get(), TextureSurfaceDescriptor(0, 0, 0, 0));
  875. cmdb->clearTextureView(g_gr->newTextureView(viewInit2).get(), clear);
  876. setTextureSurfaceBarrier(cmdb, tex, TextureUsageBit::kTransferDestination, TextureUsageBit::kSampledFragment, TextureSurfaceDescriptor(0, 0, 0, 0));
  877. setTextureSurfaceBarrier(cmdb, tex, TextureUsageBit::kNone, TextureUsageBit::kTransferDestination, TextureSurfaceDescriptor(1, 0, 0, 0));
  878. clear.m_colorf = {{0.0, 0.0, 1.0, 1.0}};
  879. TextureViewInitInfo viewInit3(tex.get(), TextureSurfaceDescriptor(1, 0, 0, 0));
  880. cmdb->clearTextureView(g_gr->newTextureView(viewInit3).get(), clear);
  881. setTextureSurfaceBarrier(cmdb, tex, TextureUsageBit::kTransferDestination, TextureUsageBit::kStorageComputeWrite, TextureSurfaceDescriptor(1, 0, 0, 0));
  882. cmdb->endRecording();
  883. GrManager::getSingleton().submit(cmdb.get());
  884. const U ITERATION_COUNT = 100;
  885. U iterations = ITERATION_COUNT;
  886. while(iterations--)
  887. {
  888. HighRezTimer timer;
  889. timer.start();
  890. CommandBufferInitInfo cinit;
  891. cinit.m_flags = CommandBufferFlag::kGeneralWork | CommandBufferFlag::kComputeWork | CommandBufferFlag::kSmallBatch;
  892. CommandBufferPtr cmdb = g_gr->newCommandBuffer(cinit);
  893. // Write image
  894. Vec4* col = SET_STORAGE(Vec4*, sizeof(*col), cmdb, 1, 0);
  895. *col = Vec4(F32(iterations) / F32(ITERATION_COUNT));
  896. setTextureSurfaceBarrier(cmdb, tex, TextureUsageBit::kNone, TextureUsageBit::kStorageComputeWrite, TextureSurfaceDescriptor(1, 0, 0, 0));
  897. cmdb->bindShaderProgram(compProg.get());
  898. cmdb->bindStorageTexture(0, 0, view.get());
  899. cmdb->dispatchCompute(WIDTH / 2, HEIGHT / 2, 1);
  900. setTextureSurfaceBarrier(cmdb, tex, TextureUsageBit::kStorageComputeWrite, TextureUsageBit::kSampledFragment, TextureSurfaceDescriptor(1, 0, 0, 0));
  901. // Present image
  902. cmdb->setViewport(0, 0, WIDTH, HEIGHT);
  903. cmdb->bindShaderProgram(prog.get());
  904. TexturePtr presentTex = g_gr->acquireNextPresentableTexture();
  905. FramebufferPtr dfb = createColorFb(*g_gr, presentTex);
  906. presentBarrierA(cmdb, presentTex);
  907. cmdb->beginRenderPass(dfb.get(), {TextureUsageBit::kFramebufferWrite}, {});
  908. // cmdb->bindTextureAndSampler(0, 0, g_gr->newTextureView(TextureViewInitInfo(tex.get())).get(), sampler.get());
  909. cmdb->draw(PrimitiveTopology::kTriangles, 6);
  910. cmdb->endRenderPass();
  911. presentBarrierB(cmdb, presentTex);
  912. cmdb->endRecording();
  913. GrManager::getSingleton().submit(cmdb.get());
  914. // End
  915. g_gr->swapBuffers();
  916. timer.stop();
  917. const F32 TICK = 1.0f / 30.0f;
  918. if(timer.getElapsedTime() < TICK)
  919. {
  920. HighRezTimer::sleep(TICK - timer.getElapsedTime());
  921. }
  922. }
  923. COMMON_END()
  924. #endif
  925. }
  926. ANKI_TEST(Gr, 3DTextures)
  927. {
  928. #if 0
  929. COMMON_BEGIN()
  930. SamplerInitInfo samplerInit;
  931. samplerInit.m_minMagFilter = SamplingFilter::kNearest;
  932. samplerInit.m_mipmapFilter = SamplingFilter::kBase;
  933. samplerInit.m_addressing = SamplingAddressing::kClamp;
  934. SamplerPtr sampler = g_gr->newSampler(samplerInit);
  935. //
  936. // Create texture A
  937. //
  938. TextureInitInfo init;
  939. init.m_depth = 1;
  940. init.m_format = Format::kR8G8B8A8_Unorm;
  941. init.m_usage = TextureUsageBit::kSampledFragment | TextureUsageBit::kTransferDestination;
  942. init.m_height = 2;
  943. init.m_width = 2;
  944. init.m_mipmapCount = 2;
  945. init.m_samples = 1;
  946. init.m_depth = 2;
  947. init.m_layerCount = 1;
  948. init.m_type = TextureType::k3D;
  949. TexturePtr a = g_gr->newTexture(init);
  950. //
  951. // Upload all textures
  952. //
  953. Array<U8, 2 * 2 * 2 * 4> mip0 = {
  954. {255, 0, 0, 0, 0, 255, 0, 0, 0, 0, 255, 0, 255, 255, 0, 0, 255, 0, 255, 0, 0, 255, 255, 0, 255, 255, 255, 0, 0, 0, 0, 0}};
  955. Array<U8, 4> mip1 = {{128, 128, 128, 0}};
  956. CommandBufferInitInfo cmdbinit;
  957. cmdbinit.m_flags = CommandBufferFlag::kGeneralWork | CommandBufferFlag::kSmallBatch;
  958. CommandBufferPtr cmdb = g_gr->newCommandBuffer(cmdbinit);
  959. setTextureVolumeBarrier(cmdb, a, TextureUsageBit::kNone, TextureUsageBit::kTransferDestination, TextureVolumeDescriptor(0));
  960. setTextureVolumeBarrier(cmdb, a, TextureUsageBit::kNone, TextureUsageBit::kTransferDestination, TextureVolumeDescriptor(1));
  961. TransferGpuAllocatorHandle handle0, handle1;
  962. UPLOAD_TEX_VOL(cmdb, a, TextureVolumeDescriptor(0), &mip0[0], sizeof(mip0), handle0);
  963. UPLOAD_TEX_VOL(cmdb, a, TextureVolumeDescriptor(1), &mip1[0], sizeof(mip1), handle1);
  964. setTextureVolumeBarrier(cmdb, a, TextureUsageBit::kTransferDestination, TextureUsageBit::kSampledFragment, TextureVolumeDescriptor(0));
  965. setTextureVolumeBarrier(cmdb, a, TextureUsageBit::kTransferDestination, TextureUsageBit::kSampledFragment, TextureVolumeDescriptor(1));
  966. FencePtr fence;
  967. cmdb->endRecording();
  968. GrManager::getSingleton().submit(cmdb.get(), {}, &fence);
  969. transfAlloc->release(handle0, fence);
  970. transfAlloc->release(handle1, fence);
  971. //
  972. // Rest
  973. //
  974. ShaderProgramPtr prog = createProgram(VERT_QUAD_SRC, FRAG_TEX3D_SRC, *g_gr);
  975. static Array<Vec4, 9> TEX_COORDS_LOD = {{Vec4(0, 0, 0, 0), Vec4(1, 0, 0, 0), Vec4(0, 1, 0, 0), Vec4(1, 1, 0, 0), Vec4(0, 0, 1, 0),
  976. Vec4(1, 0, 1, 0), Vec4(0, 1, 1, 0), Vec4(1, 1, 1, 0), Vec4(0, 0, 0, 1)}};
  977. const U ITERATION_COUNT = 100;
  978. U iterations = ITERATION_COUNT;
  979. while(iterations--)
  980. {
  981. HighRezTimer timer;
  982. timer.start();
  983. CommandBufferInitInfo cinit;
  984. cinit.m_flags = CommandBufferFlag::kGeneralWork | CommandBufferFlag::kSmallBatch;
  985. CommandBufferPtr cmdb = g_gr->newCommandBuffer(cinit);
  986. cmdb->setViewport(0, 0, WIDTH, HEIGHT);
  987. TexturePtr presentTex = g_gr->acquireNextPresentableTexture();
  988. FramebufferPtr dfb = createColorFb(*g_gr, presentTex);
  989. presentBarrierA(cmdb, presentTex);
  990. cmdb->beginRenderPass(dfb.get(), {TextureUsageBit::kFramebufferWrite}, {});
  991. cmdb->bindShaderProgram(prog.get());
  992. Vec4* uv = SET_UNIFORMS(Vec4*, sizeof(Vec4), cmdb, 0, 0);
  993. U32 idx = U32((F32(ITERATION_COUNT - iterations - 1) / F32(ITERATION_COUNT)) * F32(TEX_COORDS_LOD.getSize()));
  994. *uv = TEX_COORDS_LOD[idx];
  995. // cmdb->bindTextureAndSampler(0, 1, g_gr->newTextureView(TextureViewInitInfo(a.get())).get(), sampler.get());
  996. cmdb->draw(PrimitiveTopology::kTriangles, 6);
  997. cmdb->endRenderPass();
  998. presentBarrierB(cmdb, presentTex);
  999. cmdb->endRecording();
  1000. GrManager::getSingleton().submit(cmdb.get());
  1001. // End
  1002. g_gr->swapBuffers();
  1003. timer.stop();
  1004. const F32 TICK = 1.0f / 15.0f;
  1005. if(timer.getElapsedTime() < TICK)
  1006. {
  1007. HighRezTimer::sleep(TICK - timer.getElapsedTime());
  1008. }
  1009. }
  1010. COMMON_END()
  1011. #endif
  1012. }
  1013. static RenderTargetDescription newRTDescr(CString name)
  1014. {
  1015. RenderTargetDescription texInf(name);
  1016. texInf.m_width = texInf.m_height = 16;
  1017. texInf.m_usage = TextureUsageBit::kFramebufferWrite | TextureUsageBit::kSampledFragment;
  1018. texInf.m_format = Format::kR8G8B8A8_Unorm;
  1019. texInf.bake();
  1020. return texInf;
  1021. }
  1022. ANKI_TEST(Gr, RenderGraph)
  1023. {
  1024. #if 0
  1025. COMMON_BEGIN()
  1026. StackMemoryPool pool(allocAligned, nullptr, 2_MB);
  1027. RenderGraphDescription descr(&pool);
  1028. RenderGraphPtr rgraph = g_gr->newRenderGraph();
  1029. const U GI_MIP_COUNT = 4;
  1030. TextureInitInfo texI("dummy");
  1031. texI.m_width = texI.m_height = 16;
  1032. texI.m_usage = TextureUsageBit::kFramebufferWrite | TextureUsageBit::kSampledFragment;
  1033. texI.m_format = Format::kR8G8B8A8_Unorm;
  1034. TexturePtr dummyTex = g_gr->newTexture(texI);
  1035. // SM
  1036. RenderTargetHandle smScratchRt = descr.newRenderTarget(newRTDescr("SM scratch"));
  1037. {
  1038. GraphicsRenderPassDescription& pass = descr.newGraphicsRenderPass("SM");
  1039. pass.newTextureDependency(smScratchRt, TextureUsageBit::kAllFramebuffer);
  1040. }
  1041. // SM to exponential SM
  1042. RenderTargetHandle smExpRt = descr.importRenderTarget(dummyTex.get(), TextureUsageBit::kSampledFragment);
  1043. {
  1044. GraphicsRenderPassDescription& pass = descr.newGraphicsRenderPass("ESM");
  1045. pass.newTextureDependency(smScratchRt, TextureUsageBit::kSampledFragment);
  1046. pass.newTextureDependency(smExpRt, TextureUsageBit::kFramebufferWrite);
  1047. }
  1048. // GI gbuff
  1049. RenderTargetHandle giGbuffNormRt = descr.newRenderTarget(newRTDescr("GI GBuff norm"));
  1050. RenderTargetHandle giGbuffDiffRt = descr.newRenderTarget(newRTDescr("GI GBuff diff"));
  1051. RenderTargetHandle giGbuffDepthRt = descr.newRenderTarget(newRTDescr("GI GBuff depth"));
  1052. {
  1053. GraphicsRenderPassDescription& pass = descr.newGraphicsRenderPass("GI gbuff");
  1054. pass.newTextureDependency(giGbuffNormRt, TextureUsageBit::kFramebufferWrite);
  1055. pass.newTextureDependency(giGbuffDepthRt, TextureUsageBit::kFramebufferWrite);
  1056. pass.newTextureDependency(giGbuffDiffRt, TextureUsageBit::kFramebufferWrite);
  1057. }
  1058. // GI light
  1059. RenderTargetHandle giGiLightRt = descr.importRenderTarget(dummyTex.get(), TextureUsageBit::kSampledFragment);
  1060. for(U32 faceIdx = 0; faceIdx < 6; ++faceIdx)
  1061. {
  1062. TextureSubresourceInfo subresource(TextureSurfaceDescriptor(0, faceIdx, 0));
  1063. GraphicsRenderPassDescription& pass = descr.newGraphicsRenderPass(String().sprintf("GI lp%u", faceIdx).toCString());
  1064. pass.newTextureDependency(giGiLightRt, TextureUsageBit::kFramebufferWrite, subresource);
  1065. pass.newTextureDependency(giGbuffNormRt, TextureUsageBit::kSampledFragment);
  1066. pass.newTextureDependency(giGbuffDepthRt, TextureUsageBit::kSampledFragment);
  1067. pass.newTextureDependency(giGbuffDiffRt, TextureUsageBit::kSampledFragment);
  1068. }
  1069. // GI light mips
  1070. {
  1071. for(U32 faceIdx = 0; faceIdx < 6; ++faceIdx)
  1072. {
  1073. GraphicsRenderPassDescription& pass = descr.newGraphicsRenderPass(String().sprintf("GI mip%u", faceIdx).toCString());
  1074. for(U32 mip = 0; mip < GI_MIP_COUNT; ++mip)
  1075. {
  1076. TextureSurfaceDescriptor surf(mip, faceIdx, 0);
  1077. pass.newTextureDependency(giGiLightRt, TextureUsageBit::kGenerateMipmaps, surf);
  1078. }
  1079. }
  1080. }
  1081. // Gbuffer
  1082. RenderTargetHandle gbuffRt0 = descr.newRenderTarget(newRTDescr("GBuff RT0"));
  1083. RenderTargetHandle gbuffRt1 = descr.newRenderTarget(newRTDescr("GBuff RT1"));
  1084. RenderTargetHandle gbuffRt2 = descr.newRenderTarget(newRTDescr("GBuff RT2"));
  1085. RenderTargetHandle gbuffDepth = descr.newRenderTarget(newRTDescr("GBuff RT2"));
  1086. {
  1087. GraphicsRenderPassDescription& pass = descr.newGraphicsRenderPass("G-Buffer");
  1088. pass.newTextureDependency(gbuffRt0, TextureUsageBit::kFramebufferWrite);
  1089. pass.newTextureDependency(gbuffRt1, TextureUsageBit::kFramebufferWrite);
  1090. pass.newTextureDependency(gbuffRt2, TextureUsageBit::kFramebufferWrite);
  1091. pass.newTextureDependency(gbuffDepth, TextureUsageBit::kFramebufferWrite);
  1092. }
  1093. // Half depth
  1094. RenderTargetHandle halfDepthRt = descr.newRenderTarget(newRTDescr("Depth/2"));
  1095. {
  1096. GraphicsRenderPassDescription& pass = descr.newGraphicsRenderPass("HalfDepth");
  1097. pass.newTextureDependency(gbuffDepth, TextureUsageBit::kSampledFragment);
  1098. pass.newTextureDependency(halfDepthRt, TextureUsageBit::kFramebufferWrite);
  1099. }
  1100. // Quarter depth
  1101. RenderTargetHandle quarterDepthRt = descr.newRenderTarget(newRTDescr("Depth/4"));
  1102. {
  1103. GraphicsRenderPassDescription& pass = descr.newGraphicsRenderPass("QuarterDepth");
  1104. pass.newTextureDependency(quarterDepthRt, TextureUsageBit::kFramebufferWrite);
  1105. pass.newTextureDependency(halfDepthRt, TextureUsageBit::kSampledFragment);
  1106. }
  1107. // SSAO
  1108. RenderTargetHandle ssaoRt = descr.newRenderTarget(newRTDescr("SSAO"));
  1109. {
  1110. GraphicsRenderPassDescription& pass = descr.newGraphicsRenderPass("SSAO main");
  1111. pass.newTextureDependency(ssaoRt, TextureUsageBit::kFramebufferWrite);
  1112. pass.newTextureDependency(quarterDepthRt, TextureUsageBit::kSampledFragment);
  1113. pass.newTextureDependency(gbuffRt2, TextureUsageBit::kSampledFragment);
  1114. RenderTargetHandle ssaoVBlurRt = descr.newRenderTarget(newRTDescr("SSAO tmp"));
  1115. GraphicsRenderPassDescription& pass2 = descr.newGraphicsRenderPass("SSAO vblur");
  1116. pass2.newTextureDependency(ssaoRt, TextureUsageBit::kSampledFragment);
  1117. pass2.newTextureDependency(ssaoVBlurRt, TextureUsageBit::kFramebufferWrite);
  1118. GraphicsRenderPassDescription& pass3 = descr.newGraphicsRenderPass("SSAO hblur");
  1119. pass3.newTextureDependency(ssaoRt, TextureUsageBit::kFramebufferWrite);
  1120. pass3.newTextureDependency(ssaoVBlurRt, TextureUsageBit::kSampledFragment);
  1121. }
  1122. // Volumetric
  1123. RenderTargetHandle volRt = descr.newRenderTarget(newRTDescr("Vol"));
  1124. {
  1125. GraphicsRenderPassDescription& pass = descr.newGraphicsRenderPass("Vol main");
  1126. pass.newTextureDependency(volRt, TextureUsageBit::kFramebufferWrite);
  1127. pass.newTextureDependency(quarterDepthRt, TextureUsageBit::kSampledFragment);
  1128. RenderTargetHandle volVBlurRt = descr.newRenderTarget(newRTDescr("Vol tmp"));
  1129. GraphicsRenderPassDescription& pass2 = descr.newGraphicsRenderPass("Vol vblur");
  1130. pass2.newTextureDependency(volRt, TextureUsageBit::kSampledFragment);
  1131. pass2.newTextureDependency(volVBlurRt, TextureUsageBit::kFramebufferWrite);
  1132. GraphicsRenderPassDescription& pass3 = descr.newGraphicsRenderPass("Vol hblur");
  1133. pass3.newTextureDependency(volRt, TextureUsageBit::kFramebufferWrite);
  1134. pass3.newTextureDependency(volVBlurRt, TextureUsageBit::kSampledFragment);
  1135. }
  1136. // Forward shading
  1137. RenderTargetHandle fsRt = descr.newRenderTarget(newRTDescr("FS"));
  1138. {
  1139. GraphicsRenderPassDescription& pass = descr.newGraphicsRenderPass("Forward shading");
  1140. pass.newTextureDependency(fsRt, TextureUsageBit::kFramebufferWrite);
  1141. pass.newTextureDependency(halfDepthRt, TextureUsageBit::kSampledFragment | TextureUsageBit::kFramebufferRead);
  1142. pass.newTextureDependency(volRt, TextureUsageBit::kSampledFragment);
  1143. }
  1144. // Light shading
  1145. RenderTargetHandle lightRt = descr.importRenderTarget(dummyTex.get(), TextureUsageBit::kNone);
  1146. {
  1147. GraphicsRenderPassDescription& pass = descr.newGraphicsRenderPass("Light shading");
  1148. pass.newTextureDependency(lightRt, TextureUsageBit::kFramebufferWrite);
  1149. pass.newTextureDependency(gbuffRt0, TextureUsageBit::kSampledFragment);
  1150. pass.newTextureDependency(gbuffRt1, TextureUsageBit::kSampledFragment);
  1151. pass.newTextureDependency(gbuffRt2, TextureUsageBit::kSampledFragment);
  1152. pass.newTextureDependency(gbuffDepth, TextureUsageBit::kSampledFragment);
  1153. pass.newTextureDependency(smExpRt, TextureUsageBit::kSampledFragment);
  1154. pass.newTextureDependency(giGiLightRt, TextureUsageBit::kSampledFragment);
  1155. pass.newTextureDependency(ssaoRt, TextureUsageBit::kSampledFragment);
  1156. pass.newTextureDependency(fsRt, TextureUsageBit::kSampledFragment);
  1157. }
  1158. // TAA
  1159. RenderTargetHandle taaHistoryRt = descr.importRenderTarget(dummyTex.get(), TextureUsageBit::kSampledFragment);
  1160. RenderTargetHandle taaRt = descr.importRenderTarget(dummyTex.get(), TextureUsageBit::kNone);
  1161. {
  1162. GraphicsRenderPassDescription& pass = descr.newGraphicsRenderPass("Temporal AA");
  1163. pass.newTextureDependency(lightRt, TextureUsageBit::kSampledFragment);
  1164. pass.newTextureDependency(taaRt, TextureUsageBit::kFramebufferWrite);
  1165. pass.newTextureDependency(taaHistoryRt, TextureUsageBit::kSampledFragment);
  1166. }
  1167. rgraph->compileNewGraph(descr, pool);
  1168. COMMON_END()
  1169. #endif
  1170. }
  1171. /// Test workarounds for some unsupported formats
  1172. ANKI_TEST(Gr, VkWorkarounds)
  1173. {
  1174. #if 0
  1175. COMMON_BEGIN()
  1176. // Create program
  1177. static const char* COMP_SRC = R"(
  1178. layout(local_size_x = 8, local_size_y = 8, local_size_z = 2) in;
  1179. layout(set = 0, binding = 0) uniform usampler2D u_tex;
  1180. layout(set = 0, binding = 1) buffer s_
  1181. {
  1182. uvec4 u_result;
  1183. };
  1184. shared uint g_wrong;
  1185. void main()
  1186. {
  1187. g_wrong = 0;
  1188. memoryBarrierShared();
  1189. barrier();
  1190. int lod = -1;
  1191. uint idx;
  1192. if(gl_LocalInvocationID.z == 0)
  1193. {
  1194. // First mip
  1195. lod = 0;
  1196. idx = gl_LocalInvocationID.y * 8 + gl_LocalInvocationID.x;
  1197. }
  1198. else if(gl_LocalInvocationID.x < 4u && gl_LocalInvocationID.y < 4u)
  1199. {
  1200. lod = 1;
  1201. idx = gl_LocalInvocationID.y * 4 + gl_LocalInvocationID.x;
  1202. }
  1203. if(lod != -1)
  1204. {
  1205. uvec3 col = texelFetch(u_tex, ivec2(gl_LocalInvocationID.x, gl_LocalInvocationID.y), lod).rgb;
  1206. if(col.x != idx || col.y != idx + 1 || col.z != idx + 2)
  1207. {
  1208. atomicAdd(g_wrong, 1);
  1209. }
  1210. }
  1211. memoryBarrierShared();
  1212. barrier();
  1213. if(g_wrong != 0)
  1214. {
  1215. u_result = uvec4(1);
  1216. }
  1217. else
  1218. {
  1219. u_result = uvec4(2);
  1220. }
  1221. })";
  1222. ShaderPtr comp = createShader(COMP_SRC, ShaderType::kCompute, *g_gr);
  1223. ShaderProgramInitInfo sinf;
  1224. sinf.m_computeShader = comp.get();
  1225. ShaderProgramPtr prog = g_gr->newShaderProgram(sinf);
  1226. // Create the texture
  1227. TextureInitInfo texInit;
  1228. texInit.m_width = texInit.m_height = 8;
  1229. texInit.m_format = Format::kR8G8B8_Uint;
  1230. texInit.m_type = TextureType::k2D;
  1231. texInit.m_usage = TextureUsageBit::kTransferDestination | TextureUsageBit::kAllSampled;
  1232. texInit.m_mipmapCount = 2;
  1233. TexturePtr tex = g_gr->newTexture(texInit);
  1234. TextureViewPtr texView = g_gr->newTextureView(TextureViewInitInfo(tex.get()));
  1235. SamplerInitInfo samplerInit;
  1236. SamplerPtr sampler = g_gr->newSampler(samplerInit);
  1237. // Create the buffer to copy to the texture
  1238. BufferPtr uploadBuff =
  1239. g_gr->newBuffer(BufferInitInfo(PtrSize(texInit.m_width) * texInit.m_height * 3, BufferUsageBit::kAllTransfer, BufferMapAccessBit::kWrite));
  1240. U8* data = static_cast<U8*>(uploadBuff->map(0, uploadBuff->getSize(), BufferMapAccessBit::kWrite));
  1241. for(U32 i = 0; i < texInit.m_width * texInit.m_height; ++i)
  1242. {
  1243. data[0] = U8(i);
  1244. data[1] = U8(i + 1);
  1245. data[2] = U8(i + 2);
  1246. data += 3;
  1247. }
  1248. uploadBuff->unmap();
  1249. BufferPtr uploadBuff2 = g_gr->newBuffer(
  1250. BufferInitInfo(PtrSize(texInit.m_width >> 1) * (texInit.m_height >> 1) * 3, BufferUsageBit::kAllTransfer, BufferMapAccessBit::kWrite));
  1251. data = static_cast<U8*>(uploadBuff2->map(0, uploadBuff2->getSize(), BufferMapAccessBit::kWrite));
  1252. for(U i = 0; i < (texInit.m_width >> 1) * (texInit.m_height >> 1); ++i)
  1253. {
  1254. data[0] = U8(i);
  1255. data[1] = U8(i + 1);
  1256. data[2] = U8(i + 2);
  1257. data += 3;
  1258. }
  1259. uploadBuff2->unmap();
  1260. // Create the result buffer
  1261. BufferPtr resultBuff = g_gr->newBuffer(BufferInitInfo(sizeof(UVec4), BufferUsageBit::kStorageComputeWrite, BufferMapAccessBit::kRead));
  1262. // Upload data and test them
  1263. CommandBufferInitInfo cmdbInit;
  1264. cmdbInit.m_flags = CommandBufferFlag::kGeneralWork | CommandBufferFlag::kSmallBatch;
  1265. CommandBufferPtr cmdb = g_gr->newCommandBuffer(cmdbInit);
  1266. TextureSubresourceInfo subresource;
  1267. subresource.m_mipmapCount = texInit.m_mipmapCount;
  1268. setTextureBarrier(cmdb, tex, TextureUsageBit::kNone, TextureUsageBit::kTransferDestination, subresource);
  1269. cmdb->copyBufferToTexture(BufferView(uploadBuff.get()), g_gr->newTextureView(TextureViewInitInfo(tex.get(), TextureSurfaceDescriptor(0, 0, 0))).get());
  1270. cmdb->copyBufferToTexture(BufferView(uploadBuff2.get()), g_gr->newTextureView(TextureViewInitInfo(tex.get(), TextureSurfaceDescriptor(1, 0, 0))).get());
  1271. setTextureBarrier(cmdb, tex, TextureUsageBit::kTransferDestination, TextureUsageBit::kSampledCompute, subresource);
  1272. cmdb->bindShaderProgram(prog.get());
  1273. // cmdb->bindTextureAndSampler(0, 0, texView.get(), sampler.get());
  1274. cmdb->bindStorageBuffer(0, 1, BufferView(resultBuff.get()));
  1275. cmdb->dispatchCompute(1, 1, 1);
  1276. setBufferBarrier(cmdb, resultBuff, BufferUsageBit::kStorageComputeWrite, BufferUsageBit::kStorageComputeWrite, 0, resultBuff->getSize());
  1277. cmdb->endRecording();
  1278. GrManager::getSingleton().submit(cmdb.get());
  1279. g_gr->finish();
  1280. // Get the result
  1281. UVec4* result = static_cast<UVec4*>(resultBuff->map(0, resultBuff->getSize(), BufferMapAccessBit::kRead));
  1282. ANKI_TEST_EXPECT_EQ(result->x(), 2);
  1283. ANKI_TEST_EXPECT_EQ(result->y(), 2);
  1284. ANKI_TEST_EXPECT_EQ(result->z(), 2);
  1285. ANKI_TEST_EXPECT_EQ(result->w(), 2);
  1286. resultBuff->unmap();
  1287. COMMON_END()
  1288. #endif
  1289. }
  1290. ANKI_TEST(Gr, PushConsts)
  1291. {
  1292. #if 0
  1293. COMMON_BEGIN()
  1294. static const char* VERT_SRC = R"(
  1295. struct PC
  1296. {
  1297. vec4 color;
  1298. ivec4 icolor;
  1299. vec4 arr[2];
  1300. mat4 mat;
  1301. };
  1302. layout(push_constant, std140) uniform pc_
  1303. {
  1304. PC regs;
  1305. };
  1306. out gl_PerVertex
  1307. {
  1308. vec4 gl_Position;
  1309. };
  1310. layout(location = 0) out vec4 out_color;
  1311. void main()
  1312. {
  1313. vec2 uv = vec2(gl_VertexID & 1, gl_VertexID >> 1) * 2.0;
  1314. vec2 pos = uv * 2.0 - 1.0;
  1315. gl_Position = vec4(pos, 0.0, 1.0);
  1316. out_color = regs.color;
  1317. }
  1318. )";
  1319. static const char* FRAG_SRC = R"(
  1320. struct PC
  1321. {
  1322. vec4 color;
  1323. ivec4 icolor;
  1324. vec4 arr[2];
  1325. mat4 mat;
  1326. };
  1327. layout(push_constant, std140) uniform pc_
  1328. {
  1329. PC regs;
  1330. };
  1331. layout(location = 0) in vec4 in_color;
  1332. layout(location = 0) out vec4 out_color;
  1333. layout(set = 0, binding = 0) buffer s_
  1334. {
  1335. uvec4 u_result;
  1336. };
  1337. void main()
  1338. {
  1339. out_color = vec4(1.0);
  1340. if(gl_FragCoord.x == 0.5 && gl_FragCoord.y == 0.5)
  1341. {
  1342. if(in_color != vec4(1.0, 0.0, 1.0, 0.0) || regs.icolor != ivec4(-1, 1, 2147483647, -2147483647)
  1343. || regs.arr[0] != vec4(1, 2, 3, 4) || regs.arr[1] != vec4(10, 20, 30, 40)
  1344. || regs.mat[1][0] != 0.5)
  1345. {
  1346. u_result = uvec4(1u);
  1347. }
  1348. else
  1349. {
  1350. u_result = uvec4(2u);
  1351. }
  1352. }
  1353. }
  1354. )";
  1355. ShaderProgramPtr prog = createProgram(VERT_SRC, FRAG_SRC, *g_gr);
  1356. // Create the result buffer
  1357. BufferPtr resultBuff =
  1358. g_gr->newBuffer(BufferInitInfo(sizeof(UVec4), BufferUsageBit::kAllStorage | BufferUsageBit::kTransferDestination, BufferMapAccessBit::kRead));
  1359. // Draw
  1360. CommandBufferInitInfo cinit;
  1361. cinit.m_flags = CommandBufferFlag::kGeneralWork;
  1362. CommandBufferPtr cmdb = g_gr->newCommandBuffer(cinit);
  1363. cmdb->fillBuffer(resultBuff.get(), 0, resultBuff->getSize(), 0);
  1364. setBufferBarrier(cmdb, resultBuff, BufferUsageBit::kTransferDestination, BufferUsageBit::kStorageFragmentWrite, 0, resultBuff->getSize());
  1365. cmdb->setViewport(0, 0, WIDTH, HEIGHT);
  1366. cmdb->bindShaderProgram(prog.get());
  1367. struct PushConstants
  1368. {
  1369. Vec4 m_color = Vec4(1.0, 0.0, 1.0, 0.0);
  1370. IVec4 m_icolor = IVec4(-1, 1, 2147483647, -2147483647);
  1371. Vec4 m_arr[2] = {Vec4(1, 2, 3, 4), Vec4(10, 20, 30, 40)};
  1372. Mat4 m_mat = Mat4(0.0f);
  1373. } pc;
  1374. pc.m_mat(0, 1) = 0.5f;
  1375. cmdb->setPushConstants(&pc, sizeof(pc));
  1376. cmdb->bindStorageBuffer(0, 0, resultBuff.get(), 0, resultBuff->getSize());
  1377. TexturePtr presentTex = g_gr->acquireNextPresentableTexture();
  1378. FramebufferPtr dfb = createColorFb(*g_gr, presentTex);
  1379. presentBarrierA(cmdb, presentTex);
  1380. cmdb->beginRenderPass(dfb.get(), {TextureUsageBit::kFramebufferWrite}, {});
  1381. cmdb->draw(PrimitiveTopology::kTriangles, 3);
  1382. cmdb->endRenderPass();
  1383. presentBarrierB(cmdb, presentTex);
  1384. cmdb->endRecording();
  1385. GrManager::getSingleton().submit(cmdb.get());
  1386. g_gr->swapBuffers();
  1387. g_gr->finish();
  1388. // Get the result
  1389. UVec4* result = static_cast<UVec4*>(resultBuff->map(0, resultBuff->getSize(), BufferMapAccessBit::kRead));
  1390. ANKI_TEST_EXPECT_EQ(result->x(), 2);
  1391. ANKI_TEST_EXPECT_EQ(result->y(), 2);
  1392. ANKI_TEST_EXPECT_EQ(result->z(), 2);
  1393. ANKI_TEST_EXPECT_EQ(result->w(), 2);
  1394. resultBuff->unmap();
  1395. COMMON_END()
  1396. #endif
  1397. }
  1398. ANKI_TEST(Gr, BindingWithArray)
  1399. {
  1400. #if 0
  1401. COMMON_BEGIN()
  1402. // Create result buffer
  1403. BufferPtr resBuff = g_gr->newBuffer(BufferInitInfo(sizeof(Vec4), BufferUsageBit::kAllCompute, BufferMapAccessBit::kRead));
  1404. Array<BufferPtr, 4> uniformBuffers;
  1405. F32 count = 1.0f;
  1406. for(BufferPtr& ptr : uniformBuffers)
  1407. {
  1408. ptr = g_gr->newBuffer(BufferInitInfo(sizeof(Vec4), BufferUsageBit::kAllCompute, BufferMapAccessBit::kWrite));
  1409. Vec4* mapped = static_cast<Vec4*>(ptr->map(0, sizeof(Vec4), BufferMapAccessBit::kWrite));
  1410. *mapped = Vec4(count, count + 1.0f, count + 2.0f, count + 3.0f);
  1411. count += 4.0f;
  1412. ptr->unmap();
  1413. }
  1414. // Create program
  1415. static const char* PROG_SRC = R"(
  1416. layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
  1417. layout(set = 0, binding = 0) uniform u_
  1418. {
  1419. vec4 m_vec;
  1420. } u_ubos[4];
  1421. layout(set = 0, binding = 1) writeonly buffer ss_
  1422. {
  1423. vec4 u_result;
  1424. };
  1425. void main()
  1426. {
  1427. u_result = u_ubos[0].m_vec + u_ubos[1].m_vec + u_ubos[2].m_vec + u_ubos[3].m_vec;
  1428. })";
  1429. ShaderPtr shader = createShader(PROG_SRC, ShaderType::kCompute, *g_gr);
  1430. ShaderProgramInitInfo sprogInit;
  1431. sprogInit.m_computeShader = shader.get();
  1432. ShaderProgramPtr prog = g_gr->newShaderProgram(sprogInit);
  1433. // Run
  1434. CommandBufferInitInfo cinit;
  1435. cinit.m_flags = CommandBufferFlag::kComputeWork | CommandBufferFlag::kSmallBatch;
  1436. CommandBufferPtr cmdb = g_gr->newCommandBuffer(cinit);
  1437. for(U32 i = 0; i < uniformBuffers.getSize(); ++i)
  1438. {
  1439. cmdb->bindUniformBuffer(0, 0, BufferView(uniformBuffers[i].get()), i);
  1440. }
  1441. cmdb->bindStorageBuffer(0, 1, BufferView(resBuff.get()));
  1442. cmdb->bindShaderProgram(prog.get());
  1443. cmdb->dispatchCompute(1, 1, 1);
  1444. cmdb->endRecording();
  1445. GrManager::getSingleton().submit(cmdb.get());
  1446. g_gr->finish();
  1447. // Check result
  1448. Vec4* res = static_cast<Vec4*>(resBuff->map(0, sizeof(Vec4), BufferMapAccessBit::kRead));
  1449. ANKI_TEST_EXPECT_EQ(res->x(), 28.0f);
  1450. ANKI_TEST_EXPECT_EQ(res->y(), 32.0f);
  1451. ANKI_TEST_EXPECT_EQ(res->z(), 36.0f);
  1452. ANKI_TEST_EXPECT_EQ(res->w(), 40.0f);
  1453. resBuff->unmap();
  1454. COMMON_END();
  1455. #endif
  1456. }
  1457. ANKI_TEST(Gr, Bindless)
  1458. {
  1459. #if 0
  1460. COMMON_BEGIN()
  1461. // Create texture A
  1462. TextureInitInfo texInit;
  1463. texInit.m_width = 1;
  1464. texInit.m_height = 1;
  1465. texInit.m_format = Format::R32G32B32A32_UINT;
  1466. texInit.m_usage = TextureUsageBit::kAllStorage | TextureUsageBit::ALL_TRANSFER | TextureUsageBit::kAllSampled;
  1467. texInit.m_mipmapCount = 1;
  1468. TexturePtr texA = gr->newTexture(texInit);
  1469. // Create texture B
  1470. TexturePtr texB = gr->newTexture(texInit);
  1471. // Create texture C
  1472. texInit.m_format = Format::R32G32B32A32_SFLOAT;
  1473. TexturePtr texC = gr->newTexture(texInit);
  1474. // Create sampler
  1475. SamplerInitInfo samplerInit;
  1476. SamplerPtr sampler = gr->newSampler(samplerInit);
  1477. // Create views
  1478. TextureViewPtr viewA = gr->newTextureView(TextureViewInitInfo(texA, TextureSurfaceDescriptor()));
  1479. TextureViewPtr viewB = gr->newTextureView(TextureViewInitInfo(texB, TextureSurfaceDescriptor()));
  1480. TextureViewPtr viewC = gr->newTextureView(TextureViewInitInfo(texC, TextureSurfaceDescriptor()));
  1481. // Create result buffer
  1482. BufferPtr resBuff =
  1483. gr->newBuffer(BufferInitInfo(sizeof(UVec4), BufferUsageBit::kAllCompute, BufferMapAccessBit::kRead));
  1484. // Create program A
  1485. static const char* PROG_SRC = R"(
  1486. layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
  1487. ANKI_BINDLESS_SET(0u);
  1488. layout(set = 1, binding = 0) writeonly buffer ss_
  1489. {
  1490. uvec4 u_result;
  1491. };
  1492. layout(set = 1, binding = 1) uniform sampler u_sampler;
  1493. layout(push_constant) uniform pc_
  1494. {
  1495. uvec4 u_texIndices;
  1496. };
  1497. void main()
  1498. {
  1499. uvec4 val0 = imageLoad(u_bindlessImages2dU32[u_texIndices[0]], ivec2(0));
  1500. uvec4 val1 = texelFetch(usampler2D(u_bindlessTextures2dU32[u_texIndices[1]], u_sampler), ivec2(0), 0);
  1501. vec4 val2 = texelFetch(sampler2D(u_bindlessTextures2dF32[u_texIndices[2]], u_sampler), ivec2(0), 0);
  1502. u_result = val0 + val1 + uvec4(val2);
  1503. })";
  1504. ShaderPtr shader = createShader(PROG_SRC, ShaderType::kCompute, *gr);
  1505. ShaderProgramInitInfo sprogInit;
  1506. sprogInit.m_computeShader = shader;
  1507. ShaderProgramPtr prog = gr->newShaderProgram(sprogInit);
  1508. // Run
  1509. CommandBufferInitInfo cinit;
  1510. cinit.m_flags = CommandBufferFlag::kComputeWork | CommandBufferFlag::kSmallBatch;
  1511. CommandBufferPtr cmdb = gr->newCommandBuffer(cinit);
  1512. setTextureSurfaceBarrier(cmdb, texA, TextureUsageBit::kNone, TextureUsageBit::kTransferDestination,
  1513. TextureSurfaceDescriptor());
  1514. setTextureSurfaceBarrier(cmdb, texB, TextureUsageBit::kNone, TextureUsageBit::kTransferDestination,
  1515. TextureSurfaceDescriptor());
  1516. setTextureSurfaceBarrier(cmdb, texC, TextureUsageBit::kNone, TextureUsageBit::kTransferDestination,
  1517. TextureSurfaceDescriptor());
  1518. TransferGpuAllocatorHandle handle0, handle1, handle2;
  1519. const UVec4 mip0 = UVec4(1, 2, 3, 4);
  1520. UPLOAD_TEX_SURFACE(cmdb, texA, TextureSurfaceDescriptor(0, 0, 0, 0), &mip0[0], sizeof(mip0), handle0);
  1521. const UVec4 mip1 = UVec4(10, 20, 30, 40);
  1522. UPLOAD_TEX_SURFACE(cmdb, texB, TextureSurfaceDescriptor(0, 0, 0, 0), &mip1[0], sizeof(mip1), handle1);
  1523. const Vec4 mip2 = Vec4(2.2f, 3.3f, 4.4f, 5.5f);
  1524. UPLOAD_TEX_SURFACE(cmdb, texC, TextureSurfaceDescriptor(0, 0, 0, 0), &mip2[0], sizeof(mip2), handle2);
  1525. setTextureSurfaceBarrier(cmdb, texA, TextureUsageBit::kTransferDestination, TextureUsageBit::kStorageComputeRead,
  1526. TextureSurfaceDescriptor());
  1527. setTextureSurfaceBarrier(cmdb, texB, TextureUsageBit::kTransferDestination, TextureUsageBit::kSampledCompute,
  1528. TextureSurfaceDescriptor());
  1529. setTextureSurfaceBarrier(cmdb, texC, TextureUsageBit::kTransferDestination, TextureUsageBit::kSampledCompute,
  1530. TextureSurfaceDescriptor());
  1531. cmdb->bindStorageBuffer(1, 0, resBuff, 0, kMaxPtrSize);
  1532. cmdb->bindSampler(1, 1, sampler);
  1533. cmdb->bindShaderProgram(prog);
  1534. const U32 idx0 = viewA->getOrCreateBindlessImageIndex();
  1535. const U32 idx1 = viewB->getOrCreateBindlessTextureIndex();
  1536. const U32 idx2 = viewC->getOrCreateBindlessTextureIndex();
  1537. UVec4 pc(idx0, idx1, idx2, 0);
  1538. cmdb->setPushConstants(&pc, sizeof(pc));
  1539. cmdb->bindAllBindless(0);
  1540. cmdb->dispatchCompute(1, 1, 1);
  1541. // Read result
  1542. FencePtr fence;
  1543. cmdb->flush({}, &fence);
  1544. transfAlloc->release(handle0, fence);
  1545. transfAlloc->release(handle1, fence);
  1546. transfAlloc->release(handle2, fence);
  1547. gr->finish();
  1548. // Check result
  1549. UVec4* res = static_cast<UVec4*>(resBuff->map(0, sizeof(UVec4), BufferMapAccessBit::kRead));
  1550. ANKI_TEST_EXPECT_EQ(res->x(), 13);
  1551. ANKI_TEST_EXPECT_EQ(res->y(), 25);
  1552. ANKI_TEST_EXPECT_EQ(res->z(), 37);
  1553. ANKI_TEST_EXPECT_EQ(res->w(), 49);
  1554. resBuff->unmap();
  1555. COMMON_END()
  1556. #endif
  1557. }
  1558. ANKI_TEST(Gr, RayQuery)
  1559. {
  1560. #if 0
  1561. COMMON_BEGIN();
  1562. const Bool useRayTracing = g_gr->getDeviceCapabilities().m_rayTracingEnabled;
  1563. if(!useRayTracing)
  1564. {
  1565. ANKI_TEST_LOGW("Test will run without using ray tracing");
  1566. }
  1567. // Index buffer
  1568. BufferPtr idxBuffer;
  1569. if(useRayTracing)
  1570. {
  1571. Array<U16, 3> indices = {0, 1, 2};
  1572. BufferInitInfo init;
  1573. init.m_mapAccess = BufferMapAccessBit::kWrite;
  1574. init.m_usage = BufferUsageBit::kIndex;
  1575. init.m_size = sizeof(indices);
  1576. idxBuffer = g_gr->newBuffer(init);
  1577. void* addr = idxBuffer->map(0, kMaxPtrSize, BufferMapAccessBit::kWrite);
  1578. memcpy(addr, &indices[0], sizeof(indices));
  1579. idxBuffer->unmap();
  1580. }
  1581. // Position buffer (add some padding to complicate things a bit)
  1582. BufferPtr vertBuffer;
  1583. if(useRayTracing)
  1584. {
  1585. Array<Vec4, 3> verts = {{{-1.0f, 0.0f, 0.0f, 100.0f}, {1.0f, 0.0f, 0.0f, 100.0f}, {0.0f, 2.0f, 0.0f, 100.0f}}};
  1586. BufferInitInfo init;
  1587. init.m_mapAccess = BufferMapAccessBit::kWrite;
  1588. init.m_usage = BufferUsageBit::kVertex;
  1589. init.m_size = sizeof(verts);
  1590. vertBuffer = g_gr->newBuffer(init);
  1591. void* addr = vertBuffer->map(0, kMaxPtrSize, BufferMapAccessBit::kWrite);
  1592. memcpy(addr, &verts[0], sizeof(verts));
  1593. vertBuffer->unmap();
  1594. }
  1595. // BLAS
  1596. AccelerationStructurePtr blas;
  1597. if(useRayTracing)
  1598. {
  1599. AccelerationStructureInitInfo init;
  1600. init.m_type = AccelerationStructureType::kBottomLevel;
  1601. init.m_bottomLevel.m_indexBuffer = idxBuffer.get();
  1602. init.m_bottomLevel.m_indexCount = 3;
  1603. init.m_bottomLevel.m_indexType = IndexType::kU16;
  1604. init.m_bottomLevel.m_positionBuffer = vertBuffer.get();
  1605. init.m_bottomLevel.m_positionCount = 3;
  1606. init.m_bottomLevel.m_positionsFormat = Format::kR32G32B32_Sfloat;
  1607. init.m_bottomLevel.m_positionStride = 4 * 4;
  1608. blas = g_gr->newAccelerationStructure(init);
  1609. }
  1610. // TLAS
  1611. AccelerationStructurePtr tlas;
  1612. if(useRayTracing)
  1613. {
  1614. AccelerationStructureInitInfo init;
  1615. init.m_type = AccelerationStructureType::kTopLevel;
  1616. Array<AccelerationStructureInstanceInfo, 1> instances = {{{blas, Mat3x4::getIdentity()}}};
  1617. init.m_topLevel.m_directArgs.m_instances = instances;
  1618. tlas = g_gr->newAccelerationStructure(init);
  1619. }
  1620. // Program
  1621. ShaderProgramPtr prog;
  1622. {
  1623. CString src = R"(
  1624. #if USE_RAY_TRACING
  1625. #extension GL_EXT_ray_query : enable
  1626. #endif
  1627. layout(push_constant, std140, row_major) uniform b_pc
  1628. {
  1629. Mat4 u_vp;
  1630. Vec3 u_cameraPos;
  1631. F32 u_padding0;
  1632. };
  1633. #if USE_RAY_TRACING
  1634. layout(set = 0, binding = 0) uniform accelerationStructureEXT u_tlas;
  1635. #endif
  1636. layout(location = 0) in Vec2 in_uv;
  1637. layout(location = 0) out Vec3 out_color;
  1638. Bool rayTriangleIntersect(Vec3 orig, Vec3 dir, Vec3 v0, Vec3 v1, Vec3 v2, out F32 t, out F32 u, out F32 v)
  1639. {
  1640. const Vec3 v0v1 = v1 - v0;
  1641. const Vec3 v0v2 = v2 - v0;
  1642. const Vec3 pvec = cross(dir, v0v2);
  1643. const F32 det = dot(v0v1, pvec);
  1644. if(det < 0.00001)
  1645. {
  1646. return false;
  1647. }
  1648. const F32 invDet = 1.0 / det;
  1649. const Vec3 tvec = orig - v0;
  1650. u = dot(tvec, pvec) * invDet;
  1651. if(u < 0.0 || u > 1.0)
  1652. {
  1653. return false;
  1654. }
  1655. const Vec3 qvec = cross(tvec, v0v1);
  1656. v = dot(dir, qvec) * invDet;
  1657. if(v < 0.0 || u + v > 1.0)
  1658. {
  1659. return false;
  1660. }
  1661. t = dot(v0v2, qvec) * invDet;
  1662. return true;
  1663. }
  1664. void main()
  1665. {
  1666. // Unproject
  1667. const Vec2 ndc = in_uv * 2.0 - 1.0;
  1668. const Vec4 p4 = inverse(u_vp) * Vec4(ndc, 1.0, 1.0);
  1669. const Vec3 p3 = p4.xyz / p4.w;
  1670. const Vec3 rayDir = normalize(p3 - u_cameraPos);
  1671. const Vec3 rayOrigin = u_cameraPos;
  1672. #if USE_RAY_TRACING
  1673. Bool hit = false;
  1674. F32 u = 0.0;
  1675. F32 v = 0.0;
  1676. rayQueryEXT rayQuery;
  1677. rayQueryInitializeEXT(rayQuery, u_tlas, gl_RayFlagsOpaqueEXT | gl_RayFlagsTerminateOnFirstHitEXT, 0xFFu, rayOrigin,
  1678. 0.01, rayDir, 1000.0);
  1679. rayQueryProceedEXT(rayQuery);
  1680. const U32 committedStatus = rayQueryGetIntersectionTypeEXT(rayQuery, true);
  1681. if(committedStatus == gl_RayQueryCommittedIntersectionTriangleEXT)
  1682. {
  1683. const Vec2 bary = rayQueryGetIntersectionBarycentricsEXT(rayQuery, true);
  1684. u = bary.x;
  1685. v = bary.y;
  1686. hit = true;
  1687. }
  1688. #else
  1689. // Manual trace
  1690. Vec3 arr[3] = Vec3[](Vec3(-1.0f, 0.0f, 0.0f), Vec3(1.0f, 0.0f, 0.0f), Vec3(0.0f, 2.0f, 0.0f));
  1691. F32 t;
  1692. F32 u;
  1693. F32 v;
  1694. const Bool hit = rayTriangleIntersect(rayOrigin, rayDir, arr[0], arr[1], arr[2], t, u, v);
  1695. #endif
  1696. if(hit)
  1697. {
  1698. out_color = Vec3(u, v, 1.0 - (u + v));
  1699. }
  1700. else
  1701. {
  1702. out_color = Vec3(mix(0.5, 0.2, in_uv.x));
  1703. }
  1704. }
  1705. )";
  1706. String fragSrc;
  1707. if(useRayTracing)
  1708. {
  1709. fragSrc += "#define USE_RAY_TRACING 1\n";
  1710. }
  1711. else
  1712. {
  1713. fragSrc += "#define USE_RAY_TRACING 0\n";
  1714. }
  1715. fragSrc += src;
  1716. prog = createProgram(VERT_QUAD_STRIP_SRC, fragSrc, *g_gr);
  1717. }
  1718. // Build AS
  1719. if(useRayTracing)
  1720. {
  1721. CommandBufferInitInfo cinit;
  1722. cinit.m_flags = CommandBufferFlag::kGeneralWork | CommandBufferFlag::kSmallBatch;
  1723. CommandBufferPtr cmdb = g_gr->newCommandBuffer(cinit);
  1724. setAccelerationStructureBarrier(cmdb, blas, AccelerationStructureUsageBit::kNone, AccelerationStructureUsageBit::kBuild);
  1725. BufferInitInfo scratchInit;
  1726. scratchInit.m_size = blas->getBuildScratchBufferSize();
  1727. scratchInit.m_usage = BufferUsageBit::kAccelerationStructureBuildScratch;
  1728. BufferPtr scratchBuff = GrManager::getSingleton().newBuffer(scratchInit);
  1729. cmdb->buildAccelerationStructure(blas.get(), scratchBuff.get(), 0);
  1730. setAccelerationStructureBarrier(cmdb, blas, AccelerationStructureUsageBit::kBuild, AccelerationStructureUsageBit::kAttach);
  1731. setAccelerationStructureBarrier(cmdb, tlas, AccelerationStructureUsageBit::kNone, AccelerationStructureUsageBit::kBuild);
  1732. scratchInit.m_size = tlas->getBuildScratchBufferSize();
  1733. scratchBuff = GrManager::getSingleton().newBuffer(scratchInit);
  1734. cmdb->buildAccelerationStructure(tlas.get(), scratchBuff.get(), 0);
  1735. setAccelerationStructureBarrier(cmdb, tlas, AccelerationStructureUsageBit::kBuild, AccelerationStructureUsageBit::kFragmentRead);
  1736. cmdb->endRecording();
  1737. GrManager::getSingleton().submit(cmdb.get());
  1738. }
  1739. // Draw
  1740. constexpr U32 ITERATIONS = 200;
  1741. for(U i = 0; i < ITERATIONS; ++i)
  1742. {
  1743. HighRezTimer timer;
  1744. timer.start();
  1745. const Vec4 cameraPos(0.0f, 0.0f, 3.0f, 0.0f);
  1746. const Mat4 viewMat = Mat4(cameraPos.xyz(), Mat3::getIdentity(), Vec3(1.0f)).getInverse();
  1747. const Mat4 projMat = Mat4::calculatePerspectiveProjectionMatrix(toRad(90.0f), toRad(90.0f), 0.01f, 1000.0f);
  1748. CommandBufferInitInfo cinit;
  1749. cinit.m_flags = CommandBufferFlag::kGeneralWork | CommandBufferFlag::kSmallBatch;
  1750. CommandBufferPtr cmdb = g_gr->newCommandBuffer(cinit);
  1751. cmdb->setViewport(0, 0, WIDTH, HEIGHT);
  1752. cmdb->bindShaderProgram(prog.get());
  1753. struct PC
  1754. {
  1755. Mat4 m_vp;
  1756. Vec4 m_cameraPos;
  1757. } pc;
  1758. pc.m_vp = projMat * viewMat;
  1759. pc.m_cameraPos = cameraPos;
  1760. cmdb->setPushConstants(&pc, sizeof(pc));
  1761. if(useRayTracing)
  1762. {
  1763. cmdb->bindAccelerationStructure(0, 0, tlas.get());
  1764. }
  1765. TexturePtr presentTex = g_gr->acquireNextPresentableTexture();
  1766. FramebufferPtr fb = createColorFb(*g_gr, presentTex);
  1767. setTextureBarrier(cmdb, presentTex, TextureUsageBit::kNone, TextureUsageBit::kFramebufferWrite, TextureSubresourceInfo{});
  1768. cmdb->beginRenderPass(fb.get(), {TextureUsageBit::kFramebufferWrite}, {});
  1769. cmdb->draw(PrimitiveTopology::kTriangleStrip, 4);
  1770. cmdb->endRenderPass();
  1771. setTextureBarrier(cmdb, presentTex, TextureUsageBit::kFramebufferWrite, TextureUsageBit::kPresent, TextureSubresourceInfo{});
  1772. cmdb->endRecording();
  1773. GrManager::getSingleton().submit(cmdb.get());
  1774. g_gr->swapBuffers();
  1775. timer.stop();
  1776. const F32 TICK = 1.0f / 30.0f;
  1777. if(timer.getElapsedTime() < TICK)
  1778. {
  1779. HighRezTimer::sleep(TICK - timer.getElapsedTime());
  1780. }
  1781. }
  1782. COMMON_END();
  1783. #endif
  1784. }
  1785. static void createCubeBuffers(GrManager& gr, Vec3 min, Vec3 max, BufferPtr& indexBuffer, BufferPtr& vertBuffer, Bool turnInsideOut = false)
  1786. {
  1787. BufferInitInfo inf;
  1788. inf.m_mapAccess = BufferMapAccessBit::kWrite;
  1789. inf.m_usage = BufferUsageBit::kIndex | BufferUsageBit::kVertex | BufferUsageBit::kStorageTraceRaysRead;
  1790. inf.m_size = sizeof(Vec3) * 8;
  1791. vertBuffer = gr.newBuffer(inf);
  1792. WeakArray<Vec3, PtrSize> positions = vertBuffer->map<Vec3>(0, 8, BufferMapAccessBit::kWrite);
  1793. // 7------6
  1794. // /| /|
  1795. // 3------2 |
  1796. // | | | |
  1797. // | 4 ---|-5
  1798. // |/ |/
  1799. // 0------1
  1800. positions[0] = Vec3(min.x(), min.y(), max.z());
  1801. positions[1] = Vec3(max.x(), min.y(), max.z());
  1802. positions[2] = Vec3(max.x(), max.y(), max.z());
  1803. positions[3] = Vec3(min.x(), max.y(), max.z());
  1804. positions[4] = Vec3(min.x(), min.y(), min.z());
  1805. positions[5] = Vec3(max.x(), min.y(), min.z());
  1806. positions[6] = Vec3(max.x(), max.y(), min.z());
  1807. positions[7] = Vec3(min.x(), max.y(), min.z());
  1808. vertBuffer->unmap();
  1809. inf.m_size = sizeof(U16) * 36;
  1810. indexBuffer = gr.newBuffer(inf);
  1811. WeakArray<U16, PtrSize> indices = indexBuffer->map<U16>(0, 36, BufferMapAccessBit::kWrite);
  1812. U32 t = 0;
  1813. // Top
  1814. indices[t++] = 3;
  1815. indices[t++] = 2;
  1816. indices[t++] = 7;
  1817. indices[t++] = 2;
  1818. indices[t++] = 6;
  1819. indices[t++] = 7;
  1820. // Bottom
  1821. indices[t++] = 1;
  1822. indices[t++] = 0;
  1823. indices[t++] = 4;
  1824. indices[t++] = 1;
  1825. indices[t++] = 4;
  1826. indices[t++] = 5;
  1827. // Left
  1828. indices[t++] = 0;
  1829. indices[t++] = 3;
  1830. indices[t++] = 4;
  1831. indices[t++] = 3;
  1832. indices[t++] = 7;
  1833. indices[t++] = 4;
  1834. // Right
  1835. indices[t++] = 1;
  1836. indices[t++] = 5;
  1837. indices[t++] = 2;
  1838. indices[t++] = 2;
  1839. indices[t++] = 5;
  1840. indices[t++] = 6;
  1841. // Front
  1842. indices[t++] = 0;
  1843. indices[t++] = 1;
  1844. indices[t++] = 3;
  1845. indices[t++] = 3;
  1846. indices[t++] = 1;
  1847. indices[t++] = 2;
  1848. // Back
  1849. indices[t++] = 4;
  1850. indices[t++] = 7;
  1851. indices[t++] = 6;
  1852. indices[t++] = 5;
  1853. indices[t++] = 4;
  1854. indices[t++] = 6;
  1855. ANKI_ASSERT(t == indices.getSize());
  1856. if(turnInsideOut)
  1857. {
  1858. for(U32 i = 0; i < t; i += 3)
  1859. {
  1860. std::swap(indices[i + 1], indices[i + 2]);
  1861. }
  1862. }
  1863. indexBuffer->unmap();
  1864. }
  1865. enum class GeomWhat
  1866. {
  1867. SMALL_BOX,
  1868. BIG_BOX,
  1869. ROOM,
  1870. LIGHT,
  1871. kCount,
  1872. kFirst = 0
  1873. };
  1874. ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS(GeomWhat)
  1875. ANKI_TEST(Gr, RayGen)
  1876. {
  1877. #if 0
  1878. COMMON_BEGIN();
  1879. const Bool useRayTracing = g_gr->getDeviceCapabilities().m_rayTracingEnabled;
  1880. if(!useRayTracing)
  1881. {
  1882. ANKI_TEST_LOGW("Ray tracing not supported");
  1883. break;
  1884. }
  1885. using Mat3x4Scalar = Array2d<F32, 3, 4>;
  1886. # define MAGIC_MACRO(x) x
  1887. # include <Tests/Gr/RtTypes.h>
  1888. # undef MAGIC_MACRO
  1889. HeapMemoryPool pool(allocAligned, nullptr);
  1890. // Create the offscreen RTs
  1891. Array<TexturePtr, 2> offscreenRts;
  1892. {
  1893. TextureInitInfo inf("T_offscreen#1");
  1894. inf.m_width = WIDTH;
  1895. inf.m_height = HEIGHT;
  1896. inf.m_format = Format::kR8G8B8A8_Unorm;
  1897. inf.m_usage = TextureUsageBit::kStorageTraceRaysRead | TextureUsageBit::kStorageTraceRaysWrite | TextureUsageBit::kStorageComputeRead;
  1898. offscreenRts[0] = g_gr->newTexture(inf);
  1899. inf.setName("T_offscreen#2");
  1900. offscreenRts[1] = g_gr->newTexture(inf);
  1901. }
  1902. // Copy to present program
  1903. ShaderProgramPtr copyToPresentProg;
  1904. {
  1905. const CString src = R"(
  1906. layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
  1907. layout(set = 0, binding = 0) uniform readonly image2D u_inImg;
  1908. layout(set = 0, binding = 1) uniform writeonly image2D u_outImg;
  1909. void main()
  1910. {
  1911. const UVec2 size = UVec2(imageSize(u_inImg));
  1912. if(gl_GlobalInvocationID.x >= size.x || gl_GlobalInvocationID.y >= size.y)
  1913. {
  1914. return;
  1915. }
  1916. const Vec4 col = imageLoad(u_inImg, IVec2(gl_GlobalInvocationID.xy));
  1917. imageStore(u_outImg, IVec2(gl_GlobalInvocationID.xy), col);
  1918. })";
  1919. ShaderPtr shader = createShader(src, ShaderType::kCompute, *g_gr);
  1920. ShaderProgramInitInfo sprogInit;
  1921. sprogInit.m_computeShader = shader.get();
  1922. copyToPresentProg = g_gr->newShaderProgram(sprogInit);
  1923. }
  1924. // Create the gometries
  1925. struct Geom
  1926. {
  1927. BufferPtr m_vertexBuffer;
  1928. BufferPtr m_indexBuffer;
  1929. Aabb m_aabb;
  1930. Mat3x4 m_worldTransform;
  1931. Mat3 m_worldRotation;
  1932. Bool m_insideOut = false;
  1933. U8 m_asMask = 0b10;
  1934. AccelerationStructurePtr m_blas;
  1935. U32 m_indexCount = 36;
  1936. Vec3 m_diffuseColor = Vec3(0.0f);
  1937. Vec3 m_emissiveColor = Vec3(0.0f);
  1938. };
  1939. Array<Geom, U(GeomWhat::kCount)> geometries;
  1940. geometries[GeomWhat::SMALL_BOX].m_aabb = Aabb(Vec3(130.0f, 0.0f, 65.0f), Vec3(295.0f, 160.0f, 230.0f));
  1941. geometries[GeomWhat::SMALL_BOX].m_worldRotation = Mat3(Axisang(toRad(-18.0f), Vec3(0.0f, 1.0f, 0.0f)));
  1942. geometries[GeomWhat::SMALL_BOX].m_worldTransform =
  1943. Mat3x4(Vec3((geometries[GeomWhat::SMALL_BOX].m_aabb.getMin() + geometries[GeomWhat::SMALL_BOX].m_aabb.getMax()).xyz() / 2.0f),
  1944. geometries[GeomWhat::SMALL_BOX].m_worldRotation);
  1945. geometries[GeomWhat::SMALL_BOX].m_diffuseColor = Vec3(0.75f);
  1946. geometries[GeomWhat::BIG_BOX].m_aabb = Aabb(Vec3(265.0f, 0.0f, 295.0f), Vec3(430.0f, 330.0f, 460.0f));
  1947. geometries[GeomWhat::BIG_BOX].m_worldRotation = Mat3(Axisang(toRad(15.0f), Vec3(0.0f, 1.0f, 0.0f)));
  1948. geometries[GeomWhat::BIG_BOX].m_worldTransform =
  1949. Mat3x4(Vec3((geometries[GeomWhat::BIG_BOX].m_aabb.getMin() + geometries[GeomWhat::BIG_BOX].m_aabb.getMax()).xyz() / 2.0f),
  1950. geometries[GeomWhat::BIG_BOX].m_worldRotation);
  1951. geometries[GeomWhat::BIG_BOX].m_diffuseColor = Vec3(0.75f);
  1952. geometries[GeomWhat::ROOM].m_aabb = Aabb(Vec3(0.0f), Vec3(555.0f));
  1953. geometries[GeomWhat::ROOM].m_worldRotation = Mat3::getIdentity();
  1954. geometries[GeomWhat::ROOM].m_worldTransform =
  1955. Mat3x4(Vec3((geometries[GeomWhat::ROOM].m_aabb.getMin() + geometries[GeomWhat::ROOM].m_aabb.getMax()).xyz() / 2.0f),
  1956. geometries[GeomWhat::ROOM].m_worldRotation);
  1957. geometries[GeomWhat::ROOM].m_insideOut = true;
  1958. geometries[GeomWhat::ROOM].m_indexCount = 30;
  1959. geometries[GeomWhat::LIGHT].m_aabb = Aabb(Vec3(213.0f + 1.0f, 554.0f, 227.0f + 1.0f), Vec3(343.0f - 1.0f, 554.0f + 0.001f, 332.0f - 1.0f));
  1960. geometries[GeomWhat::LIGHT].m_worldRotation = Mat3::getIdentity();
  1961. geometries[GeomWhat::LIGHT].m_worldTransform =
  1962. Mat3x4(Vec3((geometries[GeomWhat::LIGHT].m_aabb.getMin() + geometries[GeomWhat::LIGHT].m_aabb.getMax()).xyz() / 2.0f),
  1963. geometries[GeomWhat::LIGHT].m_worldRotation);
  1964. geometries[GeomWhat::LIGHT].m_asMask = 0b01;
  1965. geometries[GeomWhat::LIGHT].m_emissiveColor = Vec3(15.0f);
  1966. // Create Buffers
  1967. for(Geom& g : geometries)
  1968. {
  1969. createCubeBuffers(*g_gr, -(g.m_aabb.getMax().xyz() - g.m_aabb.getMin().xyz()) / 2.0f,
  1970. (g.m_aabb.getMax().xyz() - g.m_aabb.getMin().xyz()) / 2.0f, g.m_indexBuffer, g.m_vertexBuffer, g.m_insideOut);
  1971. }
  1972. // Create AS
  1973. AccelerationStructurePtr tlas;
  1974. {
  1975. for(Geom& g : geometries)
  1976. {
  1977. AccelerationStructureInitInfo inf;
  1978. inf.m_type = AccelerationStructureType::kBottomLevel;
  1979. inf.m_bottomLevel.m_indexBuffer = BufferView(g.m_indexBuffer.get());
  1980. inf.m_bottomLevel.m_indexType = IndexType::kU16;
  1981. inf.m_bottomLevel.m_indexCount = g.m_indexCount;
  1982. inf.m_bottomLevel.m_positionBuffer = BufferView(g.m_vertexBuffer.get());
  1983. inf.m_bottomLevel.m_positionCount = 8;
  1984. inf.m_bottomLevel.m_positionsFormat = Format::kR32G32B32_Sfloat;
  1985. inf.m_bottomLevel.m_positionStride = sizeof(Vec3);
  1986. g.m_blas = g_gr->newAccelerationStructure(inf);
  1987. }
  1988. // TLAS
  1989. Array<AccelerationStructureInstanceInfo, U32(GeomWhat::kCount)> instances;
  1990. U32 count = 0;
  1991. for(Geom& g : geometries)
  1992. {
  1993. instances[count].m_bottomLevel = g.m_blas;
  1994. instances[count].m_transform = g.m_worldTransform;
  1995. instances[count].m_hitgroupSbtRecordIndex = count;
  1996. instances[count].m_mask = g.m_asMask;
  1997. ++count;
  1998. }
  1999. AccelerationStructureInitInfo inf;
  2000. inf.m_type = AccelerationStructureType::kTopLevel;
  2001. inf.m_topLevel.m_directArgs.m_instances = instances;
  2002. tlas = g_gr->newAccelerationStructure(inf);
  2003. }
  2004. // Create model info
  2005. BufferPtr modelBuffer;
  2006. {
  2007. BufferInitInfo inf;
  2008. inf.m_mapAccess = BufferMapAccessBit::kWrite;
  2009. inf.m_usage = BufferUsageBit::kAllStorage;
  2010. inf.m_size = sizeof(Model) * U32(GeomWhat::kCount);
  2011. modelBuffer = g_gr->newBuffer(inf);
  2012. WeakArray<Model, PtrSize> models = modelBuffer->map<Model>(0, U32(GeomWhat::kCount), BufferMapAccessBit::kWrite);
  2013. memset(&models[0], 0, inf.m_size);
  2014. for(GeomWhat i : EnumIterable<GeomWhat>())
  2015. {
  2016. const Geom& g = geometries[i];
  2017. models[U32(i)].m_mtl.m_diffuseColor = g.m_diffuseColor;
  2018. models[U32(i)].m_mtl.m_emissiveColor = g.m_emissiveColor;
  2019. models[U32(i)].m_mesh.m_indexBufferPtr = g.m_indexBuffer->getGpuAddress();
  2020. models[U32(i)].m_mesh.m_positionBufferPtr = g.m_vertexBuffer->getGpuAddress();
  2021. memcpy(&models[U32(i)].m_worldTransform, &g.m_worldTransform, sizeof(Mat3x4));
  2022. models[U32(i)].m_worldRotation = g.m_worldRotation;
  2023. }
  2024. modelBuffer->unmap();
  2025. }
  2026. // Create the ppline
  2027. ShaderProgramPtr rtProg;
  2028. constexpr U32 rayGenGroupIdx = 1;
  2029. constexpr U32 missGroupIdx = 2;
  2030. constexpr U32 shadowMissGroupIdx = 3;
  2031. constexpr U32 lambertianChitGroupIdx = 4;
  2032. constexpr U32 lambertianRoomChitGroupIdx = 5;
  2033. constexpr U32 emissiveChitGroupIdx = 6;
  2034. constexpr U32 shadowAhitGroupIdx = 7;
  2035. constexpr U32 hitgroupCount = 7;
  2036. {
  2037. const CString commonSrcPart = R"(
  2038. #define Mat3x4Scalar Mat3x4
  2039. %s
  2040. const F32 PI = 3.14159265358979323846;
  2041. struct PayLoad
  2042. {
  2043. Vec3 m_total;
  2044. Vec3 m_weight;
  2045. Vec3 m_scatteredDir;
  2046. F32 m_hitT;
  2047. };
  2048. struct ShadowPayLoad
  2049. {
  2050. F32 m_shadow;
  2051. };
  2052. layout(set = 0, binding = 0, scalar) buffer b_00
  2053. {
  2054. Model u_models[];
  2055. };
  2056. layout(set = 0, binding = 1, scalar) buffer b_01
  2057. {
  2058. Light u_lights[];
  2059. };
  2060. layout(push_constant, scalar) uniform b_pc
  2061. {
  2062. PushConstants u_regs;
  2063. };
  2064. #define PAYLOAD_LOCATION 0
  2065. #define SHADOW_PAYLOAD_LOCATION 1
  2066. ANKI_REF(U16Vec3, ANKI_SIZEOF(U16));
  2067. ANKI_REF(Vec3, ANKI_SIZEOF(F32));
  2068. Vec3 computePrimitiveNormal(Model model, U32 primitiveId)
  2069. {
  2070. const Mesh mesh = model.m_mesh;
  2071. const U32 offset = primitiveId * 6;
  2072. const U16Vec3 indices = U16Vec3Ref(nonuniformEXT(mesh.m_indexBufferPtr + offset)).m_value;
  2073. const Vec3 pos0 = Vec3Ref(nonuniformEXT(mesh.m_positionBufferPtr + indices[0] * ANKI_SIZEOF(Vec3))).m_value;
  2074. const Vec3 pos1 = Vec3Ref(nonuniformEXT(mesh.m_positionBufferPtr + indices[1] * ANKI_SIZEOF(Vec3))).m_value;
  2075. const Vec3 pos2 = Vec3Ref(nonuniformEXT(mesh.m_positionBufferPtr + indices[2] * ANKI_SIZEOF(Vec3))).m_value;
  2076. const Vec3 normal = normalize(cross(pos1 - pos0, pos2 - pos0));
  2077. return model.m_worldRotation * normal;
  2078. }
  2079. UVec3 rand3DPCG16(UVec3 v)
  2080. {
  2081. v = v * 1664525u + 1013904223u;
  2082. v.x += v.y * v.z;
  2083. v.y += v.z * v.x;
  2084. v.z += v.x * v.y;
  2085. v.x += v.y * v.z;
  2086. v.y += v.z * v.x;
  2087. v.z += v.x * v.y;
  2088. return v >> 16u;
  2089. }
  2090. Vec2 hammersleyRandom16(U32 sampleIdx, U32 sampleCount, UVec2 random)
  2091. {
  2092. const F32 e1 = fract(F32(sampleIdx) / sampleCount + F32(random.x) * (1.0 / 65536.0));
  2093. const F32 e2 = F32((bitfieldReverse(sampleIdx) >> 16) ^ random.y) * (1.0 / 65536.0);
  2094. return Vec2(e1, e2);
  2095. }
  2096. Vec3 hemisphereSampleUniform(Vec2 uv)
  2097. {
  2098. const F32 phi = uv.y * 2.0 * PI;
  2099. const F32 cosTheta = 1.0 - uv.x;
  2100. const F32 sinTheta = sqrt(1.0 - cosTheta * cosTheta);
  2101. return Vec3(cos(phi) * sinTheta, sin(phi) * sinTheta, cosTheta);
  2102. }
  2103. Mat3 rotationFromDirection(Vec3 zAxis)
  2104. {
  2105. Vec3 z = zAxis;
  2106. F32 sign = (z.z >= 0.0) ? 1.0 : -1.0;
  2107. F32 a = -1.0 / (sign + z.z);
  2108. F32 b = z.x * z.y * a;
  2109. Vec3 x = Vec3(1.0 + sign * a * pow(z.x, 2.0), sign * b, -sign * z.x);
  2110. Vec3 y = Vec3(b, sign + a * pow(z.y, 2.0), -z.y);
  2111. return Mat3(x, y, z);
  2112. }
  2113. Vec3 randomDirectionInHemisphere(Vec3 normal)
  2114. {
  2115. const UVec2 random = rand3DPCG16(UVec3(gl_LaunchIDEXT.xy, u_regs.m_frame)).xy;
  2116. const Vec2 uniformRandom = hammersleyRandom16(0, 0xFFFFu, random);
  2117. return normalize(rotationFromDirection(normal) * hemisphereSampleUniform(uniformRandom));
  2118. }
  2119. void scatterLambertian(Vec3 normal, out Vec3 scatterDir, out F32 pdf)
  2120. {
  2121. scatterDir = randomDirectionInHemisphere(normal);
  2122. pdf = dot(normal, scatterDir) / PI;
  2123. }
  2124. F32 scatteringPdfLambertian(Vec3 normal, Vec3 scatteredDir)
  2125. {
  2126. F32 cosine = dot(normal, scatteredDir);
  2127. return max(cosine / PI, 0.0);
  2128. })";
  2129. # define MAGIC_MACRO ANKI_STRINGIZE
  2130. const CString rtTypesStr =
  2131. # include <Tests/Gr/RtTypes.h>
  2132. ;
  2133. # undef MAGIC_MACRO
  2134. String commonSrc;
  2135. commonSrc.sprintf(commonSrcPart.cstr(), rtTypesStr.cstr());
  2136. const CString lambertianSrc = R"(
  2137. layout(location = PAYLOAD_LOCATION) rayPayloadInEXT PayLoad s_payLoad;
  2138. hitAttributeEXT vec2 g_attribs;
  2139. void main()
  2140. {
  2141. const Model model = u_models[nonuniformEXT(gl_InstanceID)];
  2142. const Vec3 normal = computePrimitiveNormal(model, gl_PrimitiveID);
  2143. Vec3 scatteredDir;
  2144. F32 pdf;
  2145. scatterLambertian(normal, scatteredDir, pdf);
  2146. const F32 scatteringPdf = scatteringPdfLambertian(normal, scatteredDir);
  2147. s_payLoad.m_total += model.m_mtl.m_emissiveColor * s_payLoad.m_weight;
  2148. s_payLoad.m_weight *= model.m_mtl.m_diffuseColor * scatteringPdf / pdf;
  2149. s_payLoad.m_scatteredDir = scatteredDir;
  2150. s_payLoad.m_hitT = gl_HitTEXT;
  2151. })";
  2152. const CString lambertianRoomSrc = R"(
  2153. layout(location = PAYLOAD_LOCATION) rayPayloadInEXT PayLoad s_payLoad;
  2154. void main()
  2155. {
  2156. Vec3 col;
  2157. U32 quad = gl_PrimitiveID / 2;
  2158. if(quad == 2)
  2159. {
  2160. col = Vec3(0.65, 0.05, 0.05);
  2161. }
  2162. else if(quad == 3)
  2163. {
  2164. col = Vec3(0.12, 0.45, 0.15);
  2165. }
  2166. else
  2167. {
  2168. col = Vec3(0.73f);
  2169. }
  2170. const Model model = u_models[nonuniformEXT(gl_InstanceID)];
  2171. const Vec3 normal = computePrimitiveNormal(model, gl_PrimitiveID);
  2172. Vec3 scatteredDir;
  2173. F32 pdf;
  2174. scatterLambertian(normal, scatteredDir, pdf);
  2175. const F32 scatteringPdf = scatteringPdfLambertian(normal, scatteredDir);
  2176. // Color = diff * scatteringPdf / pdf * trace(depth - 1)
  2177. s_payLoad.m_total += model.m_mtl.m_emissiveColor * s_payLoad.m_weight;
  2178. s_payLoad.m_weight *= col * scatteringPdf / pdf;
  2179. s_payLoad.m_scatteredDir = scatteredDir;
  2180. s_payLoad.m_hitT = gl_HitTEXT;
  2181. })";
  2182. const CString emissiveSrc = R"(
  2183. layout(location = PAYLOAD_LOCATION) rayPayloadInEXT PayLoad s_payLoad;
  2184. void main()
  2185. {
  2186. const Model model = u_models[nonuniformEXT(gl_InstanceID)];
  2187. s_payLoad.m_total += model.m_mtl.m_emissiveColor * s_payLoad.m_weight;
  2188. s_payLoad.m_weight = Vec3(0.0);
  2189. s_payLoad.m_scatteredDir = Vec3(1.0, 0.0, 0.0);
  2190. s_payLoad.m_hitT = -1.0;
  2191. })";
  2192. const CString missSrc = R"(
  2193. layout(location = PAYLOAD_LOCATION) rayPayloadInEXT PayLoad s_payLoad;
  2194. void main()
  2195. {
  2196. //s_payLoad.m_color =
  2197. //mix(Vec3(0.3, 0.5, 0.3), Vec3(0.1, 0.6, 0.1), F32(gl_LaunchIDEXT.y) / F32(gl_LaunchSizeEXT.y));
  2198. //Vec3(0.0);
  2199. s_payLoad.m_weight = Vec3(0.0);
  2200. s_payLoad.m_scatteredDir = Vec3(1.0, 0.0, 0.0);
  2201. s_payLoad.m_hitT = -1.0;
  2202. })";
  2203. const CString shadowAhitSrc = R"(
  2204. layout(location = SHADOW_PAYLOAD_LOCATION) rayPayloadInEXT ShadowPayLoad s_payLoad;
  2205. void main()
  2206. {
  2207. s_payLoad.m_shadow += 0.25;
  2208. //terminateRayEXT();
  2209. })";
  2210. const CString shadowChitSrc = R"(
  2211. void main()
  2212. {
  2213. })";
  2214. const CString shadowMissSrc = R"(
  2215. layout(location = SHADOW_PAYLOAD_LOCATION) rayPayloadInEXT ShadowPayLoad s_payLoad;
  2216. void main()
  2217. {
  2218. s_payLoad.m_shadow = 1.0;
  2219. })";
  2220. const CString rayGenSrc = R"(
  2221. layout(set = 1, binding = 0) uniform accelerationStructureEXT u_tlas;
  2222. layout(set = 1, binding = 1, rgba8) uniform readonly image2D u_inImg;
  2223. layout(set = 1, binding = 2, rgba8) uniform writeonly image2D u_outImg;
  2224. layout(location = PAYLOAD_LOCATION) rayPayloadEXT PayLoad s_payLoad;
  2225. layout(location = SHADOW_PAYLOAD_LOCATION) rayPayloadEXT ShadowPayLoad s_shadowPayLoad;
  2226. void main()
  2227. {
  2228. Vec2 uv = (Vec2(gl_LaunchIDEXT.xy) + 0.5) / Vec2(gl_LaunchSizeEXT.xy);
  2229. uv.y = 1.0 - uv.y;
  2230. const Vec2 ndc = uv * 2.0 - 1.0;
  2231. const Vec4 p4 = inverse(u_regs.m_vp) * Vec4(ndc, 1.0, 1.0);
  2232. const Vec3 p3 = p4.xyz / p4.w;
  2233. const UVec2 random = rand3DPCG16(UVec3(gl_LaunchIDEXT.xy, u_regs.m_frame)).xy;
  2234. const Vec2 randomCircle = hammersleyRandom16(0, 0xFFFFu, random);
  2235. Vec3 outColor = Vec3(0.0);
  2236. const U32 sampleCount = 8;
  2237. const U32 maxRecursionDepth = 2;
  2238. for(U32 s = 0; s < sampleCount; ++s)
  2239. {
  2240. Vec3 rayOrigin = u_regs.m_cameraPos;
  2241. Vec3 rayDir = normalize(p3 - u_regs.m_cameraPos);
  2242. s_payLoad.m_total = Vec3(0.0);
  2243. s_payLoad.m_weight = Vec3(1.0);
  2244. for(U32 depth = 0; depth < maxRecursionDepth; ++depth)
  2245. {
  2246. const U32 cullMask = 0xFF;
  2247. const U32 sbtRecordOffset = 0;
  2248. const U32 sbtRecordStride = 0;
  2249. const U32 missIndex = 0;
  2250. const F32 tMin = 0.1;
  2251. const F32 tMax = 10000.0;
  2252. traceRayEXT(u_tlas, gl_RayFlagsOpaqueEXT, cullMask, sbtRecordOffset, sbtRecordStride, missIndex,
  2253. rayOrigin, tMin, rayDir, tMax, PAYLOAD_LOCATION);
  2254. if(s_payLoad.m_hitT > 0.0)
  2255. {
  2256. rayOrigin = rayOrigin + rayDir * s_payLoad.m_hitT;
  2257. rayDir = s_payLoad.m_scatteredDir;
  2258. }
  2259. else
  2260. {
  2261. break;
  2262. }
  2263. }
  2264. outColor += s_payLoad.m_total + s_payLoad.m_weight;
  2265. //outColor += s_payLoad.m_scatteredDir * 0.5 + 0.5;
  2266. }
  2267. outColor /= F32(sampleCount);
  2268. #if 0
  2269. const Vec3 diffuseColor = Vec3(s_payLoad.m_diffuseColor);
  2270. const Vec3 normal = s_payLoad.m_normal;
  2271. if(s_payLoad.m_hitT > 0.0)
  2272. {
  2273. const Vec3 rayOrigin = u_regs.m_cameraPos + normalize(p3 - u_regs.m_cameraPos) * s_payLoad.m_hitT;
  2274. for(U32 i = 0; i < u_regs.m_lightCount; ++i)
  2275. {
  2276. s_shadowPayLoad.m_shadow = 0.0;
  2277. const Light light = u_lights[i];
  2278. const Vec3 randomPointInLight = mix(light.m_min, light.m_max, randomCircle.xyx);
  2279. const Vec3 rayDir = normalize(randomPointInLight - rayOrigin);
  2280. const U32 cullMask = 0x2;
  2281. const U32 sbtRecordOffset = 1;
  2282. const U32 sbtRecordStride = 0;
  2283. const U32 missIndex = 1;
  2284. const F32 tMin = 0.1;
  2285. const F32 tMax = length(randomPointInLight - rayOrigin);
  2286. const U32 flags = gl_RayFlagsOpaqueEXT;
  2287. traceRayEXT(u_tlas, flags, cullMask, sbtRecordOffset, sbtRecordStride, missIndex, rayOrigin,
  2288. tMin, rayDir, tMax, SHADOW_PAYLOAD_LOCATION);
  2289. F32 shadow = clamp(s_shadowPayLoad.m_shadow, 0.0, 1.0);
  2290. outColor += normal * light.m_intensity * shadow;
  2291. }
  2292. }
  2293. else
  2294. {
  2295. outColor = diffuseColor;
  2296. }
  2297. #endif
  2298. const Vec3 history = imageLoad(u_inImg, IVec2(gl_LaunchIDEXT.xy)).rgb;
  2299. outColor = mix(outColor, history, (u_regs.m_frame != 0) ? 0.99 : 0.0);
  2300. imageStore(u_outImg, IVec2(gl_LaunchIDEXT.xy), Vec4(outColor, 0.0));
  2301. })";
  2302. ShaderPtr lambertianShader = createShader(String().sprintf("%s\n%s", commonSrc.cstr(), lambertianSrc.cstr()), ShaderType::kClosestHit, *g_gr);
  2303. ShaderPtr lambertianRoomShader =
  2304. createShader(String().sprintf("%s\n%s", commonSrc.cstr(), lambertianRoomSrc.cstr()), ShaderType::kClosestHit, *g_gr);
  2305. ShaderPtr emissiveShader = createShader(String().sprintf("%s\n%s", commonSrc.cstr(), emissiveSrc.cstr()), ShaderType::kClosestHit, *g_gr);
  2306. ShaderPtr shadowAhitShader = createShader(String().sprintf("%s\n%s", commonSrc.cstr(), shadowAhitSrc.cstr()), ShaderType::kAnyHit, *g_gr);
  2307. ShaderPtr shadowChitShader = createShader(String().sprintf("%s\n%s", commonSrc.cstr(), shadowChitSrc.cstr()), ShaderType::kClosestHit, *g_gr);
  2308. ShaderPtr missShader = createShader(String().sprintf("%s\n%s", commonSrc.cstr(), missSrc.cstr()), ShaderType::kMiss, *g_gr);
  2309. ShaderPtr shadowMissShader = createShader(String().sprintf("%s\n%s", commonSrc.cstr(), shadowMissSrc.cstr()), ShaderType::kMiss, *g_gr);
  2310. ShaderPtr rayGenShader = createShader(String().sprintf("%s\n%s", commonSrc.cstr(), rayGenSrc.cstr()), ShaderType::kRayGen, *g_gr);
  2311. Array<RayTracingHitGroup, 4> hitGroups;
  2312. hitGroups[0].m_closestHitShader = lambertianShader.get();
  2313. hitGroups[1].m_closestHitShader = lambertianRoomShader.get();
  2314. hitGroups[2].m_closestHitShader = emissiveShader.get();
  2315. hitGroups[3].m_closestHitShader = shadowChitShader.get();
  2316. hitGroups[3].m_anyHitShader = shadowAhitShader.get();
  2317. Array<Shader*, 2> missShaders = {missShader.get(), shadowMissShader.get()};
  2318. // Add the same 2 times to test multiple ray gen shaders
  2319. Array<Shader*, 2> rayGenShaders = {rayGenShader.get(), rayGenShader.get()};
  2320. ShaderProgramInitInfo inf;
  2321. inf.m_rayTracingShaders.m_hitGroups = hitGroups;
  2322. inf.m_rayTracingShaders.m_rayGenShaders = rayGenShaders;
  2323. inf.m_rayTracingShaders.m_missShaders = missShaders;
  2324. rtProg = g_gr->newShaderProgram(inf);
  2325. }
  2326. // Create the SBT
  2327. BufferPtr sbt;
  2328. {
  2329. const U32 recordCount = 1 + 2 + U32(GeomWhat::kCount) * 2;
  2330. const U32 sbtRecordSize = g_gr->getDeviceCapabilities().m_sbtRecordAlignment;
  2331. BufferInitInfo inf;
  2332. inf.m_mapAccess = BufferMapAccessBit::kWrite;
  2333. inf.m_usage = BufferUsageBit::kShaderBindingTable;
  2334. inf.m_size = sbtRecordSize * recordCount;
  2335. sbt = g_gr->newBuffer(inf);
  2336. WeakArray<U8, PtrSize> mapped = sbt->map<U8>(0, inf.m_size, BufferMapAccessBit::kWrite);
  2337. memset(&mapped[0], 0, inf.m_size);
  2338. ConstWeakArray<U8> handles = rtProg->getShaderGroupHandles();
  2339. ANKI_TEST_EXPECT_EQ(handles.getSize(), g_gr->getDeviceCapabilities().m_shaderGroupHandleSize * (hitgroupCount + 1));
  2340. // Ray gen
  2341. U32 record = 0;
  2342. memcpy(&mapped[sbtRecordSize * record++], &handles[g_gr->getDeviceCapabilities().m_shaderGroupHandleSize * rayGenGroupIdx],
  2343. g_gr->getDeviceCapabilities().m_shaderGroupHandleSize);
  2344. // 2xMiss
  2345. memcpy(&mapped[sbtRecordSize * record++], &handles[g_gr->getDeviceCapabilities().m_shaderGroupHandleSize * missGroupIdx],
  2346. g_gr->getDeviceCapabilities().m_shaderGroupHandleSize);
  2347. memcpy(&mapped[sbtRecordSize * record++], &handles[g_gr->getDeviceCapabilities().m_shaderGroupHandleSize * shadowMissGroupIdx],
  2348. g_gr->getDeviceCapabilities().m_shaderGroupHandleSize);
  2349. // Small box
  2350. memcpy(&mapped[sbtRecordSize * record++], &handles[g_gr->getDeviceCapabilities().m_shaderGroupHandleSize * lambertianChitGroupIdx],
  2351. g_gr->getDeviceCapabilities().m_shaderGroupHandleSize);
  2352. memcpy(&mapped[sbtRecordSize * record++], &handles[g_gr->getDeviceCapabilities().m_shaderGroupHandleSize * shadowAhitGroupIdx],
  2353. g_gr->getDeviceCapabilities().m_shaderGroupHandleSize);
  2354. // Big box
  2355. memcpy(&mapped[sbtRecordSize * record++], &handles[g_gr->getDeviceCapabilities().m_shaderGroupHandleSize * lambertianChitGroupIdx],
  2356. g_gr->getDeviceCapabilities().m_shaderGroupHandleSize);
  2357. memcpy(&mapped[sbtRecordSize * record++], &handles[g_gr->getDeviceCapabilities().m_shaderGroupHandleSize * shadowAhitGroupIdx],
  2358. g_gr->getDeviceCapabilities().m_shaderGroupHandleSize);
  2359. // Room
  2360. memcpy(&mapped[sbtRecordSize * record++], &handles[g_gr->getDeviceCapabilities().m_shaderGroupHandleSize * lambertianRoomChitGroupIdx],
  2361. g_gr->getDeviceCapabilities().m_shaderGroupHandleSize);
  2362. memcpy(&mapped[sbtRecordSize * record++], &handles[g_gr->getDeviceCapabilities().m_shaderGroupHandleSize * shadowAhitGroupIdx],
  2363. g_gr->getDeviceCapabilities().m_shaderGroupHandleSize);
  2364. // Light
  2365. memcpy(&mapped[sbtRecordSize * record++], &handles[g_gr->getDeviceCapabilities().m_shaderGroupHandleSize * emissiveChitGroupIdx],
  2366. g_gr->getDeviceCapabilities().m_shaderGroupHandleSize);
  2367. memcpy(&mapped[sbtRecordSize * record++], &handles[g_gr->getDeviceCapabilities().m_shaderGroupHandleSize * shadowAhitGroupIdx],
  2368. g_gr->getDeviceCapabilities().m_shaderGroupHandleSize);
  2369. sbt->unmap();
  2370. }
  2371. // Create lights
  2372. BufferPtr lightBuffer;
  2373. constexpr U32 lightCount = 1;
  2374. {
  2375. BufferInitInfo inf;
  2376. inf.m_mapAccess = BufferMapAccessBit::kWrite;
  2377. inf.m_usage = BufferUsageBit::kAllStorage;
  2378. inf.m_size = sizeof(Light) * lightCount;
  2379. lightBuffer = g_gr->newBuffer(inf);
  2380. WeakArray<Light, PtrSize> lights = lightBuffer->map<Light>(0, lightCount, BufferMapAccessBit::kWrite);
  2381. lights[0].m_min = geometries[GeomWhat::LIGHT].m_aabb.getMin().xyz();
  2382. lights[0].m_max = geometries[GeomWhat::LIGHT].m_aabb.getMax().xyz();
  2383. lights[0].m_intensity = Vec3(1.0f);
  2384. lightBuffer->unmap();
  2385. }
  2386. // Draw
  2387. constexpr U32 ITERATIONS = 100 * 8;
  2388. for(U32 i = 0; i < ITERATIONS; ++i)
  2389. {
  2390. HighRezTimer timer;
  2391. timer.start();
  2392. const Mat4 viewMat = Mat4::lookAt(Vec3(278.0f, 278.0f, -800.0f), Vec3(278.0f, 278.0f, 0.0f), Vec3(0.0f, 1.0f, 0.0f)).getInverse();
  2393. const Mat4 projMat = Mat4::calculatePerspectiveProjectionMatrix(toRad(40.0f) * WIDTH / HEIGHT, toRad(40.0f), 0.01f, 2000.0f);
  2394. CommandBufferInitInfo cinit;
  2395. cinit.m_flags = CommandBufferFlag::kGeneralWork | CommandBufferFlag::kComputeWork | CommandBufferFlag::kSmallBatch;
  2396. CommandBufferPtr cmdb = g_gr->newCommandBuffer(cinit);
  2397. if(i == 0)
  2398. {
  2399. for(const Geom& g : geometries)
  2400. {
  2401. setAccelerationStructureBarrier(cmdb, g.m_blas, AccelerationStructureUsageBit::kNone, AccelerationStructureUsageBit::kBuild);
  2402. }
  2403. for(const Geom& g : geometries)
  2404. {
  2405. BufferInitInfo scratchInit;
  2406. scratchInit.m_size = g.m_blas->getBuildScratchBufferSize();
  2407. scratchInit.m_usage = BufferUsageBit::kAccelerationStructureBuildScratch;
  2408. BufferPtr scratchBuff = GrManager::getSingleton().newBuffer(scratchInit);
  2409. cmdb->buildAccelerationStructure(g.m_blas.get(), BufferView(scratchBuff.get()));
  2410. }
  2411. for(const Geom& g : geometries)
  2412. {
  2413. setAccelerationStructureBarrier(cmdb, g.m_blas, AccelerationStructureUsageBit::kBuild, AccelerationStructureUsageBit::kAttach);
  2414. }
  2415. setAccelerationStructureBarrier(cmdb, tlas, AccelerationStructureUsageBit::kNone, AccelerationStructureUsageBit::kBuild);
  2416. BufferInitInfo scratchInit;
  2417. scratchInit.m_size = tlas->getBuildScratchBufferSize();
  2418. scratchInit.m_usage = BufferUsageBit::kAccelerationStructureBuildScratch;
  2419. BufferPtr scratchBuff = GrManager::getSingleton().newBuffer(scratchInit);
  2420. cmdb->buildAccelerationStructure(tlas.get(), BufferView(scratchBuff.get()));
  2421. setAccelerationStructureBarrier(cmdb, tlas, AccelerationStructureUsageBit::kBuild, AccelerationStructureUsageBit::kTraceRaysRead);
  2422. }
  2423. TexturePtr presentTex = g_gr->acquireNextPresentableTexture();
  2424. TextureViewPtr presentView;
  2425. {
  2426. TextureViewInitInfo inf;
  2427. inf.m_texture = presentTex.get();
  2428. presentView = g_gr->newTextureView(inf);
  2429. }
  2430. TextureViewPtr offscreenView, offscreenHistoryView;
  2431. {
  2432. TextureViewInitInfo inf;
  2433. inf.m_texture = offscreenRts[i & 1].get();
  2434. offscreenView = g_gr->newTextureView(inf);
  2435. inf.m_texture = offscreenRts[(i + 1) & 1].get();
  2436. offscreenHistoryView = g_gr->newTextureView(inf);
  2437. }
  2438. setTextureBarrier(cmdb, offscreenRts[i & 1], TextureUsageBit::kNone, TextureUsageBit::kStorageTraceRaysWrite, TextureSubresourceInfo());
  2439. setTextureBarrier(cmdb, offscreenRts[(i + 1) & 1], TextureUsageBit::kStorageComputeRead, TextureUsageBit::kStorageTraceRaysRead,
  2440. TextureSubresourceInfo());
  2441. cmdb->bindStorageBuffer(0, 0, BufferView(modelBuffer.get()));
  2442. cmdb->bindStorageBuffer(0, 1, BufferView(lightBuffer.get()));
  2443. cmdb->bindAccelerationStructure(1, 0, tlas.get());
  2444. cmdb->bindStorageTexture(1, 1, offscreenHistoryView.get());
  2445. cmdb->bindStorageTexture(1, 2, offscreenView.get());
  2446. cmdb->bindShaderProgram(rtProg.get());
  2447. PushConstants pc;
  2448. pc.m_vp = projMat * viewMat;
  2449. pc.m_cameraPos = Vec3(278.0f, 278.0f, -800.0f);
  2450. pc.m_lightCount = lightCount;
  2451. pc.m_frame = i;
  2452. cmdb->setPushConstants(&pc, sizeof(pc));
  2453. const U32 sbtRecordSize = g_gr->getDeviceCapabilities().m_sbtRecordAlignment;
  2454. cmdb->traceRays(BufferView(sbt.get()), sbtRecordSize, U32(GeomWhat::kCount) * 2, 2, WIDTH, HEIGHT, 1);
  2455. // Copy to present
  2456. setTextureBarrier(cmdb, offscreenRts[i & 1], TextureUsageBit::kStorageTraceRaysWrite, TextureUsageBit::kStorageComputeRead,
  2457. TextureSubresourceInfo());
  2458. setTextureBarrier(cmdb, presentTex, TextureUsageBit::kNone, TextureUsageBit::kStorageComputeWrite, TextureSubresourceInfo());
  2459. cmdb->bindStorageTexture(0, 0, offscreenView.get());
  2460. cmdb->bindStorageTexture(0, 1, presentView.get());
  2461. cmdb->bindShaderProgram(copyToPresentProg.get());
  2462. const U32 sizeX = (WIDTH + 8 - 1) / 8;
  2463. const U32 sizeY = (HEIGHT + 8 - 1) / 8;
  2464. cmdb->dispatchCompute(sizeX, sizeY, 1);
  2465. setTextureBarrier(cmdb, presentTex, TextureUsageBit::kStorageComputeWrite, TextureUsageBit::kPresent, TextureSubresourceInfo());
  2466. cmdb->endRecording();
  2467. GrManager::getSingleton().submit(cmdb.get());
  2468. g_gr->swapBuffers();
  2469. timer.stop();
  2470. const F32 TICK = 1.0f / 60.0f;
  2471. if(timer.getElapsedTime() < TICK)
  2472. {
  2473. HighRezTimer::sleep(TICK - timer.getElapsedTime());
  2474. }
  2475. }
  2476. COMMON_END();
  2477. #endif
  2478. }
  2479. ANKI_TEST(Gr, AsyncCompute)
  2480. {
  2481. #if 0
  2482. COMMON_BEGIN()
  2483. constexpr U32 ARRAY_SIZE = 1000 * 1024 * 8;
  2484. // Create the counting program
  2485. static const char* PROG_SRC = R"(
  2486. layout(local_size_x = 8) in;
  2487. layout(binding = 0, std430) buffer b_buff
  2488. {
  2489. U32 u_counters[];
  2490. };
  2491. void main()
  2492. {
  2493. for(U32 i = 0u; i < gl_LocalInvocationID.x * 20u; ++i)
  2494. {
  2495. atomicAdd(u_counters[gl_GlobalInvocationID.x], i + 1u);
  2496. }
  2497. })";
  2498. ShaderPtr shader = createShader(PROG_SRC, ShaderType::kCompute, *g_gr);
  2499. ShaderProgramInitInfo sprogInit;
  2500. sprogInit.m_computeShader = shader.get();
  2501. ShaderProgramPtr incrementProg = g_gr->newShaderProgram(sprogInit);
  2502. // Create the check program
  2503. static const char* CHECK_SRC = R"(
  2504. layout(local_size_x = 8) in;
  2505. layout(binding = 0, std430) buffer b_buff
  2506. {
  2507. U32 u_counters[];
  2508. };
  2509. void main()
  2510. {
  2511. // Walk the atomics in reverse to make sure that this dispatch won't overlap with the previous one
  2512. const U32 newGlobalInvocationID = gl_NumWorkGroups.x * gl_WorkGroupSize.x - gl_GlobalInvocationID.x - 1u;
  2513. U32 expectedVal = 0u;
  2514. for(U32 i = 0u; i < (newGlobalInvocationID % gl_WorkGroupSize.x) * 20u; ++i)
  2515. {
  2516. expectedVal += i + 1u;
  2517. }
  2518. atomicCompSwap(u_counters[newGlobalInvocationID], expectedVal, 4u);
  2519. })";
  2520. shader = createShader(CHECK_SRC, ShaderType::kCompute, *g_gr);
  2521. sprogInit.m_computeShader = shader.get();
  2522. ShaderProgramPtr checkProg = g_gr->newShaderProgram(sprogInit);
  2523. // Create buffers
  2524. BufferInitInfo info;
  2525. info.m_size = sizeof(U32) * ARRAY_SIZE;
  2526. info.m_usage = BufferUsageBit::kAllCompute;
  2527. info.m_mapAccess = BufferMapAccessBit::kWrite | BufferMapAccessBit::kRead;
  2528. BufferPtr atomicsBuffer = g_gr->newBuffer(info);
  2529. U32* values = static_cast<U32*>(atomicsBuffer->map(0, kMaxPtrSize, BufferMapAccessBit::kRead | BufferMapAccessBit::kWrite));
  2530. memset(values, 0, info.m_size);
  2531. // Pre-create some CPU result buffers
  2532. DynamicArray<U32> atomicsBufferCpu;
  2533. atomicsBufferCpu.resize(ARRAY_SIZE);
  2534. DynamicArray<U32> expectedResultsBufferCpu;
  2535. expectedResultsBufferCpu.resize(ARRAY_SIZE);
  2536. for(U32 i = 0; i < ARRAY_SIZE; ++i)
  2537. {
  2538. const U32 localInvocation = i % 8;
  2539. U32 expectedVal = 4;
  2540. for(U32 j = 0; j < localInvocation * 20; ++j)
  2541. {
  2542. expectedVal += j + 1;
  2543. }
  2544. expectedResultsBufferCpu[i] = expectedVal;
  2545. }
  2546. // Create the 1st command buffer
  2547. CommandBufferInitInfo cinit;
  2548. cinit.m_flags = CommandBufferFlag::kComputeWork | CommandBufferFlag::kSmallBatch;
  2549. CommandBufferPtr incrementCmdb = g_gr->newCommandBuffer(cinit);
  2550. incrementCmdb->bindShaderProgram(incrementProg.get());
  2551. incrementCmdb->bindStorageBuffer(0, 0, BufferView(atomicsBuffer.get()));
  2552. incrementCmdb->dispatchCompute(ARRAY_SIZE / 8, 1, 1);
  2553. // Create the 2nd command buffer
  2554. cinit.m_flags = CommandBufferFlag::kGeneralWork | CommandBufferFlag::kSmallBatch;
  2555. CommandBufferPtr checkCmdb = g_gr->newCommandBuffer(cinit);
  2556. checkCmdb->bindShaderProgram(checkProg.get());
  2557. checkCmdb->bindStorageBuffer(0, 0, BufferView(atomicsBuffer.get()));
  2558. checkCmdb->dispatchCompute(ARRAY_SIZE / 8, 1, 1);
  2559. // Create the 3rd command buffer
  2560. cinit.m_flags = CommandBufferFlag::kComputeWork | CommandBufferFlag::kSmallBatch;
  2561. CommandBufferPtr incrementCmdb2 = g_gr->newCommandBuffer(cinit);
  2562. incrementCmdb2->bindShaderProgram(incrementProg.get());
  2563. incrementCmdb2->bindStorageBuffer(0, 0, BufferView(atomicsBuffer.get()));
  2564. incrementCmdb2->dispatchCompute(ARRAY_SIZE / 8, 1, 1);
  2565. // Submit
  2566. # if 1
  2567. FencePtr fence;
  2568. incrementCmdb->endRecording();
  2569. GrManager::getSingleton().submit(incrementCmdb.get(), {}, &fence);
  2570. checkCmdb->endRecording();
  2571. Fence* pFence = fence.get();
  2572. GrManager::getSingleton().submit(checkCmdb.get(), {&pFence, 1}, &fence);
  2573. incrementCmdb2->endRecording();
  2574. pFence = fence.get();
  2575. GrManager::getSingleton().submit(incrementCmdb2.get(), {&pFence, 1}, &fence);
  2576. fence->clientWait(kMaxSecond);
  2577. # else
  2578. incrementCmdb->flush();
  2579. gr->finish();
  2580. checkCmdb->flush();
  2581. gr->finish();
  2582. incrementCmdb2->flush();
  2583. gr->finish();
  2584. # endif
  2585. // Verify
  2586. memcpy(atomicsBufferCpu.getBegin(), values, atomicsBufferCpu.getSizeInBytes());
  2587. Bool correct = true;
  2588. for(U32 i = 0; i < ARRAY_SIZE; ++i)
  2589. {
  2590. correct = correct && atomicsBufferCpu[i] == expectedResultsBufferCpu[i];
  2591. if(!correct)
  2592. {
  2593. printf("%u!=%u %u\n", atomicsBufferCpu[i], expectedResultsBufferCpu[i], i);
  2594. break;
  2595. }
  2596. }
  2597. atomicsBuffer->unmap();
  2598. ANKI_TEST_EXPECT_EQ(correct, true);
  2599. COMMON_END()
  2600. #endif
  2601. }