Skip to content

Commit e2a9f55

Browse files
committed
Unify runtime shader registry API for real usage
1 parent bc3c602 commit e2a9f55

5 files changed

Lines changed: 312 additions & 83 deletions

File tree

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,17 @@ target_link_libraries(my_app PRIVATE webvulkan::llvmpipe_wasm)
216216

217217
In package mode the same helper is available after `find_package(WebVulkanLlvmpipeWasm REQUIRED CONFIG)`.
218218

219+
Runtime registry API for real usage
220+
221+
- `webvulkan_runtime_register_shader_bundle(...)` registers one shader bundle via struct.
222+
- `webvulkan_runtime_register_shader_bundles(...)` registers many bundles in one call.
223+
- `webvulkan_runtime_register_shader_bundle_params(...)` is a flat convenience API.
224+
- `webvulkan_runtime_unregister_shader_bundle(...)` removes one shader key.
225+
- `webvulkan_runtime_clear_shader_bundles()` clears all registered runtime bundles.
226+
- `webvulkan_runtime_set_active_shader_bundle(...)` selects active shader key.
227+
- `webvulkan_runtime_set_dispatch_mode_fast_wasm(...)` toggles fast wasm path on or off.
228+
- `webvulkan_runtime_get_registered_spirv_count()` and `webvulkan_runtime_get_registered_wasm_count()` expose current registry counts.
229+
219230
## How we validate it
220231

221232
We run `runtime_smoke` in CI as the runtime validation test.

runtime/include/webvulkan/webvulkan_shader_runtime_registry.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,44 @@ extern "C" {
1212
#define WEBVULKAN_RUNTIME_DEFAULT_SHADER_KEY_HI 0u
1313
#define WEBVULKAN_RUNTIME_DISPATCH_MODE_RAW_LLVM_IR 0u
1414
#define WEBVULKAN_RUNTIME_DISPATCH_MODE_FAST_WASM 1u
15+
#define WEBVULKAN_RUNTIME_SHADER_BUNDLE_HAS_WASM 0x1u
16+
#define WEBVULKAN_RUNTIME_SHADER_BUNDLE_HAS_EXPECTED_VALUE 0x2u
17+
18+
typedef struct WebVulkanRuntimeShaderBundle_t {
19+
uint32_t keyLo;
20+
uint32_t keyHi;
21+
const uint8_t* spirvBytes;
22+
uint32_t spirvByteCount;
23+
const char* spirvEntrypoint;
24+
const uint8_t* wasmBytes;
25+
uint32_t wasmByteCount;
26+
const char* wasmEntrypoint;
27+
const char* wasmProvider;
28+
uint32_t expectedDispatchValue;
29+
uint32_t flags;
30+
} WebVulkanRuntimeShaderBundle;
31+
32+
int webvulkan_runtime_register_shader_bundle(const WebVulkanRuntimeShaderBundle* bundle);
33+
int webvulkan_runtime_register_shader_bundles(const WebVulkanRuntimeShaderBundle* bundles, uint32_t bundleCount);
34+
int webvulkan_runtime_register_shader_bundle_params(
35+
uint32_t keyLo,
36+
uint32_t keyHi,
37+
const uint8_t* spirvBytes,
38+
uint32_t spirvByteCount,
39+
const char* spirvEntrypoint,
40+
const uint8_t* wasmBytes,
41+
uint32_t wasmByteCount,
42+
const char* wasmEntrypoint,
43+
const char* wasmProvider,
44+
uint32_t expectedDispatchValue,
45+
uint32_t flags
46+
);
47+
int webvulkan_runtime_unregister_shader_bundle(uint32_t keyLo, uint32_t keyHi);
48+
void webvulkan_runtime_clear_shader_bundles(void);
49+
uint32_t webvulkan_runtime_get_registered_spirv_count(void);
50+
uint32_t webvulkan_runtime_get_registered_wasm_count(void);
51+
int webvulkan_runtime_set_active_shader_bundle(uint32_t keyLo, uint32_t keyHi);
52+
int webvulkan_runtime_set_dispatch_mode_fast_wasm(int enabled);
1553

1654
int webvulkan_register_runtime_shader_spirv(
1755
uint32_t keyLo,

runtime/src/webvulkan_shader_runtime_registry.c

Lines changed: 181 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,42 @@ static int webvulkan_find_wasm_entry_index(uint32_t keyLo, uint32_t keyHi) {
9494
return -1;
9595
}
9696

97+
static void webvulkan_remove_spirv_entry_at(uint32_t index) {
98+
if (index >= g_runtime_spirv_count) {
99+
return;
100+
}
101+
WebVulkanRuntimeSpirvEntry* entry = &g_runtime_spirv_entries[index];
102+
if (entry->bytes) {
103+
free(entry->bytes);
104+
entry->bytes = 0;
105+
}
106+
for (uint32_t i = index + 1u; i < g_runtime_spirv_count; ++i) {
107+
g_runtime_spirv_entries[i - 1u] = g_runtime_spirv_entries[i];
108+
}
109+
if (g_runtime_spirv_count > 0u) {
110+
--g_runtime_spirv_count;
111+
memset(&g_runtime_spirv_entries[g_runtime_spirv_count], 0, sizeof(g_runtime_spirv_entries[0]));
112+
}
113+
}
114+
115+
static void webvulkan_remove_wasm_entry_at(uint32_t index) {
116+
if (index >= g_runtime_wasm_count) {
117+
return;
118+
}
119+
WebVulkanRuntimeWasmEntry* entry = &g_runtime_wasm_entries[index];
120+
if (entry->bytes) {
121+
free(entry->bytes);
122+
entry->bytes = 0;
123+
}
124+
for (uint32_t i = index + 1u; i < g_runtime_wasm_count; ++i) {
125+
g_runtime_wasm_entries[i - 1u] = g_runtime_wasm_entries[i];
126+
}
127+
if (g_runtime_wasm_count > 0u) {
128+
--g_runtime_wasm_count;
129+
memset(&g_runtime_wasm_entries[g_runtime_wasm_count], 0, sizeof(g_runtime_wasm_entries[0]));
130+
}
131+
}
132+
97133
EMSCRIPTEN_KEEPALIVE void webvulkan_reset_runtime_shader_registry(void) {
98134
for (uint32_t i = 0u; i < g_runtime_spirv_count; ++i) {
99135
if (g_runtime_spirv_entries[i].bytes) {
@@ -144,6 +180,44 @@ EMSCRIPTEN_KEEPALIVE uint32_t webvulkan_get_runtime_dispatch_mode(void) {
144180
return g_runtime_dispatch_mode;
145181
}
146182

183+
EMSCRIPTEN_KEEPALIVE int webvulkan_runtime_set_dispatch_mode_fast_wasm(int enabled) {
184+
if (enabled) {
185+
return webvulkan_set_runtime_dispatch_mode(WEBVULKAN_RUNTIME_DISPATCH_MODE_FAST_WASM);
186+
}
187+
return webvulkan_set_runtime_dispatch_mode(WEBVULKAN_RUNTIME_DISPATCH_MODE_RAW_LLVM_IR);
188+
}
189+
190+
EMSCRIPTEN_KEEPALIVE int webvulkan_runtime_set_active_shader_bundle(uint32_t keyLo, uint32_t keyHi) {
191+
return webvulkan_set_runtime_active_shader_key(keyLo, keyHi);
192+
}
193+
194+
EMSCRIPTEN_KEEPALIVE uint32_t webvulkan_runtime_get_registered_spirv_count(void) {
195+
return g_runtime_spirv_count;
196+
}
197+
198+
EMSCRIPTEN_KEEPALIVE uint32_t webvulkan_runtime_get_registered_wasm_count(void) {
199+
return g_runtime_wasm_count;
200+
}
201+
202+
EMSCRIPTEN_KEEPALIVE int webvulkan_runtime_unregister_shader_bundle(uint32_t keyLo, uint32_t keyHi) {
203+
int removed = 0;
204+
int spirvIndex = webvulkan_find_spirv_entry_index(keyLo, keyHi);
205+
if (spirvIndex >= 0) {
206+
webvulkan_remove_spirv_entry_at((uint32_t)spirvIndex);
207+
removed = 1;
208+
}
209+
int wasmIndex = webvulkan_find_wasm_entry_index(keyLo, keyHi);
210+
if (wasmIndex >= 0) {
211+
webvulkan_remove_wasm_entry_at((uint32_t)wasmIndex);
212+
removed = 1;
213+
}
214+
return removed ? 0 : -1;
215+
}
216+
217+
EMSCRIPTEN_KEEPALIVE void webvulkan_runtime_clear_shader_bundles(void) {
218+
webvulkan_reset_runtime_shader_registry();
219+
}
220+
147221
EMSCRIPTEN_KEEPALIVE int webvulkan_set_runtime_expected_dispatch_value(
148222
uint32_t keyLo,
149223
uint32_t keyHi,
@@ -261,6 +335,100 @@ EMSCRIPTEN_KEEPALIVE int webvulkan_register_runtime_wasm_module(
261335
return 0;
262336
}
263337

338+
EMSCRIPTEN_KEEPALIVE int webvulkan_runtime_register_shader_bundle(const WebVulkanRuntimeShaderBundle* bundle) {
339+
if (!bundle) {
340+
return -10;
341+
}
342+
if (!bundle->spirvBytes || bundle->spirvByteCount == 0u) {
343+
return -11;
344+
}
345+
346+
int spirvRc = webvulkan_register_runtime_shader_spirv(
347+
bundle->keyLo,
348+
bundle->keyHi,
349+
bundle->spirvBytes,
350+
bundle->spirvByteCount,
351+
bundle->spirvEntrypoint
352+
);
353+
if (spirvRc != 0) {
354+
return spirvRc;
355+
}
356+
357+
uint32_t expectedDispatchValue = bundle->keyLo;
358+
if ((bundle->flags & WEBVULKAN_RUNTIME_SHADER_BUNDLE_HAS_EXPECTED_VALUE) != 0u) {
359+
expectedDispatchValue = bundle->expectedDispatchValue;
360+
}
361+
(void)webvulkan_set_runtime_expected_dispatch_value(bundle->keyLo, bundle->keyHi, expectedDispatchValue);
362+
363+
int hasWasm = (bundle->flags & WEBVULKAN_RUNTIME_SHADER_BUNDLE_HAS_WASM) != 0u;
364+
if (!hasWasm && bundle->wasmBytes && bundle->wasmByteCount > 0u) {
365+
hasWasm = 1;
366+
}
367+
if (hasWasm) {
368+
if (!bundle->wasmBytes || bundle->wasmByteCount == 0u) {
369+
return -12;
370+
}
371+
int wasmRc = webvulkan_register_runtime_wasm_module(
372+
bundle->keyLo,
373+
bundle->keyHi,
374+
bundle->wasmBytes,
375+
bundle->wasmByteCount,
376+
bundle->wasmEntrypoint,
377+
bundle->wasmProvider
378+
);
379+
if (wasmRc != 0) {
380+
return wasmRc;
381+
}
382+
}
383+
384+
return 0;
385+
}
386+
387+
EMSCRIPTEN_KEEPALIVE int webvulkan_runtime_register_shader_bundles(
388+
const WebVulkanRuntimeShaderBundle* bundles,
389+
uint32_t bundleCount
390+
) {
391+
if (!bundles || bundleCount == 0u) {
392+
return -10;
393+
}
394+
for (uint32_t i = 0u; i < bundleCount; ++i) {
395+
int rc = webvulkan_runtime_register_shader_bundle(&bundles[i]);
396+
if (rc != 0) {
397+
return rc;
398+
}
399+
}
400+
return 0;
401+
}
402+
403+
EMSCRIPTEN_KEEPALIVE int webvulkan_runtime_register_shader_bundle_params(
404+
uint32_t keyLo,
405+
uint32_t keyHi,
406+
const uint8_t* spirvBytes,
407+
uint32_t spirvByteCount,
408+
const char* spirvEntrypoint,
409+
const uint8_t* wasmBytes,
410+
uint32_t wasmByteCount,
411+
const char* wasmEntrypoint,
412+
const char* wasmProvider,
413+
uint32_t expectedDispatchValue,
414+
uint32_t flags
415+
) {
416+
WebVulkanRuntimeShaderBundle bundle;
417+
memset(&bundle, 0, sizeof(bundle));
418+
bundle.keyLo = keyLo;
419+
bundle.keyHi = keyHi;
420+
bundle.spirvBytes = spirvBytes;
421+
bundle.spirvByteCount = spirvByteCount;
422+
bundle.spirvEntrypoint = spirvEntrypoint;
423+
bundle.wasmBytes = wasmBytes;
424+
bundle.wasmByteCount = wasmByteCount;
425+
bundle.wasmEntrypoint = wasmEntrypoint;
426+
bundle.wasmProvider = wasmProvider;
427+
bundle.expectedDispatchValue = expectedDispatchValue;
428+
bundle.flags = flags;
429+
return webvulkan_runtime_register_shader_bundle(&bundle);
430+
}
431+
264432
EMSCRIPTEN_KEEPALIVE int webvulkan_register_runtime_shader_bundle(
265433
uint32_t keyLo,
266434
uint32_t keyHi,
@@ -272,30 +440,19 @@ EMSCRIPTEN_KEEPALIVE int webvulkan_register_runtime_shader_bundle(
272440
const char* wasmEntrypoint,
273441
const char* wasmProvider
274442
) {
275-
int spirvRc = webvulkan_register_runtime_shader_spirv(
443+
return webvulkan_runtime_register_shader_bundle_params(
276444
keyLo,
277445
keyHi,
278446
spirvBytes,
279447
spirvByteCount,
280-
spirvEntrypoint
281-
);
282-
if (spirvRc != 0) {
283-
return spirvRc;
284-
}
285-
286-
int wasmRc = webvulkan_register_runtime_wasm_module(
287-
keyLo,
288-
keyHi,
448+
spirvEntrypoint,
289449
wasmBytes,
290450
wasmByteCount,
291451
wasmEntrypoint,
292-
wasmProvider
452+
wasmProvider,
453+
keyLo,
454+
WEBVULKAN_RUNTIME_SHADER_BUNDLE_HAS_WASM
293455
);
294-
if (wasmRc != 0) {
295-
return wasmRc;
296-
}
297-
298-
return 0;
299456
}
300457

301458
EMSCRIPTEN_KEEPALIVE int webvulkan_get_runtime_wasm_used(void) {
@@ -307,12 +464,18 @@ EMSCRIPTEN_KEEPALIVE const char* webvulkan_get_runtime_wasm_provider(void) {
307464
}
308465

309466
EMSCRIPTEN_KEEPALIVE int webvulkan_set_runtime_shader_spirv(const uint8_t* bytes, uint32_t byteCount) {
310-
return webvulkan_register_runtime_shader_spirv(
467+
return webvulkan_runtime_register_shader_bundle_params(
311468
WEBVULKAN_RUNTIME_DEFAULT_SHADER_KEY_LO,
312469
WEBVULKAN_RUNTIME_DEFAULT_SHADER_KEY_HI,
313470
bytes,
314471
byteCount,
315-
"write_const"
472+
"write_const",
473+
0,
474+
0u,
475+
0,
476+
0,
477+
WEBVULKAN_RUNTIME_DEFAULT_SHADER_KEY_LO,
478+
WEBVULKAN_RUNTIME_SHADER_BUNDLE_HAS_EXPECTED_VALUE
316479
);
317480
}
318481

tests/RunLavapipeRuntimeSmoke.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ append_rsp("-sMODULARIZE=1")
143143
append_rsp("-sEXPORT_ES6=1")
144144
append_rsp("-sENVIRONMENT=web,worker,node")
145145
if(SMOKE_REQUIRE_RUNTIME_SPIRV STREQUAL "1")
146-
append_rsp("-sEXPORTED_FUNCTIONS=['_main','${SMOKE_EXPORT}','_webvulkan_reset_runtime_shader_registry','_webvulkan_set_runtime_active_shader_key','_webvulkan_set_runtime_dispatch_mode','_webvulkan_get_runtime_dispatch_mode','_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','_webvulkan_set_runtime_bench_profile','_webvulkan_get_runtime_bench_profile','_webvulkan_set_runtime_shader_workload','_webvulkan_get_runtime_shader_workload','_webvulkan_get_last_dispatch_ms','_malloc','_free']")
146+
append_rsp("-sEXPORTED_FUNCTIONS=['_main','${SMOKE_EXPORT}','_webvulkan_reset_runtime_shader_registry','_webvulkan_runtime_clear_shader_bundles','_webvulkan_set_runtime_active_shader_key','_webvulkan_runtime_set_active_shader_bundle','_webvulkan_set_runtime_dispatch_mode','_webvulkan_runtime_set_dispatch_mode_fast_wasm','_webvulkan_get_runtime_dispatch_mode','_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_runtime_register_shader_bundle_params','_webvulkan_runtime_unregister_shader_bundle','_webvulkan_runtime_get_registered_spirv_count','_webvulkan_runtime_get_registered_wasm_count','_webvulkan_get_runtime_wasm_used','_webvulkan_get_runtime_wasm_provider','_webvulkan_set_runtime_bench_profile','_webvulkan_get_runtime_bench_profile','_webvulkan_set_runtime_shader_workload','_webvulkan_get_runtime_shader_workload','_webvulkan_get_last_dispatch_ms','_malloc','_free']")
147147
else()
148148
append_rsp("-sEXPORTED_FUNCTIONS=['_main','${SMOKE_EXPORT}']")
149149
endif()

0 commit comments

Comments
 (0)