@animech-public/playcanvas
Version:
PlayCanvas WebGL game engine
2 lines (1 loc) • 3.25 kB
JavaScript
import{hash32Fnv1a as e}from"../../../core/hash.js";import{array as t}from"../../../core/array-utils.js";import{WebgpuVertexBufferLayout as r}from"./webgpu-vertex-buffer-layout.js";import{WebgpuPipeline as a}from"./webgpu-pipeline.js";const l=["point-list","line-list",void 0,"line-strip","triangle-list","triangle-strip",void 0],s=["add","subtract","reverse-subtract","min","max"],i=["zero","one","src","one-minus-src","dst","one-minus-dst","src-alpha","src-alpha-saturated","one-minus-src-alpha","dst-alpha","one-minus-dst-alpha","constant","one-minus-constant"],n=["never","less","equal","less-equal","greater","not-equal","greater-equal","always"],o=["none","back","front"],p=["keep","zero","replace","increment-clamp","increment-wrap","decrement-clamp","decrement-wrap","invert"];class c{constructor(){this.pipeline=void 0,this.hashes=void 0}}class h extends a{constructor(e){super(e),this.lookupHashes=new Uint32Array(13),this.vertexBufferLayout=new r,this.cache=new Map}get(r,a,s,i,n,o,p,h,u,d,m,f){var g,y,v,k,w,F,b,P;const W=this.lookupHashes;W[0]=r.type,W[1]=i.id,W[2]=u,W[3]=h.key,W[4]=p.key,W[5]=null!=(g=null==a?void 0:a.renderingHash)?g:0,W[6]=null!=(y=null==s?void 0:s.renderingHash)?y:0,W[7]=n.impl.key,W[8]=null!=(v=null==(k=o[0])?void 0:k.key)?v:0,W[9]=null!=(w=null==(F=o[1])?void 0:F.key)?w:0,W[10]=null!=(b=null==(P=o[2])?void 0:P.key)?b:0,W[11]=d?m.key:0,W[12]=d?f.key:0;const B=e(W);let S=this.cache.get(B);if(S)for(let e=0;e<S.length;e++){const r=S[e];if(t.equals(r.hashes,W))return r.pipeline}const x=l[r.type],E=this.getPipelineLayout(o),M=this.vertexBufferLayout.get(a,s),O=new c;return O.hashes=new Uint32Array(W),O.pipeline=this.create(x,i,n,E,p,h,M,u,d,m,f),S?S.push(O):S=[O],this.cache.set(B,S),O.pipeline}getBlend(e){let t;return e.blend&&(t={color:{operation:s[e.colorOp],srcFactor:i[e.colorSrcFactor],dstFactor:i[e.colorDstFactor]},alpha:{operation:s[e.alphaOp],srcFactor:i[e.alphaSrcFactor],dstFactor:i[e.alphaDstFactor]}}),t}getDepthStencil(e,t,r,a,l){let s;const{depth:i,stencil:o}=t;return(i||o)&&(s={format:t.impl.depthFormat},i?(s.depthWriteEnabled=e.write,s.depthCompare=n[e.func],s.depthBias=e.depthBias,s.depthBiasSlopeScale=e.depthBiasSlope):(s.depthWriteEnabled=!1,s.depthCompare="always"),o&&r&&(s.stencilReadMas=a.readMask,s.stencilWriteMask=a.writeMask,s.stencilFront={compare:n[a.func],failOp:p[a.fail],passOp:p[a.zpass],depthFailOp:p[a.zfail]},s.stencilBack={compare:n[l.func],failOp:p[l.fail],passOp:p[l.zpass],depthFailOp:p[l.zfail]})),s}create(e,t,r,a,l,s,i,n,p,c,h){const u=this.device.wgpu,d=t.impl,m={vertex:{module:d.getVertexShaderModule(),entryPoint:d.vertexEntryPoint,buffers:i},primitive:{topology:e,frontFace:"ccw",cullMode:o[n]},depthStencil:this.getDepthStencil(s,r,p,c,h),multisample:{count:r.samples},layout:a};m.fragment={module:d.getFragmentShaderModule(),entryPoint:d.fragmentEntryPoint,targets:[]};const f=r.impl.colorAttachments;if(f.length>0){let e=0;l.redWrite&&(e|=GPUColorWrite.RED),l.greenWrite&&(e|=GPUColorWrite.GREEN),l.blueWrite&&(e|=GPUColorWrite.BLUE),l.alphaWrite&&(e|=GPUColorWrite.ALPHA);const t=this.getBlend(l);f.forEach((r=>{m.fragment.targets.push({format:r.format,writeMask:e,blend:t})}))}return u.createRenderPipeline(m)}}export{h as WebgpuRenderPipeline};