@@ -47,12 +47,82 @@ function runtimeShaderThreadgroupSizeX(workloadName) {
4747 return workloadName === "write_const" ? 1 : 64 ;
4848}
4949
50- async function compileRuntimeSpirv ( storeValue , workloadName ) {
51- const storeConst = `0x${ ( storeValue >>> 0 ) . toString ( 16 ) } u` ;
52- const threadgroupSizeX = runtimeShaderThreadgroupSizeX ( workloadName ) ;
53- const dxcWasmJs = process . env . WEBVULKAN_DXC_WASM_JS || "" ;
54- if ( dxcWasmJs ) {
55- const hlslSource = `
50+ function runtimeBenchProfileDescriptor ( profileName ) {
51+ switch ( profileName ) {
52+ case "micro" :
53+ return { dispatchesPerSubmit : 1024 , dispatchX : 1 , dispatchY : 1 , dispatchZ : 1 } ;
54+ case "realistic" :
55+ return { dispatchesPerSubmit : 64 , dispatchX : 4 , dispatchY : 1 , dispatchZ : 1 } ;
56+ case "hot_loop_single_dispatch" :
57+ return { dispatchesPerSubmit : 1 , dispatchX : 256 , dispatchY : 1 , dispatchZ : 1 } ;
58+ default :
59+ throw new Error ( `Unsupported runtime bench profile '${ profileName } '` ) ;
60+ }
61+ }
62+
63+ function runtimeShaderEntrypoint ( workloadName ) {
64+ switch ( workloadName ) {
65+ case "atomic_single_counter" :
66+ return "atomic_single_counter" ;
67+ case "atomic_per_workgroup" :
68+ return "atomic_per_workgroup" ;
69+ case "no_race_unique_writes" :
70+ return "no_race_unique_writes" ;
71+ case "write_const" :
72+ return "write_const" ;
73+ default :
74+ throw new Error ( `Unsupported runtime shader workload '${ workloadName } '` ) ;
75+ }
76+ }
77+
78+ function runtimeShaderHlslSource (
79+ storeConst ,
80+ threadgroupSizeX ,
81+ workloadName ,
82+ dispatchInvocationsPerSubmit ,
83+ dispatchWorkgroupsPerSubmit
84+ ) {
85+ const entrypoint = runtimeShaderEntrypoint ( workloadName ) ;
86+ if ( workloadName === "atomic_single_counter" ) {
87+ return `
88+ RWStructuredBuffer<uint> OutBuf : register(u0);
89+
90+ [numthreads(${ threadgroupSizeX } , 1, 1)]
91+ void ${ entrypoint } (uint3 tid : SV_DispatchThreadID) {
92+ InterlockedAdd(OutBuf[0], 1u);
93+ }
94+ ` ;
95+ }
96+
97+ if ( workloadName === "atomic_per_workgroup" ) {
98+ return `
99+ RWStructuredBuffer<uint> OutBuf : register(u0);
100+
101+ [numthreads(${ threadgroupSizeX } , 1, 1)]
102+ void ${ entrypoint } (uint3 groupThreadId : SV_GroupThreadID) {
103+ if (groupThreadId.x == 0u) {
104+ InterlockedAdd(OutBuf[0], 1u);
105+ }
106+ }
107+ ` ;
108+ }
109+
110+ if ( workloadName === "no_race_unique_writes" ) {
111+ return `
112+ RWStructuredBuffer<uint> OutBuf : register(u0);
113+
114+ [numthreads(${ threadgroupSizeX } , 1, 1)]
115+ void ${ entrypoint } (uint3 tid : SV_DispatchThreadID) {
116+ if (tid.x == 0u && tid.y == 0u && tid.z == 0u) {
117+ OutBuf[0] = ${ dispatchInvocationsPerSubmit } u;
118+ }
119+ uint idx = tid.x;
120+ OutBuf[1u + idx] = idx + 1u;
121+ }
122+ ` ;
123+ }
124+
125+ return `
56126RWStructuredBuffer<uint> OutBuf : register(u0);
57127
58128uint webvulkan_mix_const(uint v, uint salt) {
@@ -72,14 +142,36 @@ uint webvulkan_compile_time_chain() {
72142}
73143
74144[numthreads(${ threadgroupSizeX } , 1, 1)]
75- void write_const (uint3 tid : SV_DispatchThreadID) {
145+ void ${ entrypoint } (uint3 tid : SV_DispatchThreadID) {
76146 uint folded = webvulkan_compile_time_chain();
77147 if (folded == 0xdeadbeefu) {
78148 OutBuf[1] = folded;
79149 }
80150 OutBuf[0] = ${ storeConst } ;
81151}
82152` ;
153+ }
154+
155+ async function compileRuntimeSpirv ( storeValue , workloadName ) {
156+ const storeConst = `0x${ ( storeValue >>> 0 ) . toString ( 16 ) } u` ;
157+ const threadgroupSizeX = runtimeShaderThreadgroupSizeX ( workloadName ) ;
158+ const shaderEntrypoint = runtimeShaderEntrypoint ( workloadName ) ;
159+ const profile = runtimeBenchProfileDescriptor ( runtimeBenchProfile ) ;
160+ const dispatchWorkgroupsPerSubmit =
161+ profile . dispatchesPerSubmit *
162+ profile . dispatchX *
163+ profile . dispatchY *
164+ profile . dispatchZ ;
165+ const dispatchInvocationsPerSubmit = dispatchWorkgroupsPerSubmit * threadgroupSizeX ;
166+ const dxcWasmJs = process . env . WEBVULKAN_DXC_WASM_JS || "" ;
167+ if ( dxcWasmJs ) {
168+ const hlslSource = runtimeShaderHlslSource (
169+ storeConst ,
170+ threadgroupSizeX ,
171+ workloadName ,
172+ dispatchInvocationsPerSubmit ,
173+ dispatchWorkgroupsPerSubmit
174+ ) ;
83175
84176 const scratchDir = await mkdtemp ( join ( tmpdir ( ) , "webvulkan-dxc-wasm-" ) ) ;
85177 const inputFile = "runtime_smoke.hlsl" ;
@@ -94,7 +186,7 @@ void write_const(uint3 tid : SV_DispatchThreadID) {
94186 "-T" ,
95187 "cs_6_0" ,
96188 "-E" ,
97- "write_const" ,
189+ shaderEntrypoint ,
98190 "-Fo" ,
99191 outputFile ,
100192 inputFile
@@ -117,10 +209,14 @@ void write_const(uint3 tid : SV_DispatchThreadID) {
117209 return {
118210 provider : `dxc-wasm:${ dxcWasmJs } ` ,
119211 bytes,
120- entrypoint : "write_const"
212+ entrypoint : shaderEntrypoint
121213 } ;
122214 }
123215
216+ if ( workloadName !== "write_const" ) {
217+ throw new Error ( `Workload '${ workloadName } ' requires WEBVULKAN_DXC_WASM_JS` ) ;
218+ }
219+
124220 const wasmerBin = process . env . WEBVULKAN_WASMER_BIN ;
125221 if ( ! wasmerBin ) {
126222 throw new Error ( "WEBVULKAN_WASMER_BIN is required when SMOKE_REQUIRE_RUNTIME_SPIRV=1" ) ;
@@ -146,7 +242,7 @@ uint webvulkan_compile_time_chain() {
146242}
147243
148244__attribute__((reqd_work_group_size(${ threadgroupSizeX } , 1, 1)))
149- __kernel void write_const (__global uint* out) {
245+ __kernel void ${ shaderEntrypoint } (__global uint* out) {
150246 uint folded = webvulkan_compile_time_chain();
151247 if (folded == (uint)0xdeadbeefu) {
152248 out[1] = folded;
@@ -200,7 +296,7 @@ __kernel void write_const(__global uint* out) {
200296 return {
201297 provider : attempt . provider ,
202298 bytes : result . stdout ,
203- entrypoint : "write_const"
299+ entrypoint : shaderEntrypoint
204300 } ;
205301 }
206302
@@ -519,7 +615,14 @@ async function runFastWasmSmoke(shaderValue) {
519615 console . log ( ` runtime_wasm.bytes=${ runtimeWasm . bytes . length } ` ) ;
520616
521617 console . log ( "runtime smoke discover_key" ) ;
522- invokeSmokeOnce ( ) ;
618+ if ( runtimeShaderWorkload === "write_const" ) {
619+ invokeSmokeOnce ( ) ;
620+ } else {
621+ const discoverRc = smokeFn ( ) ;
622+ if ( discoverRc !== 0 ) {
623+ console . log ( `runtime smoke discover_key observed_nonzero_rc=${ discoverRc } before runtime module registration` ) ;
624+ }
625+ }
523626
524627 const hasCapturedKey = runtime . ccall ( "webvulkan_runtime_has_captured_shader_key" , "number" , [ ] , [ ] ) !== 0 ;
525628 if ( ! hasCapturedKey ) {
@@ -576,6 +679,9 @@ async function runFastWasmSmoke(shaderValue) {
576679}
577680
578681async function runRawLlvmIrSmoke ( shaderValue ) {
682+ if ( runtimeShaderWorkload !== "write_const" ) {
683+ throw new Error ( `raw_llvm_ir mode currently supports only write_const workload, got '${ runtimeShaderWorkload } '` ) ;
684+ }
579685 const spirv = await compileRuntimeSpirv ( shaderValue , runtimeShaderWorkload ) ;
580686 setRuntimeBenchProfile ( runtimeBenchProfileValue ) ;
581687 setRuntimeShaderWorkload ( runtimeShaderWorkloadValue ) ;
0 commit comments