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 /tools/render-test/render-test-main.cpp | |
| 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 'tools/render-test/render-test-main.cpp')
| -rw-r--r-- | tools/render-test/render-test-main.cpp | 254 |
1 files changed, 162 insertions, 92 deletions
diff --git a/tools/render-test/render-test-main.cpp b/tools/render-test/render-test-main.cpp index 42c14a557..18670537d 100644 --- a/tools/render-test/render-test-main.cpp +++ b/tools/render-test/render-test-main.cpp @@ -6,7 +6,6 @@ #include "slang-gfx.h" #include "tools/gfx-util/shader-cursor.h" #include "slang-support.h" -#include "surface.h" #include "png-serialize-util.h" #include "shader-renderer-util.h" @@ -26,6 +25,14 @@ #include "cpu-compute-util.h" +#define ENABLE_RENDERDOC_INTEGRATION 0 + +#if ENABLE_RENDERDOC_INTEGRATION +# include "external/renderdoc_app.h" +# define WIN32_LEAN_AND_MEAN +# include <Windows.h> +#endif + #if RENDER_TEST_CUDA # include "cuda/cuda-compute-util.h" #endif @@ -92,12 +99,12 @@ public: IRenderer* renderer, const Options& options, const ShaderCompilerUtil::Input& input) = 0; - void runCompute(); - void renderFrame(); + void runCompute(IComputeCommandEncoder* encoder); + void renderFrame(IRenderCommandEncoder* encoder); void finalize(); - virtual void applyBinding(PipelineType pipelineType) = 0; - virtual void setProjectionMatrix() = 0; + virtual void applyBinding(PipelineType pipelineType, ICommandEncoder* encoder) = 0; + virtual void setProjectionMatrix(IResourceCommandEncoder* encoder) = 0; virtual Result writeBindingOutput(BindRoot* bindRoot, const char* fileName) = 0; Result writeScreen(const char* filename); @@ -109,7 +116,7 @@ protected: IRenderer* renderer, Options::ShaderProgramType shaderType, const ShaderCompilerUtil::Input& input); - void _initializeFramebuffer(); + void _initializeRenderPass(); virtual void finalizeImpl(); uint64_t m_startTicks; @@ -118,7 +125,8 @@ protected: uintptr_t m_constantBufferSize; ComPtr<IRenderer> m_renderer; - + ComPtr<ICommandQueue> m_queue; + ComPtr<IRenderPassLayout> m_renderPass; ComPtr<IInputLayout> m_inputLayout; ComPtr<IBufferResource> m_vertexBuffer; ComPtr<IShaderProgram> m_shaderProgram; @@ -137,8 +145,8 @@ protected: class LegacyRenderTestApp : public RenderTestApp { public: - virtual void applyBinding(PipelineType pipelineType) SLANG_OVERRIDE; - virtual void setProjectionMatrix() SLANG_OVERRIDE; + virtual void applyBinding(PipelineType pipelineType, ICommandEncoder* encoder) SLANG_OVERRIDE; + virtual void setProjectionMatrix(IResourceCommandEncoder* encoder) SLANG_OVERRIDE; virtual Result initialize( SlangSession* session, IRenderer* renderer, @@ -148,6 +156,7 @@ public: BindingStateImpl* getBindingState() const { return m_bindingState; } virtual Result writeBindingOutput(BindRoot* bindRoot, const char* fileName) override; + virtual void finalizeImpl() SLANG_OVERRIDE; protected: uintptr_t m_constantBufferSize; @@ -159,8 +168,8 @@ protected: class ShaderObjectRenderTestApp : public RenderTestApp { public: - virtual void applyBinding(PipelineType pipelineType) SLANG_OVERRIDE; - virtual void setProjectionMatrix() SLANG_OVERRIDE; + virtual void applyBinding(PipelineType pipelineType, ICommandEncoder* encoder) SLANG_OVERRIDE; + virtual void setProjectionMatrix(IResourceCommandEncoder* encoder) SLANG_OVERRIDE; virtual Result initialize( SlangSession* session, IRenderer* renderer, @@ -456,14 +465,34 @@ SlangResult _assignVarsFromLayout( return SLANG_OK; } -void LegacyRenderTestApp::applyBinding(PipelineType pipelineType) +void LegacyRenderTestApp::applyBinding(PipelineType pipelineType, ICommandEncoder* encoder) { - m_bindingState->apply(m_renderer.get(), pipelineType); + m_bindingState->apply(encoder, pipelineType); } -void ShaderObjectRenderTestApp::applyBinding(PipelineType pipelineType) +void ShaderObjectRenderTestApp::applyBinding(PipelineType pipelineType, ICommandEncoder* encoder) { - m_renderer->bindRootShaderObject(pipelineType, m_programVars); + switch (pipelineType) + { + case PipelineType::Compute: + { + ComPtr<IComputeCommandEncoder> computeEncoder; + encoder->queryInterface( + SLANG_UUID_IComputeCommandEncoder, (void**)computeEncoder.writeRef()); + computeEncoder->bindRootShaderObject(m_programVars); + } + break; + case PipelineType::Graphics: + { + ComPtr<IRenderCommandEncoder> renderEncoder; + encoder->queryInterface( + SLANG_UUID_IRenderCommandEncoder, (void**)renderEncoder.writeRef()); + renderEncoder->bindRootShaderObject(m_programVars); + } + break; + default: + throw "unknown pipeline type"; + } } SlangResult LegacyRenderTestApp::initialize( @@ -478,7 +507,7 @@ SlangResult LegacyRenderTestApp::initialize( SLANG_RETURN_ON_FAIL(_initializeShaders(session, renderer, options.shaderType, input)); - _initializeFramebuffer(); + _initializeRenderPass(); m_numAddedConstantBuffers = 0; @@ -607,7 +636,7 @@ SlangResult ShaderObjectRenderTestApp::initialize( m_renderer = renderer; - _initializeFramebuffer(); + _initializeRenderPass(); { switch(m_options.shaderType) @@ -664,6 +693,13 @@ SlangResult ShaderObjectRenderTestApp::initialize( return m_pipelineState ? SLANG_OK : SLANG_FAIL; } +void LegacyRenderTestApp::finalizeImpl() +{ + m_constantBuffer = nullptr; + m_bindingState = nullptr; + RenderTestApp::finalizeImpl(); +} + void ShaderObjectRenderTestApp::finalizeImpl() { m_programVars = nullptr; @@ -682,8 +718,11 @@ Result RenderTestApp::_initializeShaders( return m_shaderProgram ? SLANG_OK : SLANG_FAIL; } -void RenderTestApp::_initializeFramebuffer() +void RenderTestApp::_initializeRenderPass() { + ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics}; + m_queue = m_renderer->createCommandQueue(queueDesc); + gfx::ITextureResource::Desc depthBufferDesc; depthBufferDesc.setDefaults(gfx::IResource::Usage::DepthWrite); depthBufferDesc.init2D( @@ -730,29 +769,43 @@ void RenderTestApp::_initializeFramebuffer() framebufferLayoutDesc.renderTargets = &colorAttachment; framebufferLayoutDesc.depthStencil = &depthAttachment; m_renderer->createFramebufferLayout(framebufferLayoutDesc, m_framebufferLayout.writeRef()); + gfx::IFramebuffer::Desc framebufferDesc; framebufferDesc.renderTargetCount = 1; framebufferDesc.depthStencilView = dsv.get(); framebufferDesc.renderTargetViews = rtv.readRef(); framebufferDesc.layout = m_framebufferLayout; m_renderer->createFramebuffer(framebufferDesc, m_framebuffer.writeRef()); + + IRenderPassLayout::Desc renderPassDesc = {}; + renderPassDesc.framebufferLayout = m_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::RenderTarget; + depthStencilAccess.loadOp = IRenderPassLayout::AttachmentLoadOp::Clear; + depthStencilAccess.storeOp = IRenderPassLayout::AttachmentStoreOp::Store; + depthStencilAccess.initialState = ResourceState::Undefined; + depthStencilAccess.finalState = ResourceState::DepthWrite; + renderPassDesc.renderTargetAccess = &renderTargetAccess; + renderPassDesc.depthStencilAccess = &depthStencilAccess; + m_renderer->createRenderPassLayout(renderPassDesc, m_renderPass.writeRef()); } -void LegacyRenderTestApp::setProjectionMatrix() +void LegacyRenderTestApp::setProjectionMatrix(IResourceCommandEncoder* encoder) { - auto mappedData = m_renderer->map(m_constantBuffer, MapFlavor::WriteDiscard); - if (mappedData) - { - const ProjectionStyle projectionStyle = - gfxGetProjectionStyle(m_renderer->getRendererType()); - gfxGetIdentityProjection(projectionStyle, (float*)mappedData); - - m_renderer->unmap(m_constantBuffer); - } + float matrix[16]; + const ProjectionStyle projectionStyle = gfxGetProjectionStyle(m_renderer->getRendererType()); + gfxGetIdentityProjection(projectionStyle, matrix); + encoder->uploadBufferData(m_constantBuffer, 0, sizeof(float) * 16, matrix); } -void ShaderObjectRenderTestApp::setProjectionMatrix() +void ShaderObjectRenderTestApp::setProjectionMatrix(IResourceCommandEncoder* encoder) { + SLANG_UNUSED(encoder); const ProjectionStyle projectionStyle = gfxGetProjectionStyle(m_renderer->getRendererType()); @@ -764,31 +817,29 @@ void ShaderObjectRenderTestApp::setProjectionMatrix() .setData(projectionMatrix, sizeof(projectionMatrix)); } -void RenderTestApp::renderFrame() +void RenderTestApp::renderFrame(IRenderCommandEncoder* encoder) { - setProjectionMatrix(); - auto pipelineType = PipelineType::Graphics; - m_renderer->setPipelineState(m_pipelineState); + encoder->setPipelineState(m_pipelineState); - m_renderer->setPrimitiveTopology(PrimitiveTopology::TriangleList); - m_renderer->setVertexBuffer(0, m_vertexBuffer, sizeof(Vertex)); + encoder->setPrimitiveTopology(PrimitiveTopology::TriangleList); + encoder->setVertexBuffer(0, m_vertexBuffer, sizeof(Vertex)); - applyBinding(pipelineType); + applyBinding(pipelineType, encoder); - m_renderer->draw(3); + encoder->draw(3); } -void RenderTestApp::runCompute() +void RenderTestApp::runCompute(IComputeCommandEncoder* encoder) { auto pipelineType = PipelineType::Compute; - m_renderer->setPipelineState(m_pipelineState); - applyBinding(pipelineType); - - m_startTicks = ProcessUtil::getClockTick(); - - m_renderer->dispatchCompute(m_options.computeDispatchSize[0], m_options.computeDispatchSize[1], m_options.computeDispatchSize[2]); + encoder->setPipelineState(m_pipelineState); + applyBinding(pipelineType, encoder); + encoder->dispatchCompute( + m_options.computeDispatchSize[0], + m_options.computeDispatchSize[1], + m_options.computeDispatchSize[2]); } void RenderTestApp::finalize() @@ -799,7 +850,11 @@ void RenderTestApp::finalize() m_vertexBuffer = nullptr; m_shaderProgram = nullptr; m_pipelineState = nullptr; - + m_renderPass = nullptr; + m_framebuffer = nullptr; + m_framebufferLayout = nullptr; + m_colorBuffer = nullptr; + m_queue = nullptr; m_renderer = nullptr; } @@ -809,10 +864,8 @@ void RenderTestApp::finalizeImpl() Result LegacyRenderTestApp::writeBindingOutput(BindRoot* bindRoot, const char* fileName) { - // Submit the work - m_renderer->submitGpuWork(); // Wait until everything is complete - m_renderer->waitForGpu(); + m_queue->wait(); FILE * f = fopen(fileName, "wb"); if (!f) @@ -832,17 +885,15 @@ Result LegacyRenderTestApp::writeBindingOutput(BindRoot* bindRoot, const char* f { IBufferResource* bufferResource = static_cast<IBufferResource*>(binding.resource.get()); const size_t bufferSize = bufferResource->getDesc()->sizeInBytes; - - unsigned int* ptr = (unsigned int*)m_renderer->map(bufferResource, MapFlavor::HostRead); - if (!ptr) + ComPtr<ISlangBlob> blob; + m_renderer->readBufferResource(bufferResource, 0, bufferSize, blob.writeRef()); + if (!blob) { return SLANG_FAIL; } - const SlangResult res = ShaderInputLayout::writeBinding(bindRoot, m_shaderInputLayout.entries[i], ptr, bufferSize, &writer); - - m_renderer->unmap(bufferResource); - + const SlangResult res = ShaderInputLayout::writeBinding( + bindRoot, m_shaderInputLayout.entries[i], blob->getBufferPointer(), bufferSize, &writer); SLANG_RETURN_ON_FAIL(res); } else @@ -856,10 +907,8 @@ Result LegacyRenderTestApp::writeBindingOutput(BindRoot* bindRoot, const char* f Result ShaderObjectRenderTestApp::writeBindingOutput(BindRoot* bindRoot, const char* fileName) { - // Submit the work - m_renderer->submitGpuWork(); // Wait until everything is complete - m_renderer->waitForGpu(); + m_queue->wait(); FILE * f = fopen(fileName, "wb"); if (!f) @@ -879,16 +928,14 @@ Result ShaderObjectRenderTestApp::writeBindingOutput(BindRoot* bindRoot, const c IBufferResource* bufferResource = static_cast<IBufferResource*>(resource.get()); const size_t bufferSize = bufferResource->getDesc()->sizeInBytes; - unsigned int* ptr = (unsigned int*)m_renderer->map(bufferResource, MapFlavor::HostRead); - if (!ptr) + ComPtr<ISlangBlob> blob; + m_renderer->readBufferResource(bufferResource, 0, bufferSize, blob.writeRef()); + if (!blob) { return SLANG_FAIL; } - - const SlangResult res = ShaderInputLayout::writeBinding(bindRoot, inputEntry, ptr, bufferSize, &writer); - - m_renderer->unmap(bufferResource); - + const SlangResult res = + ShaderInputLayout::writeBinding(bindRoot, inputEntry, blob->getBufferPointer(), bufferSize, &writer); SLANG_RETURN_ON_FAIL(res); } else @@ -904,52 +951,48 @@ Result RenderTestApp::writeScreen(const char* filename) { size_t rowPitch, pixelSize; ComPtr<ISlangBlob> blob; - SLANG_RETURN_ON_FAIL(m_renderer->readTextureResource(m_colorBuffer, blob.writeRef(), &rowPitch, &pixelSize)); + SLANG_RETURN_ON_FAIL(m_renderer->readTextureResource( + m_colorBuffer, ResourceState::RenderTarget, blob.writeRef(), &rowPitch, &pixelSize)); auto bufferSize = blob->getBufferSize(); - Surface surface; - size_t width = rowPitch / pixelSize; - size_t height = bufferSize / rowPitch; - surface.setUnowned( - (int)width, - (int)height, - gfx::Format::RGBA_Unorm_UInt8, - (int)rowPitch, - (void*)blob->getBufferPointer()); - return PngSerializeUtil::write(filename, surface); + uint32_t width = static_cast<uint32_t>(rowPitch / pixelSize); + uint32_t height = static_cast<uint32_t>(bufferSize / rowPitch); + return PngSerializeUtil::write(filename, blob, width, height); } Result RenderTestApp::update() { - m_renderer->beginFrame(); - - // Whenever we don't have Windows events to process, we render a frame. + auto commandBuffer = m_queue->createCommandBuffer(); if (m_options.shaderType == Options::ShaderProgramType::Compute) { - runCompute(); + auto encoder = commandBuffer->encodeComputeCommands(); + runCompute(encoder); + encoder->endEncoding(); } else { - static const float kClearColor[] = { 0.25, 0.25, 0.25, 1.0 }; - m_renderer->setFramebuffer(m_framebuffer); + auto resEncoder = commandBuffer->encodeResourceCommands(); + setProjectionMatrix(resEncoder); + resEncoder->endEncoding(); + auto encoder = commandBuffer->encodeRenderCommands(m_renderPass, m_framebuffer); gfx::Viewport viewport = {}; viewport.maxZ = 1.0f; viewport.extentX = (float)gWindowWidth; viewport.extentY = (float)gWindowHeight; - m_renderer->setViewportAndScissor(viewport); - - m_renderer->setClearColor(kClearColor); - m_renderer->clearFrame(); - renderFrame(); + encoder->setViewportAndScissor(viewport); + renderFrame(encoder); + encoder->endEncoding(); } + commandBuffer->close(); + + m_startTicks = ProcessUtil::getClockTick(); + m_queue->executeCommandBuffer(commandBuffer); + m_queue->wait(); // If we are in a mode where output is requested, we need to snapshot the back buffer here if (m_options.outputPath || m_options.performanceProfile) { - // Submit the work - m_renderer->submitGpuWork(); // Wait until everything is complete - m_renderer->waitForGpu(); if (m_options.performanceProfile) { @@ -1013,8 +1056,6 @@ Result RenderTestApp::update() } return SLANG_OK; } - - m_renderer->endFrame(); return SLANG_OK; } @@ -1049,11 +1090,38 @@ static SlangResult _setSessionPrelude(const Options& options, const char* exePat } // namespace renderer_test +#if ENABLE_RENDERDOC_INTEGRATION +static RENDERDOC_API_1_1_2* rdoc_api = NULL; +static void initializeRenderDoc() +{ + if (HMODULE mod = GetModuleHandleA("renderdoc.dll")) + { + pRENDERDOC_GetAPI RENDERDOC_GetAPI = + (pRENDERDOC_GetAPI)GetProcAddress(mod, "RENDERDOC_GetAPI"); + int ret = RENDERDOC_GetAPI(eRENDERDOC_API_Version_1_1_2, (void**)&rdoc_api); + assert(ret == 1); + } +} +static void renderDocBeginFrame() { if (rdoc_api) rdoc_api->StartFrameCapture(nullptr, nullptr); } +static void renderDocEndFrame() +{ + if (rdoc_api) + rdoc_api->EndFrameCapture(nullptr, nullptr); + _fgetchar(); +} +#else +static void initializeRenderDoc(){} +static void renderDocBeginFrame(){} +static void renderDocEndFrame(){} +#endif + static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* session, int argcIn, const char*const* argvIn) { using namespace renderer_test; using namespace Slang; + initializeRenderDoc(); + StdWriters::setSingleton(stdWriters); Options options; @@ -1400,8 +1468,10 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi app = new ShaderObjectRenderTestApp(); else app = new LegacyRenderTestApp(); + renderDocBeginFrame(); SLANG_RETURN_ON_FAIL(app->initialize(session, renderer, options, input)); app->update(); + renderDocEndFrame(); app->finalize(); return SLANG_OK; } |
