diff options
| author | Yong He <yonghe@outlook.com> | 2021-02-24 15:43:43 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-02-24 15:43:43 -0800 |
| commit | 9b7a007c31072bc9aebd1134aa4f1bfd28a4c541 (patch) | |
| tree | b71a48eb30b3b09ab4e77e40dc1c68ecd854ef82 /examples/shader-toy/main.cpp | |
| parent | d66b30729029bdb43892e05c9c80fd56ac95a24f (diff) | |
Explicit swapchain interface in `gfx`. (#1726)
* Explicit swapchain interface in `gfx`.
* Correctly return nullptr when `IRenderer` creation failed.
* Fix crashes on CUDA tests.
* Cleanups.
Diffstat (limited to 'examples/shader-toy/main.cpp')
| -rw-r--r-- | examples/shader-toy/main.cpp | 98 |
1 files changed, 89 insertions, 9 deletions
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<gfx::IShaderProgram>& int gWindowWidth = 1024; int gWindowHeight = 768; +const uint32_t kSwapchainImageCount = 2; gfx::ApplicationContext* gAppContext; gfx::Window* gWindow; @@ -336,6 +337,8 @@ ComPtr<gfx::IPipelineLayout> gPipelineLayout; ComPtr<gfx::IPipelineState> gPipelineState; ComPtr<gfx::IDescriptorSet> gDescriptorSet; ComPtr<gfx::IBufferResource> gVertexBuffer; +ComPtr<gfx::ISwapchain> gSwapchain; +Slang::List<ComPtr<gfx::IFramebuffer>> 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<IFramebufferLayout> 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<gfx::ITextureResource> depthBufferResource = gRenderer->createTextureResource( + gfx::IResource::Usage::DepthWrite, depthBufferDesc, nullptr); + ComPtr<gfx::ITextureResource> 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<gfx::IResourceView> 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<gfx::IResourceView> 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<gfx::IFramebuffer> 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) { |
