(currentShader, passEncoder, shaderOptionsParams)
| 1899 | } |
| 1900 | |
| 1901 | setupShaderBindGroups(currentShader, passEncoder, shaderOptionsParams) { |
| 1902 | const shaderOptions = this._shaderOptions(shaderOptionsParams); |
| 1903 | if ( |
| 1904 | shaderOptions.compute || |
| 1905 | this.activeShader !== currentShader || |
| 1906 | this._shaderOptionsDifferent(shaderOptions) |
| 1907 | ) { |
| 1908 | passEncoder.setPipeline(currentShader.getPipeline(shaderOptions)); |
| 1909 | } |
| 1910 | if (!shaderOptions.compute) { |
| 1911 | this.activeShader = currentShader; |
| 1912 | this.activeShaderOptions = shaderOptions; |
| 1913 | |
| 1914 | // Set stencil reference value for clipping |
| 1915 | const drawTarget = this.drawTarget(); |
| 1916 | if (drawTarget._isClipApplied && !this._clipping) { |
| 1917 | // When using the clip mask, test against reference value 0 (background) |
| 1918 | // WebGL uses NOTEQUAL with ref 0, so fragments pass where stencil != 0 |
| 1919 | // In WebGPU with 'not-equal', we need ref 0 to pass where stencil != 0 |
| 1920 | passEncoder.setStencilReference(0); |
| 1921 | } else if (this._clipping) { |
| 1922 | // When writing to the clip mask, write reference value 1 |
| 1923 | passEncoder.setStencilReference(1); |
| 1924 | } |
| 1925 | } |
| 1926 | |
| 1927 | for (const bufferGroup of currentShader._uniformBufferGroups) { |
| 1928 | if (bufferGroup.dynamic) { |
| 1929 | // Bind uniforms into a part of a big dynamic memory block because |
| 1930 | // the group changes often |
| 1931 | const uniformBufferInfo = this._getDynamicUniformBufferFromPool(bufferGroup); |
| 1932 | if (currentShader._lastDynamicBuffer[bufferGroup.cacheKey] !== uniformBufferInfo) { |
| 1933 | currentShader._cachedBindGroup[bufferGroup.group] = undefined; |
| 1934 | currentShader._lastDynamicBuffer[bufferGroup.cacheKey] = uniformBufferInfo; |
| 1935 | } |
| 1936 | this._packUniformGroup(currentShader, bufferGroup.uniforms, uniformBufferInfo); |
| 1937 | uniformBufferInfo.lastOffset = uniformBufferInfo.offset; |
| 1938 | uniformBufferInfo.offset += Math.ceil(bufferGroup.size / this.uniformBufferAlignment) * this.uniformBufferAlignment; |
| 1939 | |
| 1940 | // Make a shallow copy so that we keep track of the last offset for this uniform |
| 1941 | bufferGroup.currentDynamicBuffer = uniformBufferInfo; |
| 1942 | bufferGroup.lastOffset = uniformBufferInfo.lastOffset; |
| 1943 | } else { |
| 1944 | // Bind uniforms to a binding-specific buffer, which may be cached for performance |
| 1945 | let bufferInfo; |
| 1946 | const dataChanged = this._hasGroupDataChanged(currentShader, bufferGroup); |
| 1947 | |
| 1948 | if (!dataChanged && bufferGroup.currentBuffer) { |
| 1949 | // Reuse the cached buffer - no need to pack or write |
| 1950 | bufferInfo = bufferGroup.currentBuffer; |
| 1951 | bufferGroup.buffersInUse.add(bufferInfo); |
| 1952 | } else { |
| 1953 | // Data changed - get a new buffer and write to it |
| 1954 | bufferInfo = this._getUniformBufferFromPool(bufferGroup); |
| 1955 | this._packUniformGroup(currentShader, bufferGroup.uniforms, bufferInfo); |
| 1956 | this.device.queue.writeBuffer( |
| 1957 | bufferInfo.buffer, |
| 1958 | 0, |
no test coverage detected