2
0

Gr.cpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239
  1. // Copyright (C) 2009-2016, 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 <anki/Gr.h>
  7. #include <anki/core/NativeWindow.h>
  8. #include <anki/core/Config.h>
  9. #include <anki/util/HighRezTimer.h>
  10. namespace anki
  11. {
  12. const U WIDTH = 1024;
  13. const U HEIGHT = 768;
  14. static const char* VERT_SRC = R"(
  15. out gl_PerVertex
  16. {
  17. vec4 gl_Position;
  18. };
  19. void main()
  20. {
  21. const vec2 POSITIONS[3] = vec2[](vec2(-1.0, 1.0), vec2(0.0, -1.0), vec2(1.0, 1.0));
  22. ANKI_WRITE_POSITION(vec4(POSITIONS[gl_VertexID % 3], 0.0, 1.0));
  23. })";
  24. static const char* VERT_UBO_SRC = R"(
  25. out gl_PerVertex
  26. {
  27. vec4 gl_Position;
  28. };
  29. layout(ANKI_UBO_BINDING(0, 0)) uniform u0_
  30. {
  31. vec4 u_color[3];
  32. };
  33. layout(ANKI_UBO_BINDING(0, 1)) uniform u1_
  34. {
  35. vec4 u_rotation2d;
  36. };
  37. layout(location = 0) out vec3 out_color;
  38. void main()
  39. {
  40. out_color = u_color[gl_VertexID].rgb;
  41. const vec2 POSITIONS[3] = vec2[](vec2(-1.0, 1.0), vec2(0.0, -1.0), vec2(1.0, 1.0));
  42. mat2 rot = mat2(
  43. u_rotation2d.x, u_rotation2d.y, u_rotation2d.z, u_rotation2d.w);
  44. vec2 pos = rot * POSITIONS[gl_VertexID % 3];
  45. gl_Position = vec4(pos, 0.0, 1.0);
  46. })";
  47. static const char* VERT_INP_SRC = R"(
  48. layout(location = 0) in vec3 in_position;
  49. layout(location = 1) in vec3 in_color0;
  50. layout(location = 2) in vec3 in_color1;
  51. out gl_PerVertex
  52. {
  53. vec4 gl_Position;
  54. };
  55. layout(location = 0) out vec3 out_color0;
  56. layout(location = 1) out vec3 out_color1;
  57. void main()
  58. {
  59. gl_Position = vec4(in_position, 1.0);
  60. out_color0 = in_color0;
  61. out_color1 = in_color1;
  62. })";
  63. static const char* VERT_QUAD_SRC = R"(
  64. out gl_PerVertex
  65. {
  66. vec4 gl_Position;
  67. };
  68. layout(location = 0) out vec2 out_uv;
  69. void main()
  70. {
  71. const vec2 POSITIONS[6] =
  72. vec2[](vec2(-1.0, 1.0), vec2(-1.0, -1.0), vec2(1.0, -1.0),
  73. vec2(1.0, -1.0), vec2(1.0, 1.0), vec2(-1.0, 1.0));
  74. ANKI_WRITE_POSITION(vec4(POSITIONS[gl_VertexID], 0.0, 1.0));
  75. out_uv = POSITIONS[gl_VertexID] / 2.0 + 0.5;
  76. })";
  77. static const char* VERT_MRT_SRC = R"(
  78. out gl_PerVertex
  79. {
  80. vec4 gl_Position;
  81. };
  82. layout(location = 0) in vec3 in_pos;
  83. layout(ANKI_UBO_BINDING(0, 0), std140, row_major) uniform u0_
  84. {
  85. mat4 u_mvp;
  86. };
  87. void main()
  88. {
  89. ANKI_WRITE_POSITION(u_mvp * vec4(in_pos, 1.0));
  90. })";
  91. static const char* FRAG_SRC = R"(layout (location = 0) out vec4 out_color;
  92. void main()
  93. {
  94. out_color = vec4(0.5);
  95. })";
  96. static const char* FRAG_UBO_SRC = R"(layout (location = 0) out vec4 out_color;
  97. layout(location = 0) in vec3 in_color;
  98. void main()
  99. {
  100. out_color = vec4(in_color, 1.0);
  101. })";
  102. static const char* FRAG_INP_SRC = R"(layout (location = 0) out vec4 out_color;
  103. layout(location = 0) in vec3 in_color0;
  104. layout(location = 1) in vec3 in_color1;
  105. void main()
  106. {
  107. out_color = vec4(in_color0 + in_color1, 1.0);
  108. })";
  109. static const char* FRAG_TEX_SRC = R"(layout (location = 0) out vec4 out_color;
  110. layout(location = 0) in vec2 in_uv;
  111. layout(ANKI_TEX_BINDING(0, 0)) uniform sampler2D u_tex0;
  112. layout(ANKI_TEX_BINDING(0, 1)) uniform sampler2D u_tex1;
  113. ANKI_USING_FRAG_COORD(768)
  114. void main()
  115. {
  116. if(anki_fragCoord.x < 1024 / 2)
  117. {
  118. if(anki_fragCoord.y < 768 / 2)
  119. {
  120. vec2 uv = in_uv * 2.0;
  121. out_color = textureLod(u_tex0, uv, 0.0);
  122. }
  123. else
  124. {
  125. vec2 uv = in_uv * 2.0 - vec2(0.0, 1.0);
  126. out_color = textureLod(u_tex0, uv, 1.0);
  127. }
  128. }
  129. else
  130. {
  131. if(anki_fragCoord.y < 768 / 2)
  132. {
  133. vec2 uv = in_uv * 2.0 - vec2(1.0, 0.0);
  134. out_color = textureLod(u_tex1, uv, 0.0);
  135. }
  136. else
  137. {
  138. vec2 uv = in_uv * 2.0 - vec2(1.0, 1.0);
  139. out_color = textureLod(u_tex1, uv, 1.0);
  140. }
  141. }
  142. })";
  143. static const char* FRAG_TEX3D_SRC = R"(layout (location = 0) out vec4 out_color;
  144. layout(ANKI_UBO_BINDING(0, 0)) uniform u0_
  145. {
  146. vec4 u_uv;
  147. };
  148. layout(ANKI_TEX_BINDING(0, 0)) uniform sampler3D u_tex;
  149. void main()
  150. {
  151. out_color = textureLod(u_tex, u_uv.xyz, u_uv.w);
  152. })";
  153. static const char* FRAG_MRT_SRC = R"(layout (location = 0) out vec4 out_color0;
  154. layout (location = 1) out vec4 out_color1;
  155. layout(ANKI_UBO_BINDING(0, 1), std140) uniform u1_
  156. {
  157. vec4 u_color0;
  158. vec4 u_color1;
  159. };
  160. void main()
  161. {
  162. out_color0 = u_color0;
  163. out_color1 = u_color1;
  164. })";
  165. static const char* FRAG_MRT2_SRC = R"(layout (location = 0) out vec4 out_color;
  166. layout(location = 0) in vec2 in_uv;
  167. layout(ANKI_TEX_BINDING(0, 0)) uniform sampler2D u_tex0;
  168. layout(ANKI_TEX_BINDING(0, 1)) uniform sampler2D u_tex1;
  169. void main()
  170. {
  171. vec2 uv = in_uv;
  172. #ifdef ANKI_VK
  173. uv.y = 1.0 - uv.y;
  174. #endif
  175. float factor = uv.x;
  176. vec3 col0 = texture(u_tex0, uv).rgb;
  177. vec3 col1 = texture(u_tex1, uv).rgb;
  178. out_color = vec4(col1 + col0, 1.0);
  179. })";
  180. static const char* FRAG_SIMPLE_TEX_SRC = R"(
  181. layout (location = 0) out vec4 out_color;
  182. layout(location = 0) in vec2 in_uv;
  183. layout(ANKI_TEX_BINDING(0, 0)) uniform sampler2D u_tex0;
  184. void main()
  185. {
  186. out_color = textureLod(u_tex0, in_uv, 1.0);
  187. })";
  188. static const char* COMP_WRITE_IMAGE_SRC = R"(
  189. layout(ANKI_IMAGE_BINDING(0, 0), rgba8) writeonly uniform image2D u_img;
  190. layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
  191. layout(ANKI_SS_BINDING(1, 0)) buffer ss1_
  192. {
  193. vec4 u_color;
  194. };
  195. void main()
  196. {
  197. imageStore(u_img, ivec2(gl_WorkGroupID.x, gl_WorkGroupID.y), u_color);
  198. })";
  199. #define COMMON_BEGIN() \
  200. NativeWindow* win = nullptr; \
  201. GrManager* gr = nullptr; \
  202. createGrManager(win, gr); \
  203. {
  204. #define COMMON_END() \
  205. } \
  206. delete gr; \
  207. delete win;
  208. const PixelFormat DS_FORMAT = PixelFormat(ComponentFormat::D24S8, TransformFormat::UNORM);
  209. static NativeWindow* createWindow()
  210. {
  211. HeapAllocator<U8> alloc(allocAligned, nullptr);
  212. NativeWindowInitInfo inf;
  213. inf.m_width = WIDTH;
  214. inf.m_height = HEIGHT;
  215. NativeWindow* win = new NativeWindow();
  216. ANKI_TEST_EXPECT_NO_ERR(win->init(inf, alloc));
  217. return win;
  218. }
  219. static void createGrManager(NativeWindow*& win, GrManager*& gr)
  220. {
  221. win = createWindow();
  222. gr = new GrManager();
  223. Config cfg;
  224. cfg.set("debugContext", true);
  225. cfg.set("vsync", false);
  226. GrManagerInitInfo inf;
  227. inf.m_allocCallback = allocAligned;
  228. inf.m_cacheDirectory = "./";
  229. inf.m_config = &cfg;
  230. inf.m_window = win;
  231. ANKI_TEST_EXPECT_NO_ERR(gr->init(inf));
  232. }
  233. static ShaderProgramPtr createProgram(CString vertSrc, CString fragSrc, GrManager& gr)
  234. {
  235. ShaderPtr vert = gr.newInstance<Shader>(ShaderType::VERTEX, vertSrc);
  236. ShaderPtr frag = gr.newInstance<Shader>(ShaderType::FRAGMENT, fragSrc);
  237. return gr.newInstance<ShaderProgram>(vert, frag);
  238. }
  239. static FramebufferPtr createDefaultFb(GrManager& gr)
  240. {
  241. FramebufferInitInfo fbinit;
  242. fbinit.m_colorAttachmentCount = 1;
  243. fbinit.m_colorAttachments[0].m_clearValue.m_colorf = {{1.0, 0.0, 1.0, 1.0}};
  244. return gr.newInstance<Framebuffer>(fbinit);
  245. }
  246. static void createCube(GrManager& gr, BufferPtr& verts, BufferPtr& indices)
  247. {
  248. static const Array<F32, 8 * 3> pos = {
  249. {1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1}};
  250. static const Array<U16, 6 * 2 * 3> idx = {
  251. {0, 1, 3, 3, 1, 2, 1, 5, 6, 1, 6, 2, 7, 4, 0, 7, 0, 3, 6, 5, 7, 7, 5, 4, 0, 4, 5, 0, 5, 1, 3, 2, 6, 3, 6, 7}};
  252. verts = gr.newInstance<Buffer>(sizeof(pos), BufferUsageBit::VERTEX, BufferMapAccessBit::WRITE);
  253. void* mapped = verts->map(0, sizeof(pos), BufferMapAccessBit::WRITE);
  254. memcpy(mapped, &pos[0], sizeof(pos));
  255. verts->unmap();
  256. indices = gr.newInstance<Buffer>(sizeof(idx), BufferUsageBit::INDEX, BufferMapAccessBit::WRITE);
  257. mapped = indices->map(0, sizeof(idx), BufferMapAccessBit::WRITE);
  258. memcpy(mapped, &idx[0], sizeof(idx));
  259. indices->unmap();
  260. }
  261. ANKI_TEST(Gr, GrManager)
  262. {
  263. COMMON_BEGIN()
  264. COMMON_END()
  265. }
  266. ANKI_TEST(Gr, Shader)
  267. {
  268. COMMON_BEGIN()
  269. ShaderPtr shader = gr->newInstance<Shader>(ShaderType::VERTEX, VERT_SRC);
  270. COMMON_END()
  271. }
  272. ANKI_TEST(Gr, ShaderProgram)
  273. {
  274. COMMON_BEGIN()
  275. ShaderProgramPtr ppline = createProgram(VERT_SRC, FRAG_SRC, *gr);
  276. COMMON_END()
  277. }
  278. ANKI_TEST(Gr, SimpleDrawcall)
  279. {
  280. COMMON_BEGIN()
  281. ShaderProgramPtr prog = createProgram(VERT_SRC, FRAG_SRC, *gr);
  282. FramebufferPtr fb = createDefaultFb(*gr);
  283. U iterations = 100;
  284. while(iterations--)
  285. {
  286. HighRezTimer timer;
  287. timer.start();
  288. gr->beginFrame();
  289. CommandBufferInitInfo cinit;
  290. cinit.m_flags = CommandBufferFlag::GRAPHICS_WORK;
  291. CommandBufferPtr cmdb = gr->newInstance<CommandBuffer>(cinit);
  292. cmdb->setViewport(0, 0, WIDTH, HEIGHT);
  293. cmdb->bindShaderProgram(prog);
  294. cmdb->beginRenderPass(fb);
  295. cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 3);
  296. cmdb->endRenderPass();
  297. cmdb->flush();
  298. gr->swapBuffers();
  299. timer.stop();
  300. const F32 TICK = 1.0 / 30.0;
  301. if(timer.getElapsedTime() < TICK)
  302. {
  303. HighRezTimer::sleep(TICK - timer.getElapsedTime());
  304. }
  305. }
  306. COMMON_END()
  307. }
  308. ANKI_TEST(Gr, Buffer)
  309. {
  310. COMMON_BEGIN()
  311. BufferPtr a = gr->newInstance<Buffer>(512, BufferUsageBit::UNIFORM_ALL, BufferMapAccessBit::NONE);
  312. BufferPtr b =
  313. gr->newInstance<Buffer>(64, BufferUsageBit::STORAGE_ALL, BufferMapAccessBit::WRITE | BufferMapAccessBit::READ);
  314. void* ptr = b->map(0, 64, BufferMapAccessBit::WRITE);
  315. ANKI_TEST_EXPECT_NEQ(ptr, nullptr);
  316. U8 ptr2[64];
  317. memset(ptr, 0xCC, 64);
  318. memset(ptr2, 0xCC, 64);
  319. b->unmap();
  320. ptr = b->map(0, 64, BufferMapAccessBit::READ);
  321. ANKI_TEST_EXPECT_NEQ(ptr, nullptr);
  322. ANKI_TEST_EXPECT_EQ(memcmp(ptr, ptr2, 64), 0);
  323. b->unmap();
  324. COMMON_END()
  325. }
  326. ANKI_TEST(Gr, DrawWithUniforms)
  327. {
  328. COMMON_BEGIN()
  329. // A non-uploaded buffer
  330. BufferPtr b = gr->newInstance<Buffer>(sizeof(Vec4) * 3, BufferUsageBit::UNIFORM_ALL, BufferMapAccessBit::WRITE);
  331. Vec4* ptr = static_cast<Vec4*>(b->map(0, sizeof(Vec4) * 3, BufferMapAccessBit::WRITE));
  332. ANKI_TEST_EXPECT_NEQ(ptr, nullptr);
  333. ptr[0] = Vec4(1.0, 0.0, 0.0, 0.0);
  334. ptr[1] = Vec4(0.0, 1.0, 0.0, 0.0);
  335. ptr[2] = Vec4(0.0, 0.0, 1.0, 0.0);
  336. b->unmap();
  337. // Progm
  338. ShaderProgramPtr prog = createProgram(VERT_UBO_SRC, FRAG_UBO_SRC, *gr);
  339. // FB
  340. FramebufferPtr fb = createDefaultFb(*gr);
  341. const U ITERATION_COUNT = 100;
  342. U iterations = ITERATION_COUNT;
  343. while(iterations--)
  344. {
  345. HighRezTimer timer;
  346. timer.start();
  347. gr->beginFrame();
  348. // Uploaded buffer
  349. TransientMemoryToken token;
  350. Vec4* rotMat =
  351. static_cast<Vec4*>(gr->allocateFrameTransientMemory(sizeof(Vec4), BufferUsageBit::UNIFORM_ALL, token));
  352. F32 angle = toRad(360.0f / ITERATION_COUNT * iterations);
  353. (*rotMat)[0] = cos(angle);
  354. (*rotMat)[1] = -sin(angle);
  355. (*rotMat)[2] = sin(angle);
  356. (*rotMat)[3] = cos(angle);
  357. CommandBufferInitInfo cinit;
  358. CommandBufferPtr cmdb = gr->newInstance<CommandBuffer>(cinit);
  359. cmdb->setViewport(0, 0, WIDTH, HEIGHT);
  360. cmdb->bindShaderProgram(prog);
  361. cmdb->beginRenderPass(fb);
  362. cmdb->bindUniformBuffer(0, 0, b, 0);
  363. cmdb->bindUniformBuffer(0, 1, token);
  364. cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 3);
  365. cmdb->endRenderPass();
  366. cmdb->flush();
  367. gr->swapBuffers();
  368. timer.stop();
  369. const F32 TICK = 1.0 / 30.0;
  370. if(timer.getElapsedTime() < TICK)
  371. {
  372. HighRezTimer::sleep(TICK - timer.getElapsedTime());
  373. }
  374. }
  375. COMMON_END()
  376. }
  377. ANKI_TEST(Gr, DrawWithVertex)
  378. {
  379. COMMON_BEGIN()
  380. // The buffers
  381. struct Vert
  382. {
  383. Vec3 m_pos;
  384. Array<U8, 4> m_color;
  385. };
  386. static_assert(sizeof(Vert) == sizeof(Vec4), "See file");
  387. BufferPtr b = gr->newInstance<Buffer>(sizeof(Vert) * 3, BufferUsageBit::VERTEX, BufferMapAccessBit::WRITE);
  388. Vert* ptr = static_cast<Vert*>(b->map(0, sizeof(Vert) * 3, BufferMapAccessBit::WRITE));
  389. ANKI_TEST_EXPECT_NEQ(ptr, nullptr);
  390. ptr[0].m_pos = Vec3(-1.0, 1.0, 0.0);
  391. ptr[1].m_pos = Vec3(0.0, -1.0, 0.0);
  392. ptr[2].m_pos = Vec3(1.0, 1.0, 0.0);
  393. ptr[0].m_color = {{255, 0, 0}};
  394. ptr[1].m_color = {{0, 255, 0}};
  395. ptr[2].m_color = {{0, 0, 255}};
  396. b->unmap();
  397. BufferPtr c = gr->newInstance<Buffer>(sizeof(Vec3) * 3, BufferUsageBit::VERTEX, BufferMapAccessBit::WRITE);
  398. Vec3* otherColor = static_cast<Vec3*>(c->map(0, sizeof(Vec3) * 3, BufferMapAccessBit::WRITE));
  399. otherColor[0] = Vec3(0.0, 1.0, 1.0);
  400. otherColor[1] = Vec3(1.0, 0.0, 1.0);
  401. otherColor[2] = Vec3(1.0, 1.0, 0.0);
  402. c->unmap();
  403. // Prog
  404. ShaderProgramPtr prog = createProgram(VERT_INP_SRC, FRAG_INP_SRC, *gr);
  405. // FB
  406. FramebufferPtr fb = createDefaultFb(*gr);
  407. U iterations = 100;
  408. while(iterations--)
  409. {
  410. HighRezTimer timer;
  411. timer.start();
  412. gr->beginFrame();
  413. CommandBufferInitInfo cinit;
  414. cinit.m_flags = CommandBufferFlag::GRAPHICS_WORK;
  415. CommandBufferPtr cmdb = gr->newInstance<CommandBuffer>(cinit);
  416. cmdb->bindVertexBuffer(0, b, 0, sizeof(Vert));
  417. cmdb->bindVertexBuffer(1, c, 0, sizeof(Vec3));
  418. cmdb->setVertexAttribute(0, 0, PixelFormat(ComponentFormat::R32G32B32, TransformFormat::FLOAT), 0);
  419. cmdb->setVertexAttribute(1, 0, PixelFormat(ComponentFormat::R8G8B8, TransformFormat::UNORM), sizeof(Vec3));
  420. cmdb->setVertexAttribute(2, 1, PixelFormat(ComponentFormat::R32G32B32, TransformFormat::FLOAT), 0);
  421. cmdb->setViewport(0, 0, WIDTH, HEIGHT);
  422. cmdb->setPolygonOffset(0.0, 0.0);
  423. cmdb->bindShaderProgram(prog);
  424. cmdb->beginRenderPass(fb);
  425. cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 3);
  426. cmdb->endRenderPass();
  427. cmdb->flush();
  428. gr->swapBuffers();
  429. timer.stop();
  430. const F32 TICK = 1.0 / 30.0;
  431. if(timer.getElapsedTime() < TICK)
  432. {
  433. HighRezTimer::sleep(TICK - timer.getElapsedTime());
  434. }
  435. }
  436. COMMON_END()
  437. }
  438. ANKI_TEST(Gr, Sampler)
  439. {
  440. COMMON_BEGIN()
  441. SamplerInitInfo init;
  442. SamplerPtr b = gr->newInstance<Sampler>(init);
  443. COMMON_END()
  444. }
  445. ANKI_TEST(Gr, Texture)
  446. {
  447. COMMON_BEGIN()
  448. TextureInitInfo init;
  449. init.m_depth = 1;
  450. init.m_format = PixelFormat(ComponentFormat::R8G8B8, TransformFormat::UNORM);
  451. init.m_usage = TextureUsageBit::SAMPLED_FRAGMENT;
  452. init.m_height = 4;
  453. init.m_width = 4;
  454. init.m_mipmapsCount = 2;
  455. init.m_depth = 1;
  456. init.m_layerCount = 1;
  457. init.m_samples = 1;
  458. init.m_sampling.m_minMagFilter = SamplingFilter::LINEAR;
  459. init.m_sampling.m_mipmapFilter = SamplingFilter::LINEAR;
  460. init.m_type = TextureType::_2D;
  461. TexturePtr b = gr->newInstance<Texture>(init);
  462. COMMON_END()
  463. }
  464. ANKI_TEST(Gr, DrawWithTexture)
  465. {
  466. COMMON_BEGIN()
  467. //
  468. // Create texture A
  469. //
  470. TextureInitInfo init;
  471. init.m_depth = 1;
  472. init.m_format = PixelFormat(ComponentFormat::R8G8B8, TransformFormat::UNORM);
  473. init.m_usage = TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::UPLOAD;
  474. init.m_initialUsage = TextureUsageBit::SAMPLED_FRAGMENT;
  475. init.m_height = 2;
  476. init.m_width = 2;
  477. init.m_mipmapsCount = 2;
  478. init.m_samples = 1;
  479. init.m_depth = 1;
  480. init.m_layerCount = 1;
  481. init.m_sampling.m_repeat = false;
  482. init.m_sampling.m_minMagFilter = SamplingFilter::NEAREST;
  483. init.m_sampling.m_mipmapFilter = SamplingFilter::LINEAR;
  484. init.m_type = TextureType::_2D;
  485. TexturePtr a = gr->newInstance<Texture>(init);
  486. //
  487. // Create texture B
  488. //
  489. init.m_width = 4;
  490. init.m_height = 4;
  491. init.m_mipmapsCount = 3;
  492. init.m_usage = TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::UPLOAD | TextureUsageBit::GENERATE_MIPMAPS;
  493. init.m_initialUsage = TextureUsageBit::NONE;
  494. TexturePtr b = gr->newInstance<Texture>(init);
  495. //
  496. // Upload all textures
  497. //
  498. Array<U8, 2 * 2 * 3> mip0 = {{255, 0, 0, 0, 255, 0, 0, 0, 255, 255, 0, 255}};
  499. Array<U8, 3> mip1 = {{128, 128, 128}};
  500. Array<U8, 4 * 4 * 3> bmip0 = {{255,
  501. 0,
  502. 0,
  503. 0,
  504. 255,
  505. 0,
  506. 0,
  507. 0,
  508. 255,
  509. 255,
  510. 255,
  511. 0,
  512. 255,
  513. 0,
  514. 255,
  515. 0,
  516. 255,
  517. 255,
  518. 255,
  519. 255,
  520. 255,
  521. 128,
  522. 0,
  523. 0,
  524. 0,
  525. 128,
  526. 0,
  527. 0,
  528. 0,
  529. 128,
  530. 128,
  531. 128,
  532. 0,
  533. 128,
  534. 0,
  535. 128,
  536. 0,
  537. 128,
  538. 128,
  539. 128,
  540. 128,
  541. 128,
  542. 255,
  543. 128,
  544. 0,
  545. 0,
  546. 128,
  547. 255}};
  548. CommandBufferInitInfo cmdbinit;
  549. cmdbinit.m_flags = CommandBufferFlag::TRANSFER_WORK;
  550. CommandBufferPtr cmdb = gr->newInstance<CommandBuffer>(cmdbinit);
  551. // Set barriers
  552. cmdb->setTextureSurfaceBarrier(
  553. a, TextureUsageBit::SAMPLED_FRAGMENT, TextureUsageBit::UPLOAD, TextureSurfaceInfo(0, 0, 0, 0));
  554. cmdb->setTextureSurfaceBarrier(
  555. a, TextureUsageBit::SAMPLED_FRAGMENT, TextureUsageBit::UPLOAD, TextureSurfaceInfo(1, 0, 0, 0));
  556. cmdb->setTextureSurfaceBarrier(b, TextureUsageBit::NONE, TextureUsageBit::UPLOAD, TextureSurfaceInfo(0, 0, 0, 0));
  557. cmdb->uploadTextureSurfaceCopyData(a, TextureSurfaceInfo(0, 0, 0, 0), &mip0[0], sizeof(mip0));
  558. cmdb->uploadTextureSurfaceCopyData(a, TextureSurfaceInfo(1, 0, 0, 0), &mip1[0], sizeof(mip1));
  559. cmdb->uploadTextureSurfaceCopyData(b, TextureSurfaceInfo(0, 0, 0, 0), &bmip0[0], sizeof(bmip0));
  560. // Gen mips
  561. cmdb->setTextureSurfaceBarrier(
  562. b, TextureUsageBit::UPLOAD, TextureUsageBit::GENERATE_MIPMAPS, TextureSurfaceInfo(0, 0, 0, 0));
  563. cmdb->generateMipmaps2d(b, 0, 0);
  564. // Set barriers
  565. cmdb->setTextureSurfaceBarrier(
  566. a, TextureUsageBit::UPLOAD, TextureUsageBit::SAMPLED_FRAGMENT, TextureSurfaceInfo(0, 0, 0, 0));
  567. cmdb->setTextureSurfaceBarrier(
  568. a, TextureUsageBit::UPLOAD, TextureUsageBit::SAMPLED_FRAGMENT, TextureSurfaceInfo(1, 0, 0, 0));
  569. for(U i = 0; i < 3; ++i)
  570. {
  571. cmdb->setTextureSurfaceBarrier(
  572. b, TextureUsageBit::GENERATE_MIPMAPS, TextureUsageBit::SAMPLED_FRAGMENT, TextureSurfaceInfo(i, 0, 0, 0));
  573. }
  574. cmdb->flush();
  575. //
  576. // Create prog
  577. //
  578. ShaderProgramPtr prog = createProgram(VERT_QUAD_SRC, FRAG_TEX_SRC, *gr);
  579. //
  580. // Create FB
  581. //
  582. FramebufferPtr fb = createDefaultFb(*gr);
  583. //
  584. // Draw
  585. //
  586. const U ITERATION_COUNT = 200;
  587. U iterations = ITERATION_COUNT;
  588. while(iterations--)
  589. {
  590. HighRezTimer timer;
  591. timer.start();
  592. gr->beginFrame();
  593. CommandBufferInitInfo cinit;
  594. cinit.m_flags = CommandBufferFlag::GRAPHICS_WORK;
  595. CommandBufferPtr cmdb = gr->newInstance<CommandBuffer>(cinit);
  596. cmdb->setViewport(0, 0, WIDTH, HEIGHT);
  597. cmdb->bindShaderProgram(prog);
  598. cmdb->beginRenderPass(fb);
  599. cmdb->bindTexture(0, 0, a);
  600. cmdb->bindTexture(0, 1, b);
  601. cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 6);
  602. cmdb->endRenderPass();
  603. cmdb->flush();
  604. gr->swapBuffers();
  605. timer.stop();
  606. const F32 TICK = 1.0 / 30.0;
  607. if(timer.getElapsedTime() < TICK)
  608. {
  609. HighRezTimer::sleep(TICK - timer.getElapsedTime());
  610. }
  611. }
  612. COMMON_END()
  613. }
  614. static void drawOffscreenDrawcalls(GrManager& gr,
  615. ShaderProgramPtr prog,
  616. CommandBufferPtr cmdb,
  617. U viewPortSize,
  618. BufferPtr indexBuff,
  619. BufferPtr vertBuff)
  620. {
  621. static F32 ang = -2.5f;
  622. ang += toRad(2.5f);
  623. Mat4 viewMat(Vec4(0.0, 0.0, 5.0, 1.0), Mat3::getIdentity(), 1.0f);
  624. viewMat.invert();
  625. Mat4 projMat = Mat4::calculatePerspectiveProjectionMatrix(toRad(60.0), toRad(60.0), 0.1f, 100.0f);
  626. TransientMemoryToken token0, token1;
  627. Mat4 modelMat(Vec4(-0.5, -0.5, 0.0, 1.0), Mat3(Euler(ang, ang / 2.0f, ang / 3.0f)), 1.0f);
  628. Mat4* mvp = static_cast<Mat4*>(gr.allocateFrameTransientMemory(sizeof(*mvp), BufferUsageBit::UNIFORM_ALL, token0));
  629. *mvp = projMat * viewMat * modelMat;
  630. Vec4* color =
  631. static_cast<Vec4*>(gr.allocateFrameTransientMemory(sizeof(*color) * 2, BufferUsageBit::UNIFORM_ALL, token1));
  632. *color++ = Vec4(1.0, 0.0, 0.0, 0.0);
  633. *color = Vec4(0.0, 1.0, 0.0, 0.0);
  634. cmdb->bindVertexBuffer(0, vertBuff, 0, sizeof(Vec3));
  635. cmdb->setVertexAttribute(0, 0, PixelFormat(ComponentFormat::R32G32B32, TransformFormat::FLOAT), 0);
  636. cmdb->bindShaderProgram(prog);
  637. cmdb->bindIndexBuffer(indexBuff, 0, IndexType::U16);
  638. cmdb->setViewport(0, 0, viewPortSize, viewPortSize);
  639. cmdb->bindUniformBuffer(0, 0, token0);
  640. cmdb->bindUniformBuffer(0, 1, token1);
  641. cmdb->drawElements(PrimitiveTopology::TRIANGLES, 6 * 2 * 3);
  642. // 2nd draw
  643. modelMat = Mat4(Vec4(0.5, 0.5, 0.0, 1.0), Mat3(Euler(ang * 2.0, ang, ang / 3.0f * 2.0)), 1.0f);
  644. mvp = static_cast<Mat4*>(gr.allocateFrameTransientMemory(sizeof(*mvp), BufferUsageBit::UNIFORM_ALL, token0));
  645. *mvp = projMat * viewMat * modelMat;
  646. color =
  647. static_cast<Vec4*>(gr.allocateFrameTransientMemory(sizeof(*color) * 2, BufferUsageBit::UNIFORM_ALL, token1));
  648. *color++ = Vec4(0.0, 0.0, 1.0, 0.0);
  649. *color = Vec4(0.0, 1.0, 1.0, 0.0);
  650. cmdb->bindUniformBuffer(0, 0, token0);
  651. cmdb->bindUniformBuffer(0, 1, token1);
  652. cmdb->drawElements(PrimitiveTopology::TRIANGLES, 6 * 2 * 3);
  653. }
  654. static void drawOffscreen(GrManager& gr, Bool useSecondLevel)
  655. {
  656. //
  657. // Create textures
  658. //
  659. const PixelFormat COL_FORMAT = PixelFormat(ComponentFormat::R8G8B8A8, TransformFormat::UNORM);
  660. const U TEX_SIZE = 256;
  661. TextureInitInfo init;
  662. init.m_depth = 1;
  663. init.m_format = COL_FORMAT;
  664. init.m_usage = TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE;
  665. init.m_height = TEX_SIZE;
  666. init.m_width = TEX_SIZE;
  667. init.m_mipmapsCount = 1;
  668. init.m_depth = 1;
  669. init.m_layerCount = 1;
  670. init.m_samples = 1;
  671. init.m_sampling.m_minMagFilter = SamplingFilter::LINEAR;
  672. init.m_sampling.m_mipmapFilter = SamplingFilter::LINEAR;
  673. init.m_type = TextureType::_2D;
  674. TexturePtr col0 = gr.newInstance<Texture>(init);
  675. TexturePtr col1 = gr.newInstance<Texture>(init);
  676. init.m_format = DS_FORMAT;
  677. TexturePtr dp = gr.newInstance<Texture>(init);
  678. //
  679. // Create FB
  680. //
  681. FramebufferInitInfo fbinit;
  682. fbinit.m_colorAttachmentCount = 2;
  683. fbinit.m_colorAttachments[0].m_texture = col0;
  684. fbinit.m_colorAttachments[0].m_clearValue.m_colorf = {{0.1, 0.0, 0.0, 0.0}};
  685. fbinit.m_colorAttachments[1].m_texture = col1;
  686. fbinit.m_colorAttachments[1].m_clearValue.m_colorf = {{0.0, 0.1, 0.0, 0.0}};
  687. fbinit.m_depthStencilAttachment.m_texture = dp;
  688. fbinit.m_depthStencilAttachment.m_aspect = DepthStencilAspectBit::DEPTH;
  689. fbinit.m_depthStencilAttachment.m_clearValue.m_depthStencil.m_depth = 1.0;
  690. FramebufferPtr fb = gr.newInstance<Framebuffer>(fbinit);
  691. //
  692. // Create default FB
  693. //
  694. FramebufferPtr dfb = createDefaultFb(gr);
  695. //
  696. // Create buffs
  697. //
  698. BufferPtr verts, indices;
  699. createCube(gr, verts, indices);
  700. //
  701. // Create progs
  702. //
  703. ShaderProgramPtr prog = createProgram(VERT_MRT_SRC, FRAG_MRT_SRC, gr);
  704. ShaderProgramPtr resolveProg = createProgram(VERT_QUAD_SRC, FRAG_MRT2_SRC, gr);
  705. //
  706. // Draw
  707. //
  708. const U ITERATION_COUNT = 200;
  709. U iterations = ITERATION_COUNT;
  710. while(iterations--)
  711. {
  712. HighRezTimer timer;
  713. timer.start();
  714. gr.beginFrame();
  715. CommandBufferInitInfo cinit;
  716. cinit.m_flags = CommandBufferFlag::GRAPHICS_WORK;
  717. CommandBufferPtr cmdb = gr.newInstance<CommandBuffer>(cinit);
  718. cmdb->setPolygonOffset(0.0, 0.0);
  719. cmdb->setTextureSurfaceBarrier(
  720. col0, TextureUsageBit::NONE, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, TextureSurfaceInfo(0, 0, 0, 0));
  721. cmdb->setTextureSurfaceBarrier(
  722. col1, TextureUsageBit::NONE, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, TextureSurfaceInfo(0, 0, 0, 0));
  723. cmdb->setTextureSurfaceBarrier(dp,
  724. TextureUsageBit::NONE,
  725. TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE,
  726. TextureSurfaceInfo(0, 0, 0, 0));
  727. cmdb->beginRenderPass(fb);
  728. if(!useSecondLevel)
  729. {
  730. drawOffscreenDrawcalls(gr, prog, cmdb, TEX_SIZE, indices, verts);
  731. }
  732. else
  733. {
  734. CommandBufferInitInfo cinit;
  735. cinit.m_flags = CommandBufferFlag::SECOND_LEVEL | CommandBufferFlag::GRAPHICS_WORK;
  736. cinit.m_framebuffer = fb;
  737. CommandBufferPtr cmdb2 = gr.newInstance<CommandBuffer>(cinit);
  738. drawOffscreenDrawcalls(gr, prog, cmdb2, TEX_SIZE, indices, verts);
  739. cmdb->pushSecondLevelCommandBuffer(cmdb2);
  740. }
  741. cmdb->endRenderPass();
  742. cmdb->setTextureSurfaceBarrier(col0,
  743. TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
  744. TextureUsageBit::SAMPLED_FRAGMENT,
  745. TextureSurfaceInfo(0, 0, 0, 0));
  746. cmdb->setTextureSurfaceBarrier(col1,
  747. TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE,
  748. TextureUsageBit::SAMPLED_FRAGMENT,
  749. TextureSurfaceInfo(0, 0, 0, 0));
  750. cmdb->setTextureSurfaceBarrier(dp,
  751. TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE,
  752. TextureUsageBit::SAMPLED_FRAGMENT,
  753. TextureSurfaceInfo(0, 0, 0, 0));
  754. // Draw quad
  755. cmdb->beginRenderPass(dfb);
  756. cmdb->bindShaderProgram(resolveProg);
  757. cmdb->setViewport(0, 0, WIDTH, HEIGHT);
  758. cmdb->bindTexture(0, 0, col0);
  759. cmdb->bindTexture(0, 1, col1);
  760. cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 6);
  761. cmdb->endRenderPass();
  762. cmdb->flush();
  763. // End
  764. gr.swapBuffers();
  765. timer.stop();
  766. const F32 TICK = 1.0 / 30.0;
  767. if(timer.getElapsedTime() < TICK)
  768. {
  769. HighRezTimer::sleep(TICK - timer.getElapsedTime());
  770. }
  771. }
  772. }
  773. ANKI_TEST(Gr, DrawOffscreen)
  774. {
  775. COMMON_BEGIN()
  776. drawOffscreen(*gr, false);
  777. COMMON_END()
  778. }
  779. ANKI_TEST(Gr, DrawWithSecondLevel)
  780. {
  781. COMMON_BEGIN()
  782. drawOffscreen(*gr, true);
  783. COMMON_END()
  784. }
  785. ANKI_TEST(Gr, ImageLoadStore)
  786. {
  787. COMMON_BEGIN()
  788. TextureInitInfo init;
  789. init.m_width = init.m_height = 4;
  790. init.m_mipmapsCount = 2;
  791. init.m_usage = TextureUsageBit::CLEAR | TextureUsageBit::SAMPLED_ALL | TextureUsageBit::IMAGE_COMPUTE_WRITE;
  792. init.m_type = TextureType::_2D;
  793. init.m_format = PixelFormat(ComponentFormat::R8G8B8A8, TransformFormat::UNORM);
  794. init.m_sampling.m_mipmapFilter = SamplingFilter::LINEAR;
  795. TexturePtr tex = gr->newInstance<Texture>(init);
  796. // Prog
  797. ShaderProgramPtr prog = createProgram(VERT_QUAD_SRC, FRAG_SIMPLE_TEX_SRC, *gr);
  798. // Create shader & compute prog
  799. ShaderPtr shader = gr->newInstance<Shader>(ShaderType::COMPUTE, COMP_WRITE_IMAGE_SRC);
  800. ShaderProgramPtr compProg = gr->newInstance<ShaderProgram>(shader);
  801. // FB
  802. FramebufferPtr dfb = createDefaultFb(*gr);
  803. // Write texture data
  804. CommandBufferInitInfo cmdbinit;
  805. CommandBufferPtr cmdb = gr->newInstance<CommandBuffer>(cmdbinit);
  806. cmdb->setTextureSurfaceBarrier(tex, TextureUsageBit::NONE, TextureUsageBit::CLEAR, TextureSurfaceInfo(0, 0, 0, 0));
  807. ClearValue clear;
  808. clear.m_colorf = {{0.0, 1.0, 0.0, 1.0}};
  809. cmdb->clearTextureSurface(tex, TextureSurfaceInfo(0, 0, 0, 0), clear);
  810. cmdb->setTextureSurfaceBarrier(
  811. tex, TextureUsageBit::CLEAR, TextureUsageBit::SAMPLED_FRAGMENT, TextureSurfaceInfo(0, 0, 0, 0));
  812. cmdb->setTextureSurfaceBarrier(tex, TextureUsageBit::NONE, TextureUsageBit::CLEAR, TextureSurfaceInfo(1, 0, 0, 0));
  813. clear.m_colorf = {{0.0, 0.0, 1.0, 1.0}};
  814. cmdb->clearTextureSurface(tex, TextureSurfaceInfo(1, 0, 0, 0), clear);
  815. cmdb->setTextureSurfaceBarrier(
  816. tex, TextureUsageBit::CLEAR, TextureUsageBit::IMAGE_COMPUTE_WRITE, TextureSurfaceInfo(1, 0, 0, 0));
  817. cmdb->flush();
  818. const U ITERATION_COUNT = 100;
  819. U iterations = ITERATION_COUNT;
  820. while(iterations--)
  821. {
  822. HighRezTimer timer;
  823. timer.start();
  824. gr->beginFrame();
  825. CommandBufferInitInfo cinit;
  826. cinit.m_flags = CommandBufferFlag::GRAPHICS_WORK | CommandBufferFlag::COMPUTE_WORK;
  827. CommandBufferPtr cmdb = gr->newInstance<CommandBuffer>(cinit);
  828. // Write image
  829. TransientMemoryToken token;
  830. Vec4* col =
  831. static_cast<Vec4*>(gr->allocateFrameTransientMemory(sizeof(*col), BufferUsageBit::STORAGE_ALL, token));
  832. *col = Vec4(iterations / F32(ITERATION_COUNT));
  833. cmdb->setTextureSurfaceBarrier(
  834. tex, TextureUsageBit::NONE, TextureUsageBit::IMAGE_COMPUTE_WRITE, TextureSurfaceInfo(1, 0, 0, 0));
  835. cmdb->bindShaderProgram(compProg);
  836. cmdb->bindImage(0, 0, tex, 1);
  837. cmdb->bindStorageBuffer(1, 0, token);
  838. cmdb->dispatchCompute(WIDTH / 2, HEIGHT / 2, 1);
  839. cmdb->setTextureSurfaceBarrier(tex,
  840. TextureUsageBit::IMAGE_COMPUTE_WRITE,
  841. TextureUsageBit::SAMPLED_FRAGMENT,
  842. TextureSurfaceInfo(1, 0, 0, 0));
  843. // Present image
  844. cmdb->setViewport(0, 0, WIDTH, HEIGHT);
  845. cmdb->bindShaderProgram(prog);
  846. cmdb->beginRenderPass(dfb);
  847. cmdb->bindTexture(0, 0, tex);
  848. cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 6);
  849. cmdb->endRenderPass();
  850. cmdb->flush();
  851. // End
  852. gr->swapBuffers();
  853. timer.stop();
  854. const F32 TICK = 1.0 / 30.0;
  855. if(timer.getElapsedTime() < TICK)
  856. {
  857. HighRezTimer::sleep(TICK - timer.getElapsedTime());
  858. }
  859. }
  860. COMMON_END()
  861. }
  862. ANKI_TEST(Gr, 3DTextures)
  863. {
  864. COMMON_BEGIN()
  865. //
  866. // Create texture A
  867. //
  868. TextureInitInfo init;
  869. init.m_depth = 1;
  870. init.m_format = PixelFormat(ComponentFormat::R8G8B8A8, TransformFormat::UNORM);
  871. init.m_usage = TextureUsageBit::SAMPLED_FRAGMENT | TextureUsageBit::UPLOAD;
  872. init.m_initialUsage = TextureUsageBit::UPLOAD;
  873. init.m_height = 2;
  874. init.m_width = 2;
  875. init.m_mipmapsCount = 2;
  876. init.m_samples = 1;
  877. init.m_depth = 2;
  878. init.m_layerCount = 1;
  879. init.m_sampling.m_repeat = false;
  880. init.m_sampling.m_minMagFilter = SamplingFilter::NEAREST;
  881. init.m_sampling.m_mipmapFilter = SamplingFilter::NEAREST;
  882. init.m_type = TextureType::_3D;
  883. TexturePtr a = gr->newInstance<Texture>(init);
  884. //
  885. // Upload all textures
  886. //
  887. Array<U8, 2 * 2 * 2 * 4> mip0 = {{255,
  888. 0,
  889. 0,
  890. 0,
  891. 0,
  892. 255,
  893. 0,
  894. 0,
  895. 0,
  896. 0,
  897. 255,
  898. 0,
  899. 255,
  900. 255,
  901. 0,
  902. 0,
  903. 255,
  904. 0,
  905. 255,
  906. 0,
  907. 0,
  908. 255,
  909. 255,
  910. 0,
  911. 255,
  912. 255,
  913. 255,
  914. 0,
  915. 0,
  916. 0,
  917. 0,
  918. 0}};
  919. Array<U8, 4> mip1 = {{128, 128, 128, 0}};
  920. CommandBufferInitInfo cmdbinit;
  921. cmdbinit.m_flags = CommandBufferFlag::TRANSFER_WORK;
  922. CommandBufferPtr cmdb = gr->newInstance<CommandBuffer>(cmdbinit);
  923. cmdb->setTextureVolumeBarrier(a, TextureUsageBit::NONE, TextureUsageBit::UPLOAD, TextureVolumeInfo(0));
  924. cmdb->setTextureVolumeBarrier(a, TextureUsageBit::NONE, TextureUsageBit::UPLOAD, TextureVolumeInfo(1));
  925. cmdb->uploadTextureVolumeCopyData(a, TextureVolumeInfo(0), &mip0[0], sizeof(mip0));
  926. cmdb->uploadTextureVolumeCopyData(a, TextureVolumeInfo(1), &mip1[0], sizeof(mip1));
  927. cmdb->setTextureVolumeBarrier(a, TextureUsageBit::UPLOAD, TextureUsageBit::SAMPLED_FRAGMENT, TextureVolumeInfo(0));
  928. cmdb->setTextureVolumeBarrier(a, TextureUsageBit::UPLOAD, TextureUsageBit::SAMPLED_FRAGMENT, TextureVolumeInfo(1));
  929. cmdb->flush();
  930. //
  931. // Rest
  932. //
  933. ShaderProgramPtr prog = createProgram(VERT_QUAD_SRC, FRAG_TEX3D_SRC, *gr);
  934. FramebufferPtr dfb = createDefaultFb(*gr);
  935. static Array<Vec4, 9> TEX_COORDS_LOD = {{Vec4(0, 0, 0, 0),
  936. Vec4(1, 0, 0, 0),
  937. Vec4(0, 1, 0, 0),
  938. Vec4(1, 1, 0, 0),
  939. Vec4(0, 0, 1, 0),
  940. Vec4(1, 0, 1, 0),
  941. Vec4(0, 1, 1, 0),
  942. Vec4(1, 1, 1, 0),
  943. Vec4(0, 0, 0, 1)}};
  944. const U ITERATION_COUNT = 100;
  945. U iterations = ITERATION_COUNT;
  946. while(iterations--)
  947. {
  948. HighRezTimer timer;
  949. timer.start();
  950. gr->beginFrame();
  951. CommandBufferInitInfo cinit;
  952. cinit.m_flags = CommandBufferFlag::GRAPHICS_WORK;
  953. CommandBufferPtr cmdb = gr->newInstance<CommandBuffer>(cinit);
  954. cmdb->setViewport(0, 0, WIDTH, HEIGHT);
  955. cmdb->beginRenderPass(dfb);
  956. cmdb->bindShaderProgram(prog);
  957. TransientMemoryToken token;
  958. Vec4* uv =
  959. static_cast<Vec4*>(gr->allocateFrameTransientMemory(sizeof(Vec4), BufferUsageBit::UNIFORM_ALL, token));
  960. U idx = (F32(ITERATION_COUNT - iterations - 1) / ITERATION_COUNT) * TEX_COORDS_LOD.getSize();
  961. *uv = TEX_COORDS_LOD[idx];
  962. cmdb->bindUniformBuffer(0, 0, token);
  963. cmdb->bindTexture(0, 0, a);
  964. cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 6);
  965. cmdb->endRenderPass();
  966. cmdb->flush();
  967. // End
  968. gr->swapBuffers();
  969. timer.stop();
  970. const F32 TICK = 1.0 / 15.0;
  971. if(timer.getElapsedTime() < TICK)
  972. {
  973. HighRezTimer::sleep(TICK - timer.getElapsedTime());
  974. }
  975. }
  976. COMMON_END()
  977. }
  978. } // end namespace anki