yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
7e278c3ad
master
1"use strict" ; 2 3let Example = { 4initialize :async function ( slang , canvas ) { 5async function render ( shaders ) { 6if ( ! navigator . gpu ) { 7throw new Error ( "WebGPU not supported on this browser." ); 8} 9const adapter = await navigator . gpu . requestAdapter (); 10if ( ! adapter ) { 11throw new Error ( "No appropriate GPUAdapter found." ); 12} 13const device = await adapter . requestDevice (); 14const context = canvas . getContext ( "webgpu" ); 15const canvasFormat = navigator . gpu . getPreferredCanvasFormat (); 16context . configure ({ 17device :device , 18format :canvasFormat , 19}); 20 21const vertexBufferLayout = { 22arrayStride :8 , 23attributes :[{ 24format :"float32x2" , 25offset :0 , 26shaderLocation :0 , 27}], 28}; 29 30const pipeline = device . createRenderPipeline ({ 31label :"Pipeline" , 32layout :"auto" , 33vertex :{ 34module :device . createShaderModule ({ 35label :"Vertex shader module" , 36code :shaders . vertex 37}), 38entryPoint :"vertexMain" , 39buffers :[ vertexBufferLayout ] 40}, 41fragment :{ 42module :device . createShaderModule ({ 43label :"Fragment shader module" , 44code :shaders . fragment 45}), 46entryPoint :"fragmentMain" , 47targets :[{ 48format :canvasFormat 49}] 50} 51}); 52 53const vertices = new Float32Array ([ 540.0 , - 0.8 , 55+ 0.8 , + 0.8 , 56- 0.8 , + 0.8 , 57]); 58const vertexBuffer = device . createBuffer ({ 59label :"Triangle vertices" , 60size :vertices . byteLength , 61usage :GPUBufferUsage . VERTEX | GPUBufferUsage . COPY_DST , 62}); 63const bufferOffset = 0 ; 64device . queue . writeBuffer ( vertexBuffer , bufferOffset , vertices ); 65 66const encoder = device . createCommandEncoder (); 67const pass = encoder . beginRenderPass ({ 68colorAttachments :[{ 69view :context . getCurrentTexture (). createView (), 70loadOp :"clear" , 71clearValue :{ r :0 , g :0 , b :0 , a :1 }, 72storeOp :"store" , 73}] 74}); 75pass . setPipeline ( pipeline ); 76const vertexBufferSlot = 0 ; 77pass . setVertexBuffer ( vertexBufferSlot , vertexBuffer ); 78pass . draw ( vertices . length / 2 ); 79pass . end (); 80const commandBuffer = encoder . finish (); 81device . queue . submit ([ commandBuffer ]); 82} 83 84const slangCode = await fetch ( "shader.slang" ). then ( r => r . text ()); 85 86var wasmCompileTarget = null ; 87var compileTargetMap = slang . module . getCompileTargets (); 88for ( var i = 0 ; i < compileTargetMap . length ; i ++ ) { 89var target = compileTargetMap [ i ]; 90if ( target . name == "WGSL" ) { 91wasmCompileTarget = target . value ; 92} 93} 94if ( wasmCompileTarget === null ) { 95throw new Error ( "Slang/WASM module doesn't support WGSL compile target." ); 96} 97 98var slangSession = slang . globalSession . createSession ( wasmCompileTarget ); 99if ( ! slangSession ) { 100throw new Error ( "Failed to create global Slang session." ); 101} 102 103var wgslShaders = null ; 104try { 105var module = slangSession . loadModuleFromSource ( 106slangCode , "shader" , '/shader.slang' 107); 108var vertexEntryPoint = module . findAndCheckEntryPoint ( 109"vertexMain" , slang . constants . STAGE_VERTEX 110); 111var fragmentEntryPoint = module . findAndCheckEntryPoint ( 112"fragmentMain" , slang . constants . STAGE_FRAGMENT 113); 114var linkedProgram = slangSession . createCompositeComponentType ([ 115module , vertexEntryPoint , fragmentEntryPoint 116]). link (); 117wgslShaders = { 118vertex :linkedProgram . getEntryPointCode ( 1190 /* entryPointIndex */ , 0 /* targetIndex */ 120), 121fragment :linkedProgram . getEntryPointCode ( 1221 /* entryPointIndex */ , 0 /* targetIndex */ 123), 124}; 125} finally { 126if ( slangSession ) { 127slangSession . delete (); 128} 129} 130 131if ( ! wgslShaders ) { 132throw new Error ( "Failed to compile WGSL shaders." ); 133} 134 135render ( wgslShaders ); 136} 137} 138 139var Module = { 140onRuntimeInitialized :function () { 141const canvas = document . querySelector ( "canvas" ); 142 143var globalSlangSession = Module . createGlobalSession (); 144if ( ! globalSlangSession ) { 145throw new Error ( "Failed to create global Slang session." ); 146} 147 148const slang = { 149module :Module , 150globalSession :globalSlangSession , 151constants :{ 152STAGE_VERTEX :1 , 153STAGE_FRAGMENT :5 , 154}, 155}; 156Example . initialize ( slang , canvas ); 157}, 158};