diff options
| author | Yong He <yonghe@outlook.com> | 2021-03-04 16:25:58 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-03-04 16:25:58 -0800 |
| commit | a5ac4999b4dea546a7ef824669ab1809224b6448 (patch) | |
| tree | 15bb22eb98a94f7f81489deef55396461501d3dc /examples/hello-world | |
| parent | 13ff0bd345990c0fdfb7b52ebd5339cddb04889e (diff) | |
Refactor `gfx` to surface `CommandBuffer` interface. (#1735)
* Refactor `gfx` to surface `CommandBuffer` interface.
* Fixes.
* Fix code review issues, and make vulkan runnable on devices without VK_EXT_extended_dynamic_states.
* Update solution files
* Move out-of-date examples to examples/experimental
Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'examples/hello-world')
| -rw-r--r-- | examples/hello-world/main.cpp | 68 |
1 files changed, 42 insertions, 26 deletions
diff --git a/examples/hello-world/main.cpp b/examples/hello-world/main.cpp index f0ea3eb2a..47016b48d 100644 --- a/examples/hello-world/main.cpp +++ b/examples/hello-world/main.cpp @@ -219,6 +219,8 @@ ComPtr<gfx::IShaderObject> gRootObject; ComPtr<gfx::ISwapchain> gSwapchain; List<ComPtr<gfx::IFramebuffer>> gFramebuffers; ComPtr<gfx::IBufferResource> gVertexBuffer; +ComPtr<gfx::IRenderPassLayout> gRenderPass; +ComPtr<gfx::ICommandQueue> gQueue; // Now that we've covered the function that actually loads and // compiles our Slang shade code, we can go through the rest @@ -246,6 +248,10 @@ Slang::Result initialize() gfx::Result res = gfxCreateRenderer(&rendererDesc, gRenderer.writeRef()); if(SLANG_FAILED(res)) return res; + ICommandQueue::Desc queueDesc = {}; + queueDesc.type = ICommandQueue::QueueType::Graphics; + gQueue = gRenderer->createCommandQueue(queueDesc); + // Now we will create objects needed to configur the "input assembler" // (IA) stage of the D3D pipeline. // @@ -316,6 +322,7 @@ Slang::Result initialize() swapchainDesc.width = gWindowWidth; swapchainDesc.height = gWindowHeight; swapchainDesc.imageCount = kSwapchainImageCount; + swapchainDesc.queue = gQueue; gSwapchain = gRenderer->createSwapchain( swapchainDesc, gfx::WindowHandle::FromHwnd(getPlatformWindowHandle(gWindow))); @@ -331,7 +338,7 @@ Slang::Result initialize() for (uint32_t i = 0; i < kSwapchainImageCount; i++) { - gfx::ITextureResource::Desc depthBufferDesc; + gfx::ITextureResource::Desc depthBufferDesc = {}; depthBufferDesc.setDefaults(gfx::IResource::Usage::DepthWrite); depthBufferDesc.init2D( gfx::IResource::Type::Texture2D, @@ -345,23 +352,21 @@ Slang::Result initialize() ComPtr<gfx::ITextureResource> colorBuffer; gSwapchain->getImage(i, colorBuffer.writeRef()); - gfx::IResourceView::Desc colorBufferViewDesc; - memset(&colorBufferViewDesc, 0, sizeof(colorBufferViewDesc)); + gfx::IResourceView::Desc 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)); + gfx::IResourceView::Desc 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; + gfx::IFramebuffer::Desc framebufferDesc = {}; framebufferDesc.renderTargetCount = 1; framebufferDesc.depthStencilView = dsv.get(); framebufferDesc.renderTargetViews = rtv.readRef(); @@ -383,6 +388,23 @@ Slang::Result initialize() gPipelineState = pipelineState; + gfx::IRenderPassLayout::Desc renderPassDesc = {}; + renderPassDesc.framebufferLayout = framebufferLayout; + renderPassDesc.renderTargetCount = 1; + IRenderPassLayout::AttachmentAccessDesc renderTargetAccess = {}; + IRenderPassLayout::AttachmentAccessDesc depthStencilAccess = {}; + renderTargetAccess.loadOp = IRenderPassLayout::AttachmentLoadOp::Clear; + renderTargetAccess.storeOp = IRenderPassLayout::AttachmentStoreOp::Store; + renderTargetAccess.initialState = ResourceState::Undefined; + renderTargetAccess.finalState = ResourceState::Present; + depthStencilAccess.loadOp = IRenderPassLayout::AttachmentLoadOp::Clear; + depthStencilAccess.storeOp = IRenderPassLayout::AttachmentStoreOp::Store; + depthStencilAccess.initialState = ResourceState::Undefined; + depthStencilAccess.finalState = ResourceState::DepthWrite; + renderPassDesc.renderTargetAccess = &renderTargetAccess; + renderPassDesc.depthStencilAccess = &depthStencilAccess; + gRenderPass = gRenderer->createRenderPassLayout(renderPassDesc); + // Once we've initialized all the graphics API objects, // it is time to show our application window and start rendering. // @@ -398,22 +420,16 @@ Slang::Result initialize() // void renderFrame() { - gRenderer->beginFrame(); uint32_t frameBufferIndex = gSwapchain->acquireNextImage(); - gRenderer->setFramebuffer(gFramebuffers[frameBufferIndex]); + + ComPtr<ICommandBuffer> commandBuffer = gQueue->createCommandBuffer(); + auto renderEncoder = commandBuffer->encodeRenderCommands(gRenderPass, gFramebuffers[frameBufferIndex]); gfx::Viewport viewport = {}; viewport.maxZ = 1.0f; viewport.extentX = (float)gWindowWidth; viewport.extentY = (float)gWindowHeight; - gRenderer->setViewportAndScissor(viewport); - - - // We start by clearing our framebuffer, which only has a color target. - // - static const float kClearColor[] = { 0.25, 0.25, 0.25, 1.0 }; - gRenderer->setClearColor(kClearColor); - gRenderer->clearFrame(); + renderEncoder->setViewportAndScissor(viewport); // We will update the model-view-projection matrix that is passed // into the shader code via the `Uniforms` buffer on a per-frame @@ -485,31 +501,31 @@ void renderFrame() // PSO, binding our root shader object to it (which references // the `Uniforms` buffer that will filled in above). // - gRenderer->setPipelineState(gPipelineState); - gRenderer->bindRootShaderObject(PipelineType::Graphics, gRootObject); + renderEncoder->setPipelineState(gPipelineState); + renderEncoder->bindRootShaderObject(gRootObject); // We also need to set up a few pieces of fixed-function pipeline // state that are not bound by the pipeline state above. // - gRenderer->setVertexBuffer(0, gVertexBuffer, sizeof(Vertex)); - gRenderer->setPrimitiveTopology(PrimitiveTopology::TriangleList); + renderEncoder->setVertexBuffer(0, gVertexBuffer, sizeof(Vertex)); + renderEncoder->setPrimitiveTopology(PrimitiveTopology::TriangleList); // Finally, we are ready to issue a draw call for a single triangle. // - gRenderer->draw(3); + renderEncoder->draw(3); + renderEncoder->endEncoding(); + commandBuffer->close(); + gQueue->executeCommandBuffer(commandBuffer); // With that, we are done drawing for one frame, and ready for the next. // - gRenderer->makeSwapchainImagePresentable(gSwapchain); - - gRenderer->endFrame(); - gSwapchain->present(); } void finalize() { - gRenderer->waitForGpu(); + gQueue->wait(); + gSwapchain = nullptr; destroyWindow(gWindow); } |
