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.cpp278
1 files changed, 105 insertions, 173 deletions
diff --git a/tools/render-test/render-test-main.cpp b/tools/render-test/render-test-main.cpp
index 3bd257340..0abf01b5a 100644
--- a/tools/render-test/render-test-main.cpp
+++ b/tools/render-test/render-test-main.cpp
@@ -27,6 +27,8 @@
#include "../../source/core/slang-test-tool-util.h"
#include "../../source/core/slang-memory-arena.h"
+#include "cpu-memory-binding.h"
+
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <Windows.h>
@@ -322,35 +324,7 @@ static SlangResult _compile(SlangSession* session, const String& sourcePath, Opt
return ShaderCompilerUtil::compileProgram(session, input, compileRequest, output.compileOutput);
}
-struct MemoryInfo
-{
- MemoryInfo() :data(nullptr), size(0) {}
- uint8_t* data;
- size_t size;
-};
-
-static MemoryInfo _allocateMemory(MemoryArena& arena, size_t size, List<unsigned int>& initialContents)
-{
- MemoryInfo info;
-
- // Use 16 byte alignment so works for all common types including typical simd
- void* data = arena.allocateAligned(size, 16);
- ::memset(data, 0, size);
-
- if (initialContents.getCount() > 0)
- {
- size_t initialSize = initialContents.getCount() * sizeof(unsigned int);
- initialSize = (initialSize > size) ? size : initialSize;
-
- ::memcpy(data, initialContents.getBuffer(), initialSize);
- }
-
- info.data = (uint8_t*)data;
- info.size = size;
- return info;
-}
-
-static SlangResult _writeBindings(const ShaderInputLayout& layout, const List<MemoryInfo>& infos, const String& fileName)
+static SlangResult _writeBindings(const ShaderInputLayout& layout, const List<CPUMemoryBinding::Buffer>& buffers, const String& fileName)
{
FILE * f = fopen(fileName.getBuffer(), "wb");
if (!f)
@@ -365,13 +339,13 @@ static SlangResult _writeBindings(const ShaderInputLayout& layout, const List<Me
const auto& entry = entries[i];
if (entry.isOutput)
{
- const auto& info = infos[i];
+ const auto& buffer = buffers[i];
- unsigned int* ptr = (unsigned int*)info.data;
+ 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) <= info.size);
+ SLANG_ASSERT(size * sizeof(unsigned int) <= buffer.m_sizeInBytes);
for (int i = 0; i < size; ++i)
{
@@ -385,20 +359,53 @@ static SlangResult _writeBindings(const ShaderInputLayout& layout, const List<Me
return SLANG_OK;
}
+struct CPUResource: public RefObject
+{
+ void* getInterface() const { return m_interface; }
+ void* m_interface;
+};
-static slang::VariableLayoutReflection* _getParameterByName(slang::ShaderReflection* reflection, const char* name)
+template <int COUNT>
+struct OneTexture2D: public CPUResource, public CPPPrelude::ITexture2D
{
- const int parameterCount = reflection->getParameterCount();
- for (int i = 0; i < parameterCount; ++i)
+ void setOne(void* out)
{
- auto parameter = reflection->getParameterByIndex(i);
- const char* paramName = parameter->getName();
- if (strcmp(name, paramName) == 0)
+ float* dst = (float*)out;
+ for (int i = 0; i < COUNT; ++i)
{
- return parameter;
+ dst[i] = 1.0f;
}
}
- return nullptr;
+
+ 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)
@@ -433,25 +440,21 @@ static SlangResult _doCPUCompute(SlangSession* session, const String& sourcePath
return SLANG_FAIL;
}
}
- // Okay we need to find all of the bindings and match up to those in the layout
- ShaderInputLayout& layout = output.layout;
+ CPUMemoryBinding binding;
+ binding.init(reflection);
- // For general storage
- MemoryArena arena;
- // 1k blocks with minimum 16 byte alignment
- arena.init(1024, 16);
+ List<CPUMemoryBinding::Buffer> buffers;
- // We have a memory info for each of the layouts
- List<MemoryInfo> memoryInfos;
- memoryInfos.setCount(layout.entries.getCount());
+ // Okay we need to find all of the bindings and match up to those in the layout
+ ShaderInputLayout& layout = output.layout;
- List<void*> uniformState;
+ List<RefPtr<CPUResource> > resources;
{
- auto& outStream = StdWriters::getOut();
-
+ auto& outStream = StdWriters::getOut();
auto& entries = layout.entries;
+ buffers.setCount(entries.getCount());
for (int entryIndex = 0; entryIndex < entries.getCount(); ++entryIndex)
{
@@ -466,8 +469,8 @@ static SlangResult _doCPUCompute(SlangSession* session, const String& sourcePath
// We will parse the 'name' as may be path to a resource
TokenReader parser(entry.name);
- size_t offset = 0;
- slang::TypeLayoutReflection* typeLayout = nullptr;
+ CPUMemoryBinding::Location location;
+
{
Token nameToken = parser.ReadToken();
if (nameToken.Type != TokenType::Identifier)
@@ -475,15 +478,12 @@ static SlangResult _doCPUCompute(SlangSession* session, const String& sourcePath
outStream.print("Invalid input syntax at line %d", int(parser.NextToken().Position.Line));
return SLANG_FAIL;
}
- auto parameter = _getParameterByName(reflection, nameToken.Content.getBuffer());
- if (!parameter)
+ 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;
}
-
- typeLayout = parameter->getTypeLayout();
- offset = parameter->getOffset();
}
while (!parser.IsEnd())
@@ -495,47 +495,24 @@ static SlangResult _doCPUCompute(SlangSession* session, const String& sourcePath
parser.ReadToken();
int index = parser.ReadInt();
SLANG_ASSERT(index >= 0);
- parser.ReadMatchingToken(TokenType::RBracket);
- auto elementTypeLayout = typeLayout->getElementTypeLayout();
- auto elementCount = int(typeLayout->getElementCount());
-
- SLANG_ASSERT(index < elementCount);
-
- typeLayout = elementTypeLayout;
- offset += elementTypeLayout->getSize() * index;
+ location = binding.toIndex(location, 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);
- if (typeLayout->getKind() == slang::TypeReflection::Kind::Struct)
+ location = binding.toField(location, identifierToken.Content.getBuffer());
+ if (location.isInvalid())
{
- slang::VariableLayoutReflection* varLayout = nullptr;
- auto fieldCount = typeLayout->getFieldCount();
- for (uint32_t ff = 0; ff < fieldCount; ++ff)
- {
- auto field = typeLayout->getFieldByIndex(ff);
- if (identifierToken.Content == field->getName())
- {
- varLayout = field;
- break;
- }
- }
-
- if (varLayout == nullptr)
- {
- outStream.print("Couldn't field %s\n", identifierToken.Content.getBuffer());
- return SLANG_FAIL;
- }
-
- offset += varLayout->getOffset();
- typeLayout = varLayout->getTypeLayout();
- }
- else
- {
- outStream.print("Couldn't field %s\n", identifierToken.Content.getBuffer());
+ outStream.print("Unable to find field '%s' in '%s'\n", identifierToken.Content.getBuffer(), entry.name.getBuffer());
return SLANG_FAIL;
}
}
@@ -550,62 +527,26 @@ static SlangResult _doCPUCompute(SlangSession* session, const String& sourcePath
}
}
- auto count = typeLayout->getSize();
-
- 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())
+ auto typeLayout = location.m_typeLayout;
+ const auto kind = typeLayout->getKind();
+ switch (kind)
{
- default:
- break;
-
+ case slang::TypeReflection::Kind::Vector:
+ case slang::TypeReflection::Kind::Matrix:
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::Scalar:
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);
+ 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_ASSERT(typeLayout->getSize(SLANG_PARAMETER_CATEGORY_UNIFORM) == sizeof(void*));
- auto elementTypeLayout = typeLayout->getElementTypeLayout();
- const size_t elementSize = elementTypeLayout->getSize(SLANG_PARAMETER_CATEGORY_UNIFORM);
-
- const MemoryInfo info = _allocateMemory(arena, elementSize, srcEntry.bufferData);
- memoryInfos[entryIndex] = info;
- *(void**)dstEntry = info.data;
+ SLANG_RETURN_ON_FAIL(binding.setBufferContents(location, srcEntry.bufferData.getBuffer(),srcEntry.bufferData.getCount() * sizeof(unsigned int) ));
break;
}
case slang::TypeReflection::Kind::ParameterBlock:
@@ -650,48 +591,37 @@ static SlangResult _doCPUCompute(SlangSession* session, const String& sourcePath
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:
{
- auto elementTypeLayout = typeLayout->getElementTypeLayout();
- size_t elementSize = elementTypeLayout->getSize(SLANG_PARAMETER_CATEGORY_UNIFORM);
-
- // We don't know the size of the buffer, but we can work it out, based on what is initialized
+ slang::TypeReflection* typeReflection = location.m_typeLayout->getResourceResultType();
- size_t srcBufferSize = srcEntry.bufferData.getCount() * sizeof(unsigned int);
- const int numElements = int((srcBufferSize + elementSize - 1) / elementSize);
-
- size_t bufferSize = numElements * elementSize;
- SLANG_ASSERT(bufferSize >= srcBufferSize);
+ int count = 1;
+ if (typeReflection->getKind() == slang::TypeReflection::Kind::Vector)
+ {
+ count = int(typeReflection->getElementCount());
+ }
- const MemoryInfo info = _allocateMemory(arena, bufferSize, srcEntry.bufferData);
- memoryInfos[entryIndex] = info;
+ RefPtr<CPUResource> resource = _newOneTexture2D(count);
+ resources.add(resource);
- // TODO(JS): I guess this is questionable - because sizeof(unsigned int) != sizeof(uint32_t) necessarily
- CPPPrelude::StructuredBuffer<uint32_t>& dstBuf = *(CPPPrelude::StructuredBuffer<uint32_t>*)dstEntry;
- dstBuf.data = (uint32_t*)info.data;
- dstBuf.count = numElements;
+ 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:
{
- CPPPrelude::ByteAddressBuffer& dstBuf = *(CPPPrelude::ByteAddressBuffer*)dstEntry;
-
- Index numElements = srcEntry.bufferData.getCount();
- size_t bufferSize = sizeof(uint32_t) * numElements;
-
- const MemoryInfo info = _allocateMemory(arena, bufferSize, srcEntry.bufferData);
- memoryInfos[entryIndex] = info;
-
- dstBuf.data = (uint32_t*)info.data;
- dstBuf.sizeInBytes = bufferSize;
+ CPUMemoryBinding::Buffer buffer;
+ SLANG_RETURN_ON_FAIL(binding.setNewBuffer(location, srcEntry.bufferData.getBuffer(), srcEntry.bufferData.getCount() * sizeof(unsigned int), buffer ));
+ buffers[entryIndex] = buffer;
break;
}
}
@@ -714,6 +644,8 @@ static SlangResult _doCPUCompute(SlangSession* session, const String& sourcePath
entryPoint->getComputeThreadGroupSize(3, numThreadsPerAxis);
{
+ UniformState* uniformState = (UniformState*)binding.m_rootBuffer.m_data;
+
CPPPrelude::ComputeVaryingInput varying;
varying.groupID = {};
@@ -727,14 +659,14 @@ static SlangResult _doCPUCompute(SlangSession* session, const String& sourcePath
{
varying.groupThreadID.x = x;
- func(&varying, (UniformState*)uniformState.getBuffer());
+ func(&varying, uniformState);
}
}
}
}
// Dump everything out that was write (we wrote in place!)
- return _writeBindings(layout, memoryInfos, gOptions.outputPath);
+ return _writeBindings(layout, buffers, gOptions.outputPath);
}
SlangResult RenderTestApp::initialize(SlangSession* session, Renderer* renderer, Options::ShaderProgramType shaderType, const ShaderCompilerUtil::Input& input)