diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2019-08-26 15:45:28 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-08-26 15:45:28 -0400 |
| commit | 2c4307a9c1a5d1ec92599bb6afe065636ff81df3 (patch) | |
| tree | dda2f66dedfefa5b730a65250edff4a6eec66358 /tools/render-test | |
| parent | 6a0ca6c6a23b8a29320b86be6aec50263f5d7d97 (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.cpp | 450 | ||||
| -rw-r--r-- | tools/render-test/cpu-memory-binding.h | 62 | ||||
| -rw-r--r-- | tools/render-test/render-test-main.cpp | 278 | ||||
| -rw-r--r-- | tools/render-test/render-test-tool.vcxproj | 2 | ||||
| -rw-r--r-- | tools/render-test/render-test-tool.vcxproj.filters | 6 |
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> |
