Skip to content

Commit c58a7dd

Browse files
committed
Remove PoC smoke path and keep real runtime flow
1 parent c1be8c0 commit c58a7dd

9 files changed

Lines changed: 682 additions & 543 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
/package*/
44
/.3rdparty/
55
/out/
6+
/tmp/
67
.DS_Store

README.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ Why not LLVM JIT-in-Wasm right now:
5656

5757
Why not full NIR->Wasm backend today:
5858
- Mesa does not ship a complete NIR->Wasm backend for this use case.
59-
- We built a simple proof-of-concept for a minimal pattern, but a full backend from scratch is a large compiler project and not realistic for a single maintainer effort.
59+
- A full backend from scratch is a large compiler project and not realistic for a single maintainer effort.
6060

6161
Current strategy:
6262
- Keep `clang_wasm_runtime_smoke` as a clang-in-wasm toolchain proof path.
@@ -154,13 +154,10 @@ It validates:
154154

155155
This gives a realistic loader flow for consumers that use Volk, while keeping dispatch pinned to the wasm ICD path.
156156

157-
`smoke_poc_nir_to_wasm` is kept as an experimental proof-of-concept path and is not the main production direction.
158-
159157
Current shader-path split:
160158
- `lavapipe_runtime_smoke` injects runtime-generated SPIR-V (from Wasmer `clspv` by default) into the smoke module and validates Vulkan compute dispatch in the Mesa wasm driver.
161159
- `clang_wasm_runtime_smoke` validates the clang-in-wasm toolchain path and runs an SPIR-V probe through a Wasmer runtime command (`clspv` package entrypoint by default).
162160
- If that command is unavailable, smoke falls back to a direct `--target=spirv32` probe and reports the provider and failure reason.
163-
- `smoke_poc_nir_to_wasm` is a separate experimental check and is not part of `runtime_smoke`.
164161

165162
## Release channels
166163

tests/CMakeLists.txt

Lines changed: 7 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -297,9 +297,11 @@ add_custom_target(wasm_runtime_smoke DEPENDS "${WEBVULKAN_WASM_SMOKE_OK}")
297297

298298
set(WEBVULKAN_LAVAPIPE_SMOKE_OK "${CMAKE_BINARY_DIR}/lavapipe_runtime_smoke.ok")
299299
set(WEBVULKAN_LAVAPIPE_SMOKE_JS "${CMAKE_BINARY_DIR}/lavapipe-smoke/lavapipe_runtime_smoke.js")
300+
set(WEBVULKAN_RUNTIME_REGISTRY_SOURCE "${CMAKE_CURRENT_LIST_DIR}/wasm/src/webvulkan_shader_runtime_registry.c")
300301
set(_webvulkan_lavapipe_depends
301302
"${CMAKE_CURRENT_LIST_DIR}/RunLavapipeRuntimeSmoke.cmake"
302303
"${CMAKE_CURRENT_LIST_DIR}/wasm/src/lavapipe_runtime_smoke.c"
304+
"${WEBVULKAN_RUNTIME_REGISTRY_SOURCE}"
303305
"${CMAKE_CURRENT_LIST_DIR}/wasm/tools/smoke_runtime.mjs"
304306
"${WEBVULKAN_DXC_WASM_JS}"
305307
"${_webvulkan_volk_source}"
@@ -310,6 +312,10 @@ if(_webvulkan_test_mode STREQUAL "in-tree")
310312
list(APPEND _webvulkan_lavapipe_depends llvmpipe_wasm_spike)
311313
endif()
312314
list(JOIN _webvulkan_smoke_include_dirs "|" _webvulkan_smoke_include_dirs_serialized)
315+
set(_webvulkan_lavapipe_extra_sources
316+
"${WEBVULKAN_RUNTIME_REGISTRY_SOURCE}"
317+
)
318+
list(JOIN _webvulkan_lavapipe_extra_sources "|" _webvulkan_lavapipe_extra_sources_serialized)
313319

314320
add_custom_command(
315321
OUTPUT "${WEBVULKAN_LAVAPIPE_SMOKE_OK}"
@@ -318,6 +324,7 @@ add_custom_command(
318324
-DEMSDK_ROOT=${EMSDK_ROOT}
319325
-DDRIVER_ARCHIVE=${_webvulkan_driver_archive}
320326
-DSMOKE_INCLUDE_DIRS_SERIALIZED=${_webvulkan_smoke_include_dirs_serialized}
327+
-DSMOKE_EXTRA_SOURCES_SERIALIZED=${_webvulkan_lavapipe_extra_sources_serialized}
321328
-DSMOKE_SOURCE=${CMAKE_CURRENT_LIST_DIR}/wasm/src/lavapipe_runtime_smoke.c
322329
-DSMOKE_JS_OUT=${WEBVULKAN_LAVAPIPE_SMOKE_JS}
323330
-DSMOKE_EXPORT=_lavapipe_runtime_smoke
@@ -338,41 +345,6 @@ add_custom_command(
338345
)
339346
add_custom_target(lavapipe_runtime_smoke DEPENDS "${WEBVULKAN_LAVAPIPE_SMOKE_OK}")
340347

341-
set(WEBVULKAN_POC_NIR_TO_WASM_SMOKE_OK "${CMAKE_BINARY_DIR}/poc_nir_to_wasm_smoke.ok")
342-
set(WEBVULKAN_POC_NIR_TO_WASM_SMOKE_JS "${CMAKE_BINARY_DIR}/lavapipe-smoke/poc_nir_to_wasm_smoke.js")
343-
set(_webvulkan_poc_nir_to_wasm_depends
344-
"${CMAKE_CURRENT_LIST_DIR}/RunLavapipeRuntimeSmoke.cmake"
345-
"${CMAKE_CURRENT_LIST_DIR}/wasm/src/poc_nir_to_wasm_smoke.c"
346-
"${CMAKE_CURRENT_LIST_DIR}/wasm/tools/smoke_runtime.mjs"
347-
"${_webvulkan_volk_source}"
348-
"${_webvulkan_volk_header}"
349-
"${_webvulkan_driver_archive}"
350-
)
351-
if(_webvulkan_test_mode STREQUAL "in-tree")
352-
list(APPEND _webvulkan_poc_nir_to_wasm_depends llvmpipe_wasm_spike)
353-
endif()
354-
add_custom_command(
355-
OUTPUT "${WEBVULKAN_POC_NIR_TO_WASM_SMOKE_OK}"
356-
COMMAND
357-
"${CMAKE_COMMAND}"
358-
-DEMSDK_ROOT=${EMSDK_ROOT}
359-
-DDRIVER_ARCHIVE=${_webvulkan_driver_archive}
360-
-DSMOKE_INCLUDE_DIRS_SERIALIZED=${_webvulkan_smoke_include_dirs_serialized}
361-
-DSMOKE_SOURCE=${CMAKE_CURRENT_LIST_DIR}/wasm/src/poc_nir_to_wasm_smoke.c
362-
-DSMOKE_JS_OUT=${WEBVULKAN_POC_NIR_TO_WASM_SMOKE_JS}
363-
-DSMOKE_EXPORT=_poc_nir_to_wasm_smoke
364-
-DSMOKE_SCRIPT=${CMAKE_CURRENT_LIST_DIR}/wasm/tools/smoke_runtime.mjs
365-
-DSMOKE_REQUIRE_RUNTIME_SPIRV=0
366-
-DVOLK_INCLUDE_DIR=${_webvulkan_volk_include_dir}
367-
-DVOLK_SOURCE=${_webvulkan_volk_source}
368-
-P "${CMAKE_CURRENT_LIST_DIR}/RunLavapipeRuntimeSmoke.cmake"
369-
COMMAND "${CMAKE_COMMAND}" -E touch "${WEBVULKAN_POC_NIR_TO_WASM_SMOKE_OK}"
370-
DEPENDS ${_webvulkan_poc_nir_to_wasm_depends}
371-
USES_TERMINAL
372-
VERBATIM
373-
)
374-
add_custom_target(smoke_poc_nir_to_wasm DEPENDS "${WEBVULKAN_POC_NIR_TO_WASM_SMOKE_OK}")
375-
376348
set(WEBVULKAN_CLANG_WASM_SMOKE_OK "${CMAKE_BINARY_DIR}/clang_wasm_runtime_smoke.ok")
377349
add_custom_command(
378350
OUTPUT "${WEBVULKAN_CLANG_WASM_SMOKE_OK}"

tests/RunLavapipeRuntimeSmoke.cmake

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ if(DEFINED SMOKE_INCLUDE_DIRS_SERIALIZED AND NOT "${SMOKE_INCLUDE_DIRS_SERIALIZE
3737
string(REPLACE "|" ";" SMOKE_INCLUDE_DIRS "${SMOKE_INCLUDE_DIRS_SERIALIZED}")
3838
endif()
3939
require_var(SMOKE_INCLUDE_DIRS)
40+
if(DEFINED SMOKE_EXTRA_SOURCES_SERIALIZED AND NOT "${SMOKE_EXTRA_SOURCES_SERIALIZED}" STREQUAL "")
41+
string(REPLACE "|" ";" SMOKE_EXTRA_SOURCES "${SMOKE_EXTRA_SOURCES_SERIALIZED}")
42+
endif()
4043

4144
if(CMAKE_HOST_WIN32)
4245
set(EMCC_BIN "${EMSDK_ROOT}/upstream/emscripten/emcc.bat")
@@ -59,6 +62,11 @@ list(GET NODE_CANDIDATES 0 NODE_EXE)
5962
if(NOT EXISTS "${DRIVER_ARCHIVE}")
6063
message(FATAL_ERROR "Missing driver archive ${DRIVER_ARCHIVE}")
6164
endif()
65+
foreach(SMOKE_EXTRA_SOURCE IN LISTS SMOKE_EXTRA_SOURCES)
66+
if(NOT EXISTS "${SMOKE_EXTRA_SOURCE}")
67+
message(FATAL_ERROR "Missing smoke extra source ${SMOKE_EXTRA_SOURCE}")
68+
endif()
69+
endforeach()
6270
if(NOT EXISTS "${VOLK_SOURCE}")
6371
message(FATAL_ERROR "Missing volk source ${VOLK_SOURCE}")
6472
endif()
@@ -82,6 +90,9 @@ function(append_rsp ARG_VALUE)
8290
endfunction()
8391

8492
append_rsp("${SMOKE_SOURCE}")
93+
foreach(SMOKE_EXTRA_SOURCE IN LISTS SMOKE_EXTRA_SOURCES)
94+
append_rsp("${SMOKE_EXTRA_SOURCE}")
95+
endforeach()
8596
append_rsp("${VOLK_SOURCE}")
8697
append_rsp("-o")
8798
append_rsp("${SMOKE_JS_OUT}")
@@ -98,7 +109,7 @@ append_rsp("-sMODULARIZE=1")
98109
append_rsp("-sEXPORT_ES6=1")
99110
append_rsp("-sENVIRONMENT=web,worker,node")
100111
if(SMOKE_REQUIRE_RUNTIME_SPIRV STREQUAL "1")
101-
append_rsp("-sEXPORTED_FUNCTIONS=['_main','${SMOKE_EXPORT}','_webvulkan_set_runtime_shader_spirv','_malloc','_free']")
112+
append_rsp("-sEXPORTED_FUNCTIONS=['_main','${SMOKE_EXPORT}','_webvulkan_reset_runtime_shader_registry','_webvulkan_set_runtime_active_shader_key','_webvulkan_set_runtime_expected_dispatch_value','_webvulkan_runtime_reset_captured_shader_key','_webvulkan_runtime_has_captured_shader_key','_webvulkan_runtime_get_captured_shader_key_lo','_webvulkan_runtime_get_captured_shader_key_hi','_webvulkan_set_runtime_shader_spirv','_webvulkan_register_runtime_shader_spirv','_webvulkan_register_runtime_wasm_module','_webvulkan_register_runtime_shader_bundle','_webvulkan_get_runtime_wasm_used','_webvulkan_get_runtime_wasm_provider','_malloc','_free']")
102113
else()
103114
append_rsp("-sEXPORTED_FUNCTIONS=['_main','${SMOKE_EXPORT}']")
104115
endif()

tests/wasm/src/lavapipe_runtime_smoke.c

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
#include <emscripten/emscripten.h>
2+
#include <stdbool.h>
23
#include <stdint.h>
34
#include <stdio.h>
45
#include <stdlib.h>
56
#include <string.h>
67
#include <volk.h>
78

9+
#include "webvulkan_shader_runtime_registry.h"
10+
811
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(VkInstance instance, const char* pName);
912

1013
static const uint32_t kSmokeComputeSpirv[] = {
@@ -27,30 +30,7 @@ static const uint32_t kSmokeComputeSpirv[] = {
2730
0x0000000bu, 0x0003003eu, 0x0000000eu, 0x0000000cu, 0x000100fdu, 0x00010038u
2831
};
2932

30-
static uint8_t* g_runtime_shader_spirv = 0;
31-
static uint32_t g_runtime_shader_spirv_size = 0u;
32-
33-
EMSCRIPTEN_KEEPALIVE int webvulkan_set_runtime_shader_spirv(const uint8_t* bytes, uint32_t byteCount) {
34-
if (!bytes || byteCount < 4u || (byteCount % 4u) != 0u) {
35-
return -1;
36-
}
37-
if (bytes[0] != 0x03u || bytes[1] != 0x02u || bytes[2] != 0x23u || bytes[3] != 0x07u) {
38-
return -2;
39-
}
40-
41-
uint8_t* copy = (uint8_t*)malloc(byteCount);
42-
if (!copy) {
43-
return -3;
44-
}
45-
memcpy(copy, bytes, byteCount);
46-
47-
if (g_runtime_shader_spirv) {
48-
free(g_runtime_shader_spirv);
49-
}
50-
g_runtime_shader_spirv = copy;
51-
g_runtime_shader_spirv_size = byteCount;
52-
return 0;
53-
}
33+
static const uint32_t kEmbeddedExpectedDispatchValue = 0x12345678u;
5434

5535
static int string_contains(const char* haystack, const char* needle) {
5636
return haystack && needle && strstr(haystack, needle) != 0;
@@ -139,6 +119,9 @@ EMSCRIPTEN_KEEPALIVE int lavapipe_runtime_smoke(void) {
139119
VkFence submitFence = VK_NULL_HANDLE;
140120
VkQueue queue = VK_NULL_HANDLE;
141121
uint32_t dispatchObservedValue = 0u;
122+
uint32_t expectedDispatchValue = kEmbeddedExpectedDispatchValue;
123+
uint32_t shaderKeyLo = webvulkan_get_runtime_active_shader_key_lo();
124+
uint32_t shaderKeyHi = webvulkan_get_runtime_active_shader_key_hi();
142125
const uint32_t* shaderCodeWords = kSmokeComputeSpirv;
143126
size_t shaderCodeSizeBytes = sizeof(kSmokeComputeSpirv);
144127
const char* shaderSource = "embedded_static_spirv";
@@ -181,6 +164,7 @@ EMSCRIPTEN_KEEPALIVE int lavapipe_runtime_smoke(void) {
181164

182165

183166
volkInitializeCustom((PFN_vkGetInstanceProcAddr)vk_icdGetInstanceProcAddr);
167+
webvulkan_runtime_mark_wasm_usage(0, "none");
184168
if (!vkCreateInstance || !vkEnumerateInstanceVersion) {
185169
smokeRc = 21;
186170
goto cleanup;
@@ -427,11 +411,32 @@ EMSCRIPTEN_KEEPALIVE int lavapipe_runtime_smoke(void) {
427411
goto cleanup;
428412
}
429413

430-
if (g_runtime_shader_spirv && g_runtime_shader_spirv_size >= 4u && (g_runtime_shader_spirv_size % 4u) == 0u) {
431-
shaderCodeWords = (const uint32_t*)g_runtime_shader_spirv;
432-
shaderCodeSizeBytes = (size_t)g_runtime_shader_spirv_size;
433-
shaderSource = "runtime_injected_spirv";
434-
shaderEntryPoint = "write_const";
414+
const uint8_t* runtimeSpirvBytes = 0;
415+
uint32_t runtimeSpirvSize = 0u;
416+
const char* runtimeSpirvEntrypoint = 0;
417+
if (webvulkan_runtime_lookup_spirv_module(
418+
shaderKeyLo,
419+
shaderKeyHi,
420+
&runtimeSpirvBytes,
421+
&runtimeSpirvSize,
422+
&runtimeSpirvEntrypoint
423+
) &&
424+
runtimeSpirvBytes &&
425+
runtimeSpirvSize >= 4u &&
426+
(runtimeSpirvSize % 4u) == 0u) {
427+
shaderCodeWords = (const uint32_t*)runtimeSpirvBytes;
428+
shaderCodeSizeBytes = (size_t)runtimeSpirvSize;
429+
shaderSource = "runtime_registry_spirv";
430+
if (runtimeSpirvEntrypoint && runtimeSpirvEntrypoint[0]) {
431+
shaderEntryPoint = runtimeSpirvEntrypoint;
432+
}
433+
if (!webvulkan_runtime_lookup_expected_dispatch_value(
434+
shaderKeyLo,
435+
shaderKeyHi,
436+
&expectedDispatchValue
437+
)) {
438+
expectedDispatchValue = shaderKeyLo;
439+
}
435440
}
436441

437442
VkShaderModuleCreateInfo shaderCreateInfo;
@@ -696,9 +701,9 @@ EMSCRIPTEN_KEEPALIVE int lavapipe_runtime_smoke(void) {
696701
}
697702

698703
dispatchObservedValue = mappedStorageWord[0];
699-
if (dispatchObservedValue != 0x12345678u) {
704+
if (dispatchObservedValue != expectedDispatchValue) {
700705
printf("lavapipe runtime smoke dispatch mismatch\n");
701-
printf(" shader.dispatch.expected=0x%08x\n", 0x12345678u);
706+
printf(" shader.dispatch.expected=0x%08x\n", expectedDispatchValue);
702707
printf(" shader.dispatch.observed=0x%08x\n", dispatchObservedValue);
703708
smokeRc = 73;
704709
goto cleanup;
@@ -725,13 +730,14 @@ EMSCRIPTEN_KEEPALIVE int lavapipe_runtime_smoke(void) {
725730
printf(" proof.device_name_contains_llvmpipe=%s\n", proofDeviceName ? "yes" : "no");
726731
printf(" proof.driver_name_contains_llvmpipe=%s\n", proofDriverName ? "yes" : "no");
727732
printf(" vulkan_loader=volk (custom vk_icdGetInstanceProcAddr)\n");
733+
printf(" shader.key=0x%08x%08x\n", shaderKeyHi, shaderKeyLo);
728734
printf(" shader.source=%s\n", shaderSource);
729735
printf(" shader.entrypoint=%s\n", shaderEntryPoint);
730736
printf(" shader.code_bytes=%u\n", (unsigned)shaderCodeSizeBytes);
731737
printf(" shader.create_module=ok\n");
732738
printf(" shader.create_compute_pipeline=ok\n");
733739
printf(" shader.dispatch=ok\n");
734-
printf(" shader.dispatch.expected=0x%08x\n", 0x12345678u);
740+
printf(" shader.dispatch.expected=0x%08x\n", expectedDispatchValue);
735741
printf(" shader.dispatch.observed=0x%08x\n", dispatchObservedValue);
736742

737743
cleanup:

0 commit comments

Comments
 (0)