//============================================================================== void RenderingThread::start() { ANKI_ASSERT(m_tail == 0 && m_head == 0); m_queue.create(m_manager->getAllocator(), QUEUE_SIZE); // Swap buffers stuff m_swapBuffersCommands = m_manager->newInstance<CommandBuffer>(CommandBufferInitInfo()); m_swapBuffersCommands->getImplementation() .pushBackNewCommand<SwapBuffersCommand>(this); m_manager->getImplementation().pinContextToCurrentThread(false); // Start thread m_thread.start(this, threadCallback); // Create sync command buffer m_syncCommands = m_manager->newInstance<CommandBuffer>(CommandBufferInitInfo()); m_syncCommands->getImplementation().pushBackNewCommand<SyncCommand>(this); m_emptyCmdb = m_manager->newInstance<CommandBuffer>(CommandBufferInitInfo()); m_emptyCmdb->getImplementation().pushBackNewCommand<EmptyCommand>(); }
void Sampler::init(const SamplerInitInfo& init) { m_impl.reset(getAllocator().newInstance<SamplerImpl>(&getManager())); CommandBufferPtr cmdb = getManager().newInstance<CommandBuffer>(CommandBufferInitInfo()); cmdb->m_impl->pushBackNewCommand<CreateSamplerCommand>(this, init); cmdb->flush(); }
void Texture::init(const TextureInitInfo& init) { m_impl.reset(getAllocator().newInstance<TextureImpl>(&getManager())); CommandBufferPtr cmdb = getManager().newInstance<CommandBuffer>(CommandBufferInitInfo()); cmdb->getImplementation().pushBackNewCommand<CreateTextureCommand>( this, init); cmdb->flush(); }
void OcclusionQuery::init(OcclusionQueryResultBit condRenderingBit) { m_impl.reset(getAllocator().newInstance<OcclusionQueryImpl>(&getManager())); CommandBufferPtr cmdb = getManager().newInstance<CommandBuffer>(CommandBufferInitInfo()); cmdb->getImplementation().pushBackNewCommand<CreateOqCommand>( this, condRenderingBit); cmdb->flush(); }
void GlObject::destroyDeferred(GrManager& manager, GlDeleteFunction deleteCallback) { class DeleteGlObjectCommand final : public GlCommand { public: GlObject::GlDeleteFunction m_callback; GLuint m_glName; DeleteGlObjectCommand(GlObject::GlDeleteFunction callback, GLuint name) : m_callback(callback) , m_glName(name) { } Error operator()(GlState&) { m_callback(1, &m_glName); return Error::NONE; } }; if(m_glName == 0) { return; } RenderingThread& thread = static_cast<GrManagerImpl&>(manager).getRenderingThread(); if(!thread.isServerThread()) { CommandBufferPtr commands; commands = manager.newCommandBuffer(CommandBufferInitInfo()); static_cast<CommandBufferImpl&>(*commands).pushBackNewCommand<DeleteGlObjectCommand>(deleteCallback, m_glName); static_cast<CommandBufferImpl&>(*commands).flush(); } else { deleteCallback(1, &m_glName); } m_glName = 0; }
TextureView* TextureView::newInstance(GrManager* manager, const TextureViewInitInfo& init) { class CreateTextureViewCommand final : public GlCommand { public: TextureViewPtr m_view; CreateTextureViewCommand(TextureView* view) : m_view(view) { } Error operator()(GlState&) { TextureViewImpl& impl = static_cast<TextureViewImpl&>(*m_view); impl.init(); GlObject::State oldState = impl.setStateAtomically(GlObject::State::CREATED); ANKI_ASSERT(oldState == GlObject::State::TO_BE_CREATED); (void)oldState; return Error::NONE; } }; TextureViewImpl* impl = manager->getAllocator().newInstance<TextureViewImpl>(manager, init.getName()); impl->getRefcount().fetchAdd(1); // Hold a reference in case the command finishes and deletes quickly // Need to pre-init because some funcs ask for members and we don't want to serialize impl->preInit(init); CommandBufferPtr cmdb = manager->newCommandBuffer(CommandBufferInitInfo()); static_cast<CommandBufferImpl&>(*cmdb).pushBackNewCommand<CreateTextureViewCommand>(impl); static_cast<CommandBufferImpl&>(*cmdb).flush(); return impl; }
Sampler* Sampler::newInstance(GrManager* manager, const SamplerInitInfo& init) { class CreateSamplerCommand : public GlCommand { public: SamplerPtr m_sampler; SamplerInitInfo m_init; CreateSamplerCommand(Sampler* sampler, const SamplerInitInfo& init) : m_sampler(sampler) , m_init(init) { } Error operator()(GlState&) { SamplerImpl& impl = static_cast<SamplerImpl&>(*m_sampler); impl.init(m_init); GlObject::State oldState = impl.setStateAtomically(GlObject::State::CREATED); (void)oldState; ANKI_ASSERT(oldState == GlObject::State::TO_BE_CREATED); return Error::NONE; } }; SamplerImpl* impl = manager->getAllocator().newInstance<SamplerImpl>(manager, init.getName()); impl->getRefcount().fetchAdd(1); // Hold a reference in case the command finishes and deletes quickly CommandBufferPtr cmdb = manager->newCommandBuffer(CommandBufferInitInfo()); static_cast<CommandBufferImpl&>(*cmdb).pushBackNewCommand<CreateSamplerCommand>(impl, init); static_cast<CommandBufferImpl&>(*cmdb).flush(); return impl; }
//============================================================================== Error TexUploadTask::operator()(AsyncLoaderTaskContext& ctx) { CommandBufferPtr cmdb; // Upload the data for(U depth = m_ctx.m_depth; depth < m_depth; ++depth) { for(U face = m_ctx.m_face; face < m_faces; ++face) { for(U mip = m_ctx.m_mip; mip < m_loader.getMipLevelsCount(); ++mip) { U surfIdx = max(depth, face); const auto& surf = m_loader.getSurface(mip, surfIdx); DynamicBufferToken token; void* data = m_gr->allocateFrameHostVisibleMemory( surf.m_data.getSize(), BufferUsage::TRANSFER, token); if(data) { // There is enough transfer memory memcpy(data, &surf.m_data[0], surf.m_data.getSize()); if(!cmdb) { cmdb = m_gr->newInstance<CommandBuffer>( CommandBufferInitInfo()); } cmdb->textureUpload( m_tex, TextureSurfaceInfo(mip, depth, face), token); } else { // Not enough transfer memory. Move the work to the future if(cmdb) { cmdb->flush(); } m_ctx.m_depth = depth; m_ctx.m_mip = mip; m_ctx.m_face = face; ctx.m_pause = true; ctx.m_resubmitTask = true; return ErrorCode::NONE; } } } } // Finaly enque the command buffer if(cmdb) { cmdb->flush(); } return ErrorCode::NONE; }
//============================================================================== Error TexUploadTask::operator()(AsyncLoaderTaskContext& ctx) { CommandBufferPtr cmdb; // Upload the data for(U layer = m_ctx.m_layer; layer < m_layers; ++layer) { for(U depth = m_ctx.m_depth; depth < m_depth; ++depth) { for(U face = m_ctx.m_face; face < m_faces; ++face) { for(U mip = m_ctx.m_mip; mip < m_loader.getMipLevelsCount(); ++mip) { const auto& surf = m_loader.getSurface(mip, depth, face, layer); TransientMemoryToken token; Error err = ErrorCode::NONE; void* data = m_gr->allocateFrameTransientMemory( surf.m_data.getSize(), BufferUsageBit::TRANSFER_SOURCE, token, &err); if(!err) { // There is enough transfer memory memcpy(data, &surf.m_data[0], surf.m_data.getSize()); if(!cmdb) { cmdb = m_gr->newInstance<CommandBuffer>( CommandBufferInitInfo()); } cmdb->uploadTextureSurface(m_tex, TextureSurfaceInfo(mip, depth, face, layer), token); } else { // Not enough transfer memory. Move the work to the // future if(cmdb) { cmdb->flush(); } m_ctx.m_depth = depth; m_ctx.m_mip = mip; m_ctx.m_face = face; m_ctx.m_layer = layer; ctx.m_pause = true; ctx.m_resubmitTask = true; return ErrorCode::NONE; } } } } } // Finaly enque the command buffer if(cmdb) { cmdb->flush(); } return ErrorCode::NONE; }
//============================================================================== Error MeshLoadTask::operator()(AsyncLoaderTaskContext& ctx) { GrManager& gr = m_manager->getGrManager(); CommandBufferPtr cmdb; // Write vert buff if(m_vertBuff) { TransientMemoryToken token; Error err = ErrorCode::NONE; void* data = gr.allocateFrameTransientMemory( m_loader.getVertexDataSize(), BufferUsage::TRANSFER, token, &err); if(!err) { memcpy( data, m_loader.getVertexData(), m_loader.getVertexDataSize()); cmdb = gr.newInstance<CommandBuffer>(CommandBufferInitInfo()); cmdb->uploadBuffer(m_vertBuff, 0, token); m_vertBuff.reset(nullptr); } else { ctx.m_pause = true; ctx.m_resubmitTask = true; return ErrorCode::NONE; } } // Create index buffer { TransientMemoryToken token; Error err = ErrorCode::NONE; void* data = gr.allocateFrameTransientMemory( m_loader.getIndexDataSize(), BufferUsage::TRANSFER, token, &err); if(!err) { memcpy(data, m_loader.getIndexData(), m_loader.getIndexDataSize()); if(!cmdb) { cmdb = gr.newInstance<CommandBuffer>(CommandBufferInitInfo()); } cmdb->uploadBuffer(m_indicesBuff, 0, token); cmdb->flush(); } else { // Submit prev work if(cmdb) { cmdb->flush(); } ctx.m_pause = true; ctx.m_resubmitTask = true; return ErrorCode::NONE; } } return ErrorCode::NONE; }