Error MainRenderer::render(SceneGraph& scene) { ANKI_TRACE_START_EVENT(RENDER); // First thing, reset the temp mem pool m_frameAlloc.getMemoryPool().reset(); GrManager& gl = m_r->getGrManager(); CommandBufferInitInfo cinf; cinf.m_hints = m_cbInitHints; CommandBufferPtr cmdb = gl.newInstance<CommandBuffer>(cinf); // Set some of the dynamic state cmdb->setPolygonOffset(0.0, 0.0); // Run renderer RenderingContext ctx(m_frameAlloc); if(m_rDrawToDefaultFb) { ctx.m_outFb = m_defaultFb; ctx.m_outFbWidth = m_width; ctx.m_outFbHeight = m_height; } ctx.m_commandBuffer = cmdb; ctx.m_frustumComponent = &scene.getActiveCamera().getComponent<FrustumComponent>(); ANKI_CHECK(m_r->render(ctx)); // Blit renderer's result to default FB if needed if(!m_rDrawToDefaultFb) { cmdb->beginRenderPass(m_defaultFb); cmdb->setViewport(0, 0, m_width, m_height); cmdb->bindPipeline(m_blitPpline); cmdb->bindResourceGroup(m_rcGroup, 0, nullptr); m_r->drawQuad(cmdb); cmdb->endRenderPass(); } // Flush the command buffer cmdb->flush(); // Set the hints m_cbInitHints = cmdb->computeInitHints(); ANKI_TRACE_STOP_EVENT(RENDER); return ErrorCode::NONE; }
//============================================================================== Error Fs::buildCommandBuffers( RenderingContext& ctx, U threadId, U threadCount) const { // Get some stuff VisibilityTestResults& vis = ctx.m_frustumComponent->getVisibilityTestResults(); U problemSize = vis.getCount(VisibilityGroupType::RENDERABLES_FS); PtrSize start, end; ThreadPoolTask::choseStartEnd( threadId, threadCount, problemSize, start, end); if(start == end) { // Early exit return ErrorCode::NONE; } // Create the command buffer and set some state CommandBufferInitInfo cinf; cinf.m_secondLevel = true; cinf.m_framebuffer = m_fb; CommandBufferPtr cmdb = m_r->getGrManager().newInstance<CommandBuffer>(cinf); ctx.m_fs.m_commandBuffers[threadId] = cmdb; cmdb->setViewport(0, 0, m_width, m_height); cmdb->setPolygonOffset(0.0, 0.0); cmdb->bindResourceGroup(m_globalResources, 1, &ctx.m_is.m_dynBufferInfo); // Start drawing Error err = m_r->getSceneDrawer().drawRange(Pass::MS_FS, *ctx.m_frustumComponent, cmdb, vis.getBegin(VisibilityGroupType::RENDERABLES_FS) + start, vis.getBegin(VisibilityGroupType::RENDERABLES_FS) + end); return err; }
ANKI_TEST(Gr, SimpleDrawcall) { COMMON_BEGIN() PipelinePtr ppline = createSimplePpline(VERT_SRC, FRAG_SRC, *gr); FramebufferPtr fb = createDefaultFb(*gr); U iterations = 100; while(iterations--) { HighRezTimer timer; timer.start(); gr->beginFrame(); CommandBufferInitInfo cinit; CommandBufferPtr cmdb = gr->newInstance<CommandBuffer>(cinit); cmdb->setViewport(0, 0, WIDTH, HEIGHT); cmdb->setPolygonOffset(0.0, 0.0); cmdb->bindPipeline(ppline); cmdb->beginRenderPass(fb); cmdb->drawArrays(3); cmdb->endRenderPass(); cmdb->flush(); gr->swapBuffers(); timer.stop(); const F32 TICK = 1.0 / 30.0; if(timer.getElapsedTime() < TICK) { HighRezTimer::sleep(TICK - timer.getElapsedTime()); } } COMMON_END() }
ANKI_TEST(Gr, DrawWithUniforms) { COMMON_BEGIN() // A non-uploaded buffer BufferPtr b = gr->newInstance<Buffer>(sizeof(Vec4) * 3, BufferUsageBit::UNIFORM_ALL, BufferMapAccessBit::WRITE); Vec4* ptr = static_cast<Vec4*>(b->map(0, sizeof(Vec4) * 3, BufferMapAccessBit::WRITE)); ANKI_TEST_EXPECT_NEQ(ptr, nullptr); ptr[0] = Vec4(1.0, 0.0, 0.0, 0.0); ptr[1] = Vec4(0.0, 1.0, 0.0, 0.0); ptr[2] = Vec4(0.0, 0.0, 1.0, 0.0); 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); // FB FramebufferPtr fb = createDefaultFb(*gr); const U ITERATION_COUNT = 100; U iterations = ITERATION_COUNT; while(iterations--) { HighRezTimer timer; timer.start(); gr->beginFrame(); // Uploaded buffer TransientMemoryInfo transientInfo; Vec4* rotMat = static_cast<Vec4*>(gr->allocateFrameTransientMemory( sizeof(Vec4), BufferUsageBit::UNIFORM_ALL, transientInfo.m_uniformBuffers[1])); F32 angle = toRad(360.0f / ITERATION_COUNT * iterations); (*rotMat)[0] = cos(angle); (*rotMat)[1] = -sin(angle); (*rotMat)[2] = sin(angle); (*rotMat)[3] = cos(angle); CommandBufferInitInfo cinit; CommandBufferPtr cmdb = gr->newInstance<CommandBuffer>(cinit); cmdb->setViewport(0, 0, WIDTH, HEIGHT); cmdb->setPolygonOffset(0.0, 0.0); cmdb->bindPipeline(ppline); cmdb->beginRenderPass(fb); cmdb->bindResourceGroup(rc, 0, &transientInfo); cmdb->drawArrays(3); cmdb->endRenderPass(); cmdb->flush(); gr->swapBuffers(); timer.stop(); const F32 TICK = 1.0 / 30.0; if(timer.getElapsedTime() < TICK) { HighRezTimer::sleep(TICK - timer.getElapsedTime()); } } COMMON_END() }