summaryrefslogtreecommitdiffstats
path: root/tools/render-test/render-test-main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/render-test/render-test-main.cpp')
-rw-r--r--tools/render-test/render-test-main.cpp643
1 files changed, 497 insertions, 146 deletions
diff --git a/tools/render-test/render-test-main.cpp b/tools/render-test/render-test-main.cpp
index f82e03ad5..91230b9d0 100644
--- a/tools/render-test/render-test-main.cpp
+++ b/tools/render-test/render-test-main.cpp
@@ -17,7 +17,12 @@
#include <stdio.h>
#include <stdlib.h>
+// TODO(JS): We need to put the prelude into a better place
+#define SLANG_PRELUDE_NAMESPACE CPPPrelude
+#include "../../tests/cross-compile/slang-cpp-prelude.h"
+
#include "../../source/core/slang-test-tool-util.h"
+#include "../../source/core/slang-memory-arena.h"
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
@@ -200,7 +205,7 @@ class RenderTestApp
// At initialization time, we are going to load and compile our Slang shader
// code, and then create the API objects we need for rendering.
- Result initialize(Renderer* renderer, ShaderCompiler* shaderCompiler);
+ Result initialize(SlangSession* session, Renderer* renderer, Options::ShaderProgramType shaderType, const ShaderCompilerUtil::Input& input);
void runCompute();
void renderFrame();
void finalize();
@@ -213,7 +218,7 @@ class RenderTestApp
protected:
/// Called in initialize
- Result initializeShaders(ShaderCompiler* shaderCompiler);
+ Result _initializeShaders(SlangSession* session, Renderer* renderer, Options::ShaderProgramType shaderType, const ShaderCompilerUtil::Input& input);
// variables for state to be used for rendering...
uintptr_t m_constantBufferSize, m_computeResultBufferSize;
@@ -236,49 +241,432 @@ static const char vertexEntryPointName[] = "vertexMain";
static const char fragmentEntryPointName[] = "fragmentMain";
static const char computeEntryPointName[] = "computeMain";
-SlangResult RenderTestApp::initialize(Renderer* renderer, ShaderCompiler* shaderCompiler)
+static SlangResult _readSource(const String& inSourcePath, List<char>& outSourceText)
{
- SLANG_RETURN_ON_FAIL(initializeShaders(shaderCompiler));
+ // Read in the source code
+ FILE* sourceFile = fopen(inSourcePath.getBuffer(), "rb");
+ if (!sourceFile)
+ {
+ fprintf(stderr, "error: failed to open '%s' for reading\n", inSourcePath.getBuffer());
+ return SLANG_FAIL;
+ }
+ fseek(sourceFile, 0, SEEK_END);
+ size_t sourceSize = ftell(sourceFile);
+ fseek(sourceFile, 0, SEEK_SET);
- m_numAddedConstantBuffers = 0;
- m_renderer = renderer;
+ outSourceText.setCount(sourceSize + 1);
+ fread(outSourceText.getBuffer(), sourceSize, 1, sourceFile);
+ fclose(sourceFile);
+ outSourceText[sourceSize] = 0;
- // TODO(tfoley): use each API's reflection interface to query the constant-buffer size needed
+ return SLANG_OK;
+}
+
+struct CompileOutput
+{
+ ShaderCompilerUtil::Output compileOutput;
+ ShaderInputLayout layout;
+};
+
+static SlangResult _compile(SlangSession* session, const String& sourcePath, Options::ShaderProgramType shaderType, const ShaderCompilerUtil::Input& input, CompileOutput& output)
+{
+ List<char> sourceText;
+ SLANG_RETURN_ON_FAIL(_readSource(sourcePath, sourceText));
+
+ auto& layout = output.layout;
+
+ // Default the amount of renderTargets based on shader type
+ switch (shaderType)
{
- m_constantBufferSize = 16 * sizeof(float);
+ default:
+ layout.numRenderTargets = 1;
+ break;
+
+ case Options::ShaderProgramType::Compute:
+ layout.numRenderTargets = 0;
+ break;
+ }
- BufferResource::Desc constantBufferDesc;
- constantBufferDesc.init(m_constantBufferSize);
- constantBufferDesc.cpuAccessFlags = Resource::AccessFlag::Write;
+ // Parse the layout
+ layout.parse(sourceText.getBuffer());
- m_constantBuffer = renderer->createBufferResource(Resource::Usage::ConstantBuffer, constantBufferDesc);
- if (!m_constantBuffer)
- return SLANG_FAIL;
+ // Setup SourceInfo
+ ShaderCompileRequest::SourceInfo sourceInfo;
+ sourceInfo.path = sourcePath.getBuffer();
+ sourceInfo.dataBegin = sourceText.getBuffer();
+ // Subtract 1 because it's zero terminated
+ sourceInfo.dataEnd = sourceText.getBuffer() + sourceText.getCount() - 1;
+
+ ShaderCompileRequest compileRequest;
+ compileRequest.source = sourceInfo;
+ if (shaderType == Options::ShaderProgramType::Graphics || shaderType == Options::ShaderProgramType::GraphicsCompute)
+ {
+ compileRequest.vertexShader.source = sourceInfo;
+ compileRequest.vertexShader.name = vertexEntryPointName;
+ compileRequest.fragmentShader.source = sourceInfo;
+ compileRequest.fragmentShader.name = fragmentEntryPointName;
+ }
+ else
+ {
+ compileRequest.computeShader.source = sourceInfo;
+ compileRequest.computeShader.name = computeEntryPointName;
}
+ compileRequest.globalGenericTypeArguments = layout.globalGenericTypeArguments;
+ compileRequest.entryPointGenericTypeArguments = layout.entryPointGenericTypeArguments;
+ compileRequest.globalExistentialTypeArguments = layout.globalExistentialTypeArguments;
+ compileRequest.entryPointExistentialTypeArguments = layout.entryPointExistentialTypeArguments;
+
+ return ShaderCompilerUtil::compileProgram(session, input, compileRequest, output.compileOutput);
+}
+
+static SlangResult _handleResource(slang::TypeReflection* type, ShaderInputLayoutEntry& src, void* dst)
+{
+ auto shape = type->getResourceShape();
+ auto access = type->getResourceAccess();
+ switch (shape & SLANG_RESOURCE_BASE_SHAPE_MASK)
{
- //! Hack -> if doing a graphics test, add an extra binding for our dynamic constant buffer
- //
- // TODO: Should probably be more sophisticated than this - with 'dynamic' constant buffer/s binding always being specified
- // in the test file
- RefPtr<BufferResource> addedConstantBuffer;
- switch(gOptions.shaderType)
- {
default:
+ assert(!"unhandled case");
break;
+ case SLANG_TEXTURE_1D:
+ case SLANG_TEXTURE_2D:
+ case SLANG_TEXTURE_3D:
+ case SLANG_TEXTURE_CUBE:
+ case SLANG_TEXTURE_BUFFER:
+ {
+ return SLANG_FAIL;
+ }
+ case SLANG_STRUCTURED_BUFFER:
+ {
+ // TODO(JS): I guess this is questionable - because sizeof(unsigned int) != sizeof(uint32_t) necessarily
+ CPPPrelude::StructuredBuffer<uint32_t>& dstBuf = *(CPPPrelude::StructuredBuffer<uint32_t>*)dst;
+ dstBuf.data = src.bufferData.getBuffer();
+ dstBuf.count = src.bufferData.getCount();
+ break;
+ }
+ case SLANG_BYTE_ADDRESS_BUFFER:
+ {
+ CPPPrelude::ByteAddressBuffer& dstBuf = *(CPPPrelude::ByteAddressBuffer*)dst;
+ dstBuf.data = src.bufferData.getBuffer();
+ dstBuf.sizeInBytes = src.bufferData.getCount() * sizeof(unsigned int);
- case Options::ShaderProgramType::Graphics:
- case Options::ShaderProgramType::GraphicsCompute:
- addedConstantBuffer = m_constantBuffer;
- m_numAddedConstantBuffers++;
break;
}
+ }
+ if (shape & SLANG_TEXTURE_ARRAY_FLAG)
+ {
+
+ }
+ if (shape & SLANG_TEXTURE_MULTISAMPLE_FLAG)
+ {
+
+ }
+
+ if (access != SLANG_RESOURCE_ACCESS_READ)
+ {
+ switch (access)
+ {
+ default:
+ assert(!"unhandled case");
+ break;
+
+ case SLANG_RESOURCE_ACCESS_READ:
+ break;
+
+ case SLANG_RESOURCE_ACCESS_READ_WRITE: break;
+ case SLANG_RESOURCE_ACCESS_RASTER_ORDERED: break;
+ case SLANG_RESOURCE_ACCESS_APPEND: break;
+ case SLANG_RESOURCE_ACCESS_CONSUME: break;
+ }
+
+ }
+ return SLANG_OK;
+}
- BindingStateImpl* bindingState = nullptr;
- SLANG_RETURN_ON_FAIL(ShaderRendererUtil::createBindingState(m_shaderInputLayout, m_renderer, addedConstantBuffer, &bindingState));
- m_bindingState = bindingState;
+static SlangResult _writeBindings(const ShaderInputLayout& layout, const String& fileName)
+{
+ FILE * f = fopen(fileName.getBuffer(), "wb");
+ if (!f)
+ {
+ return SLANG_FAIL;
}
+ for (auto entry : layout.entries)
+ {
+ if (entry.isOutput)
+ {
+ auto ptr = entry.bufferData.getBuffer();
+ const int size = int(entry.bufferData.getCount());
+ for (int i = 0; i < size; ++i)
+ {
+ fprintf(f, "%X\n", ptr[i]);
+ }
+ }
+ }
+ fclose(f);
+ return SLANG_OK;
+}
+
+static SlangResult _doCPUCompute(SlangSession* session, const String& sourcePath, Options::ShaderProgramType shaderType, const ShaderCompilerUtil::Input& input)
+{
+ CompileOutput output;
+ SLANG_RETURN_ON_FAIL(_compile(session, sourcePath, shaderType, input, output));
+
+ ComPtr<ISlangSharedLibrary> sharedLibrary;
+ SLANG_RETURN_ON_FAIL(spGetEntryPointHostCallable(output.compileOutput.request, 0, 0, sharedLibrary.writeRef()));
+
+ // Use reflection to find the entry point name
+ auto request = output.compileOutput.request;
+
+ struct UniformState;
+ typedef void(*Func)(CPPPrelude::ComputeVaryingInput* varyingInput, UniformState* uniformState);
+
+ auto reflection = (slang::ShaderReflection*) spGetReflection(request);
+
+ slang::EntryPointReflection* entryPoint = nullptr;
+ Func func = nullptr;
+ {
+
+ auto entryPointCount = reflection->getEntryPointCount();
+ SLANG_ASSERT(entryPointCount == 1);
+
+ entryPoint = reflection->getEntryPointByIndex(0);
+
+ const char* entryPointName = entryPoint->getName();
+ func = (Func) sharedLibrary->findFuncByName(entryPointName);
+
+ if (!func)
+ {
+ return SLANG_FAIL;
+ }
+ }
+ // Okay we need to find all of the bindings and match up to those in the layout
+
+ ShaderInputLayout& layout = output.layout;
+
+ // For general storage
+ MemoryArena arena;
+ arena.init(1024);
+ List<void*> uniformState;
+
+ {
+ int parameterCount = reflection->getParameterCount();
+
+ for (int i = 0; i < parameterCount; ++i)
+ {
+ auto parameter = reflection->getParameterByIndex(i);
+
+ const char* paramName = parameter->getName();
+
+ const Index entryIndex = layout.findEntryIndexByName(paramName);
+ if (entryIndex < 0)
+ {
+ auto& outStream = StdWriters::getOut();
+
+ int numNamed = 0;
+ for (const auto& entry : layout.entries)
+ {
+ numNamed += int(entry.name.getLength() > 0);
+ }
+
+ if (layout.entries.getCount() > 0 && numNamed == 0)
+ {
+ outStream.print("No 'name' specified for resources in '%s'\n", sourcePath.getBuffer());
+ }
+ else
+ {
+ outStream.print("Unable to find entry in '%s' for '%s' (for CPU name must be specified) \n", sourcePath.getBuffer(), paramName);
+ }
+ return SLANG_FAIL;
+ }
+
+ auto stage = parameter->getStage();
+
+ auto typeLayout = parameter->getTypeLayout();
+ auto categoryCount = parameter->getCategoryCount();
+
+ SLANG_ASSERT(categoryCount == 1);
+
+ // Only dealing one category per item right now
+ auto category = parameter->getCategoryByIndex(0);
+
+ auto offset = parameter->getOffset(category);
+ auto space = parameter->getBindingSpace(category);
+ auto count = typeLayout->getSize(category);
+
+ size_t end = offset + count;
+ if (uniformState.getCount() * sizeof(void*) < end)
+ {
+ uniformState.setCount(end / sizeof(void*));
+ }
+
+ void* dstEntry = ((uint8_t*)uniformState.getBuffer()) + offset;
+ auto& srcEntry = layout.entries[entryIndex];
+
+ switch (typeLayout->getKind())
+ {
+ default:
+ break;
+
+ case slang::TypeReflection::Kind::Array:
+ {
+ auto arrayTypeLayout = typeLayout;
+ auto elementTypeLayout = arrayTypeLayout->getElementTypeLayout();
+ auto elementCount = int(arrayTypeLayout->getElementCount());
+
+ if (arrayTypeLayout->getSize(SLANG_PARAMETER_CATEGORY_UNIFORM) != 0)
+ {
+ int elementStride = int(arrayTypeLayout->getElementStride(SLANG_PARAMETER_CATEGORY_UNIFORM));
+ SLANG_UNUSED(elementStride);
+ }
+ SLANG_UNUSED(elementTypeLayout);
+ SLANG_UNUSED(elementCount);
+ break;
+ }
+ case slang::TypeReflection::Kind::Struct:
+ {
+ auto structTypeLayout = typeLayout;
+ auto name = structTypeLayout->getName();
+ SLANG_UNUSED(name);
+
+ auto fieldCount = structTypeLayout->getFieldCount();
+ for (uint32_t ff = 0; ff < fieldCount; ++ff)
+ {
+ auto field = structTypeLayout->getFieldByIndex(ff);
+ SLANG_UNUSED(field);
+ }
+ auto type = structTypeLayout->getType();
+ SLANG_UNUSED(type);
+ break;
+ }
+ case slang::TypeReflection::Kind::ConstantBuffer:
+ {
+ auto elementTypeLayout = typeLayout->getElementTypeLayout();
+ SLANG_UNUSED(elementTypeLayout);
+ break;
+ }
+ case slang::TypeReflection::Kind::ParameterBlock:
+ {
+ auto elementTypeLayout = typeLayout->getElementTypeLayout();
+ SLANG_UNUSED(elementTypeLayout);
+ break;
+ }
+ case slang::TypeReflection::Kind::TextureBuffer:
+ {
+ auto elementTypeLayout = typeLayout->getElementTypeLayout();
+ SLANG_UNUSED(elementTypeLayout);
+ break;
+ }
+ case slang::TypeReflection::Kind::ShaderStorageBuffer:
+ {
+ auto elementTypeLayout = typeLayout->getElementTypeLayout();
+ SLANG_UNUSED(elementTypeLayout);
+ break;
+ }
+ case slang::TypeReflection::Kind::GenericTypeParameter:
+ {
+ const char* name = typeLayout->getName();
+ SLANG_UNUSED(name);
+ break;
+ }
+ case slang::TypeReflection::Kind::Interface:
+ {
+ const char* name = typeLayout->getName();
+ SLANG_UNUSED(name);
+ break;
+ }
+ case slang::TypeReflection::Kind::Resource:
+ {
+ // Some resource types (notably structured buffers)
+ // encode layout information for their result/element
+ // type, but others don't. We need to check for
+ // the relevant cases here.
+ //
+ auto type = typeLayout->getType();
+ auto shape = type->getResourceShape();
+
+ if ((shape & SLANG_RESOURCE_BASE_SHAPE_MASK) == SLANG_STRUCTURED_BUFFER)
+ {
+ _handleResource(typeLayout->getType(), srcEntry, dstEntry);
+
+ }
+ else
+ {
+ //emitReflectionTypeInfoJSON(writer, typeLayout->getType());
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ SlangUInt numThreadsPerAxis[3];
+ entryPoint->getComputeThreadGroupSize(3, numThreadsPerAxis);
+
+ {
+ CPPPrelude::ComputeVaryingInput varying;
+ varying.groupID = {};
+
+ for (int z = 0; z < numThreadsPerAxis[2]; ++z)
+ {
+ varying.groupThreadID.z = z;
+ for (int y = 0; y < numThreadsPerAxis[1]; ++y)
+ {
+ varying.groupThreadID.y = y;
+ for (int x = 0; x < numThreadsPerAxis[0]; ++x)
+ {
+ varying.groupThreadID.x = x;
+
+ func(&varying, (UniformState*)uniformState.getBuffer());
+ }
+ }
+ }
+ }
+
+ // Dump everything out that was write (we wrote in place!)
+ return _writeBindings(layout, gOptions.outputPath);
+}
+
+SlangResult RenderTestApp::initialize(SlangSession* session, Renderer* renderer, Options::ShaderProgramType shaderType, const ShaderCompilerUtil::Input& input)
+{
+ SLANG_RETURN_ON_FAIL(_initializeShaders(session, renderer, shaderType, input));
+
+ m_numAddedConstantBuffers = 0;
+ m_renderer = renderer;
+
+ // TODO(tfoley): use each API's reflection interface to query the constant-buffer size needed
+ m_constantBufferSize = 16 * sizeof(float);
+
+ BufferResource::Desc constantBufferDesc;
+ constantBufferDesc.init(m_constantBufferSize);
+ constantBufferDesc.cpuAccessFlags = Resource::AccessFlag::Write;
+
+ m_constantBuffer = renderer->createBufferResource(Resource::Usage::ConstantBuffer, constantBufferDesc);
+ if (!m_constantBuffer)
+ return SLANG_FAIL;
+
+ //! Hack -> if doing a graphics test, add an extra binding for our dynamic constant buffer
+ //
+ // TODO: Should probably be more sophisticated than this - with 'dynamic' constant buffer/s binding always being specified
+ // in the test file
+ RefPtr<BufferResource> addedConstantBuffer;
+ switch(shaderType)
+ {
+ default:
+ break;
+
+ case Options::ShaderProgramType::Graphics:
+ case Options::ShaderProgramType::GraphicsCompute:
+ addedConstantBuffer = m_constantBuffer;
+ m_numAddedConstantBuffers++;
+ break;
+ }
+
+ BindingStateImpl* bindingState = nullptr;
+ SLANG_RETURN_ON_FAIL(ShaderRendererUtil::createBindingState(m_shaderInputLayout, m_renderer, addedConstantBuffer, &bindingState));
+ m_bindingState = bindingState;
+
// Do other initialization that doesn't depend on the source language.
// Input Assembler (IA)
@@ -301,7 +689,7 @@ SlangResult RenderTestApp::initialize(Renderer* renderer, ShaderCompiler* shader
return SLANG_FAIL;
{
- switch(gOptions.shaderType)
+ switch(shaderType)
{
default:
assert(!"unexpected test shader type");
@@ -336,63 +724,12 @@ SlangResult RenderTestApp::initialize(Renderer* renderer, ShaderCompiler* shader
return m_pipelineState ? SLANG_OK : SLANG_FAIL;
}
-Result RenderTestApp::initializeShaders(ShaderCompiler* shaderCompiler)
+Result RenderTestApp::_initializeShaders(SlangSession* session, Renderer* renderer, Options::ShaderProgramType shaderType, const ShaderCompilerUtil::Input& input)
{
- // Read in the source code
- char const* sourcePath = gOptions.sourcePath;
- FILE* sourceFile = fopen(sourcePath, "rb");
- if (!sourceFile)
- {
- fprintf(stderr, "error: failed to open '%s' for reading\n", sourcePath);
- return SLANG_FAIL;
- }
- fseek(sourceFile, 0, SEEK_END);
- size_t sourceSize = ftell(sourceFile);
- fseek(sourceFile, 0, SEEK_SET);
-
- List<char> sourceText;
- sourceText.setCount(sourceSize + 1);
- fread(sourceText.getBuffer(), sourceSize, 1, sourceFile);
- fclose(sourceFile);
- sourceText[sourceSize] = 0;
-
- switch( gOptions.shaderType )
- {
- default:
- m_shaderInputLayout.numRenderTargets = 1;
- break;
-
- case Options::ShaderProgramType::Compute:
- m_shaderInputLayout.numRenderTargets = 0;
- break;
- }
- m_shaderInputLayout.Parse(sourceText.getBuffer());
-
- ShaderCompileRequest::SourceInfo sourceInfo;
- sourceInfo.path = sourcePath;
- sourceInfo.dataBegin = sourceText.getBuffer();
- sourceInfo.dataEnd = sourceText.getBuffer() + sourceSize;
-
- ShaderCompileRequest compileRequest;
- compileRequest.source = sourceInfo;
- if (gOptions.shaderType == Options::ShaderProgramType::Graphics || gOptions.shaderType == Options::ShaderProgramType::GraphicsCompute)
- {
- compileRequest.vertexShader.source = sourceInfo;
- compileRequest.vertexShader.name = vertexEntryPointName;
- compileRequest.fragmentShader.source = sourceInfo;
- compileRequest.fragmentShader.name = fragmentEntryPointName;
- }
- else
- {
- compileRequest.computeShader.source = sourceInfo;
- compileRequest.computeShader.name = computeEntryPointName;
- }
- compileRequest.globalGenericTypeArguments = m_shaderInputLayout.globalGenericTypeArguments;
- compileRequest.entryPointGenericTypeArguments = m_shaderInputLayout.entryPointGenericTypeArguments;
- compileRequest.globalExistentialTypeArguments = m_shaderInputLayout.globalExistentialTypeArguments;
- compileRequest.entryPointExistentialTypeArguments = m_shaderInputLayout.entryPointExistentialTypeArguments;
- m_shaderProgram = shaderCompiler->compileProgram(compileRequest);
-
+ CompileOutput output;
+ SLANG_RETURN_ON_FAIL(_compile(session, gOptions.sourcePath, shaderType, input, output));
+ m_shaderInputLayout = output.layout;
+ m_shaderProgram = renderer->createProgram(output.compileOutput.desc);
return m_shaderProgram ? SLANG_OK : SLANG_FAIL;
}
@@ -501,61 +838,90 @@ SLANG_TEST_TOOL_API SlangResult innerMain(Slang::StdWriters* stdWriters, SlangSe
// Parse command-line options
SLANG_RETURN_ON_FAIL(parseOptions(argcIn, argvIn, StdWriters::getError()));
- RefPtr<renderer_test::Window> window(new renderer_test::Window);
- SLANG_RETURN_ON_FAIL(window->initialize(gWindowWidth, gWindowHeight));
Slang::RefPtr<Renderer> renderer;
+ ShaderCompilerUtil::Input input;
+
+ input.profile = "";
+ input.target = SLANG_TARGET_NONE;
+ input.args = &gOptions.slangArgs[0];
+ input.argCount = gOptions.slangArgCount;
+
SlangSourceLanguage nativeLanguage = SLANG_SOURCE_LANGUAGE_UNKNOWN;
- SlangCompileTarget slangTarget = SLANG_TARGET_NONE;
- SlangPassThrough slangPassThrough = SLANG_PASS_THROUGH_NONE;
+ SlangPassThrough slangPassThrough = SLANG_PASS_THROUGH_NONE;
char const* profileName = "";
switch (gOptions.rendererType)
{
case RendererType::DirectX11:
renderer = createD3D11Renderer();
- slangTarget = SLANG_DXBC;
+ input.target = SLANG_DXBC;
+ input.profile = "sm_5_0";
nativeLanguage = SLANG_SOURCE_LANGUAGE_HLSL;
slangPassThrough = SLANG_PASS_THROUGH_FXC;
- profileName = "sm_5_0";
+
break;
case RendererType::DirectX12:
renderer = createD3D12Renderer();
- slangTarget = SLANG_DXBC;
+ input.target = SLANG_DXBC;
+ input.profile = "sm_5_0";
nativeLanguage = SLANG_SOURCE_LANGUAGE_HLSL;
slangPassThrough = SLANG_PASS_THROUGH_FXC;
- profileName = "sm_5_0";
+
if( gOptions.useDXIL )
{
- slangTarget = SLANG_DXIL;
+ input.target = SLANG_DXIL;
+ input.profile = "sm_6_0";
slangPassThrough = SLANG_PASS_THROUGH_DXC;
- profileName = "sm_6_0";
}
break;
case RendererType::OpenGl:
renderer = createGLRenderer();
- slangTarget = SLANG_GLSL;
+ input.target = SLANG_GLSL;
+ input.profile = "glsl_430";
nativeLanguage = SLANG_SOURCE_LANGUAGE_GLSL;
slangPassThrough = SLANG_PASS_THROUGH_GLSLANG;
- profileName = "glsl_430";
break;
case RendererType::Vulkan:
renderer = createVKRenderer();
- slangTarget = SLANG_SPIRV;
+ input.target = SLANG_SPIRV;
+ input.profile = "glsl_430";
nativeLanguage = SLANG_SOURCE_LANGUAGE_GLSL;
slangPassThrough = SLANG_PASS_THROUGH_GLSLANG;
- profileName = "glsl_430";
break;
-
+ case RendererType::CPU:
+ input.target = SLANG_HOST_CALLABLE;
+ input.profile = "";
+ nativeLanguage = SLANG_SOURCE_LANGUAGE_CPP;
+ slangPassThrough = SLANG_PASS_THROUGH_GENERIC_C_CPP;
+ break;
default:
fprintf(stderr, "error: unexpected\n");
return SLANG_FAIL;
}
-
+ switch (gOptions.inputLanguageID)
+ {
+ case Options::InputLanguageID::Slang:
+ input.sourceLanguage = SLANG_SOURCE_LANGUAGE_SLANG;
+ input.passThrough = SLANG_PASS_THROUGH_NONE;
+ break;
+
+ case Options::InputLanguageID::Native:
+ input.sourceLanguage = nativeLanguage;
+ input.passThrough = slangPassThrough;
+ break;
+
+ default:
+ break;
+ }
+
+ // Use the profile name set on options if set
+ input.profile = gOptions.profileName ? gOptions.profileName : input.profile;
+
StringBuilder rendererName;
rendererName << "[" << RendererUtil::toText(gOptions.rendererType) << "] ";
if (gOptions.adapter.getLength())
@@ -563,22 +929,18 @@ SLANG_TEST_TOOL_API SlangResult innerMain(Slang::StdWriters* stdWriters, SlangSe
rendererName << "'" << gOptions.adapter << "'";
}
+ RefPtr<renderer_test::Window> window;
- if (!renderer)
+ if (renderer)
{
- if (!gOptions.onlyStartup)
- {
- fprintf(stderr, "Unable to create renderer %s\n", rendererName.getBuffer());
- }
- return SLANG_FAIL;
- }
+ Renderer::Desc desc;
+ desc.width = gWindowWidth;
+ desc.height = gWindowHeight;
+ desc.adapter = gOptions.adapter;
- Renderer::Desc desc;
- desc.width = gWindowWidth;
- desc.height = gWindowHeight;
- desc.adapter = gOptions.adapter;
+ window = new renderer_test::Window;
+ SLANG_RETURN_ON_FAIL(window->initialize(gWindowWidth, gWindowHeight));
- {
SlangResult res = renderer->initialize(desc, (HWND)window->getHandle());
if (SLANG_FAILED(res))
{
@@ -588,15 +950,7 @@ SLANG_TEST_TOOL_API SlangResult innerMain(Slang::StdWriters* stdWriters, SlangSe
}
return res;
}
- }
-
- // If the only test is we can startup, then we are done
- if (gOptions.onlyStartup)
- {
- return SLANG_OK;
- }
- {
for (const auto& feature : gOptions.renderFeatures)
{
// If doesn't have required feature... we have to give up
@@ -606,36 +960,33 @@ SLANG_TEST_TOOL_API SlangResult innerMain(Slang::StdWriters* stdWriters, SlangSe
}
}
}
+ else
+ {
+ if (gOptions.rendererType != RendererType::CPU)
+ {
+ if (!gOptions.onlyStartup)
+ {
+ fprintf(stderr, "Unable to create renderer %s\n", rendererName.getBuffer());
+ }
+ return SLANG_FAIL;
+ }
+ }
- // Use the profile name set on options if set
- profileName = gOptions.profileName ? gOptions.profileName : profileName;
-
- ShaderCompiler shaderCompiler;
- shaderCompiler.renderer = renderer;
- shaderCompiler.target = slangTarget;
- shaderCompiler.profile = profileName;
- shaderCompiler.slangSession = session;
-
- switch (gOptions.inputLanguageID)
- {
- case Options::InputLanguageID::Slang:
- shaderCompiler.sourceLanguage = SLANG_SOURCE_LANGUAGE_SLANG;
- shaderCompiler.passThrough = SLANG_PASS_THROUGH_NONE;
- break;
-
- case Options::InputLanguageID::Native:
- shaderCompiler.sourceLanguage = nativeLanguage;
- shaderCompiler.passThrough = slangPassThrough;
- break;
+ // If the only test is we can startup, then we are done
+ if (gOptions.onlyStartup)
+ {
+ return SLANG_OK;
+ }
- default:
- break;
- }
+ if (!renderer)
+ {
+ SLANG_RETURN_ON_FAIL(_doCPUCompute(session, gOptions.sourcePath, gOptions.shaderType, input));
+ return SLANG_OK;
+ }
{
RenderTestApp app;
-
- SLANG_RETURN_ON_FAIL(app.initialize(renderer, &shaderCompiler));
+ SLANG_RETURN_ON_FAIL(app.initialize(session, renderer, gOptions.shaderType, input));
window->show();