@@ -156,13 +156,25 @@ SlangResult CPUMemoryBinding::_add(slang::VariableLayoutReflection* varLayout, s
156
156
{
157
157
auto elementTypeLayout = typeLayout->getElementTypeLayout ();
158
158
auto elementCount = int (typeLayout->getElementCount ());
159
- const size_t stride = elementTypeLayout->getSize ();
160
- uint8_t * cur = (uint8_t *)dst;
161
- for (int i = 0 ; i < elementCount; ++i)
159
+
160
+ if (elementCount == 0 )
161
+ {
162
+ // We don't currently know the size that this array will be. So let's initially size it to 0.
163
+
164
+ CPPPrelude::Array<uint8_t >& dstBuf = *(CPPPrelude::Array<uint8_t >*)dst;
165
+ dstBuf.data = nullptr ;
166
+ dstBuf.count = 0 ;
167
+ }
168
+ else
162
169
{
163
- Buffer elementBuffer;
164
- _add (nullptr , elementTypeLayout, cur, elementBuffer);
165
- cur += stride;
170
+ const size_t stride = elementTypeLayout->getSize ();
171
+ uint8_t * cur = (uint8_t *)dst;
172
+ for (int i = 0 ; i < elementCount; ++i)
173
+ {
174
+ Buffer elementBuffer;
175
+ _add (nullptr , elementTypeLayout, cur, elementBuffer);
176
+ cur += stride;
177
+ }
166
178
}
167
179
break ;
168
180
}
@@ -305,6 +317,11 @@ CPUMemoryBinding::Location CPUMemoryBinding::Location::toIndex(int index) const
305
317
{
306
318
return *this ;
307
319
}
320
+ SLANG_ASSERT (index >= 0 );
321
+ if (index < 0 )
322
+ {
323
+ return Location ();
324
+ }
308
325
309
326
auto typeLayout = m_typeLayout;
310
327
uint8_t * cur = m_cur;
@@ -318,20 +335,38 @@ CPUMemoryBinding::Location CPUMemoryBinding::Location::toIndex(int index) const
318
335
const auto elementCount = int (typeLayout->getElementCount ());
319
336
const auto elementStride = typeLayout->getElementStride (SLANG_PARAMETER_CATEGORY_UNIFORM);
320
337
321
- if (index < 0 || index >= elementCount )
338
+ if (elementCount == 0 )
322
339
{
323
- SLANG_ASSERT (index < elementCount);
340
+ CPPPrelude::Array<uint8_t >& array = *(CPPPrelude::Array<uint8_t >*)cur;
341
+ if (index < array.count )
342
+ {
343
+ return Location (elementTypeLayout, array.data + elementStride * index );
344
+ }
324
345
return Location ();
325
346
}
326
-
327
- return Location (elementTypeLayout, cur + elementStride * index );
347
+ else
348
+ {
349
+ if (index >= elementCount)
350
+ {
351
+ SLANG_ASSERT (index < elementCount);
352
+ return Location ();
353
+ }
354
+ return Location (elementTypeLayout, cur + elementStride * index );
355
+ }
328
356
}
329
357
default : break ;
330
358
}
331
359
332
360
return Location ();
333
361
}
334
362
363
+ SlangResult CPUMemoryBinding::initValue (slang::TypeLayoutReflection* typeLayout, void * dst)
364
+ {
365
+ auto size = typeLayout->getSize ();
366
+ // Zeroing works for built in types, and object types
367
+ memset (dst, 0 , size);
368
+ return SLANG_OK;
369
+ }
335
370
336
371
SlangResult CPUMemoryBinding::setBufferContents (const Location& location, const void * initialData, size_t sizeInBytes)
337
372
{
@@ -520,4 +555,87 @@ SlangResult CPUMemoryBinding::setInplace(const Location& location, const void* d
520
555
return SLANG_OK;
521
556
}
522
557
558
+ Index CPUMemoryBinding::findBufferIndex (const void * ptr) const
559
+ {
560
+ const Index count = m_allBuffers.getCount ();
561
+
562
+ for (Index i = 0 ; i < count; ++i)
563
+ {
564
+ if (m_allBuffers[i].m_data == ptr)
565
+ {
566
+ return i;
567
+ }
568
+ }
569
+ return -1 ;
570
+ }
571
+
572
+ SlangResult CPUMemoryBinding::setArrayCount (const Location& location, int count, Buffer& outBuffer)
573
+ {
574
+ if (!location.isValid ())
575
+ {
576
+ return SLANG_FAIL;
577
+ }
578
+
579
+ auto typeLayout = location.getTypeLayout ();
580
+ uint8_t * cur = location.getPtr ();
581
+
582
+ const auto kind = typeLayout->getKind ();
583
+
584
+ if (!(typeLayout->getKind () == slang::TypeReflection::Kind::Array && typeLayout->getElementCount () == 0 ))
585
+ {
586
+ return SLANG_FAIL;
587
+ }
588
+
589
+ CPPPrelude::Array<uint8_t >& array = *(CPPPrelude::Array<uint8_t >*)cur;
590
+ uint8_t * elements = array.data ;
591
+
592
+ // Making smaller, just reduce the count.
593
+ // NOTE! Nothing is done here about deallocating resources which are perhaps no longer reachable.
594
+ // This isn't a leakage problem tho, as all buffers are released automatically when scope is left.
595
+ if (count <= array.count )
596
+ {
597
+ array.count = count;
598
+ return SLANG_OK;
599
+ }
600
+
601
+ const size_t elementStride = typeLayout->getElementStride (SLANG_PARAMETER_CATEGORY_UNIFORM);
602
+
603
+ const Index bufferIndex = elements ? findBufferIndex (elements) : -1 ;
604
+ if (bufferIndex > 0 )
605
+ {
606
+ int maxCount = int (m_allBuffers[bufferIndex].m_sizeInBytes / elementStride);
607
+ if (count <= maxCount)
608
+ {
609
+ // Just initialize the space
610
+ memset (elements + elementStride * array.count , 0 , (count - array.count ) * elementStride);
611
+ array.count = count;
612
+ return SLANG_OK;
613
+ }
614
+ }
615
+
616
+ // Ok allocate a buffer that can hold all the elements
617
+
618
+ const size_t newBufferSize = count * elementStride;
619
+ Buffer newBuffer = _allocateBuffer (newBufferSize);
620
+
621
+ // Copy over the data from the old buffer if there is any
622
+ if (elements && array.count )
623
+ {
624
+ memcpy (newBuffer.m_data , elements, array.count * elementStride);
625
+ }
626
+
627
+ // Remove the old buffer as no longer needed
628
+ if (bufferIndex >= 0 )
629
+ {
630
+ m_allBuffers.removeAt (bufferIndex);
631
+ }
632
+
633
+ // Set data
634
+ array.count = count;
635
+ array.data = newBuffer.m_data ;
636
+
637
+ outBuffer = newBuffer;
638
+ return SLANG_OK;
639
+ }
640
+
523
641
} // renderer_test
0 commit comments