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.cpp453
1 files changed, 13 insertions, 440 deletions
diff --git a/tools/render-test/render-test-main.cpp b/tools/render-test/render-test-main.cpp
index 440ba9c82..5b9621142 100644
--- a/tools/render-test/render-test-main.cpp
+++ b/tools/render-test/render-test-main.cpp
@@ -21,13 +21,9 @@
#include <stdio.h>
#include <stdlib.h>
-#define SLANG_PRELUDE_NAMESPACE CPPPrelude
-#include "../../prelude/slang-cpp-types.h"
-
#include "../../source/core/slang-test-tool-util.h"
-#include "../../source/core/slang-memory-arena.h"
-#include "cpu-memory-binding.h"
+#include "cpu-compute-util.h"
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
@@ -241,436 +237,6 @@ class RenderTestApp
int m_numAddedConstantBuffers; ///< Constant buffers can be added to the binding directly. Will be added at the end.
};
-// Entry point name to use for vertex/fragment shader
-static const char vertexEntryPointName[] = "vertexMain";
-static const char fragmentEntryPointName[] = "fragmentMain";
-static const char computeEntryPointName[] = "computeMain";
-
-static SlangResult _readSource(const String& inSourcePath, List<char>& outSourceText)
-{
- // 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);
-
- outSourceText.setCount(sourceSize + 1);
- fread(outSourceText.getBuffer(), sourceSize, 1, sourceFile);
- fclose(sourceFile);
- outSourceText[sourceSize] = 0;
-
- 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)
- {
- default:
- layout.numRenderTargets = 1;
- break;
-
- case Options::ShaderProgramType::Compute:
- layout.numRenderTargets = 0;
- break;
- }
-
- // Parse the layout
- layout.parse(sourceText.getBuffer());
- layout.updateForTarget(input.target);
-
- // 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 _writeBindings(const ShaderInputLayout& layout, const List<CPUMemoryBinding::Buffer>& buffers, const String& fileName)
-{
- FILE * f = fopen(fileName.getBuffer(), "wb");
- if (!f)
- {
- return SLANG_FAIL;
- }
-
- const auto& entries = layout.entries;
-
- for (int i = 0; i < entries.getCount(); ++i)
- {
- const auto& entry = entries[i];
- if (entry.isOutput)
- {
- const auto& buffer = buffers[i];
-
- unsigned int* ptr = (unsigned int*)buffer.m_data;
-
- const int size = int(entry.bufferData.getCount());
- // Must be the same size or less thatn allocated buffer
- SLANG_ASSERT(size * sizeof(unsigned int) <= buffer.m_sizeInBytes);
-
- for (int i = 0; i < size; ++i)
- {
- unsigned int v = ptr[i];
-
- fprintf(f, "%X\n", v);
- }
- }
- }
- fclose(f);
- return SLANG_OK;
-}
-
-struct CPUResource: public RefObject
-{
- void* getInterface() const { return m_interface; }
- void* m_interface;
-};
-
-template <int COUNT>
-struct OneTexture2D: public CPUResource, public CPPPrelude::ITexture2D
-{
- void setOne(void* out)
- {
- float* dst = (float*)out;
- for (int i = 0; i < COUNT; ++i)
- {
- dst[i] = 1.0f;
- }
- }
-
- virtual void Load(const CPPPrelude::int3& v, void* out) SLANG_OVERRIDE
- {
- setOne(out);
- }
- virtual void Sample(CPPPrelude::SamplerState samplerState, const CPPPrelude::float2& loc, void* out) SLANG_OVERRIDE
- {
- setOne(out);
- }
- virtual void SampleLevel(CPPPrelude::SamplerState samplerState, const CPPPrelude::float2& loc, float level, void* out) SLANG_OVERRIDE
- {
- setOne(out);
- }
-
- OneTexture2D()
- {
- m_interface = static_cast<CPPPrelude::ITexture2D*>(this);
- }
-};
-
-static CPUResource* _newOneTexture2D(int elemCount)
-{
- switch (elemCount)
- {
- case 1: return new OneTexture2D<1>();
- case 2: return new OneTexture2D<2>();
- case 3: return new OneTexture2D<3>();
- case 4: return new OneTexture2D<4>();
- default: return nullptr;
- }
-}
-
-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, CPPPrelude::UniformEntryPointParams* params, 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;
- }
- }
-
- CPUMemoryBinding binding;
- SLANG_RETURN_ON_FAIL(binding.init(reflection, 0));
-
- List<CPUMemoryBinding::Buffer> buffers;
-
- // Okay we need to find all of the bindings and match up to those in the layout
- ShaderInputLayout& layout = output.layout;
-
- List<RefPtr<CPUResource> > resources;
-
- {
- auto& outStream = StdWriters::getOut();
- auto& entries = layout.entries;
- buffers.setCount(entries.getCount());
-
- for (int entryIndex = 0; entryIndex < entries.getCount(); ++entryIndex)
- {
- auto& entry = entries[entryIndex];
-
- if (entry.name.getLength() == 0)
- {
- outStream.print("No 'name' specified for resources in '%s'\n", sourcePath.getBuffer());
- return SLANG_FAIL;
- }
-
- // We will parse the 'name' as may be path to a resource
- TokenReader parser(entry.name);
-
- CPUMemoryBinding::Location location;
-
- {
- Token nameToken = parser.ReadToken();
- if (nameToken.Type != TokenType::Identifier)
- {
- outStream.print("Invalid input syntax at line %d", int(parser.NextToken().Position.Line));
- return SLANG_FAIL;
- }
- location = binding.find(nameToken.Content.getBuffer());
- if (location.isInvalid())
- {
- outStream.print("Unable to find entry in '%s' for '%s' (for CPU name must be specified) \n", sourcePath.getBuffer(), entry.name.getBuffer());
- return SLANG_FAIL;
- }
- }
-
- while (!parser.IsEnd())
- {
- Token token = parser.NextToken(0);
-
- if (token.Type == TokenType::LBracket)
- {
- parser.ReadToken();
- int index = parser.ReadInt();
- SLANG_ASSERT(index >= 0);
-
- location = location.toIndex(index);
- if (location.isInvalid())
- {
- outStream.print("Unable to find entry in '%d' in '%s'\n", index, entry.name.getBuffer());
- return SLANG_FAIL;
- }
- parser.ReadMatchingToken(TokenType::RBracket);
- }
- else if (token.Type == TokenType::Dot)
- {
- parser.ReadToken();
- Token identifierToken = parser.ReadMatchingToken(TokenType::Identifier);
-
- location = location.toField(identifierToken.Content.getBuffer());
- if (location.isInvalid())
- {
- outStream.print("Unable to find field '%s' in '%s'\n", identifierToken.Content.getBuffer(), entry.name.getBuffer());
- return SLANG_FAIL;
- }
- }
- else if (token.Type == TokenType::Comma)
- {
- // Break out
- break;
- }
- else
- {
- throw TextFormatException("Invalid input syntax at line " + parser.NextToken().Position.Line);
- }
- }
-
- auto& srcEntry = layout.entries[entryIndex];
-
- auto typeLayout = location.getTypeLayout();
- const auto kind = typeLayout->getKind();
- switch (kind)
- {
- case slang::TypeReflection::Kind::Vector:
- case slang::TypeReflection::Kind::Matrix:
- case slang::TypeReflection::Kind::Array:
- case slang::TypeReflection::Kind::Scalar:
- case slang::TypeReflection::Kind::Struct:
- {
- SLANG_RETURN_ON_FAIL(binding.setInplace(location, srcEntry.bufferData.getBuffer(), srcEntry.bufferData.getCount() * sizeof(unsigned int)));
- break;
- }
- default:
- break;
- case slang::TypeReflection::Kind::ConstantBuffer:
- {
- SLANG_RETURN_ON_FAIL(binding.setBufferContents(location, srcEntry.bufferData.getBuffer(),srcEntry.bufferData.getCount() * sizeof(unsigned int) ));
- 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:
- {
- auto type = typeLayout->getType();
- auto shape = type->getResourceShape();
-
- //auto access = type->getResourceAccess();
-
- switch (shape & SLANG_RESOURCE_BASE_SHAPE_MASK)
- {
- default:
- assert(!"unhandled case");
- break;
- case SLANG_TEXTURE_2D:
- {
- slang::TypeReflection* typeReflection = location.getTypeLayout()->getResourceResultType();
-
- int count = 1;
- if (typeReflection->getKind() == slang::TypeReflection::Kind::Vector)
- {
- count = int(typeReflection->getElementCount());
- }
-
- RefPtr<CPUResource> resource = _newOneTexture2D(count);
- resources.add(resource);
-
- SLANG_RETURN_ON_FAIL(binding.setObject(location, resource->getInterface()));
- break;
- }
- case SLANG_TEXTURE_1D:
- case SLANG_TEXTURE_3D:
- case SLANG_TEXTURE_CUBE:
- case SLANG_TEXTURE_BUFFER:
- {
- // Just set to null for now
- SLANG_RETURN_ON_FAIL(binding.setObject(location, nullptr));
- break;
- }
- case SLANG_BYTE_ADDRESS_BUFFER:
- case SLANG_STRUCTURED_BUFFER:
- {
- CPUMemoryBinding::Buffer buffer;
- SLANG_RETURN_ON_FAIL(binding.setNewBuffer(location, srcEntry.bufferData.getBuffer(), srcEntry.bufferData.getCount() * sizeof(unsigned int), buffer ));
- buffers[entryIndex] = buffer;
- break;
- }
- }
- if (shape & SLANG_TEXTURE_ARRAY_FLAG)
- {
-
- }
- if (shape & SLANG_TEXTURE_MULTISAMPLE_FLAG)
- {
-
- }
-
- break;
- }
- }
- }
- }
-
- SlangUInt numThreadsPerAxis[3];
- entryPoint->getComputeThreadGroupSize(3, numThreadsPerAxis);
-
- {
- UniformState* uniformState = (UniformState*)binding.m_rootBuffer.m_data;
- CPPPrelude::UniformEntryPointParams* params = (CPPPrelude::UniformEntryPointParams*)binding.m_entryPointBuffer.m_data;
-
- CPPPrelude::ComputeVaryingInput varying;
- varying.groupID = {};
-
- for (int z = 0; z < int(numThreadsPerAxis[2]); ++z)
- {
- varying.groupThreadID.z = z;
- for (int y = 0; y < int(numThreadsPerAxis[1]); ++y)
- {
- varying.groupThreadID.y = y;
- for (int x = 0; x < int(numThreadsPerAxis[0]); ++x)
- {
- varying.groupThreadID.x = x;
-
- func(&varying, params, uniformState);
- }
- }
- }
- }
-
- // Dump everything out that was write (we wrote in place!)
- return _writeBindings(layout, buffers, 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));
@@ -769,10 +335,10 @@ SlangResult RenderTestApp::initialize(SlangSession* session, Renderer* renderer,
Result RenderTestApp::_initializeShaders(SlangSession* session, Renderer* renderer, Options::ShaderProgramType shaderType, const ShaderCompilerUtil::Input& input)
{
- CompileOutput output;
- SLANG_RETURN_ON_FAIL(_compile(session, gOptions.sourcePath, shaderType, input, output));
+ ShaderCompilerUtil::OutputAndLayout output;
+ SLANG_RETURN_ON_FAIL(ShaderCompilerUtil::compileWithLayout(session, gOptions.sourcePath, shaderType, input, output));
m_shaderInputLayout = output.layout;
- m_shaderProgram = renderer->createProgram(output.compileOutput.desc);
+ m_shaderProgram = renderer->createProgram(output.output.desc);
return m_shaderProgram ? SLANG_OK : SLANG_FAIL;
}
@@ -1024,8 +590,15 @@ SLANG_TEST_TOOL_API SlangResult innerMain(Slang::StdWriters* stdWriters, SlangSe
if (!renderer)
{
- SLANG_RETURN_ON_FAIL(_doCPUCompute(session, gOptions.sourcePath, gOptions.shaderType, input));
- return SLANG_OK;
+ ShaderCompilerUtil::OutputAndLayout compilationAndLayout;
+ SLANG_RETURN_ON_FAIL(ShaderCompilerUtil::compileWithLayout(session, gOptions.sourcePath, gOptions.shaderType, input, compilationAndLayout));
+
+ CPUComputeUtil::Context context;
+ SLANG_RETURN_ON_FAIL(CPUComputeUtil::calcBindings(compilationAndLayout, context));
+ SLANG_RETURN_ON_FAIL(CPUComputeUtil::execute(compilationAndLayout, context));
+
+ // Dump everything out that was written
+ return CPUComputeUtil::writeBindings(compilationAndLayout.layout, context.buffers, gOptions.outputPath);
}
{