summaryrefslogtreecommitdiffstats
path: root/tools/render-test
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2019-08-26 15:45:28 -0400
committerGitHub <noreply@github.com>2019-08-26 15:45:28 -0400
commit2c4307a9c1a5d1ec92599bb6afe065636ff81df3 (patch)
treedda2f66dedfefa5b730a65250edff4a6eec66358 /tools/render-test
parent6a0ca6c6a23b8a29320b86be6aec50263f5d7d97 (diff)
WIP: CPU sample working with Texture2D (#1033)
* WIP: Memory binding. * WIP for binding. * Fix handling of writing to constant buffer. * Fix bug in handling indices.
Diffstat (limited to 'tools/render-test')
-rw-r--r--tools/render-test/cpu-memory-binding.cpp450
-rw-r--r--tools/render-test/cpu-memory-binding.h62
-rw-r--r--tools/render-test/render-test-main.cpp278
-rw-r--r--tools/render-test/render-test-tool.vcxproj2
-rw-r--r--tools/render-test/render-test-tool.vcxproj.filters6
5 files changed, 625 insertions, 173 deletions
diff --git a/tools/render-test/cpu-memory-binding.cpp b/tools/render-test/cpu-memory-binding.cpp
new file mode 100644
index 000000000..157716b60
--- /dev/null
+++ b/tools/render-test/cpu-memory-binding.cpp
@@ -0,0 +1,450 @@
+
+#include "cpu-memory-binding.h"
+
+#include "../../slang-com-helper.h"
+
+#define SLANG_PRELUDE_NAMESPACE CPPPrelude
+#include "../../prelude/slang-cpp-types.h"
+
+namespace renderer_test {
+using namespace Slang;
+
+CPUMemoryBinding::CPUMemoryBinding()
+{
+ m_arena.init(1024, 16);
+}
+
+CPUMemoryBinding::Buffer CPUMemoryBinding::_allocateBuffer(size_t size)
+{
+ Buffer buffer;
+
+ // Use 16 byte alignment so works for all common types including typical simd
+ void* data = m_arena.allocateAligned(size, 16);
+ ::memset(data, 0, size);
+
+ buffer.m_data = (uint8_t*)data;
+ buffer.m_sizeInBytes = size;
+
+ m_allBuffers.add(buffer);
+ return buffer;
+}
+
+CPUMemoryBinding::Buffer CPUMemoryBinding::_allocateBuffer(size_t size, const void* initialData, size_t initialSize)
+{
+ SLANG_ASSERT(initialSize <= size);
+ Buffer buffer = _allocateBuffer(size);
+
+ if (initialData)
+ {
+ memcpy(buffer.m_data, initialData, initialSize);
+ }
+
+ return buffer;
+}
+
+SlangResult CPUMemoryBinding::init(slang::ShaderReflection* reflection)
+{
+ m_reflection = reflection;
+ m_rootBuffer = Buffer();
+
+ m_allBuffers.clear();
+ m_arena.deallocateAll();
+
+ size_t globalConstantBuffer = reflection->getGlobalConstantBufferSize();
+
+ size_t rootSizeInBytes = 0;
+ const int parameterCount = reflection->getParameterCount();
+ for (int i = 0; i < parameterCount; ++i)
+ {
+ auto parameter = reflection->getParameterByIndex(i);
+
+ auto offset = parameter->getOffset();
+
+ auto typeLayout = parameter->getTypeLayout();
+ auto sizeInBytes = typeLayout->getSize();
+
+ size_t endOffset = offset + sizeInBytes;
+
+ rootSizeInBytes = (endOffset > rootSizeInBytes) ? endOffset : rootSizeInBytes;
+ }
+ SLANG_ASSERT(rootSizeInBytes == globalConstantBuffer);
+
+ // Allocate the root (0 is the root)
+ m_rootBuffer = _allocateBuffer(rootSizeInBytes);
+
+ {
+ uint8_t*const buffer = m_rootBuffer.m_data;
+ for (int i = 0; i < parameterCount; ++i)
+ {
+ auto parameter = reflection->getParameterByIndex(i);
+ auto offset = parameter->getOffset();
+
+ auto typeLayout = parameter->getTypeLayout();
+ Buffer paramBuffer;
+ SLANG_RETURN_ON_FAIL(_add(parameter, typeLayout, buffer + offset, paramBuffer));
+ }
+ }
+
+ return SLANG_OK;
+}
+
+SlangResult CPUMemoryBinding::_add(slang::VariableLayoutReflection* varLayout, slang::TypeLayoutReflection* typeLayout, void* dst, Buffer& outBuffer)
+{
+ const auto kind = typeLayout->getKind();
+ switch (kind)
+ {
+ case slang::TypeReflection::Kind::Array:
+ {
+ auto elementTypeLayout = typeLayout->getElementTypeLayout();
+ auto elementCount = int(typeLayout->getElementCount());
+ const size_t stride = elementTypeLayout->getSize();
+ uint8_t* cur = (uint8_t*)dst;
+ for (int i = 0; i < elementCount; ++i)
+ {
+ Buffer elementBuffer;
+ _add(nullptr, elementTypeLayout, cur, elementBuffer);
+ cur += stride;
+ }
+ 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);
+ auto offset = field->getOffset();
+
+ Buffer fieldBuffer;
+ SLANG_RETURN_ON_FAIL(_add(nullptr, field->getTypeLayout(), ((uint8_t*)dst) + offset, fieldBuffer));
+ }
+ break;
+ }
+ case slang::TypeReflection::Kind::ConstantBuffer:
+ {
+ SLANG_ASSERT(typeLayout->getSize() == sizeof(void*));
+
+ auto elementTypeLayout = typeLayout->getElementTypeLayout();
+ const size_t elementSize = elementTypeLayout->getSize();
+
+ outBuffer = _allocateBuffer(elementSize);
+
+ // Constant buffers map to a pointer
+ *(void**)dst = outBuffer.m_data;
+
+ // On CPU constant buffers can contain pointers to other resources (including constant buffers)
+ Buffer innerBuffer;
+ SLANG_RETURN_ON_FAIL(_add(nullptr, elementTypeLayout, outBuffer.m_data, innerBuffer));
+ break;
+ }
+ default: break;
+ }
+ return SLANG_OK;
+}
+
+slang::VariableLayoutReflection* CPUMemoryBinding::getParameterByName(const char* name)
+{
+ const int parameterCount = m_reflection->getParameterCount();
+ for (int i = 0; i < parameterCount; ++i)
+ {
+ auto parameter = m_reflection->getParameterByIndex(i);
+ const char* paramName = parameter->getName();
+ if (strcmp(name, paramName) == 0)
+ {
+ return parameter;
+ }
+ }
+ return nullptr;
+}
+
+CPUMemoryBinding::Location CPUMemoryBinding::find(const char* name)
+{
+ auto varLayout = getParameterByName(name);
+ if (varLayout == nullptr)
+ {
+ return Location();
+ }
+
+ Location location;
+ location.m_cur = m_rootBuffer.m_data + varLayout->getOffset();
+ location.m_typeLayout = varLayout->getTypeLayout();
+
+ return location;
+}
+
+CPUMemoryBinding::Location CPUMemoryBinding::toField(const Location& location, const char* name)
+{
+ if (!location.isValid())
+ {
+ return location;
+ }
+
+ auto typeLayout = location.m_typeLayout;
+ uint8_t* cur = location.m_cur;
+
+ // Strip constantBuffer wrapping
+ {
+ const auto kind = typeLayout->getKind();
+ if (kind == slang::TypeReflection::Kind::ConstantBuffer)
+ {
+ // Follow the pointer
+ cur = *(uint8_t**)cur;
+ typeLayout = typeLayout->getElementTypeLayout();
+ }
+ }
+
+ {
+ const auto kind = typeLayout->getKind();
+ if (kind == slang::TypeReflection::Kind::Struct)
+ {
+ slang::VariableLayoutReflection* varLayout = nullptr;
+ auto fieldCount = typeLayout->getFieldCount();
+ for (uint32_t ff = 0; ff < fieldCount; ++ff)
+ {
+ auto field = typeLayout->getFieldByIndex(ff);
+ if (strcmp(field->getName(), name) == 0)
+ {
+ Location newLocation;
+ newLocation.m_cur = cur + field->getOffset();
+ newLocation.m_typeLayout = field->getTypeLayout();
+ return newLocation;
+ }
+ }
+ }
+ }
+
+ return Location();
+}
+
+CPUMemoryBinding::Location CPUMemoryBinding::toIndex(const Location& location, int index)
+{
+ if (!location.isValid())
+ {
+ return location;
+ }
+
+ auto typeLayout = location.m_typeLayout;
+ uint8_t* cur = location.m_cur;
+
+ const auto kind = typeLayout->getKind();
+ switch (kind)
+ {
+ case slang::TypeReflection::Kind::Array:
+ {
+ auto elementTypeLayout = typeLayout->getElementTypeLayout();
+ auto elementCount = int(typeLayout->getElementCount());
+
+ if (index < 0 || index >= elementCount)
+ {
+ SLANG_ASSERT(index < elementCount);
+ return Location();
+ }
+
+ Location newLocation;
+ newLocation.m_typeLayout = elementTypeLayout;
+ newLocation.m_cur = cur + elementTypeLayout->getSize() * index;
+ return newLocation;
+ }
+ default: break;
+ }
+
+ return Location();
+}
+
+
+SlangResult CPUMemoryBinding::setBufferContents(const Location& location, const void* initialData, size_t sizeInBytes)
+{
+ if (!location.isValid())
+ {
+ return SLANG_FAIL;
+ }
+
+ auto typeLayout = location.m_typeLayout;
+ uint8_t* cur = location.m_cur;
+
+ const auto kind = typeLayout->getKind();
+ switch (kind)
+ {
+ case slang::TypeReflection::Kind::ConstantBuffer:
+ {
+ typeLayout = typeLayout->getElementTypeLayout();
+
+ size_t bufferSize = typeLayout->getSize();
+ sizeInBytes = (sizeInBytes > bufferSize) ? bufferSize : sizeInBytes;
+
+ void* buffer = *(void**)cur;
+ memcpy(buffer, initialData, sizeInBytes);
+ return SLANG_OK;
+ }
+ default: break;
+ }
+ return SLANG_FAIL;
+}
+
+SlangResult CPUMemoryBinding::setNewBuffer(const Location& location, const void* initialData, size_t sizeInBytes, Buffer& outBuffer)
+{
+ if (!location.isValid())
+ {
+ return SLANG_FAIL;
+ }
+
+ auto typeLayout = location.m_typeLayout;
+ uint8_t* cur = location.m_cur;
+
+ const auto kind = typeLayout->getKind();
+ switch (kind)
+ {
+ case slang::TypeReflection::Kind::ConstantBuffer:
+ {
+ // All should be allocated (!)
+ SLANG_ASSERT(typeLayout->getSize() == sizeof(void*));
+ SLANG_ASSERT(*(void**)cur);
+ return SLANG_FAIL;
+ }
+ case slang::TypeReflection::Kind::Resource:
+ {
+ auto type = typeLayout->getType();
+ auto shape = type->getResourceShape();
+
+ switch (shape & SLANG_RESOURCE_BASE_SHAPE_MASK)
+ {
+ 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
+ const int numElements = int((sizeInBytes + elementSize - 1) / elementSize);
+
+ const size_t bufferSize = numElements * elementSize;
+ SLANG_ASSERT(bufferSize >= sizeInBytes);
+
+ outBuffer = _allocateBuffer(bufferSize, initialData, sizeInBytes);
+
+ CPPPrelude::StructuredBuffer<uint8_t>& dstBuf = *(CPPPrelude::StructuredBuffer<uint8_t>*)cur;
+ dstBuf.data = (uint8_t*)outBuffer.m_data;
+ dstBuf.count = numElements;
+ return SLANG_OK;
+ }
+ case SLANG_BYTE_ADDRESS_BUFFER:
+ {
+ const size_t bufferSize = (sizeInBytes + 3) & ~size_t(3);
+
+ outBuffer = _allocateBuffer(bufferSize, initialData, sizeInBytes);
+
+ CPPPrelude::ByteAddressBuffer& dstBuf = *(CPPPrelude::ByteAddressBuffer*)cur;
+ dstBuf.data = (uint32_t*)outBuffer.m_data;
+ dstBuf.sizeInBytes = bufferSize;
+ return SLANG_OK;
+ }
+ }
+ break;
+ }
+ default: break;
+ }
+
+ return SLANG_FAIL;
+}
+
+SlangResult CPUMemoryBinding::setObject(const Location& location, void* object)
+{
+ if (!location.isValid())
+ {
+ return SLANG_FAIL;
+ }
+
+ auto typeLayout = location.m_typeLayout;
+ uint8_t* cur = location.m_cur;
+
+ const auto kind = typeLayout->getKind();
+ switch (kind)
+ {
+ default:
+ 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_1D:
+ case SLANG_TEXTURE_2D:
+ case SLANG_TEXTURE_3D:
+ case SLANG_TEXTURE_CUBE:
+ case SLANG_TEXTURE_BUFFER:
+ {
+ *(void**)cur = object;
+ return SLANG_OK;
+ }
+ }
+ if (shape & SLANG_TEXTURE_ARRAY_FLAG)
+ {
+
+ }
+ if (shape & SLANG_TEXTURE_MULTISAMPLE_FLAG)
+ {
+
+ }
+
+ break;
+ }
+ }
+
+ return SLANG_FAIL;
+}
+
+SlangResult CPUMemoryBinding::setInplace(const Location& location, const void* data, size_t sizeInBytes)
+{
+ if (!location.isValid())
+ {
+ return SLANG_FAIL;
+ }
+
+ size_t dstSize = location.m_typeLayout->getSize();
+ sizeInBytes = (sizeInBytes > dstSize) ? dstSize : sizeInBytes;
+ memcpy(location.m_cur, data, sizeInBytes);
+ return SLANG_OK;
+}
+
+} // renderer_test
diff --git a/tools/render-test/cpu-memory-binding.h b/tools/render-test/cpu-memory-binding.h
new file mode 100644
index 000000000..4ca9091b8
--- /dev/null
+++ b/tools/render-test/cpu-memory-binding.h
@@ -0,0 +1,62 @@
+#ifndef CPU_MEMORY_BINDING_H
+#define CPU_MEMORY_BINDING_H
+
+#include "core/slang-basic.h"
+
+#include "core/slang-memory-arena.h"
+
+namespace renderer_test {
+
+struct CPUMemoryBinding
+{
+ struct Buffer
+ {
+ Buffer() : m_data(nullptr), m_sizeInBytes(0) {}
+ uint8_t* m_data;
+ size_t m_sizeInBytes;
+ };
+
+ struct Location
+ {
+ bool isValid() const { return m_cur != nullptr; }
+ bool isInvalid() const { return m_cur == nullptr; }
+
+ Location():m_cur(nullptr) {}
+
+ slang::TypeLayoutReflection* m_typeLayout;
+ uint8_t* m_cur;
+ };
+
+ slang::VariableLayoutReflection* getParameterByName(const char* name);
+
+ Location find(const char* name);
+
+ Location toField(const Location& location, const char* name);
+ Location toIndex(const Location& location, int index);
+
+ SlangResult setBufferContents(const Location& location, const void* initialData, size_t sizeInBytes);
+ SlangResult setNewBuffer(const Location& location, const void* initialData, size_t sizeInBytes, Buffer& outBuffer);
+ SlangResult setObject(const Location& location, void* object);
+ SlangResult setInplace(const Location& location, const void* data, size_t sizeInBytes);
+
+ SlangResult init(slang::ShaderReflection* reflection);
+ CPUMemoryBinding();
+
+ Buffer _allocateBuffer(size_t size);
+ Buffer _allocateBuffer(size_t size, const void* initialData, size_t initialSize);
+
+ SlangResult _add(slang::VariableLayoutReflection* var, slang::TypeLayoutReflection* type, void* dst, Buffer& outBuffer);
+
+ Slang::MemoryArena m_arena; ///< Storage for buffers
+
+ Buffer m_rootBuffer;
+
+ slang::ShaderReflection* m_reflection;
+
+ // All buffers
+ Slang::List<Buffer> m_allBuffers;
+};
+
+} // renderer_test
+
+#endif //CPU_MEMORY_BINDING_H
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)
diff --git a/tools/render-test/render-test-tool.vcxproj b/tools/render-test/render-test-tool.vcxproj
index dea8627e3..8ab5d9859 100644
--- a/tools/render-test/render-test-tool.vcxproj
+++ b/tools/render-test/render-test-tool.vcxproj
@@ -179,6 +179,7 @@
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
+ <ClInclude Include="cpu-memory-binding.h" />
<ClInclude Include="options.h" />
<ClInclude Include="png-serialize-util.h" />
<ClInclude Include="shader-input-layout.h" />
@@ -186,6 +187,7 @@
<ClInclude Include="slang-support.h" />
</ItemGroup>
<ItemGroup>
+ <ClCompile Include="cpu-memory-binding.cpp" />
<ClCompile Include="options.cpp" />
<ClCompile Include="png-serialize-util.cpp" />
<ClCompile Include="render-test-main.cpp" />
diff --git a/tools/render-test/render-test-tool.vcxproj.filters b/tools/render-test/render-test-tool.vcxproj.filters
index 39197c7e9..43767fc8d 100644
--- a/tools/render-test/render-test-tool.vcxproj.filters
+++ b/tools/render-test/render-test-tool.vcxproj.filters
@@ -9,6 +9,9 @@
</Filter>
</ItemGroup>
<ItemGroup>
+ <ClInclude Include="cpu-memory-binding.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="options.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -26,6 +29,9 @@
</ClInclude>
</ItemGroup>
<ItemGroup>
+ <ClCompile Include="cpu-memory-binding.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="options.cpp">
<Filter>Source Files</Filter>
</ClCompile>