|
@@ -298,20 +298,11 @@ static void createGrManager(NativeWindow*& win, GrManager*& gr)
|
|
|
ANKI_TEST_EXPECT_NO_ERR(gr->init(inf));
|
|
ANKI_TEST_EXPECT_NO_ERR(gr->init(inf));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static PipelinePtr createSimplePpline(CString vertSrc, CString fragSrc, GrManager& gr)
|
|
|
|
|
|
|
+static ShaderProgramPtr createProgram(CString vertSrc, CString fragSrc, GrManager& gr)
|
|
|
{
|
|
{
|
|
|
ShaderPtr vert = gr.newInstance<Shader>(ShaderType::VERTEX, vertSrc);
|
|
ShaderPtr vert = gr.newInstance<Shader>(ShaderType::VERTEX, vertSrc);
|
|
|
ShaderPtr frag = gr.newInstance<Shader>(ShaderType::FRAGMENT, fragSrc);
|
|
ShaderPtr frag = gr.newInstance<Shader>(ShaderType::FRAGMENT, fragSrc);
|
|
|
-
|
|
|
|
|
- PipelineInitInfo init;
|
|
|
|
|
- init.m_shaders[ShaderType::VERTEX] = vert;
|
|
|
|
|
- init.m_shaders[ShaderType::FRAGMENT] = frag;
|
|
|
|
|
- init.m_color.m_attachments[0].m_format.m_components = ComponentFormat::DEFAULT_FRAMEBUFFER;
|
|
|
|
|
- init.m_color.m_attachmentCount = 1;
|
|
|
|
|
- init.m_depthStencil.m_depthWriteEnabled = false;
|
|
|
|
|
- init.m_depthStencil.m_depthCompareFunction = CompareOperation::ALWAYS;
|
|
|
|
|
-
|
|
|
|
|
- return gr.newInstance<Pipeline>(init);
|
|
|
|
|
|
|
+ return gr.newInstance<ShaderProgram>(vert, frag);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static FramebufferPtr createDefaultFb(GrManager& gr)
|
|
static FramebufferPtr createDefaultFb(GrManager& gr)
|
|
@@ -358,11 +349,11 @@ ANKI_TEST(Gr, Shader)
|
|
|
COMMON_END()
|
|
COMMON_END()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-ANKI_TEST(Gr, Pipeline)
|
|
|
|
|
|
|
+ANKI_TEST(Gr, ShaderProgram)
|
|
|
{
|
|
{
|
|
|
COMMON_BEGIN()
|
|
COMMON_BEGIN()
|
|
|
|
|
|
|
|
- PipelinePtr ppline = createSimplePpline(VERT_SRC, FRAG_SRC, *gr);
|
|
|
|
|
|
|
+ ShaderProgramPtr ppline = createProgram(VERT_SRC, FRAG_SRC, *gr);
|
|
|
|
|
|
|
|
COMMON_END()
|
|
COMMON_END()
|
|
|
}
|
|
}
|
|
@@ -371,7 +362,7 @@ ANKI_TEST(Gr, SimpleDrawcall)
|
|
|
{
|
|
{
|
|
|
COMMON_BEGIN()
|
|
COMMON_BEGIN()
|
|
|
|
|
|
|
|
- PipelinePtr ppline = createSimplePpline(VERT_SRC, FRAG_SRC, *gr);
|
|
|
|
|
|
|
+ ShaderProgramPtr prog = createProgram(VERT_SRC, FRAG_SRC, *gr);
|
|
|
FramebufferPtr fb = createDefaultFb(*gr);
|
|
FramebufferPtr fb = createDefaultFb(*gr);
|
|
|
|
|
|
|
|
U iterations = 100;
|
|
U iterations = 100;
|
|
@@ -383,13 +374,13 @@ ANKI_TEST(Gr, SimpleDrawcall)
|
|
|
gr->beginFrame();
|
|
gr->beginFrame();
|
|
|
|
|
|
|
|
CommandBufferInitInfo cinit;
|
|
CommandBufferInitInfo cinit;
|
|
|
|
|
+ cinit.m_flags = CommandBufferFlag::GRAPHICS_WORK;
|
|
|
CommandBufferPtr cmdb = gr->newInstance<CommandBuffer>(cinit);
|
|
CommandBufferPtr cmdb = gr->newInstance<CommandBuffer>(cinit);
|
|
|
|
|
|
|
|
cmdb->setViewport(0, 0, WIDTH, HEIGHT);
|
|
cmdb->setViewport(0, 0, WIDTH, HEIGHT);
|
|
|
- cmdb->setPolygonOffset(0.0, 0.0);
|
|
|
|
|
- cmdb->bindPipeline(ppline);
|
|
|
|
|
|
|
+ cmdb->bindShaderProgram(prog);
|
|
|
cmdb->beginRenderPass(fb);
|
|
cmdb->beginRenderPass(fb);
|
|
|
- cmdb->drawArrays(3);
|
|
|
|
|
|
|
+ cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 3);
|
|
|
cmdb->endRenderPass();
|
|
cmdb->endRenderPass();
|
|
|
cmdb->flush();
|
|
cmdb->flush();
|
|
|
|
|
|
|
@@ -430,20 +421,6 @@ ANKI_TEST(Gr, Buffer)
|
|
|
COMMON_END()
|
|
COMMON_END()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-ANKI_TEST(Gr, ResourceGroup)
|
|
|
|
|
-{
|
|
|
|
|
- COMMON_BEGIN()
|
|
|
|
|
-
|
|
|
|
|
- BufferPtr b = gr->newInstance<Buffer>(sizeof(F32) * 4, BufferUsageBit::UNIFORM_ALL, BufferMapAccessBit::WRITE);
|
|
|
|
|
-
|
|
|
|
|
- ResourceGroupInitInfo rcinit;
|
|
|
|
|
- rcinit.m_uniformBuffers[0].m_buffer = b;
|
|
|
|
|
- rcinit.m_uniformBuffers[0].m_usage = BufferUsageBit::UNIFORM_ALL_GRAPHICS;
|
|
|
|
|
- ResourceGroupPtr rc = gr->newInstance<ResourceGroup>(rcinit);
|
|
|
|
|
-
|
|
|
|
|
- COMMON_END()
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
ANKI_TEST(Gr, DrawWithUniforms)
|
|
ANKI_TEST(Gr, DrawWithUniforms)
|
|
|
{
|
|
{
|
|
|
COMMON_BEGIN()
|
|
COMMON_BEGIN()
|
|
@@ -458,16 +435,8 @@ ANKI_TEST(Gr, DrawWithUniforms)
|
|
|
ptr[2] = Vec4(0.0, 0.0, 1.0, 0.0);
|
|
ptr[2] = Vec4(0.0, 0.0, 1.0, 0.0);
|
|
|
b->unmap();
|
|
b->unmap();
|
|
|
|
|
|
|
|
- // Resource group
|
|
|
|
|
- ResourceGroupInitInfo rcinit;
|
|
|
|
|
- rcinit.m_uniformBuffers[0].m_buffer = b;
|
|
|
|
|
- rcinit.m_uniformBuffers[0].m_usage = BufferUsageBit::UNIFORM_ALL_GRAPHICS;
|
|
|
|
|
- rcinit.m_uniformBuffers[1].m_uploadedMemory = true;
|
|
|
|
|
- rcinit.m_uniformBuffers[1].m_usage = BufferUsageBit::UNIFORM_ALL_GRAPHICS;
|
|
|
|
|
- ResourceGroupPtr rc = gr->newInstance<ResourceGroup>(rcinit);
|
|
|
|
|
-
|
|
|
|
|
- // Ppline
|
|
|
|
|
- PipelinePtr ppline = createSimplePpline(VERT_UBO_SRC, FRAG_UBO_SRC, *gr);
|
|
|
|
|
|
|
+ // Progm
|
|
|
|
|
+ ShaderProgramPtr prog = createProgram(VERT_UBO_SRC, FRAG_UBO_SRC, *gr);
|
|
|
|
|
|
|
|
// FB
|
|
// FB
|
|
|
FramebufferPtr fb = createDefaultFb(*gr);
|
|
FramebufferPtr fb = createDefaultFb(*gr);
|
|
@@ -481,9 +450,9 @@ ANKI_TEST(Gr, DrawWithUniforms)
|
|
|
gr->beginFrame();
|
|
gr->beginFrame();
|
|
|
|
|
|
|
|
// Uploaded buffer
|
|
// Uploaded buffer
|
|
|
- TransientMemoryInfo transientInfo;
|
|
|
|
|
- Vec4* rotMat = static_cast<Vec4*>(gr->allocateFrameTransientMemory(
|
|
|
|
|
- sizeof(Vec4), BufferUsageBit::UNIFORM_ALL, transientInfo.m_uniformBuffers[1]));
|
|
|
|
|
|
|
+ TransientMemoryToken token;
|
|
|
|
|
+ Vec4* rotMat =
|
|
|
|
|
+ static_cast<Vec4*>(gr->allocateFrameTransientMemory(sizeof(Vec4), BufferUsageBit::UNIFORM_ALL, token));
|
|
|
F32 angle = toRad(360.0f / ITERATION_COUNT * iterations);
|
|
F32 angle = toRad(360.0f / ITERATION_COUNT * iterations);
|
|
|
(*rotMat)[0] = cos(angle);
|
|
(*rotMat)[0] = cos(angle);
|
|
|
(*rotMat)[1] = -sin(angle);
|
|
(*rotMat)[1] = -sin(angle);
|
|
@@ -494,11 +463,13 @@ ANKI_TEST(Gr, DrawWithUniforms)
|
|
|
CommandBufferPtr cmdb = gr->newInstance<CommandBuffer>(cinit);
|
|
CommandBufferPtr cmdb = gr->newInstance<CommandBuffer>(cinit);
|
|
|
|
|
|
|
|
cmdb->setViewport(0, 0, WIDTH, HEIGHT);
|
|
cmdb->setViewport(0, 0, WIDTH, HEIGHT);
|
|
|
- cmdb->setPolygonOffset(0.0, 0.0);
|
|
|
|
|
- cmdb->bindPipeline(ppline);
|
|
|
|
|
|
|
+ cmdb->bindShaderProgram(prog);
|
|
|
cmdb->beginRenderPass(fb);
|
|
cmdb->beginRenderPass(fb);
|
|
|
- cmdb->bindResourceGroup(rc, 0, &transientInfo);
|
|
|
|
|
- cmdb->drawArrays(3);
|
|
|
|
|
|
|
+
|
|
|
|
|
+ cmdb->bindUniformBuffer(0, 0, b, 0);
|
|
|
|
|
+ cmdb->bindUniformBuffer(0, 1, token);
|
|
|
|
|
+
|
|
|
|
|
+ cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 3);
|
|
|
cmdb->endRenderPass();
|
|
cmdb->endRenderPass();
|
|
|
cmdb->flush();
|
|
cmdb->flush();
|
|
|
|
|
|
|
@@ -550,37 +521,8 @@ ANKI_TEST(Gr, DrawWithVertex)
|
|
|
otherColor[2] = Vec3(1.0, 1.0, 0.0);
|
|
otherColor[2] = Vec3(1.0, 1.0, 0.0);
|
|
|
c->unmap();
|
|
c->unmap();
|
|
|
|
|
|
|
|
- // Resource group
|
|
|
|
|
- ResourceGroupInitInfo rcinit;
|
|
|
|
|
- rcinit.m_vertexBuffers[0].m_buffer = b;
|
|
|
|
|
- rcinit.m_vertexBuffers[1].m_buffer = c;
|
|
|
|
|
- ResourceGroupPtr rc = gr->newInstance<ResourceGroup>(rcinit);
|
|
|
|
|
-
|
|
|
|
|
- // Shaders
|
|
|
|
|
- ShaderPtr vert = gr->newInstance<Shader>(ShaderType::VERTEX, VERT_INP_SRC);
|
|
|
|
|
- ShaderPtr frag = gr->newInstance<Shader>(ShaderType::FRAGMENT, FRAG_INP_SRC);
|
|
|
|
|
-
|
|
|
|
|
- // Ppline
|
|
|
|
|
- PipelineInitInfo init;
|
|
|
|
|
- init.m_shaders[ShaderType::VERTEX] = vert;
|
|
|
|
|
- init.m_shaders[ShaderType::FRAGMENT] = frag;
|
|
|
|
|
- init.m_color.m_attachments[0].m_format.m_components = ComponentFormat::DEFAULT_FRAMEBUFFER;
|
|
|
|
|
- init.m_color.m_attachmentCount = 1;
|
|
|
|
|
- init.m_depthStencil.m_depthWriteEnabled = false;
|
|
|
|
|
- init.m_depthStencil.m_depthCompareFunction = CompareOperation::ALWAYS;
|
|
|
|
|
-
|
|
|
|
|
- init.m_vertex.m_attributeCount = 3;
|
|
|
|
|
- init.m_vertex.m_attributes[0].m_format = PixelFormat(ComponentFormat::R32G32B32, TransformFormat::FLOAT);
|
|
|
|
|
- init.m_vertex.m_attributes[1].m_format = PixelFormat(ComponentFormat::R8G8B8, TransformFormat::UNORM);
|
|
|
|
|
- init.m_vertex.m_attributes[1].m_offset = sizeof(Vec3);
|
|
|
|
|
- init.m_vertex.m_attributes[2].m_format = PixelFormat(ComponentFormat::R32G32B32, TransformFormat::FLOAT);
|
|
|
|
|
- init.m_vertex.m_attributes[2].m_binding = 1;
|
|
|
|
|
-
|
|
|
|
|
- init.m_vertex.m_bindingCount = 2;
|
|
|
|
|
- init.m_vertex.m_bindings[0].m_stride = sizeof(Vert);
|
|
|
|
|
- init.m_vertex.m_bindings[1].m_stride = sizeof(Vec3);
|
|
|
|
|
-
|
|
|
|
|
- PipelinePtr ppline = gr->newInstance<Pipeline>(init);
|
|
|
|
|
|
|
+ // Prog
|
|
|
|
|
+ ShaderProgramPtr prog = createProgram(VERT_INP_SRC, FRAG_INP_SRC, *gr);
|
|
|
|
|
|
|
|
// FB
|
|
// FB
|
|
|
FramebufferPtr fb = createDefaultFb(*gr);
|
|
FramebufferPtr fb = createDefaultFb(*gr);
|
|
@@ -594,14 +536,20 @@ ANKI_TEST(Gr, DrawWithVertex)
|
|
|
gr->beginFrame();
|
|
gr->beginFrame();
|
|
|
|
|
|
|
|
CommandBufferInitInfo cinit;
|
|
CommandBufferInitInfo cinit;
|
|
|
|
|
+ cinit.m_flags = CommandBufferFlag::GRAPHICS_WORK;
|
|
|
CommandBufferPtr cmdb = gr->newInstance<CommandBuffer>(cinit);
|
|
CommandBufferPtr cmdb = gr->newInstance<CommandBuffer>(cinit);
|
|
|
|
|
|
|
|
|
|
+ cmdb->bindVertexBuffer(0, b, 0, sizeof(Vert));
|
|
|
|
|
+ cmdb->bindVertexBuffer(1, c, 0, sizeof(Vec3));
|
|
|
|
|
+ cmdb->setVertexAttribute(0, 0, PixelFormat(ComponentFormat::R32G32B32, TransformFormat::FLOAT), 0);
|
|
|
|
|
+ cmdb->setVertexAttribute(1, 0, PixelFormat(ComponentFormat::R8G8B8, TransformFormat::UNORM), sizeof(Vec3));
|
|
|
|
|
+ cmdb->setVertexAttribute(2, 1, PixelFormat(ComponentFormat::R32G32B32, TransformFormat::FLOAT), 0);
|
|
|
|
|
+
|
|
|
cmdb->setViewport(0, 0, WIDTH, HEIGHT);
|
|
cmdb->setViewport(0, 0, WIDTH, HEIGHT);
|
|
|
cmdb->setPolygonOffset(0.0, 0.0);
|
|
cmdb->setPolygonOffset(0.0, 0.0);
|
|
|
- cmdb->bindPipeline(ppline);
|
|
|
|
|
|
|
+ cmdb->bindShaderProgram(prog);
|
|
|
cmdb->beginRenderPass(fb);
|
|
cmdb->beginRenderPass(fb);
|
|
|
- cmdb->bindResourceGroup(rc, 0, nullptr);
|
|
|
|
|
- cmdb->drawArrays(3);
|
|
|
|
|
|
|
+ cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 3);
|
|
|
cmdb->endRenderPass();
|
|
cmdb->endRenderPass();
|
|
|
cmdb->flush();
|
|
cmdb->flush();
|
|
|
|
|
|
|
@@ -756,7 +704,6 @@ ANKI_TEST(Gr, DrawWithTexture)
|
|
|
a, TextureUsageBit::SAMPLED_FRAGMENT, TextureUsageBit::UPLOAD, TextureSurfaceInfo(1, 0, 0, 0));
|
|
a, TextureUsageBit::SAMPLED_FRAGMENT, TextureUsageBit::UPLOAD, TextureSurfaceInfo(1, 0, 0, 0));
|
|
|
|
|
|
|
|
cmdb->setTextureSurfaceBarrier(b, TextureUsageBit::NONE, TextureUsageBit::UPLOAD, TextureSurfaceInfo(0, 0, 0, 0));
|
|
cmdb->setTextureSurfaceBarrier(b, TextureUsageBit::NONE, TextureUsageBit::UPLOAD, TextureSurfaceInfo(0, 0, 0, 0));
|
|
|
- ;
|
|
|
|
|
|
|
|
|
|
cmdb->uploadTextureSurfaceCopyData(a, TextureSurfaceInfo(0, 0, 0, 0), &mip0[0], sizeof(mip0));
|
|
cmdb->uploadTextureSurfaceCopyData(a, TextureSurfaceInfo(0, 0, 0, 0), &mip0[0], sizeof(mip0));
|
|
|
|
|
|
|
@@ -786,17 +733,9 @@ ANKI_TEST(Gr, DrawWithTexture)
|
|
|
cmdb->flush();
|
|
cmdb->flush();
|
|
|
|
|
|
|
|
//
|
|
//
|
|
|
- // Create resource group
|
|
|
|
|
- //
|
|
|
|
|
- ResourceGroupInitInfo rcinit;
|
|
|
|
|
- rcinit.m_textures[0].m_texture = a;
|
|
|
|
|
- rcinit.m_textures[1].m_texture = b;
|
|
|
|
|
- ResourceGroupPtr rc = gr->newInstance<ResourceGroup>(rcinit);
|
|
|
|
|
-
|
|
|
|
|
- //
|
|
|
|
|
- // Create ppline
|
|
|
|
|
|
|
+ // Create prog
|
|
|
//
|
|
//
|
|
|
- PipelinePtr ppline = createSimplePpline(VERT_QUAD_SRC, FRAG_TEX_SRC, *gr);
|
|
|
|
|
|
|
+ ShaderProgramPtr prog = createProgram(VERT_QUAD_SRC, FRAG_TEX_SRC, *gr);
|
|
|
|
|
|
|
|
//
|
|
//
|
|
|
// Create FB
|
|
// Create FB
|
|
@@ -816,14 +755,15 @@ ANKI_TEST(Gr, DrawWithTexture)
|
|
|
gr->beginFrame();
|
|
gr->beginFrame();
|
|
|
|
|
|
|
|
CommandBufferInitInfo cinit;
|
|
CommandBufferInitInfo cinit;
|
|
|
|
|
+ cinit.m_flags = CommandBufferFlag::GRAPHICS_WORK;
|
|
|
CommandBufferPtr cmdb = gr->newInstance<CommandBuffer>(cinit);
|
|
CommandBufferPtr cmdb = gr->newInstance<CommandBuffer>(cinit);
|
|
|
|
|
|
|
|
cmdb->setViewport(0, 0, WIDTH, HEIGHT);
|
|
cmdb->setViewport(0, 0, WIDTH, HEIGHT);
|
|
|
- cmdb->setPolygonOffset(0.0, 0.0);
|
|
|
|
|
- cmdb->bindPipeline(ppline);
|
|
|
|
|
|
|
+ cmdb->bindShaderProgram(prog);
|
|
|
cmdb->beginRenderPass(fb);
|
|
cmdb->beginRenderPass(fb);
|
|
|
- cmdb->bindResourceGroup(rc, 0, nullptr);
|
|
|
|
|
- cmdb->drawArrays(6);
|
|
|
|
|
|
|
+ cmdb->bindTexture(0, 0, a);
|
|
|
|
|
+ cmdb->bindTexture(0, 1, b);
|
|
|
|
|
+ cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 6);
|
|
|
cmdb->endRenderPass();
|
|
cmdb->endRenderPass();
|
|
|
cmdb->flush();
|
|
cmdb->flush();
|
|
|
|
|
|
|
@@ -840,8 +780,12 @@ ANKI_TEST(Gr, DrawWithTexture)
|
|
|
COMMON_END()
|
|
COMMON_END()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-static void drawOffscreenDrawcalls(
|
|
|
|
|
- GrManager& gr, PipelinePtr ppline, ResourceGroupPtr rc0, CommandBufferPtr cmdb, U viewPortSize)
|
|
|
|
|
|
|
+static void drawOffscreenDrawcalls(GrManager& gr,
|
|
|
|
|
+ ShaderProgramPtr prog,
|
|
|
|
|
+ CommandBufferPtr cmdb,
|
|
|
|
|
+ U viewPortSize,
|
|
|
|
|
+ BufferPtr indexBuff,
|
|
|
|
|
+ BufferPtr vertBuff)
|
|
|
{
|
|
{
|
|
|
static F32 ang = -2.5f;
|
|
static F32 ang = -2.5f;
|
|
|
ang += toRad(2.5f);
|
|
ang += toRad(2.5f);
|
|
@@ -851,38 +795,41 @@ static void drawOffscreenDrawcalls(
|
|
|
|
|
|
|
|
Mat4 projMat = Mat4::calculatePerspectiveProjectionMatrix(toRad(60.0), toRad(60.0), 0.1f, 100.0f);
|
|
Mat4 projMat = Mat4::calculatePerspectiveProjectionMatrix(toRad(60.0), toRad(60.0), 0.1f, 100.0f);
|
|
|
|
|
|
|
|
- TransientMemoryInfo transientInfo;
|
|
|
|
|
|
|
+ TransientMemoryToken token0, token1;
|
|
|
|
|
|
|
|
Mat4 modelMat(Vec4(-0.5, -0.5, 0.0, 1.0), Mat3(Euler(ang, ang / 2.0f, ang / 3.0f)), 1.0f);
|
|
Mat4 modelMat(Vec4(-0.5, -0.5, 0.0, 1.0), Mat3(Euler(ang, ang / 2.0f, ang / 3.0f)), 1.0f);
|
|
|
|
|
|
|
|
- Mat4* mvp = static_cast<Mat4*>(
|
|
|
|
|
- gr.allocateFrameTransientMemory(sizeof(*mvp), BufferUsageBit::UNIFORM_ALL, transientInfo.m_uniformBuffers[0]));
|
|
|
|
|
|
|
+ Mat4* mvp = static_cast<Mat4*>(gr.allocateFrameTransientMemory(sizeof(*mvp), BufferUsageBit::UNIFORM_ALL, token0));
|
|
|
*mvp = projMat * viewMat * modelMat;
|
|
*mvp = projMat * viewMat * modelMat;
|
|
|
|
|
|
|
|
- Vec4* color = static_cast<Vec4*>(gr.allocateFrameTransientMemory(
|
|
|
|
|
- sizeof(*color) * 2, BufferUsageBit::UNIFORM_ALL, transientInfo.m_uniformBuffers[1]));
|
|
|
|
|
|
|
+ Vec4* color =
|
|
|
|
|
+ static_cast<Vec4*>(gr.allocateFrameTransientMemory(sizeof(*color) * 2, BufferUsageBit::UNIFORM_ALL, token1));
|
|
|
*color++ = Vec4(1.0, 0.0, 0.0, 0.0);
|
|
*color++ = Vec4(1.0, 0.0, 0.0, 0.0);
|
|
|
*color = Vec4(0.0, 1.0, 0.0, 0.0);
|
|
*color = Vec4(0.0, 1.0, 0.0, 0.0);
|
|
|
|
|
|
|
|
- cmdb->bindPipeline(ppline);
|
|
|
|
|
|
|
+ cmdb->bindVertexBuffer(0, vertBuff, 0, sizeof(Vec3));
|
|
|
|
|
+ cmdb->setVertexAttribute(0, 0, PixelFormat(ComponentFormat::R32G32B32, TransformFormat::FLOAT), 0);
|
|
|
|
|
+ cmdb->bindShaderProgram(prog);
|
|
|
|
|
+ cmdb->bindIndexBuffer(indexBuff, 0, IndexType::U16);
|
|
|
cmdb->setViewport(0, 0, viewPortSize, viewPortSize);
|
|
cmdb->setViewport(0, 0, viewPortSize, viewPortSize);
|
|
|
- cmdb->bindResourceGroup(rc0, 0, &transientInfo);
|
|
|
|
|
- cmdb->drawElements(6 * 2 * 3);
|
|
|
|
|
|
|
+ cmdb->bindUniformBuffer(0, 0, token0);
|
|
|
|
|
+ cmdb->bindUniformBuffer(0, 1, token1);
|
|
|
|
|
+ cmdb->drawElements(PrimitiveTopology::TRIANGLES, 6 * 2 * 3);
|
|
|
|
|
|
|
|
// 2nd draw
|
|
// 2nd draw
|
|
|
modelMat = Mat4(Vec4(0.5, 0.5, 0.0, 1.0), Mat3(Euler(ang * 2.0, ang, ang / 3.0f * 2.0)), 1.0f);
|
|
modelMat = Mat4(Vec4(0.5, 0.5, 0.0, 1.0), Mat3(Euler(ang * 2.0, ang, ang / 3.0f * 2.0)), 1.0f);
|
|
|
|
|
|
|
|
- mvp = static_cast<Mat4*>(
|
|
|
|
|
- gr.allocateFrameTransientMemory(sizeof(*mvp), BufferUsageBit::UNIFORM_ALL, transientInfo.m_uniformBuffers[0]));
|
|
|
|
|
|
|
+ mvp = static_cast<Mat4*>(gr.allocateFrameTransientMemory(sizeof(*mvp), BufferUsageBit::UNIFORM_ALL, token0));
|
|
|
*mvp = projMat * viewMat * modelMat;
|
|
*mvp = projMat * viewMat * modelMat;
|
|
|
|
|
|
|
|
- color = static_cast<Vec4*>(gr.allocateFrameTransientMemory(
|
|
|
|
|
- sizeof(*color) * 2, BufferUsageBit::UNIFORM_ALL, transientInfo.m_uniformBuffers[1]));
|
|
|
|
|
|
|
+ color =
|
|
|
|
|
+ static_cast<Vec4*>(gr.allocateFrameTransientMemory(sizeof(*color) * 2, BufferUsageBit::UNIFORM_ALL, token1));
|
|
|
*color++ = Vec4(0.0, 0.0, 1.0, 0.0);
|
|
*color++ = Vec4(0.0, 0.0, 1.0, 0.0);
|
|
|
*color = Vec4(0.0, 1.0, 1.0, 0.0);
|
|
*color = Vec4(0.0, 1.0, 1.0, 0.0);
|
|
|
|
|
|
|
|
- cmdb->bindResourceGroup(rc0, 0, &transientInfo);
|
|
|
|
|
- cmdb->drawElements(6 * 2 * 3);
|
|
|
|
|
|
|
+ cmdb->bindUniformBuffer(0, 0, token0);
|
|
|
|
|
+ cmdb->bindUniformBuffer(0, 1, token1);
|
|
|
|
|
+ cmdb->drawElements(PrimitiveTopology::TRIANGLES, 6 * 2 * 3);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static void drawOffscreen(GrManager& gr, Bool useSecondLevel)
|
|
static void drawOffscreen(GrManager& gr, Bool useSecondLevel)
|
|
@@ -923,6 +870,7 @@ static void drawOffscreen(GrManager& gr, Bool useSecondLevel)
|
|
|
fbinit.m_colorAttachments[1].m_texture = col1;
|
|
fbinit.m_colorAttachments[1].m_texture = col1;
|
|
|
fbinit.m_colorAttachments[1].m_clearValue.m_colorf = {0.0, 0.1, 0.0, 0.0};
|
|
fbinit.m_colorAttachments[1].m_clearValue.m_colorf = {0.0, 0.1, 0.0, 0.0};
|
|
|
fbinit.m_depthStencilAttachment.m_texture = dp;
|
|
fbinit.m_depthStencilAttachment.m_texture = dp;
|
|
|
|
|
+ fbinit.m_depthStencilAttachment.m_aspect = DepthStencilAspectMask::DEPTH;
|
|
|
fbinit.m_depthStencilAttachment.m_clearValue.m_depthStencil.m_depth = 1.0;
|
|
fbinit.m_depthStencilAttachment.m_clearValue.m_depthStencil.m_depth = 1.0;
|
|
|
|
|
|
|
|
FramebufferPtr fb = gr.newInstance<Framebuffer>(fbinit);
|
|
FramebufferPtr fb = gr.newInstance<Framebuffer>(fbinit);
|
|
@@ -933,51 +881,16 @@ static void drawOffscreen(GrManager& gr, Bool useSecondLevel)
|
|
|
FramebufferPtr dfb = createDefaultFb(gr);
|
|
FramebufferPtr dfb = createDefaultFb(gr);
|
|
|
|
|
|
|
|
//
|
|
//
|
|
|
- // Create buffs and rc groups
|
|
|
|
|
|
|
+ // Create buffs
|
|
|
//
|
|
//
|
|
|
BufferPtr verts, indices;
|
|
BufferPtr verts, indices;
|
|
|
createCube(gr, verts, indices);
|
|
createCube(gr, verts, indices);
|
|
|
|
|
|
|
|
- ResourceGroupInitInfo rcinit;
|
|
|
|
|
- rcinit.m_uniformBuffers[0].m_uploadedMemory = true;
|
|
|
|
|
- rcinit.m_uniformBuffers[0].m_usage = BufferUsageBit::UNIFORM_FRAGMENT | BufferUsageBit::UNIFORM_VERTEX;
|
|
|
|
|
- rcinit.m_uniformBuffers[1].m_uploadedMemory = true;
|
|
|
|
|
- rcinit.m_uniformBuffers[1].m_usage = BufferUsageBit::UNIFORM_FRAGMENT | BufferUsageBit::UNIFORM_VERTEX;
|
|
|
|
|
- rcinit.m_vertexBuffers[0].m_buffer = verts;
|
|
|
|
|
- rcinit.m_indexBuffer.m_buffer = indices;
|
|
|
|
|
- rcinit.m_indexSize = 2;
|
|
|
|
|
-
|
|
|
|
|
- ResourceGroupPtr rc0 = gr.newInstance<ResourceGroup>(rcinit);
|
|
|
|
|
-
|
|
|
|
|
- rcinit = {};
|
|
|
|
|
- rcinit.m_textures[0].m_texture = col0;
|
|
|
|
|
- rcinit.m_textures[1].m_texture = col1;
|
|
|
|
|
- ResourceGroupPtr rc1 = gr.newInstance<ResourceGroup>(rcinit);
|
|
|
|
|
-
|
|
|
|
|
//
|
|
//
|
|
|
- // Create pplines
|
|
|
|
|
|
|
+ // Create progs
|
|
|
//
|
|
//
|
|
|
- ShaderPtr vert = gr.newInstance<Shader>(ShaderType::VERTEX, VERT_MRT_SRC);
|
|
|
|
|
- ShaderPtr frag = gr.newInstance<Shader>(ShaderType::FRAGMENT, FRAG_MRT_SRC);
|
|
|
|
|
-
|
|
|
|
|
- PipelineInitInfo pinit;
|
|
|
|
|
- pinit.m_shaders[ShaderType::VERTEX] = vert;
|
|
|
|
|
- pinit.m_shaders[ShaderType::FRAGMENT] = frag;
|
|
|
|
|
- pinit.m_color.m_attachmentCount = 2;
|
|
|
|
|
- pinit.m_color.m_attachments[0].m_format = COL_FORMAT;
|
|
|
|
|
- pinit.m_color.m_attachments[1].m_format = COL_FORMAT;
|
|
|
|
|
- pinit.m_depthStencil.m_depthWriteEnabled = true;
|
|
|
|
|
- pinit.m_depthStencil.m_format = DS_FORMAT;
|
|
|
|
|
-
|
|
|
|
|
- pinit.m_vertex.m_attributeCount = 1;
|
|
|
|
|
- pinit.m_vertex.m_attributes[0].m_format = PixelFormat(ComponentFormat::R32G32B32, TransformFormat::FLOAT);
|
|
|
|
|
-
|
|
|
|
|
- pinit.m_vertex.m_bindingCount = 1;
|
|
|
|
|
- pinit.m_vertex.m_bindings[0].m_stride = sizeof(Vec3);
|
|
|
|
|
-
|
|
|
|
|
- PipelinePtr ppline = gr.newInstance<Pipeline>(pinit);
|
|
|
|
|
-
|
|
|
|
|
- PipelinePtr pplineResolve = createSimplePpline(VERT_QUAD_SRC, FRAG_MRT2_SRC, gr);
|
|
|
|
|
|
|
+ ShaderProgramPtr prog = createProgram(VERT_MRT_SRC, FRAG_MRT_SRC, gr);
|
|
|
|
|
+ ShaderProgramPtr resolveProg = createProgram(VERT_QUAD_SRC, FRAG_MRT2_SRC, gr);
|
|
|
|
|
|
|
|
//
|
|
//
|
|
|
// Draw
|
|
// Draw
|
|
@@ -991,6 +904,7 @@ static void drawOffscreen(GrManager& gr, Bool useSecondLevel)
|
|
|
gr.beginFrame();
|
|
gr.beginFrame();
|
|
|
|
|
|
|
|
CommandBufferInitInfo cinit;
|
|
CommandBufferInitInfo cinit;
|
|
|
|
|
+ cinit.m_flags = CommandBufferFlag::GRAPHICS_WORK;
|
|
|
CommandBufferPtr cmdb = gr.newInstance<CommandBuffer>(cinit);
|
|
CommandBufferPtr cmdb = gr.newInstance<CommandBuffer>(cinit);
|
|
|
|
|
|
|
|
cmdb->setPolygonOffset(0.0, 0.0);
|
|
cmdb->setPolygonOffset(0.0, 0.0);
|
|
@@ -1007,18 +921,16 @@ static void drawOffscreen(GrManager& gr, Bool useSecondLevel)
|
|
|
|
|
|
|
|
if(!useSecondLevel)
|
|
if(!useSecondLevel)
|
|
|
{
|
|
{
|
|
|
- drawOffscreenDrawcalls(gr, ppline, rc0, cmdb, TEX_SIZE);
|
|
|
|
|
|
|
+ drawOffscreenDrawcalls(gr, prog, cmdb, TEX_SIZE, indices, verts);
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
|
CommandBufferInitInfo cinit;
|
|
CommandBufferInitInfo cinit;
|
|
|
- cinit.m_flags = CommandBufferFlag::SECOND_LEVEL;
|
|
|
|
|
|
|
+ cinit.m_flags = CommandBufferFlag::SECOND_LEVEL | CommandBufferFlag::GRAPHICS_WORK;
|
|
|
cinit.m_framebuffer = fb;
|
|
cinit.m_framebuffer = fb;
|
|
|
CommandBufferPtr cmdb2 = gr.newInstance<CommandBuffer>(cinit);
|
|
CommandBufferPtr cmdb2 = gr.newInstance<CommandBuffer>(cinit);
|
|
|
|
|
|
|
|
- cmdb2->setPolygonOffset(0.0, 0.0);
|
|
|
|
|
-
|
|
|
|
|
- drawOffscreenDrawcalls(gr, ppline, rc0, cmdb2, TEX_SIZE);
|
|
|
|
|
|
|
+ drawOffscreenDrawcalls(gr, prog, cmdb2, TEX_SIZE, indices, verts);
|
|
|
|
|
|
|
|
cmdb->pushSecondLevelCommandBuffer(cmdb2);
|
|
cmdb->pushSecondLevelCommandBuffer(cmdb2);
|
|
|
}
|
|
}
|
|
@@ -1040,10 +952,11 @@ static void drawOffscreen(GrManager& gr, Bool useSecondLevel)
|
|
|
|
|
|
|
|
// Draw quad
|
|
// Draw quad
|
|
|
cmdb->beginRenderPass(dfb);
|
|
cmdb->beginRenderPass(dfb);
|
|
|
- cmdb->bindPipeline(pplineResolve);
|
|
|
|
|
|
|
+ cmdb->bindShaderProgram(resolveProg);
|
|
|
cmdb->setViewport(0, 0, WIDTH, HEIGHT);
|
|
cmdb->setViewport(0, 0, WIDTH, HEIGHT);
|
|
|
- cmdb->bindResourceGroup(rc1, 0, nullptr);
|
|
|
|
|
- cmdb->drawArrays(6);
|
|
|
|
|
|
|
+ cmdb->bindTexture(0, 0, col0);
|
|
|
|
|
+ cmdb->bindTexture(0, 1, col1);
|
|
|
|
|
+ cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 6);
|
|
|
cmdb->endRenderPass();
|
|
cmdb->endRenderPass();
|
|
|
|
|
|
|
|
cmdb->flush();
|
|
cmdb->flush();
|
|
@@ -1092,31 +1005,12 @@ ANKI_TEST(Gr, ImageLoadStore)
|
|
|
|
|
|
|
|
TexturePtr tex = gr->newInstance<Texture>(init);
|
|
TexturePtr tex = gr->newInstance<Texture>(init);
|
|
|
|
|
|
|
|
- // Ppline
|
|
|
|
|
- PipelinePtr ppline = createSimplePpline(VERT_QUAD_SRC, FRAG_SIMPLE_TEX_SRC, *gr);
|
|
|
|
|
|
|
+ // Prog
|
|
|
|
|
+ ShaderProgramPtr prog = createProgram(VERT_QUAD_SRC, FRAG_SIMPLE_TEX_SRC, *gr);
|
|
|
|
|
|
|
|
- // Create shader & compute ppline
|
|
|
|
|
|
|
+ // Create shader & compute prog
|
|
|
ShaderPtr shader = gr->newInstance<Shader>(ShaderType::COMPUTE, COMP_WRITE_IMAGE_SRC);
|
|
ShaderPtr shader = gr->newInstance<Shader>(ShaderType::COMPUTE, COMP_WRITE_IMAGE_SRC);
|
|
|
-
|
|
|
|
|
- PipelineInitInfo ppinit;
|
|
|
|
|
- ppinit.m_shaders[ShaderType::COMPUTE] = shader;
|
|
|
|
|
- PipelinePtr compPpline = gr->newInstance<Pipeline>(ppinit);
|
|
|
|
|
-
|
|
|
|
|
- // RC group
|
|
|
|
|
- ResourceGroupInitInfo rcinit;
|
|
|
|
|
- rcinit.m_textures[0].m_texture = tex;
|
|
|
|
|
- ResourceGroupPtr rc0 = gr->newInstance<ResourceGroup>(rcinit);
|
|
|
|
|
-
|
|
|
|
|
- rcinit = ResourceGroupInitInfo();
|
|
|
|
|
- rcinit.m_images[0].m_texture = tex;
|
|
|
|
|
- rcinit.m_images[0].m_usage = TextureUsageBit::IMAGE_COMPUTE_WRITE;
|
|
|
|
|
- rcinit.m_images[0].m_level = 1;
|
|
|
|
|
- ResourceGroupPtr rc1 = gr->newInstance<ResourceGroup>(rcinit);
|
|
|
|
|
-
|
|
|
|
|
- rcinit = ResourceGroupInitInfo();
|
|
|
|
|
- rcinit.m_storageBuffers[0].m_uploadedMemory = true;
|
|
|
|
|
- rcinit.m_storageBuffers[0].m_usage = BufferUsageBit::STORAGE_COMPUTE_READ;
|
|
|
|
|
- ResourceGroupPtr rc2 = gr->newInstance<ResourceGroup>(rcinit);
|
|
|
|
|
|
|
+ ShaderProgramPtr compProg = gr->newInstance<ShaderProgram>(shader);
|
|
|
|
|
|
|
|
// FB
|
|
// FB
|
|
|
FramebufferPtr dfb = createDefaultFb(*gr);
|
|
FramebufferPtr dfb = createDefaultFb(*gr);
|
|
@@ -1153,19 +1047,20 @@ ANKI_TEST(Gr, ImageLoadStore)
|
|
|
gr->beginFrame();
|
|
gr->beginFrame();
|
|
|
|
|
|
|
|
CommandBufferInitInfo cinit;
|
|
CommandBufferInitInfo cinit;
|
|
|
|
|
+ cinit.m_flags = CommandBufferFlag::GRAPHICS_WORK | CommandBufferFlag::COMPUTE_WORK;
|
|
|
CommandBufferPtr cmdb = gr->newInstance<CommandBuffer>(cinit);
|
|
CommandBufferPtr cmdb = gr->newInstance<CommandBuffer>(cinit);
|
|
|
|
|
|
|
|
// Write image
|
|
// Write image
|
|
|
- TransientMemoryInfo trans;
|
|
|
|
|
- Vec4* col = static_cast<Vec4*>(
|
|
|
|
|
- gr->allocateFrameTransientMemory(sizeof(*col), BufferUsageBit::STORAGE_ALL, trans.m_storageBuffers[0]));
|
|
|
|
|
|
|
+ TransientMemoryToken token;
|
|
|
|
|
+ Vec4* col =
|
|
|
|
|
+ static_cast<Vec4*>(gr->allocateFrameTransientMemory(sizeof(*col), BufferUsageBit::STORAGE_ALL, token));
|
|
|
*col = Vec4(iterations / F32(ITERATION_COUNT));
|
|
*col = Vec4(iterations / F32(ITERATION_COUNT));
|
|
|
|
|
|
|
|
cmdb->setTextureSurfaceBarrier(
|
|
cmdb->setTextureSurfaceBarrier(
|
|
|
tex, TextureUsageBit::NONE, TextureUsageBit::IMAGE_COMPUTE_WRITE, TextureSurfaceInfo(1, 0, 0, 0));
|
|
tex, TextureUsageBit::NONE, TextureUsageBit::IMAGE_COMPUTE_WRITE, TextureSurfaceInfo(1, 0, 0, 0));
|
|
|
- cmdb->bindPipeline(compPpline);
|
|
|
|
|
- cmdb->bindResourceGroup(rc1, 0, nullptr);
|
|
|
|
|
- cmdb->bindResourceGroup(rc2, 1, &trans);
|
|
|
|
|
|
|
+ cmdb->bindShaderProgram(compProg);
|
|
|
|
|
+ cmdb->bindImage(0, 0, tex, 1);
|
|
|
|
|
+ cmdb->bindStorageBuffer(1, 0, token);
|
|
|
cmdb->dispatchCompute(WIDTH / 2, HEIGHT / 2, 1);
|
|
cmdb->dispatchCompute(WIDTH / 2, HEIGHT / 2, 1);
|
|
|
cmdb->setTextureSurfaceBarrier(tex,
|
|
cmdb->setTextureSurfaceBarrier(tex,
|
|
|
TextureUsageBit::IMAGE_COMPUTE_WRITE,
|
|
TextureUsageBit::IMAGE_COMPUTE_WRITE,
|
|
@@ -1173,13 +1068,12 @@ ANKI_TEST(Gr, ImageLoadStore)
|
|
|
TextureSurfaceInfo(1, 0, 0, 0));
|
|
TextureSurfaceInfo(1, 0, 0, 0));
|
|
|
|
|
|
|
|
// Present image
|
|
// Present image
|
|
|
- cmdb->setPolygonOffset(0.0, 0.0);
|
|
|
|
|
cmdb->setViewport(0, 0, WIDTH, HEIGHT);
|
|
cmdb->setViewport(0, 0, WIDTH, HEIGHT);
|
|
|
|
|
|
|
|
- cmdb->bindPipeline(ppline);
|
|
|
|
|
|
|
+ cmdb->bindShaderProgram(prog);
|
|
|
cmdb->beginRenderPass(dfb);
|
|
cmdb->beginRenderPass(dfb);
|
|
|
- cmdb->bindResourceGroup(rc0, 0, nullptr);
|
|
|
|
|
- cmdb->drawArrays(6);
|
|
|
|
|
|
|
+ cmdb->bindTexture(0, 0, tex);
|
|
|
|
|
+ cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 6);
|
|
|
cmdb->endRenderPass();
|
|
cmdb->endRenderPass();
|
|
|
|
|
|
|
|
cmdb->flush();
|
|
cmdb->flush();
|
|
@@ -1282,14 +1176,7 @@ ANKI_TEST(Gr, 3DTextures)
|
|
|
//
|
|
//
|
|
|
// Rest
|
|
// Rest
|
|
|
//
|
|
//
|
|
|
- PipelinePtr ppline = createSimplePpline(VERT_QUAD_SRC, FRAG_TEX3D_SRC, *gr);
|
|
|
|
|
-
|
|
|
|
|
- ResourceGroupInitInfo rcinit;
|
|
|
|
|
- rcinit.m_uniformBuffers[0].m_uploadedMemory = true;
|
|
|
|
|
- rcinit.m_uniformBuffers[0].m_usage = BufferUsageBit::UNIFORM_FRAGMENT;
|
|
|
|
|
- rcinit.m_textures[0].m_texture = a;
|
|
|
|
|
- rcinit.m_textures[0].m_usage = TextureUsageBit::SAMPLED_FRAGMENT;
|
|
|
|
|
- ResourceGroupPtr rc = gr->newInstance<ResourceGroup>(rcinit);
|
|
|
|
|
|
|
+ ShaderProgramPtr prog = createProgram(VERT_QUAD_SRC, FRAG_TEX3D_SRC, *gr);
|
|
|
|
|
|
|
|
FramebufferPtr dfb = createDefaultFb(*gr);
|
|
FramebufferPtr dfb = createDefaultFb(*gr);
|
|
|
|
|
|
|
@@ -1312,23 +1199,24 @@ ANKI_TEST(Gr, 3DTextures)
|
|
|
gr->beginFrame();
|
|
gr->beginFrame();
|
|
|
|
|
|
|
|
CommandBufferInitInfo cinit;
|
|
CommandBufferInitInfo cinit;
|
|
|
|
|
+ cinit.m_flags = CommandBufferFlag::GRAPHICS_WORK;
|
|
|
CommandBufferPtr cmdb = gr->newInstance<CommandBuffer>(cinit);
|
|
CommandBufferPtr cmdb = gr->newInstance<CommandBuffer>(cinit);
|
|
|
|
|
|
|
|
- cmdb->setPolygonOffset(0.0, 0.0);
|
|
|
|
|
cmdb->setViewport(0, 0, WIDTH, HEIGHT);
|
|
cmdb->setViewport(0, 0, WIDTH, HEIGHT);
|
|
|
cmdb->beginRenderPass(dfb);
|
|
cmdb->beginRenderPass(dfb);
|
|
|
|
|
|
|
|
- cmdb->bindPipeline(ppline);
|
|
|
|
|
|
|
+ cmdb->bindShaderProgram(prog);
|
|
|
|
|
|
|
|
- TransientMemoryInfo transientInfo;
|
|
|
|
|
- Vec4* uv = static_cast<Vec4*>(gr->allocateFrameTransientMemory(
|
|
|
|
|
- sizeof(Vec4), BufferUsageBit::UNIFORM_ALL, transientInfo.m_uniformBuffers[0]));
|
|
|
|
|
|
|
+ TransientMemoryToken token;
|
|
|
|
|
+ Vec4* uv =
|
|
|
|
|
+ static_cast<Vec4*>(gr->allocateFrameTransientMemory(sizeof(Vec4), BufferUsageBit::UNIFORM_ALL, token));
|
|
|
|
|
|
|
|
U idx = (F32(ITERATION_COUNT - iterations - 1) / ITERATION_COUNT) * TEX_COORDS_LOD.getSize();
|
|
U idx = (F32(ITERATION_COUNT - iterations - 1) / ITERATION_COUNT) * TEX_COORDS_LOD.getSize();
|
|
|
*uv = TEX_COORDS_LOD[idx];
|
|
*uv = TEX_COORDS_LOD[idx];
|
|
|
|
|
|
|
|
- cmdb->bindResourceGroup(rc, 0, &transientInfo);
|
|
|
|
|
- cmdb->drawArrays(6);
|
|
|
|
|
|
|
+ cmdb->bindUniformBuffer(0, 0, token);
|
|
|
|
|
+ cmdb->bindTexture(0, 0, a);
|
|
|
|
|
+ cmdb->drawArrays(PrimitiveTopology::TRIANGLES, 6);
|
|
|
|
|
|
|
|
cmdb->endRenderPass();
|
|
cmdb->endRenderPass();
|
|
|
|
|
|