@@ -13,6 +13,12 @@ var codeGenArea;
1313
1414var sourceCodeChange = true ;
1515
16+ var currentWindowSize = [ 300 , 150 ] ;
17+
18+ const RENDER_MODE = SlangCompiler . RENDER_SHADER ;
19+ const PRINT_MODE = SlangCompiler . PRINT_SHADER ;
20+ var currentMode = RENDER_MODE ;
21+
1622// TODO: Question?
1723// When we generate the shader code to wgsl, the uniform variable (float time) will have 16 bytes alignment, which is not shown in the slang
1824// code. So how the user can know the correct alignment of the uniform variable without using the slang reflection API or
@@ -86,6 +92,13 @@ function resizeCanvas(entries)
8692{
8793 const canvas = entries [ 0 ] . target ;
8894
95+ if ( canvas . style . display == "none" )
96+ {
97+ var parentDiv = document . getElementById ( "output" ) ;
98+ currentWindowSize = [ parentDiv . clientWidth , parentDiv . clientHeight ] ;
99+ return true ;
100+ }
101+
89102 const width = canvas . clientWidth ;
90103 const height = canvas . clientHeight ;
91104
@@ -95,6 +108,7 @@ function resizeCanvas(entries)
95108 canvas . width = Math . max ( 1 , Math . min ( width , device . limits . maxTextureDimension2D ) ) ;
96109 canvas . height = Math . max ( 1 , Math . min ( height , device . limits . maxTextureDimension2D ) ) ;
97110
111+ currentWindowSize = [ canvas . width , canvas . height ] ;
98112 return true ;
99113 }
100114
@@ -111,16 +125,51 @@ function resizeCanvasHandler(entries)
111125 {
112126 if ( computePipeline && passThroughPipeline )
113127 {
114- computePipeline . createOutput ( true ) ;
128+ computePipeline . createOutput ( true , currentWindowSize ) ;
115129 computePipeline . createBindGroup ( ) ;
116130 passThroughPipeline . inputTexture = computePipeline . outputTexture ;
117131 passThroughPipeline . createBindGroup ( ) ;
118- requestAnimationFrame ( render ) ;
132+ if ( canvas . style . display != "none" )
133+ {
134+ requestAnimationFrame ( render ) ;
135+ }
119136 }
120137 }
121138 } , 100 ) ;
122139}
123140
141+ function toggleDisplayMode ( displayMode )
142+ {
143+ if ( currentMode == displayMode )
144+ return ;
145+
146+ if ( displayMode == RENDER_MODE )
147+ {
148+ var printResult = document . getElementById ( "printResult" )
149+ printResult . style . display = "none" ;
150+
151+ canvas . style . display = "grid" ;
152+ canvas . style . width = "100%" ;
153+ canvas . style . height = "100%" ;
154+
155+ currentMode = RENDER_MODE ;
156+ }
157+ else if ( displayMode == PRINT_MODE )
158+ {
159+ canvas . style . display = "none" ;
160+ var printResult = document . getElementById ( "printResult" )
161+ printResult . style . display = "grid" ;
162+ printResult . style . width = "100%" ;
163+ printResult . style . height = "100%" ;
164+ printResult . style . backgroundColor = "white" ;
165+
166+ currentMode = PRINT_MODE ;
167+ }
168+ else
169+ {
170+ console . log ( "Invalid display mode " + displayMode ) ;
171+ }
172+ }
124173
125174async function render ( timeMS )
126175{
@@ -140,55 +189,61 @@ async function render(timeMS)
140189
141190 pass . setBindGroup ( 0 , computePipeline . bindGroup ) ;
142191 pass . setPipeline ( computePipeline . pipeline ) ;
143- pass . dispatchWorkgroups ( canvas . clientWidth , canvas . clientHeight ) ;
192+ pass . dispatchWorkgroups ( currentWindowSize [ 0 ] , currentWindowSize [ 1 ] ) ;
144193 pass . end ( ) ;
145194
146- // Get a WebGPU context from the canvas and configure it
147-
148- var renderPassDescriptor = passThroughPipeline . createRenderPassDesc ( ) ;
149- renderPassDescriptor . colorAttachments [ 0 ] . view = context . getCurrentTexture ( ) . createView ( ) ;
150- const renderPass = encoder . beginRenderPass ( renderPassDescriptor ) ;
151-
152- renderPass . setBindGroup ( 0 , passThroughPipeline . bindGroup ) ;
153- renderPass . setPipeline ( passThroughPipeline . pipeline ) ;
154- renderPass . draw ( 6 ) ; // call our vertex shader 6 times.
155- renderPass . end ( ) ;
195+ if ( compiler . shaderType == SlangCompiler . RENDER_SHADER )
196+ {
197+ var renderPassDescriptor = passThroughPipeline . createRenderPassDesc ( ) ;
198+ renderPassDescriptor . colorAttachments [ 0 ] . view = context . getCurrentTexture ( ) . createView ( ) ;
199+ const renderPass = encoder . beginRenderPass ( renderPassDescriptor ) ;
200+
201+ renderPass . setBindGroup ( 0 , passThroughPipeline . bindGroup ) ;
202+ renderPass . setPipeline ( passThroughPipeline . pipeline ) ;
203+ renderPass . draw ( 6 ) ; // call our vertex shader 6 times.
204+ renderPass . end ( ) ;
205+ }
156206
157- // copy output buffer back
158- // encoder.copyBufferToBuffer(computePipeline.outputBuffer, 0, computePipeline.outputBufferRead, 0, computePipeline.outputBuffer.size);
207+ // copy output buffer back in print mode
208+ if ( compiler . shaderType == SlangCompiler . PRINT_SHADER )
209+ encoder . copyBufferToBuffer ( computePipeline . outputBuffer , 0 , computePipeline . outputBufferRead , 0 , computePipeline . outputBuffer . size ) ;
159210
160211 // Finish encoding and submit the commands
161212 const commandBuffer = encoder . finish ( ) ;
162213 device . queue . submit ( [ commandBuffer ] ) ;
163214
164- requestAnimationFrame ( render ) ;
215+ // Only request the next frame if we are in the render mode
216+ if ( compiler . shaderType == SlangCompiler . RENDER_SHADER )
217+ requestAnimationFrame ( render ) ;
165218}
166219
167- async function waitForComplete ( outputBufferRead )
220+ async function printResult ( outputBufferRead )
168221{
169- // Read the results
222+ await device . queue . onSubmittedWorkDone ( ) ;
223+ // Read the results once the job is done
170224 await Promise . all ( [
171225 outputBufferRead . mapAsync ( GPUMapMode . READ ) ,
172226 ] ) ;
173227
174228 const output = new Int32Array ( outputBufferRead . getMappedRange ( ) ) ;
175229
176- outputResult ( output ) . then ( ( ) => {
177- outputBufferRead . unmap ( )
178- } ) ;
230+ const textResult = formatResult ( output ) ;
231+ outputBufferRead . unmap ( ) ;
232+
233+ console . log ( canvas . style . display ) ;
234+
235+ document . getElementById ( "printResult" ) . value = textResult ;
179236}
180237
181- async function outputResult ( output )
238+ function formatResult ( output )
182239{
183- // TODO: Optional - output the printable result to the output area
184- // we don't have such area in the current UI
185- // var result = "";
186- // for (let i = 0; i < output.length; i++)
187- // {
188- // result += output[i] + '\n';
189- // }
190- //
191- // document.getElementById("result").value = result;
240+ var result = "" ;
241+ for ( let i = 0 ; i < output . length ; i ++ )
242+ {
243+ result += output [ i ] + '\n' ;
244+ }
245+
246+ return result ;
192247}
193248
194249
@@ -199,7 +254,7 @@ var onRun = () => {
199254 if ( ! computePipeline )
200255 {
201256 computePipeline = new ComputePipeline ( device ) ;
202- computePipeline . setupComputePipeline ( ) ;
257+ computePipeline . setupComputePipeline ( currentWindowSize ) ;
203258 computePipeline . createUniformBuffer ( 4 ) ; // 4 bytes for float number
204259 }
205260
@@ -221,11 +276,12 @@ var onRun = () => {
221276 return ;
222277 }
223278
279+ toggleDisplayMode ( compiler . shaderType ) ;
280+
224281 render ( 0 ) ;
225- // TODO: This function is used to read the output buffer from GPU, and print out.
226- // We will add an option to select render Mode and print mode. Once print mode is selected,
227- // we will not enable the animation, and will call this function to print results on screen.
228- // waitForComplete(computePipeline.outputBufferRead);
282+
283+ if ( compiler . shaderType == SlangCompiler . PRINT_SHADER )
284+ printResult ( computePipeline . outputBufferRead ) ;
229285}
230286
231287function compileShader ( entryPoint )
0 commit comments