From 9b7a007c31072bc9aebd1134aa4f1bfd28a4c541 Mon Sep 17 00:00:00 2001 From: Yong He Date: Wed, 24 Feb 2021 15:43:43 -0800 Subject: Explicit swapchain interface in `gfx`. (#1726) * Explicit swapchain interface in `gfx`. * Correctly return nullptr when `IRenderer` creation failed. * Fix crashes on CUDA tests. * Cleanups. --- examples/shader-toy/main.cpp | 98 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 89 insertions(+), 9 deletions(-) (limited to 'examples/shader-toy/main.cpp') diff --git a/examples/shader-toy/main.cpp b/examples/shader-toy/main.cpp index 89aa74ccb..697bb1044 100644 --- a/examples/shader-toy/main.cpp +++ b/examples/shader-toy/main.cpp @@ -327,6 +327,7 @@ Result loadShaderProgram(gfx::IRenderer* renderer, ComPtr& int gWindowWidth = 1024; int gWindowHeight = 768; +const uint32_t kSwapchainImageCount = 2; gfx::ApplicationContext* gAppContext; gfx::Window* gWindow; @@ -336,6 +337,8 @@ ComPtr gPipelineLayout; ComPtr gPipelineState; ComPtr gDescriptorSet; ComPtr gVertexBuffer; +ComPtr gSwapchain; +Slang::List> gFramebuffers; Result initialize() { @@ -349,9 +352,7 @@ Result initialize() IRenderer::Desc rendererDesc; rendererDesc.rendererType = RendererType::DirectX11; - rendererDesc.width = gWindowWidth; - rendererDesc.height = gWindowHeight; - Result res = gfxCreateRenderer(&rendererDesc, getPlatformWindowHandle(gWindow), gRenderer.writeRef()); + Result res = gfxCreateRenderer(&rendererDesc, gRenderer.writeRef()); if(SLANG_FAILED(res)) return res; int constantBufferSize = sizeof(Uniforms); @@ -409,20 +410,82 @@ Result initialize() gPipelineLayout = pipelineLayout; - auto descriptorSet = gRenderer->createDescriptorSet(descriptorSetLayout); + auto descriptorSet = gRenderer->createDescriptorSet(descriptorSetLayout, IDescriptorSet::Flag::Transient); if(!descriptorSet) return SLANG_FAIL; descriptorSet->setConstantBuffer(0, 0, gConstantBuffer); gDescriptorSet = descriptorSet; + // Create swapchain and framebuffers. + gfx::ISwapchain::Desc swapchainDesc = {}; + swapchainDesc.format = gfx::Format::RGBA_Unorm_UInt8; + swapchainDesc.width = gWindowWidth; + swapchainDesc.height = gWindowHeight; + swapchainDesc.imageCount = kSwapchainImageCount; + gSwapchain = gRenderer->createSwapchain( + swapchainDesc, gfx::WindowHandle::FromHwnd(getPlatformWindowHandle(gWindow))); + + IFramebufferLayout::AttachmentLayout renderTargetLayout = {gSwapchain->getDesc().format, 1}; + IFramebufferLayout::AttachmentLayout depthLayout = {gfx::Format::D_Float32, 1}; + IFramebufferLayout::Desc framebufferLayoutDesc; + framebufferLayoutDesc.renderTargetCount = 1; + framebufferLayoutDesc.renderTargets = &renderTargetLayout; + framebufferLayoutDesc.depthStencil = &depthLayout; + ComPtr framebufferLayout; + SLANG_RETURN_ON_FAIL( + gRenderer->createFramebufferLayout(framebufferLayoutDesc, framebufferLayout.writeRef())); + + for (uint32_t i = 0; i < kSwapchainImageCount; i++) + { + gfx::ITextureResource::Desc depthBufferDesc; + depthBufferDesc.setDefaults(gfx::IResource::Usage::DepthWrite); + depthBufferDesc.init2D( + gfx::IResource::Type::Texture2D, + gfx::Format::D_Float32, + gSwapchain->getDesc().width, + gSwapchain->getDesc().height, + 0); + + ComPtr depthBufferResource = gRenderer->createTextureResource( + gfx::IResource::Usage::DepthWrite, depthBufferDesc, nullptr); + ComPtr colorBuffer; + gSwapchain->getImage(i, colorBuffer.writeRef()); + + gfx::IResourceView::Desc colorBufferViewDesc; + memset(&colorBufferViewDesc, 0, sizeof(colorBufferViewDesc)); + colorBufferViewDesc.format = gSwapchain->getDesc().format; + colorBufferViewDesc.renderTarget.shape = gfx::IResource::Type::Texture2D; + colorBufferViewDesc.type = gfx::IResourceView::Type::RenderTarget; + ComPtr rtv = + gRenderer->createTextureView(colorBuffer.get(), colorBufferViewDesc); + + gfx::IResourceView::Desc depthBufferViewDesc; + memset(&depthBufferViewDesc, 0, sizeof(depthBufferViewDesc)); + depthBufferViewDesc.format = gfx::Format::D_Float32; + depthBufferViewDesc.renderTarget.shape = gfx::IResource::Type::Texture2D; + depthBufferViewDesc.type = gfx::IResourceView::Type::DepthStencil; + ComPtr dsv = + gRenderer->createTextureView(depthBufferResource.get(), depthBufferViewDesc); + + gfx::IFramebuffer::Desc framebufferDesc; + framebufferDesc.renderTargetCount = 1; + framebufferDesc.depthStencilView = dsv.get(); + framebufferDesc.renderTargetViews = rtv.readRef(); + framebufferDesc.layout = framebufferLayout; + ComPtr frameBuffer = gRenderer->createFramebuffer(framebufferDesc); + gFramebuffers.add(frameBuffer); + } + + // Create pipeline. GraphicsPipelineStateDesc desc; - desc.pipelineLayout = gPipelineLayout; desc.inputLayout = inputLayout; desc.program = shaderProgram; - desc.renderTargetCount = 1; + desc.framebufferLayout = framebufferLayout; + desc.pipelineLayout = pipelineLayout; auto pipelineState = gRenderer->createGraphicsPipelineState(desc); - if(!pipelineState) return SLANG_FAIL; + if (!pipelineState) + return SLANG_FAIL; gPipelineState = pipelineState; @@ -443,12 +506,21 @@ uint64_t startTime = 0; void renderFrame() { + gRenderer->beginFrame(); + auto frameIndex = gSwapchain->acquireNextImage(); + gRenderer->setFramebuffer(gFramebuffers[frameIndex]); if( firstTime ) { startTime = getCurrentTime(); firstTime = false; } + gfx::Viewport viewport = {}; + viewport.maxZ = 1.0f; + viewport.extentX = (float)gWindowWidth; + viewport.extentY = (float)gWindowHeight; + gRenderer->setViewportAndScissor(viewport); + static const float kClearColor[] = { 0.25, 0.25, 0.25, 1.0 }; gRenderer->setClearColor(kClearColor); gRenderer->clearFrame(); @@ -483,10 +555,18 @@ void renderFrame() gRenderer->draw(3); - gRenderer->presentFrame(); + gRenderer->makeSwapchainImagePresentable(gSwapchain); + + gRenderer->endFrame(); + + gSwapchain->present(); } -void finalize() { destroyWindow(gWindow); } +void finalize() +{ + gRenderer->waitForGpu(); + destroyWindow(gWindow); +} void handleEvent(Event const& event) { -- cgit v1.2.3