QuickShade
QuickShade is a composite Vulkan rendering library and tool designed to allow changes to rendering pipelines during the runtime of an application.
To connect these pipelines into an application, use the C++ QuickShade API to load in the graph and build the resources, which can then be added to the command buffer, with the ability to access any resources created through the graph. Here is a brief example of using a QuickShade pipeline to render to a texture.
/************************************************************************/ /* @brief Simple example of using Quickshade API to render to texture for single pass. @param context Manager for global Vulkan resources such as device and command buffer. @param target Texture to render to. @param pipeline_path Filepath to QuickShade pipeline graph. */ /************************************************************************/ void generateBRDFLUT_RG(const vks::Context& context, vks::texture::Texture2D& target, const std::filesystem::path& pipeline_path) { // Load render graph through QuickShade API and qs::RenderGraph graph; graph.LoadGraph(pipeline_path); graph.BuildVulkanResources(context); // access data from QuickShade pipeline graph needed for rendering auto pipeline = graph.m_pipeline; auto renderpass = graph.Get<qs::RenderPassNode>("BRDFLutRPNode_1"); auto viewport = graph.Get<qs::ViewportNode>("ViewportNode_1"); auto scissor = graph.Get<qs::Rect2DNode>("Rect2DNode_1"); auto framebuffer = graph.Get<qs::FrameBufferNode>("FrameBufferNode_1"); auto tex2d = graph.Get<qs::Tex2DNode>("Tex2DNode_1"); auto clearValues = graph.Get<qs::ClearValuesNode>("ClearValuesNode_1"); // add lookup to rendering target texture for future access target = tex2d->resource; target.updateDescriptor(); qs::RenderGraph::AddDataLookup("brdfLutTex", target); // Use built resources to add the renderpass to the command buffer vk::RenderPassBeginInfo renderPassBeginInfo; renderPassBeginInfo.renderPass = renderpass->resource; renderPassBeginInfo.renderArea.extent.width = viewport->width; renderPassBeginInfo.renderArea.extent.height = viewport->height; renderPassBeginInfo.clearValueCount = clearValues->count; renderPassBeginInfo.pClearValues = clearValues; renderPassBeginInfo.framebuffer = framebuffer->resource; context.withPrimaryCommandBuffer([&](const vk::CommandBuffer& cmdBuf) { cmdBuf.beginRenderPass(renderPassBeginInfo, vk::SubpassContents::eInline); cmdBuf.setViewport(0, viewport->resource); cmdBuf.setScissor(0, scissor->resource); cmdBuf.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline->resource); cmdBuf.draw(3, 1, 0, 0); cmdBuf.endRenderPass(); }); context.queue.waitIdle(); }