diff options
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/render-test/cpu-compute-util.cpp | 19 | ||||
| -rw-r--r-- | tools/render-test/cpu-memory-binding.cpp | 138 | ||||
| -rw-r--r-- | tools/render-test/cpu-memory-binding.h | 11 | ||||
| -rw-r--r-- | tools/render-test/shader-input-layout.cpp | 16 | ||||
| -rw-r--r-- | tools/render-test/shader-input-layout.h | 8 |
5 files changed, 177 insertions, 15 deletions
diff --git a/tools/render-test/cpu-compute-util.cpp b/tools/render-test/cpu-compute-util.cpp index 688e6b254..ef5755275 100644 --- a/tools/render-test/cpu-compute-util.cpp +++ b/tools/render-test/cpu-compute-util.cpp @@ -191,9 +191,24 @@ static CPUComputeUtil::Resource* _newOneTexture2D(int elemCount) const auto kind = typeLayout->getKind(); switch (kind) { - case slang::TypeReflection::Kind::Vector: - case slang::TypeReflection::Kind::Matrix: case slang::TypeReflection::Kind::Array: + { + auto elementCount = int(typeLayout->getElementCount()); + if (elementCount == 0) + { + if (srcEntry.type == ShaderInputType::Array) + { + // We need to set the size + CPUMemoryBinding::Buffer buffer; + SLANG_RETURN_ON_FAIL(binding.setArrayCount(location, srcEntry.arrayDesc.size, buffer)); + } + break; + } + SLANG_RETURN_ON_FAIL(binding.setInplace(location, srcEntry.bufferData.getBuffer(), srcEntry.bufferData.getCount() * sizeof(unsigned int))); + break; + } + case slang::TypeReflection::Kind::Vector: + case slang::TypeReflection::Kind::Matrix: case slang::TypeReflection::Kind::Scalar: case slang::TypeReflection::Kind::Struct: { diff --git a/tools/render-test/cpu-memory-binding.cpp b/tools/render-test/cpu-memory-binding.cpp index 3bf1f1bbd..24d16756d 100644 --- a/tools/render-test/cpu-memory-binding.cpp +++ b/tools/render-test/cpu-memory-binding.cpp @@ -156,13 +156,25 @@ SlangResult CPUMemoryBinding::_add(slang::VariableLayoutReflection* varLayout, s { 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) + + 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 { - Buffer elementBuffer; - _add(nullptr, elementTypeLayout, cur, elementBuffer); - cur += stride; + 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; } @@ -305,6 +317,11 @@ CPUMemoryBinding::Location CPUMemoryBinding::Location::toIndex(int index) const { return *this; } + SLANG_ASSERT(index >= 0); + if (index < 0) + { + return Location(); + } auto typeLayout = m_typeLayout; uint8_t* cur = m_cur; @@ -318,13 +335,24 @@ CPUMemoryBinding::Location CPUMemoryBinding::Location::toIndex(int index) const const auto elementCount = int(typeLayout->getElementCount()); const auto elementStride = typeLayout->getElementStride(SLANG_PARAMETER_CATEGORY_UNIFORM); - if (index < 0 || index >= elementCount) + if (elementCount == 0) { - SLANG_ASSERT(index < elementCount); + CPPPrelude::Array<uint8_t>& array = *(CPPPrelude::Array<uint8_t>*)cur; + if (index < array.count) + { + return Location(elementTypeLayout, array.data + elementStride * index); + } return Location(); } - - return Location(elementTypeLayout, cur + elementStride * index); + else + { + if (index >= elementCount) + { + SLANG_ASSERT(index < elementCount); + return Location(); + } + return Location(elementTypeLayout, cur + elementStride * index); + } } default: break; } @@ -332,6 +360,13 @@ CPUMemoryBinding::Location CPUMemoryBinding::Location::toIndex(int index) const 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) { @@ -520,4 +555,87 @@ SlangResult CPUMemoryBinding::setInplace(const Location& location, const void* d 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 <= 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 diff --git a/tools/render-test/cpu-memory-binding.h b/tools/render-test/cpu-memory-binding.h index 36bc15c6b..8ca8e0681 100644 --- a/tools/render-test/cpu-memory-binding.h +++ b/tools/render-test/cpu-memory-binding.h @@ -43,6 +43,8 @@ struct CPUMemoryBinding slang::VariableLayoutReflection* getParameterByName(const char* name); slang::VariableLayoutReflection* getEntryPointParameterByName(const char* name); + /// Finds which buffer starts at the ptr index + Slang::Index findBufferIndex(const void* ptr) const; Location find(const char* name); @@ -50,6 +52,15 @@ struct CPUMemoryBinding 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); + /// Initialize memory with a 'sensible' value based on type. Pointer types become null. + SlangResult initValue(slang::TypeLayoutReflection* typeLayout, void* dst); + SlangResult initValue(const Location& location) { return initValue(location.getTypeLayout(), location.getPtr()); } + + /// Set the size of a *non fixed size* array at location. + /// A non fixed size array is reflected as having a count of 0 elements. + /// Only returns a buffer in outBuffer if a new buffer is created. + SlangResult setArrayCount(const Location& location, int count, Buffer& outBuffer); + SlangResult init(slang::ShaderReflection* reflection, int entryPointIndex); CPUMemoryBinding(); diff --git a/tools/render-test/shader-input-layout.cpp b/tools/render-test/shader-input-layout.cpp index b5b65f52d..37aa5dab6 100644 --- a/tools/render-test/shader-input-layout.cpp +++ b/tools/render-test/shader-input-layout.cpp @@ -138,7 +138,11 @@ namespace renderer_test { ShaderInputLayoutEntry entry; - if (parser.LookAhead("cbuffer")) + if (parser.LookAhead("array")) + { + entry.type = ShaderInputType::Array; + } + else if (parser.LookAhead("cbuffer")) { entry.type = ShaderInputType::Buffer; entry.bufferDesc.type = InputBufferType::ConstantBuffer; @@ -253,7 +257,15 @@ namespace renderer_test else if (word == "size") { parser.Read("="); - entry.textureDesc.size = parser.ReadInt(); + auto size = parser.ReadInt(); + if (entry.type == ShaderInputType::Array) + { + entry.arrayDesc.size = size; + } + else + { + entry.textureDesc.size = size; + } } else if (word == "random") { diff --git a/tools/render-test/shader-input-layout.h b/tools/render-test/shader-input-layout.h index 009be7514..8a00980d9 100644 --- a/tools/render-test/shader-input-layout.h +++ b/tools/render-test/shader-input-layout.h @@ -12,7 +12,7 @@ using namespace gfx; enum class ShaderInputType { - Buffer, Texture, Sampler, CombinedTextureSampler + Buffer, Texture, Sampler, CombinedTextureSampler, Array }; enum class InputTextureContent @@ -51,6 +51,11 @@ struct InputSamplerDesc bool isCompareSampler = false; }; +struct ArrayDesc +{ + int size = 0; +}; + class ShaderInputLayoutEntry { public: @@ -59,6 +64,7 @@ public: InputTextureDesc textureDesc; InputBufferDesc bufferDesc; InputSamplerDesc samplerDesc; + ArrayDesc arrayDesc; bool isOutput = false; bool isCPUOnly = false; int hlslBinding = -1; |
