void Volumetric::setPostRunBarriers(RenderingContext& ctx) { ctx.m_commandBuffer->setTextureSurfaceBarrier(m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, TextureUsageBit::SAMPLED_FRAGMENT, TextureSurfaceInfo(0, 0, 0, 0)); }
void Is::setPreRunBarriers(RenderingContext& ctx) { ctx.m_commandBuffer->setTextureSurfaceBarrier(m_rt, TextureUsageBit::NONE, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE, TextureSurfaceInfo(0, 0, 0, 0)); }
void Volumetric::run(RenderingContext& ctx) { CommandBufferPtr& cmdb = ctx.m_commandBuffer; const Frustum& frc = ctx.m_frustumComponent->getFrustum(); // Update uniforms TransientMemoryInfo dyn = ctx.m_is.m_dynBufferInfo; Vec4* uniforms = static_cast<Vec4*>(getGrManager().allocateFrameTransientMemory( sizeof(Vec4) * 2, BufferUsageBit::UNIFORM_ALL, dyn.m_uniformBuffers[3])); computeLinearizeDepthOptimal(frc.getNear(), frc.getFar(), uniforms[0].x(), uniforms[0].y()); uniforms[1] = Vec4(m_fogColor, m_fogFactor); // pass 0 cmdb->setViewport(0, 0, m_r->getWidth() / VOLUMETRIC_FRACTION, m_r->getHeight() / VOLUMETRIC_FRACTION); cmdb->beginRenderPass(m_vblurFb); cmdb->bindPipeline(m_ppline); cmdb->bindResourceGroup(m_rc, 0, &dyn); m_r->drawQuad(cmdb); cmdb->endRenderPass(); // hpass cmdb->setTextureSurfaceBarrier(m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, TextureUsageBit::SAMPLED_FRAGMENT, TextureSurfaceInfo(0, 0, 0, 0)); cmdb->setTextureSurfaceBarrier( m_tmpRt, TextureUsageBit::NONE, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, TextureSurfaceInfo(0, 0, 0, 0)); cmdb->beginRenderPass(m_hblurFb); cmdb->bindPipeline(m_hblurPpline); cmdb->bindResourceGroup(m_hblurRc, 0, nullptr); m_r->drawQuad(cmdb); cmdb->endRenderPass(); // vpass cmdb->setTextureSurfaceBarrier(m_tmpRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, TextureUsageBit::SAMPLED_FRAGMENT, TextureSurfaceInfo(0, 0, 0, 0)); cmdb->setTextureSurfaceBarrier( m_rt, TextureUsageBit::NONE, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, TextureSurfaceInfo(0, 0, 0, 0)); cmdb->beginRenderPass(m_vblurFb); cmdb->bindPipeline(m_vblurPpline); cmdb->bindResourceGroup(m_vblurRc, 0, nullptr); m_r->drawQuad(cmdb); cmdb->endRenderPass(); }
Error Pps::run(RenderingContext& ctx) { CommandBufferPtr& cmdb = ctx.m_commandBuffer; // Get the drawing parameters Bool drawToDefaultFb = ctx.m_outFb.isCreated(); Bool dbgEnabled = m_r->getDbg().getEnabled(); // Get or create the ppline PipelinePtr& ppline = m_ppline[drawToDefaultFb][dbgEnabled]; if(!ppline) { // Need to create it ShaderResourcePtr& frag = m_frag[drawToDefaultFb][dbgEnabled]; if(!frag) { StringAuto pps(ctx.m_tempAllocator); pps.sprintf("#define BLOOM_ENABLED %u\n" "#define SHARPEN_ENABLED %u\n" "#define FBO_WIDTH %u\n" "#define FBO_HEIGHT %u\n" "#define LUT_SIZE %u.0\n" "#define DBG_ENABLED %u\n" "#define DRAW_TO_DEFAULT %u\n" "#define SMAA_ENABLED 1\n" "#define SMAA_RT_METRICS vec4(%f, %f, %f, %f)\n" "#define SMAA_PRESET_%s\n", true, m_sharpenEnabled, m_r->getWidth(), m_r->getHeight(), LUT_SIZE, dbgEnabled, drawToDefaultFb, 1.0 / m_r->getWidth(), 1.0 / m_r->getHeight(), F32(m_r->getWidth()), F32(m_r->getHeight()), &m_r->getSmaa().m_qualityPerset[0]); ANKI_CHECK(getResourceManager().loadResourceToCache(frag, "shaders/Pps.frag.glsl", pps.toCString(), "r_")); } if(!m_vert) { StringAuto pps(ctx.m_tempAllocator); pps.sprintf("#define SMAA_ENABLED 1\n" "#define SMAA_RT_METRICS vec4(%f, %f, %f, %f)\n" "#define SMAA_PRESET_%s\n", 1.0 / m_r->getWidth(), 1.0 / m_r->getHeight(), F32(m_r->getWidth()), F32(m_r->getHeight()), &m_r->getSmaa().m_qualityPerset[0]); ANKI_CHECK( getResourceManager().loadResourceToCache(m_vert, "shaders/Pps.vert.glsl", pps.toCString(), "r_")); } PixelFormat pfs = (drawToDefaultFb) ? PixelFormat(ComponentFormat::DEFAULT_FRAMEBUFFER, TransformFormat::NONE) : RT_PIXEL_FORMAT; PipelineInitInfo ppinit; ppinit.m_inputAssembler.m_topology = PrimitiveTopology::TRIANGLE_STRIP; ppinit.m_depthStencil.m_depthWriteEnabled = false; ppinit.m_depthStencil.m_depthCompareFunction = CompareOperation::ALWAYS; ppinit.m_color.m_attachmentCount = 1; ppinit.m_color.m_attachments[0].m_format = pfs; ppinit.m_shaders[ShaderType::VERTEX] = m_vert->getGrShader(); ppinit.m_shaders[ShaderType::FRAGMENT] = frag->getGrShader(); ppline = m_r->getGrManager().newInstance<Pipeline>(ppinit); } // Get or create the resource group ResourceGroupPtr& rsrc = m_rcGroup[dbgEnabled]; if(!rsrc || m_lutDirty) { ResourceGroupInitInfo rcInit; rcInit.m_textures[0].m_texture = m_r->getIs().getRt(); rcInit.m_textures[1].m_texture = m_r->getBloom().m_upscale.m_rt; rcInit.m_textures[2].m_texture = m_lut->getGrTexture(); rcInit.m_textures[3].m_texture = m_r->getSmaa().m_weights.m_rt; if(dbgEnabled) { rcInit.m_textures[4].m_texture = m_r->getDbg().getRt(); } rcInit.m_storageBuffers[0].m_buffer = m_r->getTm().getAverageLuminanceBuffer(); rcInit.m_storageBuffers[0].m_usage = BufferUsageBit::STORAGE_FRAGMENT_READ; rsrc = getGrManager().newInstance<ResourceGroup>(rcInit); m_lutDirty = false; } // Get or create FB FramebufferPtr* fb = nullptr; U width, height; if(drawToDefaultFb) { fb = &ctx.m_outFb; width = ctx.m_outFbWidth; height = ctx.m_outFbHeight; } else { width = m_r->getWidth(); height = m_r->getHeight(); fb = &m_fb; } cmdb->beginRenderPass(*fb); cmdb->setViewport(0, 0, width, height); cmdb->bindPipeline(ppline); cmdb->bindResourceGroup(rsrc, 0, nullptr); m_r->drawQuad(cmdb); cmdb->endRenderPass(); if(!drawToDefaultFb) { cmdb->setTextureSurfaceBarrier(m_rt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_WRITE, TextureUsageBit::SAMPLED_FRAGMENT, TextureSurfaceInfo(0, 0, 0, 0)); } return ErrorCode::NONE; }
//============================================================================== 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; }
//============================================================================== void CommandBufferImpl::generateMipmaps( TexturePtr tex, U depth, U face, U layer) { commandCommon(); const TextureImpl& impl = tex->getImplementation(); ANKI_ASSERT(impl.m_type != TextureType::_3D && "Not design for that ATM"); U mipCount = computeMaxMipmapCount(impl.m_width, impl.m_height); for(U i = 0; i < mipCount - 1; ++i) { // Transition source if(i > 0) { VkImageSubresourceRange range; impl.computeSubResourceRange( TextureSurfaceInfo(i, depth, face, layer), range); setImageBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, impl.m_imageHandle, range); } // Transition destination { VkImageSubresourceRange range; impl.computeSubResourceRange( TextureSurfaceInfo(i + 1, depth, face, layer), range); setImageBarrier(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, VK_IMAGE_LAYOUT_UNDEFINED, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, impl.m_imageHandle, range); } // Setup the blit struct I32 srcWidth = impl.m_width >> i; I32 srcHeight = impl.m_height >> i; I32 dstWidth = impl.m_width >> i; I32 dstHeight = impl.m_height >> i; ANKI_ASSERT( srcWidth > 0 && srcHeight > 0 && dstWidth > 0 && dstHeight > 0); VkImageBlit blit; blit.srcSubresource.aspectMask = impl.m_aspect; blit.srcSubresource.baseArrayLayer = layer; blit.srcSubresource.layerCount = 1; blit.srcSubresource.mipLevel = i; blit.srcOffsets[0] = {0, 0, 0}; blit.srcOffsets[1] = {srcWidth, srcHeight, 1}; blit.dstSubresource.aspectMask = impl.m_aspect; blit.dstSubresource.baseArrayLayer = layer; blit.dstSubresource.layerCount = 1; blit.dstSubresource.mipLevel = i + 1; blit.dstOffsets[0] = {0, 0, 0}; blit.dstOffsets[1] = {dstWidth, dstHeight, 1}; vkCmdBlitImage(m_handle, impl.m_imageHandle, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, impl.m_imageHandle, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit, VK_FILTER_LINEAR); } // Hold the reference m_texList.pushBack(m_alloc, tex); }