summaryrefslogtreecommitdiffstats
path: root/tools/render-test/cpu-memory-binding.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/render-test/cpu-memory-binding.cpp')
-rw-r--r--tools/render-test/cpu-memory-binding.cpp641
1 files changed, 0 insertions, 641 deletions
diff --git a/tools/render-test/cpu-memory-binding.cpp b/tools/render-test/cpu-memory-binding.cpp
deleted file mode 100644
index be4ad96e7..000000000
--- a/tools/render-test/cpu-memory-binding.cpp
+++ /dev/null
@@ -1,641 +0,0 @@
-
-#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, int entryPointIndex)
-{
- m_reflection = reflection;
- m_rootBuffer = Buffer();
- m_entryPointBuffer = 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);
-
- if (rootSizeInBytes)
- {
- // Allocate the 'root' buffer
- m_rootBuffer = _allocateBuffer(rootSizeInBytes);
-
- // Create default empty constant buffers
- 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));
- }
- }
- }
-
- {
- auto entryPointCount = int(reflection->getEntryPointCount());
- if (entryPointIndex < 0 || entryPointIndex >= entryPointCount)
- {
- SLANG_ASSERT(!"Entry point index out of range");
- return SLANG_FAIL;
- }
-
- m_entryPoint = reflection->getEntryPointByIndex(entryPointIndex);
- size_t entryPointParamsSizeInBytes = 0;
-
- const int parameterCount = int(m_entryPoint->getParameterCount());
- for (int i = 0 ; i < parameterCount; i++)
- {
- slang::VariableLayoutReflection* parameter = m_entryPoint->getParameterByIndex(i);
-
- // If has a semantic, then isn't uniform parameter
- if (auto semanticName = parameter->getSemanticName())
- {
- continue;
- }
-
- auto offset = parameter->getOffset();
-
- auto typeLayout = parameter->getTypeLayout();
- auto sizeInBytes = typeLayout->getSize();
-
- size_t endOffset = offset + sizeInBytes;
- entryPointParamsSizeInBytes = (endOffset > entryPointParamsSizeInBytes) ? endOffset : entryPointParamsSizeInBytes;
- }
-
- if (entryPointParamsSizeInBytes)
- {
- m_entryPointBuffer = _allocateBuffer(entryPointParamsSizeInBytes);
-
- uint8_t*const buffer = m_entryPointBuffer.m_data;
- for (int i = 0; i < parameterCount; ++i)
- {
- auto parameter = m_entryPoint->getParameterByIndex(i);
- // If has a semantic, then isn't uniform parameter
- if (auto semanticName = parameter->getSemanticName())
- {
- continue;
- }
-
- 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());
-
- if (elementCount == 0)
- {
- // We don't currently know the size that this array will be. So let's initially size it to 0.
-
- CPPPrelude::Array<uint8_t>& dstBuf = *(CPPPrelude::Array<uint8_t>*)dst;
- dstBuf.data = nullptr;
- dstBuf.count = 0;
- }
- else
- {
- 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::ParameterBlock:
- 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;
-}
-
-slang::VariableLayoutReflection* CPUMemoryBinding::getEntryPointParameterByName(const char* name)
-{
- const int parameterCount = int(m_entryPoint->getParameterCount());
- for (int i = 0; i < parameterCount; ++i)
- {
- auto parameter = m_entryPoint->getParameterByIndex(i);
- // If has a semantic we will ignore
- if (parameter->getSemanticName())
- {
- continue;
- }
- if (strcmp(parameter->getName(), name) == 0)
- {
- return parameter;
- }
- }
- return nullptr;
-}
-
-CPUMemoryBinding::Location CPUMemoryBinding::find(const char* name)
-{
- auto varLayout = getParameterByName(name);
- if (varLayout)
- {
- return Location(varLayout->getTypeLayout(), m_rootBuffer.m_data + varLayout->getOffset());
- }
-
- varLayout = getEntryPointParameterByName(name);
- if (varLayout)
- {
- return Location(varLayout->getTypeLayout(), m_entryPointBuffer.m_data + varLayout->getOffset());
- }
- return Location();
-}
-
-CPUMemoryBinding::Location CPUMemoryBinding::Location::toField(const char* name) const
-{
- if (!isValid())
- {
- return *this;
- }
-
- auto typeLayout = m_typeLayout;
- uint8_t* cur = m_cur;
-
- // Strip constantBuffer wrapping
- {
- const auto kind = typeLayout->getKind();
- if (kind == slang::TypeReflection::Kind::ConstantBuffer ||
- kind == slang::TypeReflection::Kind::ParameterBlock)
- {
- // 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)
- {
- return Location(field->getTypeLayout(), cur + field->getOffset());
- }
- }
- }
- }
-
- return Location();
-}
-
-CPUMemoryBinding::Location CPUMemoryBinding::Location::toIndex(int index) const
-{
- if (!isValid())
- {
- return *this;
- }
- SLANG_ASSERT(index >= 0);
- if (index < 0)
- {
- return Location();
- }
-
- auto typeLayout = m_typeLayout;
- uint8_t* cur = m_cur;
-
- const auto kind = typeLayout->getKind();
- switch (kind)
- {
- case slang::TypeReflection::Kind::Array:
- {
- auto elementTypeLayout = typeLayout->getElementTypeLayout();
- const auto elementCount = int(typeLayout->getElementCount());
- const auto elementStride = typeLayout->getElementStride(SLANG_PARAMETER_CATEGORY_UNIFORM);
-
- if (elementCount == 0)
- {
- CPPPrelude::Array<uint8_t>& array = *(CPPPrelude::Array<uint8_t>*)cur;
- if (index < int(array.count))
- {
- return Location(elementTypeLayout, array.data + elementStride * index);
- }
- return Location();
- }
- else
- {
- if (index >= elementCount)
- {
- SLANG_ASSERT(index < elementCount);
- return Location();
- }
- return Location(elementTypeLayout, cur + elementStride * index);
- }
- }
- default: break;
- }
-
- return Location();
-}
-
-SlangResult CPUMemoryBinding::initValue(slang::TypeLayoutReflection* typeLayout, void* dst)
-{
- auto size = typeLayout->getSize();
- // Zeroing works for built in types, and object types
- memset(dst, 0, size);
- return SLANG_OK;
-}
-
-SlangResult CPUMemoryBinding::setBufferContents(const Location& location, const void* initialData, size_t sizeInBytes)
-{
- if (!location.isValid())
- {
- return SLANG_FAIL;
- }
-
- auto typeLayout = location.getTypeLayout();
- uint8_t* cur = location.getPtr();
-
- const auto kind = typeLayout->getKind();
- switch (kind)
- {
- case slang::TypeReflection::Kind::ParameterBlock:
- 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.getTypeLayout();
- uint8_t* cur = location.getPtr();
-
- const auto kind = typeLayout->getKind();
- switch (kind)
- {
- case slang::TypeReflection::Kind::ParameterBlock:
- 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.getTypeLayout();
- uint8_t* cur = location.getPtr();
-
- const auto kind = typeLayout->getKind();
- switch (kind)
- {
- default:
- 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.getTypeLayout()->getSize();
- sizeInBytes = (sizeInBytes > dstSize) ? dstSize : sizeInBytes;
- memcpy(location.getPtr(), data, sizeInBytes);
- return SLANG_OK;
-}
-
-Index CPUMemoryBinding::findBufferIndex(const void* ptr) const
-{
- const Index count = m_allBuffers.getCount();
-
- for (Index i = 0; i < count; ++i)
- {
- if (m_allBuffers[i].m_data == ptr)
- {
- return i;
- }
- }
- return -1;
-}
-
-SlangResult CPUMemoryBinding::setArrayCount(const Location& location, int count, Buffer& outBuffer)
-{
- if (!location.isValid())
- {
- return SLANG_FAIL;
- }
-
- auto typeLayout = location.getTypeLayout();
- uint8_t* cur = location.getPtr();
-
- const auto kind = typeLayout->getKind();
-
- if (!(typeLayout->getKind() == slang::TypeReflection::Kind::Array && typeLayout->getElementCount() == 0))
- {
- return SLANG_FAIL;
- }
-
- CPPPrelude::Array<uint8_t>& array = *(CPPPrelude::Array<uint8_t>*)cur;
- uint8_t* elements = array.data;
-
- // Making smaller, just reduce the count.
- // NOTE! Nothing is done here about deallocating resources which are perhaps no longer reachable.
- // This isn't a leakage problem tho, as all buffers are released automatically when scope is left.
- if (count <= int(array.count))
- {
- array.count = count;
- return SLANG_OK;
- }
-
- const size_t elementStride = typeLayout->getElementStride(SLANG_PARAMETER_CATEGORY_UNIFORM);
-
- const Index bufferIndex = elements ? findBufferIndex(elements) : -1;
- if (bufferIndex > 0)
- {
- int maxCount = int(m_allBuffers[bufferIndex].m_sizeInBytes / elementStride);
- if (count <= maxCount)
- {
- // Just initialize the space
- memset(elements + elementStride * array.count, 0, (count - array.count) * elementStride);
- array.count = count;
- return SLANG_OK;
- }
- }
-
- // Ok allocate a buffer that can hold all the elements
-
- const size_t newBufferSize = count * elementStride;
- Buffer newBuffer = _allocateBuffer(newBufferSize);
-
- // Copy over the data from the old buffer if there is any
- if (elements && array.count)
- {
- memcpy(newBuffer.m_data, elements, array.count * elementStride);
- }
-
- // Remove the old buffer as no longer needed
- if (bufferIndex >= 0)
- {
- m_allBuffers.removeAt(bufferIndex);
- }
-
- // Set data
- array.count = count;
- array.data = newBuffer.m_data;
-
- outBuffer = newBuffer;
- return SLANG_OK;
-}
-
-} // renderer_test