summaryrefslogtreecommitdiffstats
path: root/tools/render-test
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2021-03-04 16:25:58 -0800
committerGitHub <noreply@github.com>2021-03-04 16:25:58 -0800
commita5ac4999b4dea546a7ef824669ab1809224b6448 (patch)
tree15bb22eb98a94f7f81489deef55396461501d3dc /tools/render-test
parent13ff0bd345990c0fdfb7b52ebd5339cddb04889e (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.cpp25
-rw-r--r--tools/render-test/png-serialize-util.h6
-rw-r--r--tools/render-test/render-test-main.cpp254
-rw-r--r--tools/render-test/shader-renderer-util.cpp27
-rw-r--r--tools/render-test/shader-renderer-util.h11
-rw-r--r--tools/render-test/surface.cpp223
-rw-r--r--tools/render-test/surface.h86
-rw-r--r--tools/render-test/window.cpp21
-rw-r--r--tools/render-test/window.h45
-rw-r--r--tools/render-test/windows/win-window.cpp185
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