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 | |
| 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')
| -rw-r--r-- | tools/render-test/png-serialize-util.cpp | 25 | ||||
| -rw-r--r-- | tools/render-test/png-serialize-util.h | 6 | ||||
| -rw-r--r-- | tools/render-test/render-test-main.cpp | 254 | ||||
| -rw-r--r-- | tools/render-test/shader-renderer-util.cpp | 27 | ||||
| -rw-r--r-- | tools/render-test/shader-renderer-util.h | 11 | ||||
| -rw-r--r-- | tools/render-test/surface.cpp | 223 | ||||
| -rw-r--r-- | tools/render-test/surface.h | 86 | ||||
| -rw-r--r-- | tools/render-test/window.cpp | 21 | ||||
| -rw-r--r-- | tools/render-test/window.h | 45 | ||||
| -rw-r--r-- | tools/render-test/windows/win-window.cpp | 185 |
10 files changed, 193 insertions, 690 deletions
diff --git a/tools/render-test/png-serialize-util.cpp b/tools/render-test/png-serialize-util.cpp index a7f6aa83a..dc1a9f241 100644 --- a/tools/render-test/png-serialize-util.cpp +++ b/tools/render-test/png-serialize-util.cpp @@ -12,25 +12,14 @@ namespace renderer_test { using namespace Slang; -/* static */Slang::Result PngSerializeUtil::write(const char* filename, const Surface& surface) +/* static */ Slang::Result PngSerializeUtil::write( + const char* filename, + ISlangBlob* pixels, + uint32_t width, + uint32_t height) { - int numComps = 0; - switch (surface.m_format) - { - case Format::RGBA_Unorm_UInt8: - { - numComps = 4; - break; - } - default: break; - } - - if (numComps <= 0) - { - return SLANG_FAIL; - } - - int stbResult = stbi_write_png(filename, surface.m_width, surface.m_height, numComps, surface.m_data, surface.m_rowStrideInBytes); + int stbResult = + stbi_write_png(filename, width, height, 4, pixels->getBufferPointer(), width * 4); return stbResult ? SLANG_OK : SLANG_FAIL; } diff --git a/tools/render-test/png-serialize-util.h b/tools/render-test/png-serialize-util.h index 1ec5204f7..80eda3729 100644 --- a/tools/render-test/png-serialize-util.h +++ b/tools/render-test/png-serialize-util.h @@ -1,15 +1,13 @@ // png-serialize-util.h #pragma once -#include "surface.h" +#include "core/slang-blob.h" namespace renderer_test { -using namespace gfx; - struct PngSerializeUtil { - static Slang::Result write(const char* filename, const Surface& surface); + static Slang::Result write(const char* filename, ISlangBlob* pixels, uint32_t width, uint32_t height); }; 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; } diff --git a/tools/render-test/shader-renderer-util.cpp b/tools/render-test/shader-renderer-util.cpp index 5b3867848..d42c5c7ef 100644 --- a/tools/render-test/shader-renderer-util.cpp +++ b/tools/render-test/shader-renderer-util.cpp @@ -7,13 +7,28 @@ namespace renderer_test { using namespace Slang; using Slang::Result; -void BindingStateImpl::apply(IRenderer* renderer, PipelineType pipelineType) +void BindingStateImpl::apply(ICommandEncoder* encoder, PipelineType pipelineType) { - renderer->setDescriptorSet( - pipelineType, - pipelineLayout, - 0, - descriptorSet); + switch (pipelineType) + { + case PipelineType::Compute: + { + ComPtr<IComputeCommandEncoder> computeEncoder; + encoder->queryInterface(SLANG_UUID_IComputeCommandEncoder, (void**)computeEncoder.writeRef()); + computeEncoder->setDescriptorSet(pipelineLayout, 0, descriptorSet); + } + break; + case PipelineType::Graphics: + { + ComPtr<IRenderCommandEncoder> renderEncoder; + encoder->queryInterface( + SLANG_UUID_IRenderCommandEncoder, (void**)renderEncoder.writeRef()); + renderEncoder->setDescriptorSet(pipelineLayout, 0, descriptorSet); + } + break; + default: + throw "unknown pipeline type"; + } } /* static */ Result ShaderRendererUtil::generateTextureResource( diff --git a/tools/render-test/shader-renderer-util.h b/tools/render-test/shader-renderer-util.h index 815bf2248..b79403bb4 100644 --- a/tools/render-test/shader-renderer-util.h +++ b/tools/render-test/shader-renderer-util.h @@ -33,7 +33,7 @@ struct BindingStateImpl : public Slang::RefObject uint16_t size; ///< The amount of register indices }; - void apply(IRenderer* renderer, PipelineType pipelineType); + void apply(ICommandEncoder* encoder, PipelineType pipelineType); struct OutputBinding { @@ -80,15 +80,6 @@ struct ShaderRendererUtil IRenderer* renderer, IBufferResource* addedConstantBuffer, BindingStateImpl** outBindingState); - -private: - /// Create BindingState::Desc from a list of ShaderInputLayout entries - static Slang::Result _createBindingState( - ShaderInputLayoutEntry* srcEntries, - int numEntries, - IRenderer* renderer, - IBufferResource* addedConstantBuffer, - BindingStateImpl** outBindingState); }; } // renderer_test diff --git a/tools/render-test/surface.cpp b/tools/render-test/surface.cpp deleted file mode 100644 index 636881fca..000000000 --- a/tools/render-test/surface.cpp +++ /dev/null @@ -1,223 +0,0 @@ -// surface.cpp -#include "surface.h" - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#include "../../source/core/slang-list.h" - -namespace gfx { -using namespace Slang; - -class MallocSurfaceAllocator: public SurfaceAllocator -{ - public: - - virtual Slang::Result allocate(int width, int height, Format format, int alignment, Surface& surface) override; - virtual void deallocate(Surface& surface) override; -}; - -static MallocSurfaceAllocator s_mallocSurfaceAllocator; - -/// Get the malloc allocator -/* static */SurfaceAllocator* SurfaceAllocator::getMallocAllocator() -{ - return &s_mallocSurfaceAllocator; -} - -Slang::Result MallocSurfaceAllocator::allocate(int width, int height, Format format, int alignment, Surface& surface) -{ - assert(surface.m_data == nullptr); - - // Calculate row size - - const int rowSizeInBytes = Surface::calcRowSize(format, width); - const int numRows = Surface::calcNumRows(format, height); - - alignment = (alignment <= 0) ? int(sizeof(void*)) : alignment; - // It must be a power of 2 - assert( ((alignment - 1) & alignment) == 0); - - // Align rowSize - const int alignedRowSizeInBytes = (rowSizeInBytes + alignment - 1) & -alignment; - - size_t totalSize = numRows * alignedRowSizeInBytes; - - uint8_t* data = (uint8_t*)::malloc(totalSize); - if (!data) - { - return SLANG_E_OUT_OF_MEMORY; - } - - surface.m_data = data; - surface.m_width = width; - surface.m_height = height; - surface.m_format = format; - surface.m_numRows = numRows; - surface.m_rowStrideInBytes = alignedRowSizeInBytes; - - surface.m_allocator = this; - return SLANG_OK; -} - -void MallocSurfaceAllocator::deallocate(Surface& surface) -{ - assert(surface.m_data); - // Make sure it's not an inverted, cos otherwise m_data is not the start address - assert(surface.m_rowStrideInBytes > 0); - ::free(surface.m_data); -} - -// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Surface !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -/* static */int Surface::calcRowSize(Format format, int width) -{ - size_t pixelSize = gfxGetFormatSize(format); - if (pixelSize == 0) - { - return 0; - } - return int(pixelSize * width); -} - -/* static */int Surface::calcNumRows(Format format, int height) -{ - // Don't have any compressed types, so number of rows is same as the height - return height; -} - -void Surface::init() -{ - m_width = 0; - m_height = 0; - m_format = Format::Unknown; - m_data = nullptr; - m_numRows = 0; - m_rowStrideInBytes = 0; - // NOTE! does not clear the allocator. - // If called with an allocation memory will leak! -} - -Surface::~Surface() -{ - if (m_data && m_allocator) - { - m_allocator->deallocate(*this); - } -} - -void Surface::deallocate() -{ - if (m_data && m_allocator) - { - m_allocator->deallocate(*this); - init(); - } -} - -Result Surface::allocate(int width, int height, Format format, int alignment, SurfaceAllocator* allocator) -{ - deallocate(); - allocator = allocator ? allocator : m_allocator; - if (!allocator) - { - // An allocator needs to be set on the surface, or one passed in. - return SLANG_FAIL; - } - return allocator->allocate(width, height, format, alignment, *this); -} - -void Surface::setUnowned(int width, int height, Format format, int strideInBytes, void* data) -{ - deallocate(); - - // This is unowned - m_allocator = nullptr; - - m_width = width; - m_height = height; - m_format = format; - m_rowStrideInBytes = strideInBytes; - m_data = (uint8_t*)data; - - m_numRows = Surface::calcNumRows(format, height); - - const int rowSizeInBytes = Surface::calcRowSize(format, width); - assert((strideInBytes > 0 && rowSizeInBytes <= strideInBytes) || (strideInBytes < 0 && rowSizeInBytes <= -strideInBytes)); -} - -void Surface::zeroContents() -{ - const int rowSizeInBytes = Surface::calcRowSize(m_format, m_width); - - const int stride = m_rowStrideInBytes; - uint8_t* dst = m_data; - - for (int i = 0; i < m_numRows; i++, dst += stride) - { - ::memset(dst, 0, rowSizeInBytes); - } -} - -void Surface::flipInplaceVertically() -{ - // Can only flip when m_height matches number of rows - assert(m_numRows == m_height); - - const int rowSizeInBytes = Surface::calcRowSize(m_format, m_width); - if (rowSizeInBytes <= 0 || m_numRows <= 1) - { - return; - } - - uint8_t* top = m_data; - uint8_t* bottom = m_data + (m_numRows - 1) * m_rowStrideInBytes; - - List<uint8_t> bufferList; - bufferList.setCount(rowSizeInBytes); - uint8_t* buffer = bufferList.getBuffer(); - - const int stride = m_rowStrideInBytes; - - const int num = m_height >> 1; - for (int i = 0; i < num; ++i, top += stride, bottom -= stride) - { - ::memcpy(buffer, top, rowSizeInBytes); - ::memcpy(top, bottom, rowSizeInBytes); - ::memcpy(bottom, buffer, rowSizeInBytes); - } -} - -SlangResult Surface::set(int width, int height, Format format, int srcRowStride, const void* data, SurfaceAllocator* allocator) -{ - if (hasContents() && m_width == width && m_height == height && m_format == format) - { - // I can just overwrite the contents that is there - } - else - { - SLANG_RETURN_ON_FAIL(allocate(width, height, format, 0, allocator)); - } - - // Okay just need to set the contents - - { - const size_t rowSize = calcRowSize(format, width); - - const uint8_t* srcRow = (const uint8_t*)data; - uint8_t* dstRow = (uint8_t*)m_data; - - for (int i = 0; i < m_numRows; i++) - { - ::memcpy(dstRow, srcRow, rowSize); - - srcRow += srcRowStride; - dstRow += m_rowStrideInBytes; - } - } - - return SLANG_OK; -} - -} // renderer_test diff --git a/tools/render-test/surface.h b/tools/render-test/surface.h deleted file mode 100644 index f6e888745..000000000 --- a/tools/render-test/surface.h +++ /dev/null @@ -1,86 +0,0 @@ -// surface.h -#pragma once - -#include "slang-gfx.h" - -namespace gfx { - -class Surface; - -class SurfaceAllocator -{ - public: - virtual Slang::Result allocate(int width, int height, Format format, int alignment, Surface& surface) = 0; - virtual void deallocate(Surface& surface) = 0; - - /// Get the malloc allocator - static SurfaceAllocator* getMallocAllocator(); -}; - -class Surface -{ - public: - - enum - { - kDefaultAlignment = sizeof(void*) - }; - - /// Allocate - Slang::Result allocate(int width, int height, Format format, int alignment = kDefaultAlignment, SurfaceAllocator* allocator = nullptr); - - /// Deallocate contents - void deallocate(); - /// Initialize contents (zero sized, no data). Note that the allocator pointer is left as is - void init(); - - /// Set unowned - void setUnowned(int width, int height, Format format, int strideInBytes, void* data); - - /// Set the contents - the memory will be owned by this surface (ie will be freed by the allocator when goes out of scope or is deallocated) - Slang::Result set(int width, int height, Format format, int strideInBytes, const void* data, SurfaceAllocator* allocator); - - template <typename T> - T* calcNextRow(T* ptr) const { return (T*)calcNextRow((void*)ptr); } - template <typename T> - const T* calcNextRow(const T* ptr) const { return (const T*)calcNextRow((const void*)ptr); } - - void* calcNextRow(void* ptr) const { return (void*)(((uint8_t*)ptr) + m_rowStrideInBytes); } - const void* calcNextRow(const void* ptr) const { return (const void*)(((const uint8_t*)ptr) + m_rowStrideInBytes); } - - /// Writes zero to all of the contents - void zeroContents(); - - /// Flips the contents vertically in place - void flipInplaceVertically(); - - /// True if has some contents - bool hasContents() const { return m_data != nullptr; } - - /// Ctor - Surface() : - m_allocator(nullptr) - { - init(); - } - /// Dtor - ~Surface(); - - /// Get the size of the row in bytes - static int calcRowSize(Format format, int width); - /// Calculates the number of rows - static int calcNumRows(Format format, int height); - - int m_width; - int m_height; - Format m_format; - - uint8_t* m_data; /// The data that makes up the image. If nullptr, has no data. Pointer to first 'row' of the image. - - int m_numRows; ///< Total amount of rows (typically same as height, but in compressed formats may be less) - int m_rowStrideInBytes; ///< The number of bytes between rows - - SurfaceAllocator* m_allocator; ///< Can be null if so contents is 'unowned', if set -}; - -} // renderer_test diff --git a/tools/render-test/window.cpp b/tools/render-test/window.cpp deleted file mode 100644 index 0ab4ff412..000000000 --- a/tools/render-test/window.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// window.cpp - -#include "window.h" - -namespace renderer_test { -using namespace Slang; - -#if SLANG_WINDOWS_FAMILY -extern Window* createWinWindow(); -#endif - -/* static */Window* Window::create() -{ -#if SLANG_WINDOWS_FAMILY - return createWinWindow(); -#else - return nullptr; -#endif -} - -} // renderer_test diff --git a/tools/render-test/window.h b/tools/render-test/window.h deleted file mode 100644 index e647a602c..000000000 --- a/tools/render-test/window.h +++ /dev/null @@ -1,45 +0,0 @@ -// window.h -#pragma once - -#include <slang.h> -#include "../../source/core/slang-smart-pointer.h" - -namespace renderer_test { - -class Window; - -class WindowListener : public Slang::RefObject -{ -public: - virtual SlangResult update(Window* window) = 0; -}; - -class Window : public Slang::RefObject -{ -public: - virtual SlangResult initialize(int width, int height) = 0; - - virtual void show() = 0; - virtual void* getHandle() const = 0; - virtual void postQuit() { m_isQuitting = true; } - - /// Run the event loop. Events will be sent to the WindowListener - virtual SlangResult runLoop(WindowListener* listener) = 0; - - bool isQuitting() const { return m_isQuitting; } - int getQuitValue() const { return m_quitValue; } - - static Window* create(); - - virtual ~Window() {} - -protected: - Window() {} - - bool m_isQuitting = false; - int m_quitValue = 0; -}; - -Window* createWindow(); - -} // renderer_test diff --git a/tools/render-test/windows/win-window.cpp b/tools/render-test/windows/win-window.cpp deleted file mode 100644 index 7f45f9789..000000000 --- a/tools/render-test/windows/win-window.cpp +++ /dev/null @@ -1,185 +0,0 @@ -// win-window.cpp - -#define _CRT_SECURE_NO_WARNINGS 1 - -#include <slang.h> -#include <slang-com-helper.h> - -#include "../window.h" - -#define WIN32_LEAN_AND_MEAN -#define NOMINMAX -#include <Windows.h> -#undef WIN32_LEAN_AND_MEAN -#undef NOMINMAX - -#ifdef _MSC_VER -#pragma warning(disable: 4996) -#endif - -#include <stdio.h> - -namespace renderer_test { - -class WinWindow : public Window -{ -public: - virtual SlangResult initialize(int width, int height) SLANG_OVERRIDE; - - virtual void show() SLANG_OVERRIDE; - virtual void* getHandle() const SLANG_OVERRIDE { return m_hwnd; } - virtual SlangResult runLoop(WindowListener* listener) SLANG_OVERRIDE; - - virtual ~WinWindow(); - - static LRESULT CALLBACK windowProc(HWND windowHandle, UINT message, WPARAM wParam, LPARAM lParam); - -protected: - - HINSTANCE m_hinst = nullptr; - HWND m_hwnd = nullptr; -}; - -// -// We use a bare-minimum window procedure to get things up and running. -// - -/* static */LRESULT CALLBACK WinWindow::windowProc(HWND windowHandle, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch (message) - { - case WM_CLOSE: - PostQuitMessage(0); - return 0; - } - return DefWindowProcW(windowHandle, message, wParam, lParam); -} - -static ATOM _getWindowClassAtom(HINSTANCE hinst) -{ - static ATOM s_windowClassAtom; - - if (s_windowClassAtom) - { - return s_windowClassAtom; - } - WNDCLASSEXW windowClassDesc; - windowClassDesc.cbSize = sizeof(windowClassDesc); - windowClassDesc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; - windowClassDesc.lpfnWndProc = &WinWindow::windowProc; - windowClassDesc.cbClsExtra = 0; - windowClassDesc.cbWndExtra = 0; - windowClassDesc.hInstance = hinst; - windowClassDesc.hIcon = 0; - windowClassDesc.hCursor = 0; - windowClassDesc.hbrBackground = 0; - windowClassDesc.lpszMenuName = 0; - windowClassDesc.lpszClassName = L"SlangRenderTest"; - windowClassDesc.hIconSm = 0; - s_windowClassAtom = RegisterClassExW(&windowClassDesc); - - return s_windowClassAtom; -} - -SlangResult WinWindow::initialize(int widthIn, int heightIn) -{ - // Do initial window-creation stuff here, rather than in the renderer-specific files - - m_hinst = GetModuleHandleA(0); - - // First we register a window class. - ATOM windowClassAtom = _getWindowClassAtom(m_hinst); - if (!windowClassAtom) - { - fprintf(stderr, "error: failed to register window class\n"); - return SLANG_FAIL; - } - - // Next, we create a window using that window class. - - // We will create a borderless window since our screen-capture logic in GL - // seems to get thrown off by having to deal with a window frame. - DWORD windowStyle = WS_POPUP; - DWORD windowExtendedStyle = 0; - - RECT windowRect = { 0, 0, widthIn, heightIn }; - AdjustWindowRectEx(&windowRect, windowStyle, /*hasMenu=*/false, windowExtendedStyle); - - { - auto width = windowRect.right - windowRect.left; - auto height = windowRect.bottom - windowRect.top; - - LPWSTR windowName = L"Slang Render Test"; - m_hwnd = CreateWindowExW( - windowExtendedStyle, - (LPWSTR)windowClassAtom, - windowName, - windowStyle, - 0, 0, // x, y - width, height, - NULL, // parent - NULL, // menu - m_hinst, - NULL); - } - if (!m_hwnd) - { - fprintf(stderr, "error: failed to create window\n"); - return SLANG_FAIL; - } - - return SLANG_OK; -} - - -void WinWindow::show() -{ - // Once initialization is all complete, we show the window... - int showCommand = SW_SHOW; - ShowWindow(m_hwnd, showCommand); -} - -SlangResult WinWindow::runLoop(WindowListener* listener) -{ - // ... and enter the event loop: - while (!m_isQuitting) - { - MSG message; - int result = PeekMessageW(&message, NULL, 0, 0, PM_REMOVE); - if (result != 0) - { - if (message.message == WM_QUIT) - { - m_quitValue = (int)message.wParam; - return SLANG_OK; - } - - TranslateMessage(&message); - DispatchMessageW(&message); - } - else - { - if (listener) - { - SLANG_RETURN_ON_FAIL(listener->update(this)); - } - } - } - - return SLANG_OK; -} - -WinWindow::~WinWindow() -{ - if (m_hwnd) - { - DestroyWindow(m_hwnd); - } -} - -Window* createWinWindow() -{ - return new WinWindow; -} - -} // namespace renderer_test |
