summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml8
-rw-r--r--CMakePresets.json8
-rw-r--r--source/compiler-core/slang-json-value.cpp9
-rw-r--r--tests/wasm/smoke/rand_float.slang63
-rw-r--r--tests/wasm/smoke/smoke-test.js116
5 files changed, 198 insertions, 6 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 46db88275..e2598cd73 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -135,8 +135,12 @@ jobs:
cmake --install build --config Release --component generators --prefix generators
emcmake cmake -DSLANG_GENERATORS_PATH=generators/bin --preset emscripten -DSLANG_SLANG_LLVM_FLAVOR=DISABLE
cmake --build --preset emscripten --config "$cmake_config" --target slang-wasm
- [ -f "build.em/$cmake_config/bin/slang-wasm.wasm" ]
- [ -f "build.em/$cmake_config/bin/slang-wasm.js" ]
+ mkdir "build.em/$cmake_config/bin/smoke"
+ cp tests/wasm/smoke/* "build.em/$cmake_config/bin/smoke/"
+ cd "build.em/$cmake_config/bin"
+ [ -f "slang-wasm.wasm" ]
+ [ -f "slang-wasm.js" ]
+ node smoke/smoke-test.js smoke/rand_float.slang computeMain
else
if [[ "${{ matrix.os }}" =~ "windows" && "${{ matrix.config }}" != "release" && "${{ matrix.config }}" != "releaseWithDebugInfo" ]]; then
# Doing a debug build will try to link against a release built llvm, this
diff --git a/CMakePresets.json b/CMakePresets.json
index 2632f522c..91f37de08 100644
--- a/CMakePresets.json
+++ b/CMakePresets.json
@@ -24,8 +24,14 @@
"binaryDir": "${sourceDir}/build.em",
"cacheVariables": {
"SLANG_SLANG_LLVM_FLAVOR": "DISABLE",
- "SLANG_ENABLE_SPLIT_DEBUG_INFO": "OFF",
+ "SLANG_ENABLE_AFTERMATH": "OFF",
+ "SLANG_ENABLE_CUDA": "OFF",
+ "SLANG_ENABLE_GFX": "OFF",
+ "SLANG_ENABLE_OPTIX": "OFF",
+ "SLANG_ENABLE_REPLAYER": "OFF",
"SLANG_ENABLE_SLANG_RHI": "OFF",
+ "SLANG_ENABLE_SPLIT_DEBUG_INFO": "OFF",
+ "SLANG_ENABLE_TESTS": "OFF",
"CMAKE_C_FLAGS_INIT": "-fwasm-exceptions -Os",
"CMAKE_CXX_FLAGS_INIT": "-fwasm-exceptions -Os",
"CMAKE_EXE_LINKER_FLAGS": "-sASSERTIONS -sALLOW_MEMORY_GROWTH -fwasm-exceptions --export=__cpp_exception"
diff --git a/source/compiler-core/slang-json-value.cpp b/source/compiler-core/slang-json-value.cpp
index ae38bd086..56d003737 100644
--- a/source/compiler-core/slang-json-value.cpp
+++ b/source/compiler-core/slang-json-value.cpp
@@ -869,8 +869,8 @@ void JSONContainer::_removeKey(JSONValue& obj, Index globalIndex)
{
auto localBuf = m_objectValues.getBuffer() + range.startIndex;
::memmove(
- localBuf + localIndex,
- localBuf + localIndex + 1,
+ (void*)(localBuf + localIndex),
+ (void*)(localBuf + localIndex + 1),
sizeof(*localBuf) * (range.count - (localIndex + 1)));
}
@@ -925,7 +925,10 @@ template<typename T>
ioList.growToCount(newStartIndex + ioRange.count + 1);
auto buffer = ioList.getBuffer();
- ::memmove(buffer + newStartIndex, buffer + ioRange.startIndex, sizeof(*buffer) * ioRange.count);
+ ::memmove(
+ (void*)(buffer + newStartIndex),
+ (void*)(buffer + ioRange.startIndex),
+ sizeof(*buffer) * ioRange.count);
buffer[newStartIndex + ioRange.count] = value;
diff --git a/tests/wasm/smoke/rand_float.slang b/tests/wasm/smoke/rand_float.slang
new file mode 100644
index 000000000..732cff093
--- /dev/null
+++ b/tests/wasm/smoke/rand_float.slang
@@ -0,0 +1,63 @@
+// Hybrid Tausworthe PRNG
+//
+// Code adapted from: https://indico.cern.ch/event/93877/papers/2118070/files/4416-acat3.pdf (See document for license)
+//
+
+uniform float seed;
+RWStructuredBuffer<float> outputBuffer;
+
+uint seedPerThread(uint idx)
+{
+ return ((uint)idx + (uint)(seed * 1000000)) * 1099087573UL;
+}
+
+uint tauStep(uint z, uint s1, uint s2, uint s3, uint M)
+{
+ uint b = (((z << s1) ^ z) >> s2);
+ return (((z & M) << s3) ^ b);
+}
+
+[shader("compute")]
+[numthreads(64, 1, 1)]
+void computeMain(uint2 dispatchThreadId : SV_DispatchThreadID)
+{
+ uint idx = dispatchThreadId.x;
+ uint val = ((uint)idx) * 1099087573UL + ((uint)seed) * 12003927;
+
+ uint z = tauStep(val, 13, 19, 12, 4294967294);
+ z = tauStep(z, 2, 25, 4, 4294967288);
+ z = tauStep(z, 3, 11, 17, 4294967280);
+
+ uint z1, z2, z3, z4;
+ uint r0, r1, r2, r3;
+
+ // STEP 1
+ uint _seed = seedPerThread(idx);
+ z1 = tauStep(_seed, 13, 19, 12, 429496729UL);
+ z2 = tauStep(_seed, 2, 25, 4, 4294967288UL);
+ z3 = tauStep(_seed, 3, 11, 17, 429496280UL);
+ z4 = (1664525 * _seed + 1013904223UL);
+ r0 = (z1 ^ z2 ^ z3 ^ z4);
+ // STEP 2
+ z1 = tauStep(r0, 13, 19, 12, 429496729UL);
+ z2 = tauStep(r0, 2, 25, 4, 4294967288UL);
+ z3 = tauStep(r0, 3, 11, 17, 429496280UL);
+ z4 = (1664525 * r0 + 1013904223UL);
+ r1 = (z1 ^ z2 ^ z3 ^ z4);
+ // STEP 3
+ z1 = tauStep(r1, 13, 19, 12, 429496729UL);
+ z2 = tauStep(r1, 2, 25, 4, 4294967288UL);
+ z3 = tauStep(r1, 3, 11, 17, 429496280UL);
+ z4 = (1664525 * r1 + 1013904223UL);
+ r2 = (z1 ^ z2 ^ z3 ^ z4);
+ // STEP 4
+ z1 = tauStep(r2, 13, 19, 12, 429496729UL);
+ z2 = tauStep(r2, 2, 25, 4, 4294967288UL);
+ z3 = tauStep(r2, 3, 11, 17, 429496280UL);
+ z4 = (1664525 * r2 + 1013904223UL);
+ r3 = (z1 ^ z2 ^ z3 ^ z4);
+
+ float u4 = r3 * 2.3283064365387e-10;
+
+ outputBuffer[idx] = u4;
+} \ No newline at end of file
diff --git a/tests/wasm/smoke/smoke-test.js b/tests/wasm/smoke/smoke-test.js
new file mode 100644
index 000000000..32611c923
--- /dev/null
+++ b/tests/wasm/smoke/smoke-test.js
@@ -0,0 +1,116 @@
+import * as wasmModule from '../slang-wasm.js';
+import { readFileSync } from 'fs';
+import { resolve, basename } from 'path';
+
+async function runSmokeTest() {
+ try {
+ // Get the file path from command line arguments
+ const filePath = process.argv[2];
+ const entryPointName = process.argv[3];
+ if (!filePath || !entryPointName) {
+ console.error('Please provide a path to a .slang file and an entry point name');
+ console.error('Usage: node test/smoke-test.js <path-to-slang-file> <entry-point-name>');
+ process.exit(1);
+ }
+
+ console.log(`Starting Slang WASM smoke test with file: ${filePath} and entry point: ${entryPointName}`);
+
+ // Read the source file
+ const absolutePath = resolve(filePath);
+ const source = readFileSync(absolutePath, 'utf8');
+ const fileName = basename(filePath);
+
+ // Load the WASM module
+ const module = await wasmModule.default();
+ console.log('WASM module loaded successfully');
+
+ // Print available compile targets
+ const targets = module.getCompileTargets();
+ if (!targets) {
+ throw new Error('Failed to get compile targets');
+ }
+ console.log('Available compile targets:', JSON.stringify(targets, null, 2));
+
+ // Find SPIRV target value
+ const spirvTarget = targets.findIndex(target => target.name.toLowerCase() === 'spirv');
+ if (spirvTarget === -1) {
+ throw new Error('SPIRV target not found in available targets');
+ }
+ console.log('Found SPIRV target at index:', spirvTarget);
+
+ // Get the actual SPIRV target value
+ const spirvTargetValue = targets[spirvTarget].value;
+ console.log('SPIRV target value:', spirvTargetValue);
+
+ // Create a global session
+ const globalSession = module.createGlobalSession();
+ if (!globalSession) {
+ throw new Error('Failed to create global session');
+ }
+ console.log('Global session created');
+
+ // Create a session with SPIRV as the target
+ const session = globalSession.createSession(spirvTargetValue);
+ if (!session) {
+ throw new Error('Failed to create session');
+ }
+ console.log('Session created with SPIRV target');
+
+ // Load the shader source
+ const module1 = session.loadModuleFromSource(source, fileName, '');
+ if (!module1) {
+ const error = module.getLastError();
+ throw new Error(`Failed to load module: ${error ? error.message : 'Unknown error'}`);
+ }
+ console.log('Shader module loaded');
+
+ // Check for compilation errors
+ const error = module.getLastError();
+ if (error && error.result !== module.SLANG_OK) {
+ throw new Error(`Compilation failed: ${error.message}`);
+ }
+ console.log('No compilation errors found');
+
+ // Try to find the entry point
+ const entryPoint = module1.findEntryPointByName(entryPointName);
+ if (!entryPoint) {
+ throw new Error(`Could not find entry point "${entryPointName}"`);
+ }
+ console.log(`Entry point "${entryPointName}" found`);
+
+ // Create and link the program
+ const program = session.createCompositeComponentType([module1]);
+ if (!program) {
+ throw new Error('Failed to create composite component type');
+ }
+ const linkedProgram = program.link();
+ if (!linkedProgram) {
+ throw new Error('Failed to link program');
+ }
+ console.log('Program created and linked successfully');
+
+ // Try to get the SPIRV code
+ console.log('\nTrying to generate SPIRV code:');
+ const spirvBinary = linkedProgram.getTargetCodeBlob(0); // 0 is the target index
+ if (!spirvBinary) {
+ throw new Error('Could not generate SPIRV binary');
+ }
+ console.log('SPIRV binary generated successfully');
+ console.log('Generated binary length:', spirvBinary.length);
+
+ // Clean up
+ linkedProgram.delete();
+ program.delete();
+ entryPoint.delete();
+ module1.delete();
+ session.delete();
+ globalSession.delete();
+ console.log('Smoke test completed successfully');
+ process.exit(0); // Explicit success exit code
+ } catch (error) {
+ console.error('Smoke test failed:', error);
+ process.exit(1); // Error exit code
+ }
+}
+
+runSmokeTest(); \ No newline at end of file