summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/render-test/cpu-compute-util.cpp19
-rw-r--r--tools/render-test/cpu-memory-binding.cpp138
-rw-r--r--tools/render-test/cpu-memory-binding.h11
-rw-r--r--tools/render-test/shader-input-layout.cpp16
-rw-r--r--tools/render-test/shader-input-layout.h8
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;