Skip to content

Commit 06a0e39

Browse files
authored
WIP: CPU compute coverage (shader-slang#1030)
* Add support for '=' when defining a name in test. * Add support for double intrinsics. * Add support for asdouble Add findOrAddInst - used instead of findOrEmitHoistableInst, for nominal instructions. Support cloning of string literals. C++ working on more compute tests. * Constant buffer support in reflection. Fixed debugging into source for generated C++. buffer-layout.slang works. * Added cpu test result. * Remove some commented out code. Comment on next fixes. * Improvements to reflection CPU code. * C++ working with ByteAddressBuffer. * Enabled more compute tests for CPU. * Enabled more compute tests on CPU. Added support for [] style access to a vector. * Enabled more CPU compute tests. * Handling of buffer-type-splitting.slang Named buffers can be paths to resources * Fix some warnings, remove some dead code. * Fix problem with verification of number of operands for asuint/asint as they can have 1 or 3 operands. asdouble takes 2. * Fix handling in MemoryArena around aligned allocations. That _allocateAlignedFromNewBlock assumed the block allocated has the aligment that was requested and so did not correct the start address.
1 parent bc392f9 commit 06a0e39

File tree

70 files changed

+748
-259
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+748
-259
lines changed

prelude/slang-cpp-scalar-intrinsics.h

+40-5
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@ union Union32
2020
float f;
2121
};
2222

23+
union Union64
24+
{
25+
uint64_t u;
26+
int64_t i;
27+
double d;
28+
};
29+
2330
// Helpers
2431
SLANG_FORCE_INLINE float F32_calcSafeRadians(float radians)
2532
{
@@ -112,10 +119,6 @@ SLANG_FORCE_INLINE double F64_lerp(double x, double y, double s) { return x + s
112119
SLANG_FORCE_INLINE double F64_clamp(double x, double min, double max) { return (x < min) ? min : ((x > max) ? max : x); }
113120
SLANG_FORCE_INLINE void F64_sincos(double f, double& outSin, double& outCos) { outSin = F64_sin(f); outCos = F64_cos(f); }
114121

115-
// TODO!
116-
//uint32_t F64_asuint(float f);
117-
//int32_t F64_asint(float f);
118-
119122
// ----------------------------- I32 -----------------------------------------
120123

121124
SLANG_FORCE_INLINE int32_t I32_abs(int32_t f) { return (f < 0) ? -f : f; }
@@ -126,7 +129,13 @@ SLANG_FORCE_INLINE int32_t I32_max(int32_t a, int32_t b) { return a > b ? a : b;
126129
SLANG_FORCE_INLINE int32_t I32_clamp(int32_t x, int32_t min, int32_t max) { return ( x < min) ? min : ((x > max) ? max : x); }
127130

128131
SLANG_FORCE_INLINE float I32_asfloat(int32_t x) { Union32 u; u.i = x; return u.f; }
129-
SLANG_FORCE_INLINE uint32_t I32_asuint(int32_t x) { return uint32_t(x); }
132+
SLANG_FORCE_INLINE uint32_t I32_asuint(int32_t x) { return uint32_t(x); }
133+
SLANG_FORCE_INLINE double I32_asdouble(int32_t low, int32_t hi )
134+
{
135+
Union64 u;
136+
u.i = (int64_t(hi) << 32) | low;
137+
return u.d;
138+
}
130139

131140
// ----------------------------- U32 -----------------------------------------
132141

@@ -140,6 +149,32 @@ SLANG_FORCE_INLINE uint32_t U32_clamp(uint32_t x, uint32_t min, uint32_t max) {
140149
SLANG_FORCE_INLINE float U32_asfloat(uint32_t x) { Union32 u; u.u = x; return u.f; }
141150
SLANG_FORCE_INLINE uint32_t U32_asint(int32_t x) { return uint32_t(x); }
142151

152+
SLANG_FORCE_INLINE double U32_asdouble(uint32_t low, uint32_t hi)
153+
{
154+
Union64 u;
155+
u.u = (uint64_t(hi) << 32) | low;
156+
return u.d;
157+
}
158+
159+
// ----------------------------- F64 -----------------------------------------
160+
161+
SLANG_FORCE_INLINE void F64_asuint(double d, uint32_t& low, uint32_t& hi)
162+
{
163+
Union64 u;
164+
u.d = d;
165+
low = uint32_t(u.u);
166+
hi = uint32_t(u.u >> 32);
167+
}
168+
169+
SLANG_FORCE_INLINE void F64_asint(double d, int32_t& low, uint32_t& hi)
170+
{
171+
Union64 u;
172+
u.d = d;
173+
low = int32_t(u.u);
174+
hi = int32_t(u.u >> 32);
175+
}
176+
177+
143178
#ifdef SLANG_PRELUDE_NAMESPACE
144179
}
145180
#endif

source/core/slang-memory-arena.cpp

+21-14
Original file line numberDiff line numberDiff line change
@@ -42,19 +42,19 @@ void MemoryArena::_initialize(size_t blockPayloadSize, size_t alignment)
4242
// Ensure it's alignment is at least kMinAlignment
4343
alignment = (alignment < kMinAlignment) ? kMinAlignment : alignment;
4444

45+
const size_t alignMask = alignment - 1;
46+
47+
// Make sure the payload is rounded up to the alignment
48+
blockPayloadSize = (blockPayloadSize + alignMask) & ~alignMask;
49+
4550
m_blockPayloadSize = blockPayloadSize;
46-
size_t blockAllocSize = blockPayloadSize;
4751

4852
// If alignment required is larger then the backing allocators then
4953
// make larger to ensure when alignment correction takes place it will be aligned
50-
if (alignment > kMinAlignment)
51-
{
52-
blockAllocSize += alignment;
53-
}
54-
54+
const size_t blockAllocSize = (alignment > kMinAlignment) ? (blockPayloadSize + alignment) : blockPayloadSize;
55+
5556
m_blockAllocSize = blockAllocSize;
5657
m_blockAlignment = alignment;
57-
5858
m_availableBlocks = nullptr;
5959

6060
m_blockFreeList.init(sizeof(Block), sizeof(void*), 16);
@@ -217,12 +217,17 @@ MemoryArena::Block* MemoryArena::_newNormalBlock()
217217
return block;
218218
}
219219

220-
return _newBlock(m_blockAllocSize, m_blockAlignment);
220+
Block* block = _newBlock(m_blockAllocSize, m_blockAlignment);
221+
// Check that every normal block has m_blockPayloadSize space
222+
assert(size_t(block->m_end - block->m_start) >= m_blockPayloadSize);
223+
return block;
221224
}
222225

223226
MemoryArena::Block* MemoryArena::_newBlock(size_t allocSize, size_t alignment)
224227
{
225228
assert(alignment >= m_blockAlignment);
229+
// Alignment must be a power of 2
230+
assert(((alignment - 1) & alignment) == 0);
226231

227232
// Allocate block
228233
Block* block = (Block*)m_blockFreeList.allocate();
@@ -289,9 +294,10 @@ void* MemoryArena::_allocateAlignedFromNewBlock(size_t size, size_t alignment)
289294
//
290295
// An improvement might be to have some abstraction that sits on top that can do this tracking (or have the blocks
291296
// themselves record if they alias over a previously used block - but we don't bother with this here.
292-
if (allocSize > m_blockAllocSize)
297+
// If the alignment is greater than regular alignment we need to handle specially
298+
if (allocSize > m_blockPayloadSize || (alignment > m_blockAlignment && allocSize + alignment > m_blockPayloadSize))
293299
{
294-
// This is an odd-sized block so just allocate the whole thing
300+
// This is an odd-sized block so just allocate the whole thing.
295301
block = _newBlock(allocSize, alignment);
296302
}
297303
else
@@ -310,10 +316,11 @@ void* MemoryArena::_allocateAlignedFromNewBlock(size_t size, size_t alignment)
310316
// Make the current block
311317
_addCurrentBlock(block);
312318

313-
// Allocated memory is just the start of this block
314-
uint8_t* memory = m_current;
315-
// It must already be aligned
316-
assert((size_t(m_current) & alignMask) == 0);
319+
// Align the memory
320+
uint8_t* memory = (uint8_t*)((size_t(m_current) + alignMask) & ~alignMask);
321+
322+
// It must be aligned
323+
assert((size_t(memory) & alignMask) == 0);
317324

318325
// Do the aligned allocation (which must fit) by aligning the pointer
319326
// It must fit if the previous code is correct...

source/core/slang-token-reader.h

+9
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,15 @@ namespace Slang
189189
{
190190
tokenPtr -= count;
191191
}
192+
Token ReadMatchingToken(TokenType type)
193+
{
194+
auto token = ReadToken();
195+
if (token.Type != type)
196+
{
197+
throw TextFormatException("Text parsing error: unexpected token.");
198+
}
199+
return token;
200+
}
192201
Token ReadToken()
193202
{
194203
if (tokenPtr < (int)tokens.getCount())

source/slang/slang-compiler.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -1529,6 +1529,11 @@ SlangResult dissassembleDXILUsingDXC(
15291529
sharedLib->m_temporaryFileSet = productFileSet;
15301530
productFileSet.clear();
15311531

1532+
// Copy the paths in the temporary file set
1533+
// We particularly want to do this to keep the source
1534+
sharedLib->m_temporaryFileSet.add(temporaryFileSet.m_paths);
1535+
temporaryFileSet.clear();
1536+
15321537
// Output the shared library
15331538
outSharedLib = sharedLib;
15341539
}

0 commit comments

Comments
 (0)