@luma.gl/engine 9.3.0-alpha.2 → 9.3.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dist.dev.js +752 -271
- package/dist/dist.min.js +182 -23
- package/dist/dynamic-texture/dynamic-texture.d.ts.map +1 -1
- package/dist/dynamic-texture/dynamic-texture.js +37 -4
- package/dist/dynamic-texture/dynamic-texture.js.map +1 -1
- package/dist/dynamic-texture/mipmaps.d.ts +6 -0
- package/dist/dynamic-texture/mipmaps.d.ts.map +1 -0
- package/dist/dynamic-texture/mipmaps.js +441 -0
- package/dist/dynamic-texture/mipmaps.js.map +1 -0
- package/dist/dynamic-texture/texture-data.js +1 -1
- package/dist/dynamic-texture/texture-data.js.map +1 -1
- package/dist/index.cjs +759 -295
- package/dist/index.cjs.map +4 -4
- package/dist/utils/buffer-layout-order.d.ts.map +1 -1
- package/dist/utils/buffer-layout-order.js +12 -2
- package/dist/utils/buffer-layout-order.js.map +1 -1
- package/package.json +4 -4
- package/src/dynamic-texture/dynamic-texture.ts +54 -6
- package/src/dynamic-texture/mipmaps.ts +517 -0
- package/src/dynamic-texture/texture-data.ts +1 -1
- package/src/utils/buffer-layout-order.ts +18 -2
package/dist/dist.dev.js
CHANGED
|
@@ -899,8 +899,8 @@ var __exports__ = (() => {
|
|
|
899
899
|
}
|
|
900
900
|
|
|
901
901
|
// src/model/model.ts
|
|
902
|
-
var
|
|
903
|
-
var
|
|
902
|
+
var import_core12 = __toESM(require_core(), 1);
|
|
903
|
+
var import_shadertools3 = __toESM(require_shadertools(), 1);
|
|
904
904
|
|
|
905
905
|
// src/geometry/gpu-geometry.ts
|
|
906
906
|
var import_core3 = __toESM(require_core(), 1);
|
|
@@ -1408,6 +1408,16 @@ var __exports__ = (() => {
|
|
|
1408
1408
|
};
|
|
1409
1409
|
|
|
1410
1410
|
// src/utils/buffer-layout-order.ts
|
|
1411
|
+
function getMinLocation(attributeNames, shaderLayoutMap) {
|
|
1412
|
+
let minLocation = Infinity;
|
|
1413
|
+
for (const name of attributeNames) {
|
|
1414
|
+
const location = shaderLayoutMap[name];
|
|
1415
|
+
if (location !== void 0) {
|
|
1416
|
+
minLocation = Math.min(minLocation, location);
|
|
1417
|
+
}
|
|
1418
|
+
}
|
|
1419
|
+
return minLocation;
|
|
1420
|
+
}
|
|
1411
1421
|
function sortedBufferLayoutByShaderSourceLocations(shaderLayout, bufferLayout) {
|
|
1412
1422
|
const shaderLayoutMap = Object.fromEntries(
|
|
1413
1423
|
shaderLayout.attributes.map((attr) => [attr.name, attr.location])
|
|
@@ -1416,8 +1426,8 @@ var __exports__ = (() => {
|
|
|
1416
1426
|
sortedLayout.sort((a, b) => {
|
|
1417
1427
|
const attributeNamesA = a.attributes ? a.attributes.map((attr) => attr.attribute) : [a.name];
|
|
1418
1428
|
const attributeNamesB = b.attributes ? b.attributes.map((attr) => attr.attribute) : [b.name];
|
|
1419
|
-
const minLocationA =
|
|
1420
|
-
const minLocationB =
|
|
1429
|
+
const minLocationA = getMinLocation(attributeNamesA, shaderLayoutMap);
|
|
1430
|
+
const minLocationB = getMinLocation(attributeNamesB, shaderLayoutMap);
|
|
1421
1431
|
return minLocationA - minLocationB;
|
|
1422
1432
|
});
|
|
1423
1433
|
return sortedLayout;
|
|
@@ -1564,7 +1574,7 @@ var __exports__ = (() => {
|
|
|
1564
1574
|
};
|
|
1565
1575
|
|
|
1566
1576
|
// src/dynamic-texture/dynamic-texture.ts
|
|
1567
|
-
var
|
|
1577
|
+
var import_core11 = __toESM(require_core(), 1);
|
|
1568
1578
|
|
|
1569
1579
|
// src/dynamic-texture/texture-data.ts
|
|
1570
1580
|
var import_core8 = __toESM(require_core(), 1);
|
|
@@ -1700,12 +1710,662 @@ var __exports__ = (() => {
|
|
|
1700
1710
|
data.forEach((cubeData, cubeIndex) => {
|
|
1701
1711
|
for (const [face, faceData] of Object.entries(cubeData)) {
|
|
1702
1712
|
const faceDepth = getCubeArrayFaceIndex(cubeIndex, face);
|
|
1703
|
-
getTexture2DSubresources(faceDepth, faceData);
|
|
1713
|
+
subresources.push(...getTexture2DSubresources(faceDepth, faceData));
|
|
1704
1714
|
}
|
|
1705
1715
|
});
|
|
1706
1716
|
return subresources;
|
|
1707
1717
|
}
|
|
1708
1718
|
|
|
1719
|
+
// src/dynamic-texture/mipmaps.ts
|
|
1720
|
+
var import_core10 = __toESM(require_core(), 1);
|
|
1721
|
+
|
|
1722
|
+
// src/compute/computation.ts
|
|
1723
|
+
var import_core9 = __toESM(require_core(), 1);
|
|
1724
|
+
var import_shadertools2 = __toESM(require_shadertools(), 1);
|
|
1725
|
+
var LOG_DRAW_PRIORITY = 2;
|
|
1726
|
+
var LOG_DRAW_TIMEOUT = 1e4;
|
|
1727
|
+
var _Computation = class {
|
|
1728
|
+
device;
|
|
1729
|
+
id;
|
|
1730
|
+
pipelineFactory;
|
|
1731
|
+
shaderFactory;
|
|
1732
|
+
userData = {};
|
|
1733
|
+
/** Bindings (textures, samplers, uniform buffers) */
|
|
1734
|
+
bindings = {};
|
|
1735
|
+
/** The underlying GPU pipeline. */
|
|
1736
|
+
pipeline;
|
|
1737
|
+
/** Assembled compute shader source */
|
|
1738
|
+
source;
|
|
1739
|
+
/** the underlying compiled compute shader */
|
|
1740
|
+
// @ts-ignore Set in function called from constructor
|
|
1741
|
+
shader;
|
|
1742
|
+
/** ShaderInputs instance */
|
|
1743
|
+
shaderInputs;
|
|
1744
|
+
// @ts-ignore Set in function called from constructor
|
|
1745
|
+
_uniformStore;
|
|
1746
|
+
_pipelineNeedsUpdate = "newly created";
|
|
1747
|
+
_getModuleUniforms;
|
|
1748
|
+
props;
|
|
1749
|
+
_destroyed = false;
|
|
1750
|
+
constructor(device, props) {
|
|
1751
|
+
if (device.type !== "webgpu") {
|
|
1752
|
+
throw new Error("Computation is only supported in WebGPU");
|
|
1753
|
+
}
|
|
1754
|
+
this.props = { ..._Computation.defaultProps, ...props };
|
|
1755
|
+
props = this.props;
|
|
1756
|
+
this.id = props.id || uid("model");
|
|
1757
|
+
this.device = device;
|
|
1758
|
+
Object.assign(this.userData, props.userData);
|
|
1759
|
+
const moduleMap = Object.fromEntries(
|
|
1760
|
+
this.props.modules?.map((module) => [module.name, module]) || []
|
|
1761
|
+
);
|
|
1762
|
+
this.shaderInputs = props.shaderInputs || new ShaderInputs(moduleMap);
|
|
1763
|
+
this.setShaderInputs(this.shaderInputs);
|
|
1764
|
+
this.props.shaderLayout ||= device.getShaderLayout(this.props.source);
|
|
1765
|
+
const platformInfo = getPlatformInfo(device);
|
|
1766
|
+
const modules = (this.props.modules?.length > 0 ? this.props.modules : this.shaderInputs?.getModules()) || [];
|
|
1767
|
+
this.pipelineFactory = props.pipelineFactory || PipelineFactory.getDefaultPipelineFactory(this.device);
|
|
1768
|
+
this.shaderFactory = props.shaderFactory || ShaderFactory.getDefaultShaderFactory(this.device);
|
|
1769
|
+
const { source: source3, getUniforms: getUniforms2 } = this.props.shaderAssembler.assembleWGSLShader({
|
|
1770
|
+
platformInfo,
|
|
1771
|
+
...this.props,
|
|
1772
|
+
modules
|
|
1773
|
+
});
|
|
1774
|
+
this.source = source3;
|
|
1775
|
+
this._getModuleUniforms = getUniforms2;
|
|
1776
|
+
this.pipeline = this._updatePipeline();
|
|
1777
|
+
if (props.bindings) {
|
|
1778
|
+
this.setBindings(props.bindings);
|
|
1779
|
+
}
|
|
1780
|
+
Object.seal(this);
|
|
1781
|
+
}
|
|
1782
|
+
destroy() {
|
|
1783
|
+
if (this._destroyed)
|
|
1784
|
+
return;
|
|
1785
|
+
this.pipelineFactory.release(this.pipeline);
|
|
1786
|
+
this.shaderFactory.release(this.shader);
|
|
1787
|
+
this._uniformStore.destroy();
|
|
1788
|
+
this._destroyed = true;
|
|
1789
|
+
}
|
|
1790
|
+
// Draw call
|
|
1791
|
+
predraw() {
|
|
1792
|
+
this.updateShaderInputs();
|
|
1793
|
+
}
|
|
1794
|
+
dispatch(computePass, x, y, z) {
|
|
1795
|
+
try {
|
|
1796
|
+
this._logDrawCallStart();
|
|
1797
|
+
this.pipeline = this._updatePipeline();
|
|
1798
|
+
this.pipeline.setBindings(this.bindings);
|
|
1799
|
+
computePass.setPipeline(this.pipeline);
|
|
1800
|
+
computePass.setBindings([]);
|
|
1801
|
+
computePass.dispatch(x, y, z);
|
|
1802
|
+
} finally {
|
|
1803
|
+
this._logDrawCallEnd();
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1806
|
+
// Update fixed fields (can trigger pipeline rebuild)
|
|
1807
|
+
// Update dynamic fields
|
|
1808
|
+
/**
|
|
1809
|
+
* Updates the vertex count (used in draw calls)
|
|
1810
|
+
* @note Any attributes with stepMode=vertex need to be at least this big
|
|
1811
|
+
*/
|
|
1812
|
+
setVertexCount(vertexCount) {
|
|
1813
|
+
}
|
|
1814
|
+
/**
|
|
1815
|
+
* Updates the instance count (used in draw calls)
|
|
1816
|
+
* @note Any attributes with stepMode=instance need to be at least this big
|
|
1817
|
+
*/
|
|
1818
|
+
setInstanceCount(instanceCount) {
|
|
1819
|
+
}
|
|
1820
|
+
setShaderInputs(shaderInputs) {
|
|
1821
|
+
this.shaderInputs = shaderInputs;
|
|
1822
|
+
this._uniformStore = new import_core9.UniformStore(this.shaderInputs.modules);
|
|
1823
|
+
for (const moduleName of Object.keys(this.shaderInputs.modules)) {
|
|
1824
|
+
const uniformBuffer = this._uniformStore.getManagedUniformBuffer(this.device, moduleName);
|
|
1825
|
+
this.bindings[`${moduleName}Uniforms`] = uniformBuffer;
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
/**
|
|
1829
|
+
* Updates shader module settings (which results in uniforms being set)
|
|
1830
|
+
*/
|
|
1831
|
+
setShaderModuleProps(props) {
|
|
1832
|
+
const uniforms = this._getModuleUniforms(props);
|
|
1833
|
+
const keys = Object.keys(uniforms).filter((k) => {
|
|
1834
|
+
const uniform = uniforms[k];
|
|
1835
|
+
return !isNumericArray(uniform) && typeof uniform !== "number" && typeof uniform !== "boolean";
|
|
1836
|
+
});
|
|
1837
|
+
const bindings = {};
|
|
1838
|
+
for (const k of keys) {
|
|
1839
|
+
bindings[k] = uniforms[k];
|
|
1840
|
+
delete uniforms[k];
|
|
1841
|
+
}
|
|
1842
|
+
}
|
|
1843
|
+
updateShaderInputs() {
|
|
1844
|
+
this._uniformStore.setUniforms(this.shaderInputs.getUniformValues());
|
|
1845
|
+
}
|
|
1846
|
+
/**
|
|
1847
|
+
* Sets bindings (textures, samplers, uniform buffers)
|
|
1848
|
+
*/
|
|
1849
|
+
setBindings(bindings) {
|
|
1850
|
+
Object.assign(this.bindings, bindings);
|
|
1851
|
+
}
|
|
1852
|
+
_setPipelineNeedsUpdate(reason) {
|
|
1853
|
+
this._pipelineNeedsUpdate = this._pipelineNeedsUpdate || reason;
|
|
1854
|
+
}
|
|
1855
|
+
_updatePipeline() {
|
|
1856
|
+
if (this._pipelineNeedsUpdate) {
|
|
1857
|
+
let prevShader = null;
|
|
1858
|
+
if (this.pipeline) {
|
|
1859
|
+
import_core9.log.log(
|
|
1860
|
+
1,
|
|
1861
|
+
`Model ${this.id}: Recreating pipeline because "${this._pipelineNeedsUpdate}".`
|
|
1862
|
+
)();
|
|
1863
|
+
prevShader = this.shader;
|
|
1864
|
+
}
|
|
1865
|
+
this._pipelineNeedsUpdate = false;
|
|
1866
|
+
this.shader = this.shaderFactory.createShader({
|
|
1867
|
+
id: `${this.id}-fragment`,
|
|
1868
|
+
stage: "compute",
|
|
1869
|
+
source: this.source,
|
|
1870
|
+
debugShaders: this.props.debugShaders
|
|
1871
|
+
});
|
|
1872
|
+
this.pipeline = this.pipelineFactory.createComputePipeline({
|
|
1873
|
+
...this.props,
|
|
1874
|
+
shader: this.shader
|
|
1875
|
+
});
|
|
1876
|
+
if (prevShader) {
|
|
1877
|
+
this.shaderFactory.release(prevShader);
|
|
1878
|
+
}
|
|
1879
|
+
}
|
|
1880
|
+
return this.pipeline;
|
|
1881
|
+
}
|
|
1882
|
+
/** Throttle draw call logging */
|
|
1883
|
+
_lastLogTime = 0;
|
|
1884
|
+
_logOpen = false;
|
|
1885
|
+
_logDrawCallStart() {
|
|
1886
|
+
const logDrawTimeout = import_core9.log.level > 3 ? 0 : LOG_DRAW_TIMEOUT;
|
|
1887
|
+
if (import_core9.log.level < 2 || Date.now() - this._lastLogTime < logDrawTimeout) {
|
|
1888
|
+
return;
|
|
1889
|
+
}
|
|
1890
|
+
this._lastLogTime = Date.now();
|
|
1891
|
+
this._logOpen = true;
|
|
1892
|
+
import_core9.log.group(LOG_DRAW_PRIORITY, `>>> DRAWING MODEL ${this.id}`, { collapsed: import_core9.log.level <= 2 })();
|
|
1893
|
+
}
|
|
1894
|
+
_logDrawCallEnd() {
|
|
1895
|
+
if (this._logOpen) {
|
|
1896
|
+
const uniformTable = this.shaderInputs.getDebugTable();
|
|
1897
|
+
import_core9.log.table(LOG_DRAW_PRIORITY, uniformTable)();
|
|
1898
|
+
import_core9.log.groupEnd(LOG_DRAW_PRIORITY)();
|
|
1899
|
+
this._logOpen = false;
|
|
1900
|
+
}
|
|
1901
|
+
}
|
|
1902
|
+
_drawCount = 0;
|
|
1903
|
+
// TODO - fix typing of luma data types
|
|
1904
|
+
_getBufferOrConstantValues(attribute, dataType) {
|
|
1905
|
+
const TypedArrayConstructor = (0, import_core9.getTypedArrayConstructor)(dataType);
|
|
1906
|
+
const typedArray = attribute instanceof import_core9.Buffer ? new TypedArrayConstructor(attribute.debugData) : attribute;
|
|
1907
|
+
return typedArray.toString();
|
|
1908
|
+
}
|
|
1909
|
+
};
|
|
1910
|
+
var Computation = _Computation;
|
|
1911
|
+
__publicField(Computation, "defaultProps", {
|
|
1912
|
+
...import_core9.ComputePipeline.defaultProps,
|
|
1913
|
+
id: "unnamed",
|
|
1914
|
+
handle: void 0,
|
|
1915
|
+
userData: {},
|
|
1916
|
+
source: "",
|
|
1917
|
+
modules: [],
|
|
1918
|
+
defines: {},
|
|
1919
|
+
bindings: void 0,
|
|
1920
|
+
shaderInputs: void 0,
|
|
1921
|
+
pipelineFactory: void 0,
|
|
1922
|
+
shaderFactory: void 0,
|
|
1923
|
+
shaderAssembler: import_shadertools2.ShaderAssembler.getDefaultShaderAssembler(),
|
|
1924
|
+
debugShaders: void 0
|
|
1925
|
+
});
|
|
1926
|
+
function getPlatformInfo(device) {
|
|
1927
|
+
return {
|
|
1928
|
+
type: device.type,
|
|
1929
|
+
shaderLanguage: device.info.shadingLanguage,
|
|
1930
|
+
shaderLanguageVersion: device.info.shadingLanguageVersion,
|
|
1931
|
+
gpu: device.info.gpu,
|
|
1932
|
+
// HACK - we pretend that the DeviceFeatures is a Set, it has a similar API
|
|
1933
|
+
features: device.features
|
|
1934
|
+
};
|
|
1935
|
+
}
|
|
1936
|
+
|
|
1937
|
+
// src/dynamic-texture/mipmaps.ts
|
|
1938
|
+
var RENDER_DIMENSIONS = [
|
|
1939
|
+
"2d",
|
|
1940
|
+
"2d-array",
|
|
1941
|
+
"cube",
|
|
1942
|
+
"cube-array"
|
|
1943
|
+
];
|
|
1944
|
+
var WORKGROUP_SIZE = {
|
|
1945
|
+
x: 4,
|
|
1946
|
+
y: 4,
|
|
1947
|
+
z: 4
|
|
1948
|
+
};
|
|
1949
|
+
function generateMipmap(device, texture) {
|
|
1950
|
+
if (texture.mipLevels <= 1) {
|
|
1951
|
+
return;
|
|
1952
|
+
}
|
|
1953
|
+
if (device.type !== "webgpu") {
|
|
1954
|
+
throw new Error(
|
|
1955
|
+
`Cannot generate mipmaps on device type "${device.type}". Use generateMipmapsWebGL for WebGL devices.`
|
|
1956
|
+
);
|
|
1957
|
+
}
|
|
1958
|
+
if (texture.dimension === "3d") {
|
|
1959
|
+
generateMipmaps3D(device, texture);
|
|
1960
|
+
return;
|
|
1961
|
+
}
|
|
1962
|
+
if (RENDER_DIMENSIONS.includes(texture.dimension)) {
|
|
1963
|
+
generateMipmapsRender(device, texture);
|
|
1964
|
+
return;
|
|
1965
|
+
}
|
|
1966
|
+
throw new Error(
|
|
1967
|
+
`Cannot generate mipmaps for texture dimension "${texture.dimension}" with WebGPU.`
|
|
1968
|
+
);
|
|
1969
|
+
}
|
|
1970
|
+
function generateMipmapsRender(device, texture) {
|
|
1971
|
+
validateFormatCapabilities(device, texture, ["render", "filter"], "render");
|
|
1972
|
+
const colorAttachmentFormat = getColorAttachmentFormat(
|
|
1973
|
+
texture.format,
|
|
1974
|
+
"render",
|
|
1975
|
+
texture.dimension
|
|
1976
|
+
);
|
|
1977
|
+
const viewDimension = texture.dimension;
|
|
1978
|
+
const shader = getRenderMipmapWGSL(viewDimension);
|
|
1979
|
+
const sampler = device.createSampler({ minFilter: "linear", magFilter: "linear" });
|
|
1980
|
+
const uniformValues = new Uint32Array(1);
|
|
1981
|
+
const uniformsBuffer = device.createBuffer({
|
|
1982
|
+
byteLength: 16,
|
|
1983
|
+
usage: import_core10.Buffer.UNIFORM | import_core10.Buffer.COPY_DST
|
|
1984
|
+
});
|
|
1985
|
+
const model = new Model(device, {
|
|
1986
|
+
source: shader,
|
|
1987
|
+
colorAttachmentFormats: [colorAttachmentFormat],
|
|
1988
|
+
topology: "triangle-list",
|
|
1989
|
+
vertexCount: 3,
|
|
1990
|
+
shaderLayout: {
|
|
1991
|
+
attributes: [],
|
|
1992
|
+
bindings: [
|
|
1993
|
+
{ type: "sampler", name: "sourceSampler", group: 0, location: 0 },
|
|
1994
|
+
{
|
|
1995
|
+
type: "texture",
|
|
1996
|
+
name: "sourceTexture",
|
|
1997
|
+
group: 0,
|
|
1998
|
+
location: 1,
|
|
1999
|
+
viewDimension,
|
|
2000
|
+
sampleType: "float"
|
|
2001
|
+
},
|
|
2002
|
+
{ type: "uniform", name: "uniforms", group: 0, location: 2 }
|
|
2003
|
+
]
|
|
2004
|
+
},
|
|
2005
|
+
bindings: {
|
|
2006
|
+
sourceSampler: sampler,
|
|
2007
|
+
sourceTexture: texture,
|
|
2008
|
+
uniforms: uniformsBuffer
|
|
2009
|
+
}
|
|
2010
|
+
});
|
|
2011
|
+
let sourceWidth = texture.width;
|
|
2012
|
+
let sourceHeight = texture.height;
|
|
2013
|
+
const layerCount = texture.dimension === "2d" ? 1 : texture.depth;
|
|
2014
|
+
try {
|
|
2015
|
+
for (let baseMipLevel = 1; baseMipLevel < texture.mipLevels; ++baseMipLevel) {
|
|
2016
|
+
validateFormatCapabilities(device, texture, ["render", "filter"], "render");
|
|
2017
|
+
const sourceMipLevel = baseMipLevel - 1;
|
|
2018
|
+
const destinationWidth = Math.max(1, sourceWidth >> 1);
|
|
2019
|
+
const destinationHeight = Math.max(1, sourceHeight >> 1);
|
|
2020
|
+
const sourceView = texture.createView({
|
|
2021
|
+
dimension: viewDimension,
|
|
2022
|
+
baseMipLevel: sourceMipLevel,
|
|
2023
|
+
mipLevelCount: 1,
|
|
2024
|
+
baseArrayLayer: 0,
|
|
2025
|
+
arrayLayerCount: texture.depth
|
|
2026
|
+
});
|
|
2027
|
+
model.setBindings({ sourceTexture: sourceView });
|
|
2028
|
+
for (let baseArrayLayer = 0; baseArrayLayer < layerCount; ++baseArrayLayer) {
|
|
2029
|
+
uniformValues[0] = baseArrayLayer;
|
|
2030
|
+
uniformsBuffer.write(uniformValues);
|
|
2031
|
+
const destinationView = texture.createView({
|
|
2032
|
+
dimension: "2d",
|
|
2033
|
+
baseMipLevel,
|
|
2034
|
+
mipLevelCount: 1,
|
|
2035
|
+
baseArrayLayer,
|
|
2036
|
+
arrayLayerCount: 1
|
|
2037
|
+
});
|
|
2038
|
+
const framebuffer = device.createFramebuffer({
|
|
2039
|
+
colorAttachments: [destinationView]
|
|
2040
|
+
});
|
|
2041
|
+
const renderPass = device.beginRenderPass({
|
|
2042
|
+
id: `mipmap-generation:${texture.format}:${baseMipLevel}:${baseArrayLayer}`,
|
|
2043
|
+
framebuffer
|
|
2044
|
+
});
|
|
2045
|
+
renderPass.setParameters({
|
|
2046
|
+
viewport: [0, 0, destinationWidth, destinationHeight, 0, 1],
|
|
2047
|
+
scissorRect: [0, 0, destinationWidth, destinationHeight]
|
|
2048
|
+
});
|
|
2049
|
+
model.draw(renderPass);
|
|
2050
|
+
renderPass.end();
|
|
2051
|
+
device.submit();
|
|
2052
|
+
destinationView.destroy();
|
|
2053
|
+
framebuffer.destroy();
|
|
2054
|
+
}
|
|
2055
|
+
sourceView.destroy();
|
|
2056
|
+
sourceWidth = destinationWidth;
|
|
2057
|
+
sourceHeight = destinationHeight;
|
|
2058
|
+
}
|
|
2059
|
+
} finally {
|
|
2060
|
+
model.destroy();
|
|
2061
|
+
sampler.destroy();
|
|
2062
|
+
uniformsBuffer.destroy();
|
|
2063
|
+
}
|
|
2064
|
+
}
|
|
2065
|
+
function getColorAttachmentFormat(format, path, dimension) {
|
|
2066
|
+
if (import_core10.textureFormatDecoder.isColor(format)) {
|
|
2067
|
+
return format;
|
|
2068
|
+
}
|
|
2069
|
+
throw new Error(
|
|
2070
|
+
`Cannot run ${path} mipmap generation for ${dimension} texture with format "${format}". Only color textures can be used for this operation. Required capabilities: color. Actual capabilities: color=false.`
|
|
2071
|
+
);
|
|
2072
|
+
}
|
|
2073
|
+
function generateMipmaps3D(device, texture) {
|
|
2074
|
+
validateFormatCapabilities(device, texture, ["filter", "store"], "compute");
|
|
2075
|
+
const format = getColorAttachmentFormat(texture.format, "compute", texture.dimension);
|
|
2076
|
+
const shaderSource = get3DComputeMipmapWGSL(format);
|
|
2077
|
+
const uniformsBuffer = device.createBuffer({
|
|
2078
|
+
byteLength: 32,
|
|
2079
|
+
usage: import_core10.Buffer.UNIFORM | import_core10.Buffer.COPY_DST
|
|
2080
|
+
});
|
|
2081
|
+
const uniformValues = new Uint32Array(8);
|
|
2082
|
+
let sourceWidth = texture.width;
|
|
2083
|
+
let sourceHeight = texture.height;
|
|
2084
|
+
let sourceDepth = texture.depth;
|
|
2085
|
+
try {
|
|
2086
|
+
for (let destinationMipLevel = 1; destinationMipLevel < texture.mipLevels; ++destinationMipLevel) {
|
|
2087
|
+
validateFormatCapabilities(device, texture, ["filter", "store"], "compute");
|
|
2088
|
+
const destinationWidth = Math.max(1, sourceWidth >> 1);
|
|
2089
|
+
const destinationHeight = Math.max(1, sourceHeight >> 1);
|
|
2090
|
+
const destinationDepth = Math.max(1, sourceDepth >> 1);
|
|
2091
|
+
uniformValues[0] = sourceWidth;
|
|
2092
|
+
uniformValues[1] = sourceHeight;
|
|
2093
|
+
uniformValues[2] = sourceDepth;
|
|
2094
|
+
uniformValues[3] = destinationWidth;
|
|
2095
|
+
uniformValues[4] = destinationHeight;
|
|
2096
|
+
uniformValues[5] = destinationDepth;
|
|
2097
|
+
uniformValues[6] = 0;
|
|
2098
|
+
uniformsBuffer.write(uniformValues);
|
|
2099
|
+
const sourceView = texture.createView({
|
|
2100
|
+
dimension: "3d",
|
|
2101
|
+
baseMipLevel: destinationMipLevel - 1,
|
|
2102
|
+
mipLevelCount: 1,
|
|
2103
|
+
baseArrayLayer: 0,
|
|
2104
|
+
arrayLayerCount: 1
|
|
2105
|
+
});
|
|
2106
|
+
const destinationView = texture.createView({
|
|
2107
|
+
dimension: "3d",
|
|
2108
|
+
baseMipLevel: destinationMipLevel,
|
|
2109
|
+
mipLevelCount: 1,
|
|
2110
|
+
baseArrayLayer: 0,
|
|
2111
|
+
arrayLayerCount: 1
|
|
2112
|
+
});
|
|
2113
|
+
const computation = new Computation(device, {
|
|
2114
|
+
source: shaderSource,
|
|
2115
|
+
shaderLayout: {
|
|
2116
|
+
bindings: [
|
|
2117
|
+
{
|
|
2118
|
+
type: "texture",
|
|
2119
|
+
name: "sourceTexture",
|
|
2120
|
+
group: 0,
|
|
2121
|
+
location: 0,
|
|
2122
|
+
viewDimension: "3d",
|
|
2123
|
+
sampleType: "float"
|
|
2124
|
+
},
|
|
2125
|
+
{
|
|
2126
|
+
type: "storage",
|
|
2127
|
+
name: "destinationTexture",
|
|
2128
|
+
group: 0,
|
|
2129
|
+
location: 1,
|
|
2130
|
+
format,
|
|
2131
|
+
viewDimension: "3d",
|
|
2132
|
+
access: "write-only"
|
|
2133
|
+
},
|
|
2134
|
+
{ type: "uniform", name: "uniforms", group: 0, location: 2 }
|
|
2135
|
+
]
|
|
2136
|
+
},
|
|
2137
|
+
bindings: {
|
|
2138
|
+
sourceTexture: sourceView,
|
|
2139
|
+
destinationTexture: destinationView,
|
|
2140
|
+
uniforms: uniformsBuffer
|
|
2141
|
+
}
|
|
2142
|
+
});
|
|
2143
|
+
const workgroupsX = Math.ceil(destinationWidth / WORKGROUP_SIZE.x);
|
|
2144
|
+
const workgroupsY = Math.ceil(destinationHeight / WORKGROUP_SIZE.y);
|
|
2145
|
+
const workgroupsZ = Math.ceil(destinationDepth / WORKGROUP_SIZE.z);
|
|
2146
|
+
const computePass = device.beginComputePass({});
|
|
2147
|
+
computation.dispatch(computePass, workgroupsX, workgroupsY, workgroupsZ);
|
|
2148
|
+
computePass.end();
|
|
2149
|
+
device.submit();
|
|
2150
|
+
computation.destroy();
|
|
2151
|
+
sourceView.destroy();
|
|
2152
|
+
destinationView.destroy();
|
|
2153
|
+
sourceWidth = destinationWidth;
|
|
2154
|
+
sourceHeight = destinationHeight;
|
|
2155
|
+
sourceDepth = destinationDepth;
|
|
2156
|
+
}
|
|
2157
|
+
} finally {
|
|
2158
|
+
uniformsBuffer.destroy();
|
|
2159
|
+
}
|
|
2160
|
+
}
|
|
2161
|
+
function validateFormatCapabilities(device, texture, requiredCapabilities, path) {
|
|
2162
|
+
const { format, dimension } = texture;
|
|
2163
|
+
const capabilities = device.getTextureFormatCapabilities(format);
|
|
2164
|
+
const missingCapabilities = requiredCapabilities.filter((capability) => !capabilities[capability]);
|
|
2165
|
+
if (missingCapabilities.length > 0) {
|
|
2166
|
+
const required = requiredCapabilities.join(" + ");
|
|
2167
|
+
const actual = requiredCapabilities.map((capability) => `${capability}=${capabilities[capability]}`).join(", ");
|
|
2168
|
+
throw new Error(
|
|
2169
|
+
`Cannot run ${path} mipmap generation for ${dimension} texture with format "${format}". Required capabilities: ${required}. Actual capabilities: ${actual}.`
|
|
2170
|
+
);
|
|
2171
|
+
}
|
|
2172
|
+
}
|
|
2173
|
+
function getSourceTextureType(dimension) {
|
|
2174
|
+
switch (dimension) {
|
|
2175
|
+
case "2d":
|
|
2176
|
+
return "texture_2d<f32>";
|
|
2177
|
+
case "2d-array":
|
|
2178
|
+
return "texture_2d_array<f32>";
|
|
2179
|
+
case "cube":
|
|
2180
|
+
return "texture_cube<f32>";
|
|
2181
|
+
case "cube-array":
|
|
2182
|
+
return "texture_cube_array<f32>";
|
|
2183
|
+
default:
|
|
2184
|
+
throw new Error(`Unsupported render dimension "${dimension}" for mipmap generation.`);
|
|
2185
|
+
}
|
|
2186
|
+
}
|
|
2187
|
+
function getRenderMipmapWGSL(dimension) {
|
|
2188
|
+
const sourceSnippet = getRenderMipmapSampleSnippet(dimension);
|
|
2189
|
+
return `
|
|
2190
|
+
struct MipmapUniforms {
|
|
2191
|
+
sourceLayer: u32,
|
|
2192
|
+
};
|
|
2193
|
+
|
|
2194
|
+
fn _touchUniform(uniforms: MipmapUniforms) {
|
|
2195
|
+
let unusedSourceLayer = uniforms.sourceLayer;
|
|
2196
|
+
}
|
|
2197
|
+
|
|
2198
|
+
const faceMat = array(
|
|
2199
|
+
mat3x3f(
|
|
2200
|
+
0.0, 0.0, -2.0,
|
|
2201
|
+
0.0, -2.0, 0.0,
|
|
2202
|
+
1.0, 1.0, 1.0
|
|
2203
|
+
), // pos-x
|
|
2204
|
+
mat3x3f(
|
|
2205
|
+
0.0, 0.0, 2.0,
|
|
2206
|
+
0.0, -2.0, 0.0,
|
|
2207
|
+
-1.0, 1.0, -1.0
|
|
2208
|
+
), // neg-x
|
|
2209
|
+
mat3x3f(
|
|
2210
|
+
2.0, 0.0, 0.0,
|
|
2211
|
+
0.0, 0.0, 2.0,
|
|
2212
|
+
-1.0, 1.0, -1.0
|
|
2213
|
+
), // pos-y
|
|
2214
|
+
mat3x3f(
|
|
2215
|
+
2.0, 0.0, 0.0,
|
|
2216
|
+
0.0, 0.0, -2.0,
|
|
2217
|
+
-1.0, -1.0, 1.0
|
|
2218
|
+
), // neg-y
|
|
2219
|
+
mat3x3f(
|
|
2220
|
+
2.0, 0.0, 0.0,
|
|
2221
|
+
0.0, -2.0, 0.0,
|
|
2222
|
+
-1.0, 1.0, 1.0
|
|
2223
|
+
), // pos-z
|
|
2224
|
+
mat3x3f(
|
|
2225
|
+
-2.0, 0.0, 0.0,
|
|
2226
|
+
0.0, -2.0, 0.0,
|
|
2227
|
+
1.0, 1.0, -1.0
|
|
2228
|
+
) // neg-z
|
|
2229
|
+
);
|
|
2230
|
+
|
|
2231
|
+
struct FragmentInputs {
|
|
2232
|
+
@builtin(position) position: vec4f,
|
|
2233
|
+
@location(0) texcoord: vec2f
|
|
2234
|
+
};
|
|
2235
|
+
|
|
2236
|
+
struct VertexOutput {
|
|
2237
|
+
@builtin(position) position: vec4f,
|
|
2238
|
+
@location(0) texcoord: vec2f
|
|
2239
|
+
};
|
|
2240
|
+
|
|
2241
|
+
@group(0) @binding(0) var sourceSampler: sampler;
|
|
2242
|
+
@group(0) @binding(1) var sourceTexture: ${getSourceTextureType(dimension)};
|
|
2243
|
+
@group(0) @binding(2) var<uniform> uniforms: MipmapUniforms;
|
|
2244
|
+
|
|
2245
|
+
@vertex
|
|
2246
|
+
fn vertexMain(
|
|
2247
|
+
@builtin(vertex_index) vertexIndex: u32
|
|
2248
|
+
) -> VertexOutput {
|
|
2249
|
+
const positions = array(
|
|
2250
|
+
vec2f(-1.0, -1.0),
|
|
2251
|
+
vec2f(-1.0, 3.0),
|
|
2252
|
+
vec2f( 3.0, -1.0)
|
|
2253
|
+
);
|
|
2254
|
+
|
|
2255
|
+
let xy = positions[vertexIndex];
|
|
2256
|
+
return VertexOutput(
|
|
2257
|
+
vec4f(xy, 0.0, 1.0),
|
|
2258
|
+
xy * vec2f(0.5, -0.5) + vec2f(0.5)
|
|
2259
|
+
);
|
|
2260
|
+
}
|
|
2261
|
+
|
|
2262
|
+
@fragment
|
|
2263
|
+
fn fragmentMain(fsInput: VertexOutput) -> @location(0) vec4f {
|
|
2264
|
+
_touchUniform(uniforms);
|
|
2265
|
+
return ${sourceSnippet};
|
|
2266
|
+
}
|
|
2267
|
+
`;
|
|
2268
|
+
}
|
|
2269
|
+
function getRenderMipmapSampleSnippet(dimension) {
|
|
2270
|
+
const layer = "uniforms.sourceLayer";
|
|
2271
|
+
switch (dimension) {
|
|
2272
|
+
case "2d":
|
|
2273
|
+
return "textureSampleLevel(sourceTexture, sourceSampler, fsInput.texcoord, 0.0)";
|
|
2274
|
+
case "2d-array":
|
|
2275
|
+
return `textureSampleLevel(sourceTexture, sourceSampler, fsInput.texcoord, i32(${layer}), 0.0)`;
|
|
2276
|
+
case "cube":
|
|
2277
|
+
return `textureSampleLevel(sourceTexture, sourceSampler, faceMat[i32(${layer})] * vec3f(fract(fsInput.texcoord), 1.0), 0.0)`;
|
|
2278
|
+
case "cube-array":
|
|
2279
|
+
return `textureSampleLevel(sourceTexture, sourceSampler, faceMat[i32(${layer} % 6u)] * vec3f(fract(fsInput.texcoord), 1.0), i32(${layer} / 6u), 0.0)`;
|
|
2280
|
+
default:
|
|
2281
|
+
throw new Error(`Unsupported render dimension "${dimension}" for mipmap generation.`);
|
|
2282
|
+
}
|
|
2283
|
+
}
|
|
2284
|
+
function get3DComputeMipmapWGSL(format) {
|
|
2285
|
+
return `
|
|
2286
|
+
struct MipmapUniforms {
|
|
2287
|
+
sourceWidth: u32,
|
|
2288
|
+
sourceHeight: u32,
|
|
2289
|
+
sourceDepth: u32,
|
|
2290
|
+
destinationWidth: u32,
|
|
2291
|
+
destinationHeight: u32,
|
|
2292
|
+
destinationDepth: u32,
|
|
2293
|
+
padding: u32,
|
|
2294
|
+
};
|
|
2295
|
+
|
|
2296
|
+
@group(0) @binding(0) var sourceTexture: texture_3d<f32>;
|
|
2297
|
+
@group(0) @binding(1) var destinationTexture: texture_storage_3d<${format}, write>;
|
|
2298
|
+
@group(0) @binding(2) var<uniform> uniforms: MipmapUniforms;
|
|
2299
|
+
|
|
2300
|
+
@compute @workgroup_size(${WORKGROUP_SIZE.x}, ${WORKGROUP_SIZE.y}, ${WORKGROUP_SIZE.z})
|
|
2301
|
+
fn main(@builtin(global_invocation_id) id: vec3<u32>) {
|
|
2302
|
+
if (
|
|
2303
|
+
id.x >= uniforms.destinationWidth ||
|
|
2304
|
+
id.y >= uniforms.destinationHeight ||
|
|
2305
|
+
id.z >= uniforms.destinationDepth
|
|
2306
|
+
) {
|
|
2307
|
+
return;
|
|
2308
|
+
}
|
|
2309
|
+
|
|
2310
|
+
let sourceBase = id * 2u;
|
|
2311
|
+
let sourceX0 = min(sourceBase.x, uniforms.sourceWidth - 1u);
|
|
2312
|
+
let sourceY0 = min(sourceBase.y, uniforms.sourceHeight - 1u);
|
|
2313
|
+
let sourceZ0 = min(sourceBase.z, uniforms.sourceDepth - 1u);
|
|
2314
|
+
|
|
2315
|
+
let sourceX1 = min(sourceBase.x + 1u, uniforms.sourceWidth - 1u);
|
|
2316
|
+
let sourceY1 = min(sourceBase.y + 1u, uniforms.sourceHeight - 1u);
|
|
2317
|
+
let sourceZ1 = min(sourceBase.z + 1u, uniforms.sourceDepth - 1u);
|
|
2318
|
+
|
|
2319
|
+
var sum = textureLoad(
|
|
2320
|
+
sourceTexture,
|
|
2321
|
+
vec3<i32>(i32(sourceX0), i32(sourceY0), i32(sourceZ0)),
|
|
2322
|
+
0
|
|
2323
|
+
);
|
|
2324
|
+
sum += textureLoad(
|
|
2325
|
+
sourceTexture,
|
|
2326
|
+
vec3<i32>(i32(sourceX1), i32(sourceY0), i32(sourceZ0)),
|
|
2327
|
+
0
|
|
2328
|
+
);
|
|
2329
|
+
sum += textureLoad(
|
|
2330
|
+
sourceTexture,
|
|
2331
|
+
vec3<i32>(i32(sourceX0), i32(sourceY1), i32(sourceZ0)),
|
|
2332
|
+
0
|
|
2333
|
+
);
|
|
2334
|
+
sum += textureLoad(
|
|
2335
|
+
sourceTexture,
|
|
2336
|
+
vec3<i32>(i32(sourceX1), i32(sourceY1), i32(sourceZ0)),
|
|
2337
|
+
0
|
|
2338
|
+
);
|
|
2339
|
+
sum += textureLoad(
|
|
2340
|
+
sourceTexture,
|
|
2341
|
+
vec3<i32>(i32(sourceX0), i32(sourceY0), i32(sourceZ1)),
|
|
2342
|
+
0
|
|
2343
|
+
);
|
|
2344
|
+
sum += textureLoad(
|
|
2345
|
+
sourceTexture,
|
|
2346
|
+
vec3<i32>(i32(sourceX1), i32(sourceY0), i32(sourceZ1)),
|
|
2347
|
+
0
|
|
2348
|
+
);
|
|
2349
|
+
sum += textureLoad(
|
|
2350
|
+
sourceTexture,
|
|
2351
|
+
vec3<i32>(i32(sourceX0), i32(sourceY1), i32(sourceZ1)),
|
|
2352
|
+
0
|
|
2353
|
+
);
|
|
2354
|
+
sum += textureLoad(
|
|
2355
|
+
sourceTexture,
|
|
2356
|
+
vec3<i32>(i32(sourceX1), i32(sourceY1), i32(sourceZ1)),
|
|
2357
|
+
0
|
|
2358
|
+
);
|
|
2359
|
+
|
|
2360
|
+
textureStore(
|
|
2361
|
+
destinationTexture,
|
|
2362
|
+
vec3<i32>(i32(id.x), i32(id.y), i32(id.z)),
|
|
2363
|
+
vec4<f32>(sum.xyz / 8.0, sum.w / 8.0)
|
|
2364
|
+
);
|
|
2365
|
+
}
|
|
2366
|
+
`;
|
|
2367
|
+
}
|
|
2368
|
+
|
|
1709
2369
|
// src/dynamic-texture/dynamic-texture.ts
|
|
1710
2370
|
var _DynamicTexture = class {
|
|
1711
2371
|
device;
|
|
@@ -1783,6 +2443,10 @@ var __exports__ = (() => {
|
|
|
1783
2443
|
// temporary; updated below
|
|
1784
2444
|
data: void 0
|
|
1785
2445
|
};
|
|
2446
|
+
if (this.device.type === "webgpu" && this.props.mipmaps) {
|
|
2447
|
+
const requiredUsage = this.props.dimension === "3d" ? import_core11.Texture.SAMPLE | import_core11.Texture.STORAGE | import_core11.Texture.COPY_DST | import_core11.Texture.COPY_SRC : import_core11.Texture.SAMPLE | import_core11.Texture.RENDER | import_core11.Texture.COPY_DST | import_core11.Texture.COPY_SRC;
|
|
2448
|
+
baseTextureProps.usage |= requiredUsage;
|
|
2449
|
+
}
|
|
1786
2450
|
const maxMips = this.device.getMipLevelCount(baseTextureProps.width, baseTextureProps.height);
|
|
1787
2451
|
const desired = this.props.mipLevels === "auto" ? maxMips : Math.max(1, Math.min(maxMips, this.props.mipLevels ?? 1));
|
|
1788
2452
|
const finalTextureProps = { ...baseTextureProps, mipLevels: desired };
|
|
@@ -1819,7 +2483,7 @@ var __exports__ = (() => {
|
|
|
1819
2483
|
}
|
|
1820
2484
|
this.isReady = true;
|
|
1821
2485
|
this.resolveReady(this.texture);
|
|
1822
|
-
|
|
2486
|
+
import_core11.log.info(0, `${this} created`)();
|
|
1823
2487
|
} catch (e) {
|
|
1824
2488
|
const err = e instanceof Error ? e : new Error(String(e));
|
|
1825
2489
|
this.rejectReady(err);
|
|
@@ -1838,16 +2502,16 @@ var __exports__ = (() => {
|
|
|
1838
2502
|
generateMipmaps() {
|
|
1839
2503
|
if (this.device.type === "webgl") {
|
|
1840
2504
|
this.texture.generateMipmapsWebGL();
|
|
2505
|
+
} else if (this.device.type === "webgpu") {
|
|
2506
|
+
generateMipmap(this.device, this.texture);
|
|
1841
2507
|
} else {
|
|
1842
|
-
|
|
1843
|
-
"Mipmap generation not yet implemented on WebGPU: your texture data will not be correctly initialized"
|
|
1844
|
-
);
|
|
2508
|
+
import_core11.log.warn(`${this} mipmaps not supported on ${this.device.type}`);
|
|
1845
2509
|
}
|
|
1846
2510
|
}
|
|
1847
2511
|
/** Set sampler or create one from props */
|
|
1848
2512
|
setSampler(sampler = {}) {
|
|
1849
2513
|
this._checkReady();
|
|
1850
|
-
const s = sampler instanceof
|
|
2514
|
+
const s = sampler instanceof import_core11.Sampler ? sampler : this.device.createSampler(sampler);
|
|
1851
2515
|
this.texture.setSampler(s);
|
|
1852
2516
|
this._sampler = s;
|
|
1853
2517
|
}
|
|
@@ -1865,7 +2529,7 @@ var __exports__ = (() => {
|
|
|
1865
2529
|
this._sampler = this.texture.sampler;
|
|
1866
2530
|
this._view = this.texture.view;
|
|
1867
2531
|
prev.destroy();
|
|
1868
|
-
|
|
2532
|
+
import_core11.log.info(`${this} resized`);
|
|
1869
2533
|
return true;
|
|
1870
2534
|
}
|
|
1871
2535
|
/** Convert cube face label to texture slice index. Index can be used with `setTexture2DData()`. */
|
|
@@ -1940,7 +2604,15 @@ var __exports__ = (() => {
|
|
|
1940
2604
|
break;
|
|
1941
2605
|
case "texture-data":
|
|
1942
2606
|
const { data } = subresource;
|
|
1943
|
-
this.texture.
|
|
2607
|
+
this.texture.writeData(getAlignedUploadData(this.texture, data), {
|
|
2608
|
+
x: 0,
|
|
2609
|
+
y: 0,
|
|
2610
|
+
z,
|
|
2611
|
+
width: data.width,
|
|
2612
|
+
height: data.height,
|
|
2613
|
+
depthOrArrayLayers: 1,
|
|
2614
|
+
mipLevel
|
|
2615
|
+
});
|
|
1944
2616
|
break;
|
|
1945
2617
|
default:
|
|
1946
2618
|
throw new Error("Unsupported 2D mip-level payload");
|
|
@@ -1956,22 +2628,46 @@ var __exports__ = (() => {
|
|
|
1956
2628
|
}
|
|
1957
2629
|
_checkNotDestroyed() {
|
|
1958
2630
|
if (this.destroyed) {
|
|
1959
|
-
|
|
2631
|
+
import_core11.log.warn(`${this} already destroyed`);
|
|
1960
2632
|
}
|
|
1961
2633
|
}
|
|
1962
2634
|
_checkReady() {
|
|
1963
2635
|
if (!this.isReady) {
|
|
1964
|
-
|
|
2636
|
+
import_core11.log.warn(`${this} Cannot perform this operation before ready`);
|
|
1965
2637
|
}
|
|
1966
2638
|
}
|
|
1967
2639
|
};
|
|
1968
2640
|
var DynamicTexture = _DynamicTexture;
|
|
1969
2641
|
__publicField(DynamicTexture, "defaultProps", {
|
|
1970
|
-
...
|
|
2642
|
+
...import_core11.Texture.defaultProps,
|
|
1971
2643
|
dimension: "2d",
|
|
1972
2644
|
data: null,
|
|
1973
2645
|
mipmaps: false
|
|
1974
2646
|
});
|
|
2647
|
+
function getAlignedUploadData(texture, data) {
|
|
2648
|
+
const { width, height, data: uploadData } = data;
|
|
2649
|
+
const { bytesPerPixel } = texture.device.getTextureFormatInfo(texture.format);
|
|
2650
|
+
const bytesPerRow = width * bytesPerPixel;
|
|
2651
|
+
const alignedBytesPerRow = Math.ceil(bytesPerRow / texture.byteAlignment) * texture.byteAlignment;
|
|
2652
|
+
if (alignedBytesPerRow === bytesPerRow) {
|
|
2653
|
+
return uploadData;
|
|
2654
|
+
}
|
|
2655
|
+
const sourceBytes = new Uint8Array(
|
|
2656
|
+
uploadData.buffer,
|
|
2657
|
+
uploadData.byteOffset,
|
|
2658
|
+
uploadData.byteLength
|
|
2659
|
+
);
|
|
2660
|
+
const paddedBytes = new Uint8Array(alignedBytesPerRow * height);
|
|
2661
|
+
for (let row = 0; row < height; row++) {
|
|
2662
|
+
const sourceOffset = row * bytesPerRow;
|
|
2663
|
+
const destinationOffset = row * alignedBytesPerRow;
|
|
2664
|
+
paddedBytes.set(
|
|
2665
|
+
sourceBytes.subarray(sourceOffset, sourceOffset + bytesPerRow),
|
|
2666
|
+
destinationOffset
|
|
2667
|
+
);
|
|
2668
|
+
}
|
|
2669
|
+
return paddedBytes;
|
|
2670
|
+
}
|
|
1975
2671
|
async function awaitAllPromises(x) {
|
|
1976
2672
|
x = await x;
|
|
1977
2673
|
if (Array.isArray(x)) {
|
|
@@ -1991,8 +2687,8 @@ var __exports__ = (() => {
|
|
|
1991
2687
|
}
|
|
1992
2688
|
|
|
1993
2689
|
// src/model/model.ts
|
|
1994
|
-
var
|
|
1995
|
-
var
|
|
2690
|
+
var LOG_DRAW_PRIORITY2 = 2;
|
|
2691
|
+
var LOG_DRAW_TIMEOUT2 = 1e4;
|
|
1996
2692
|
var _Model = class {
|
|
1997
2693
|
/** Device that created this model */
|
|
1998
2694
|
device;
|
|
@@ -2075,7 +2771,7 @@ var __exports__ = (() => {
|
|
|
2075
2771
|
);
|
|
2076
2772
|
const shaderInputs = props.shaderInputs || new ShaderInputs(moduleMap, { disableWarnings: this.props.disableWarnings });
|
|
2077
2773
|
this.setShaderInputs(shaderInputs);
|
|
2078
|
-
const platformInfo =
|
|
2774
|
+
const platformInfo = getPlatformInfo2(device);
|
|
2079
2775
|
const modules = (
|
|
2080
2776
|
// @ts-ignore shaderInputs is assigned in setShaderInputs above.
|
|
2081
2777
|
(this.props.modules?.length > 0 ? this.props.modules : this.shaderInputs?.getModules()) || []
|
|
@@ -2182,7 +2878,7 @@ var __exports__ = (() => {
|
|
|
2182
2878
|
draw(renderPass) {
|
|
2183
2879
|
const loadingBinding = this._areBindingsLoading();
|
|
2184
2880
|
if (loadingBinding) {
|
|
2185
|
-
|
|
2881
|
+
import_core12.log.info(LOG_DRAW_PRIORITY2, `>>> DRAWING ABORTED ${this.id}: ${loadingBinding} not loaded`)();
|
|
2186
2882
|
return false;
|
|
2187
2883
|
}
|
|
2188
2884
|
try {
|
|
@@ -2312,7 +3008,7 @@ var __exports__ = (() => {
|
|
|
2312
3008
|
/** Set the shader inputs */
|
|
2313
3009
|
setShaderInputs(shaderInputs) {
|
|
2314
3010
|
this.shaderInputs = shaderInputs;
|
|
2315
|
-
this._uniformStore = new
|
|
3011
|
+
this._uniformStore = new import_core12.UniformStore(this.shaderInputs.modules);
|
|
2316
3012
|
for (const [moduleName, module] of Object.entries(this.shaderInputs.modules)) {
|
|
2317
3013
|
if (shaderModuleHasUniforms(module)) {
|
|
2318
3014
|
const uniformBuffer = this._uniformStore.getManagedUniformBuffer(this.device, moduleName);
|
|
@@ -2356,7 +3052,7 @@ var __exports__ = (() => {
|
|
|
2356
3052
|
setAttributes(buffers, options) {
|
|
2357
3053
|
const disableWarnings = options?.disableWarnings ?? this.props.disableWarnings;
|
|
2358
3054
|
if (buffers["indices"]) {
|
|
2359
|
-
|
|
3055
|
+
import_core12.log.warn(
|
|
2360
3056
|
`Model:${this.id} setAttributes() - indexBuffer should be set using setIndexBuffer()`
|
|
2361
3057
|
)();
|
|
2362
3058
|
}
|
|
@@ -2369,7 +3065,7 @@ var __exports__ = (() => {
|
|
|
2369
3065
|
const bufferLayout = bufferLayoutHelper.getBufferLayout(bufferName);
|
|
2370
3066
|
if (!bufferLayout) {
|
|
2371
3067
|
if (!disableWarnings) {
|
|
2372
|
-
|
|
3068
|
+
import_core12.log.warn(`Model(${this.id}): Missing layout for buffer "${bufferName}".`)();
|
|
2373
3069
|
}
|
|
2374
3070
|
continue;
|
|
2375
3071
|
}
|
|
@@ -2384,7 +3080,7 @@ var __exports__ = (() => {
|
|
|
2384
3080
|
}
|
|
2385
3081
|
}
|
|
2386
3082
|
if (!set && !disableWarnings) {
|
|
2387
|
-
|
|
3083
|
+
import_core12.log.warn(
|
|
2388
3084
|
`Model(${this.id}): Ignoring buffer "${buffer.id}" for unknown attribute "${bufferName}"`
|
|
2389
3085
|
)();
|
|
2390
3086
|
}
|
|
@@ -2405,7 +3101,7 @@ var __exports__ = (() => {
|
|
|
2405
3101
|
if (attributeInfo) {
|
|
2406
3102
|
this.vertexArray.setConstantWebGL(attributeInfo.location, value);
|
|
2407
3103
|
} else if (!(options?.disableWarnings ?? this.props.disableWarnings)) {
|
|
2408
|
-
|
|
3104
|
+
import_core12.log.warn(
|
|
2409
3105
|
`Model "${this.id}: Ignoring constant supplied for unknown attribute "${attributeName}"`
|
|
2410
3106
|
)();
|
|
2411
3107
|
}
|
|
@@ -2440,16 +3136,16 @@ var __exports__ = (() => {
|
|
|
2440
3136
|
_getBindingsUpdateTimestamp() {
|
|
2441
3137
|
let timestamp = 0;
|
|
2442
3138
|
for (const binding of Object.values(this.bindings)) {
|
|
2443
|
-
if (binding instanceof
|
|
3139
|
+
if (binding instanceof import_core12.TextureView) {
|
|
2444
3140
|
timestamp = Math.max(timestamp, binding.texture.updateTimestamp);
|
|
2445
|
-
} else if (binding instanceof
|
|
3141
|
+
} else if (binding instanceof import_core12.Buffer || binding instanceof import_core12.Texture) {
|
|
2446
3142
|
timestamp = Math.max(timestamp, binding.updateTimestamp);
|
|
2447
3143
|
} else if (binding instanceof DynamicTexture) {
|
|
2448
3144
|
timestamp = binding.texture ? Math.max(timestamp, binding.texture.updateTimestamp) : (
|
|
2449
3145
|
// The texture will become available in the future
|
|
2450
3146
|
Infinity
|
|
2451
3147
|
);
|
|
2452
|
-
} else if (!(binding instanceof
|
|
3148
|
+
} else if (!(binding instanceof import_core12.Sampler)) {
|
|
2453
3149
|
timestamp = Math.max(timestamp, binding.buffer.updateTimestamp);
|
|
2454
3150
|
}
|
|
2455
3151
|
}
|
|
@@ -2484,7 +3180,7 @@ var __exports__ = (() => {
|
|
|
2484
3180
|
let prevShaderVs = null;
|
|
2485
3181
|
let prevShaderFs = null;
|
|
2486
3182
|
if (this.pipeline) {
|
|
2487
|
-
|
|
3183
|
+
import_core12.log.log(
|
|
2488
3184
|
1,
|
|
2489
3185
|
`Model ${this.id}: Recreating pipeline because "${this._pipelineNeedsUpdate}".`
|
|
2490
3186
|
)();
|
|
@@ -2520,7 +3216,7 @@ var __exports__ = (() => {
|
|
|
2520
3216
|
vs: vs3,
|
|
2521
3217
|
fs: fs3
|
|
2522
3218
|
});
|
|
2523
|
-
this._attributeInfos = (0,
|
|
3219
|
+
this._attributeInfos = (0, import_core12.getAttributeInfosFromLayouts)(
|
|
2524
3220
|
this.pipeline.shaderLayout,
|
|
2525
3221
|
this.bufferLayout
|
|
2526
3222
|
);
|
|
@@ -2535,24 +3231,24 @@ var __exports__ = (() => {
|
|
|
2535
3231
|
_lastLogTime = 0;
|
|
2536
3232
|
_logOpen = false;
|
|
2537
3233
|
_logDrawCallStart() {
|
|
2538
|
-
const logDrawTimeout =
|
|
2539
|
-
if (
|
|
3234
|
+
const logDrawTimeout = import_core12.log.level > 3 ? 0 : LOG_DRAW_TIMEOUT2;
|
|
3235
|
+
if (import_core12.log.level < 2 || Date.now() - this._lastLogTime < logDrawTimeout) {
|
|
2540
3236
|
return;
|
|
2541
3237
|
}
|
|
2542
3238
|
this._lastLogTime = Date.now();
|
|
2543
3239
|
this._logOpen = true;
|
|
2544
|
-
|
|
3240
|
+
import_core12.log.group(LOG_DRAW_PRIORITY2, `>>> DRAWING MODEL ${this.id}`, { collapsed: import_core12.log.level <= 2 })();
|
|
2545
3241
|
}
|
|
2546
3242
|
_logDrawCallEnd() {
|
|
2547
3243
|
if (this._logOpen) {
|
|
2548
3244
|
const shaderLayoutTable = getDebugTableForShaderLayout(this.pipeline.shaderLayout, this.id);
|
|
2549
|
-
|
|
3245
|
+
import_core12.log.table(LOG_DRAW_PRIORITY2, shaderLayoutTable)();
|
|
2550
3246
|
const uniformTable = this.shaderInputs.getDebugTable();
|
|
2551
|
-
|
|
3247
|
+
import_core12.log.table(LOG_DRAW_PRIORITY2, uniformTable)();
|
|
2552
3248
|
const attributeTable = this._getAttributeDebugTable();
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
3249
|
+
import_core12.log.table(LOG_DRAW_PRIORITY2, this._attributeInfos)();
|
|
3250
|
+
import_core12.log.table(LOG_DRAW_PRIORITY2, attributeTable)();
|
|
3251
|
+
import_core12.log.groupEnd(LOG_DRAW_PRIORITY2)();
|
|
2556
3252
|
this._logOpen = false;
|
|
2557
3253
|
}
|
|
2558
3254
|
}
|
|
@@ -2591,14 +3287,14 @@ var __exports__ = (() => {
|
|
|
2591
3287
|
}
|
|
2592
3288
|
// TODO - fix typing of luma data types
|
|
2593
3289
|
_getBufferOrConstantValues(attribute, dataType) {
|
|
2594
|
-
const TypedArrayConstructor = (0,
|
|
2595
|
-
const typedArray = attribute instanceof
|
|
3290
|
+
const TypedArrayConstructor = (0, import_core12.getTypedArrayConstructor)(dataType);
|
|
3291
|
+
const typedArray = attribute instanceof import_core12.Buffer ? new TypedArrayConstructor(attribute.debugData) : attribute;
|
|
2596
3292
|
return typedArray.toString();
|
|
2597
3293
|
}
|
|
2598
3294
|
};
|
|
2599
3295
|
var Model = _Model;
|
|
2600
3296
|
__publicField(Model, "defaultProps", {
|
|
2601
|
-
...
|
|
3297
|
+
...import_core12.RenderPipeline.defaultProps,
|
|
2602
3298
|
source: void 0,
|
|
2603
3299
|
vs: null,
|
|
2604
3300
|
fs: null,
|
|
@@ -2619,14 +3315,14 @@ var __exports__ = (() => {
|
|
|
2619
3315
|
pipelineFactory: void 0,
|
|
2620
3316
|
shaderFactory: void 0,
|
|
2621
3317
|
transformFeedback: void 0,
|
|
2622
|
-
shaderAssembler:
|
|
3318
|
+
shaderAssembler: import_shadertools3.ShaderAssembler.getDefaultShaderAssembler(),
|
|
2623
3319
|
debugShaders: void 0,
|
|
2624
3320
|
disableWarnings: void 0
|
|
2625
3321
|
});
|
|
2626
3322
|
function shaderModuleHasUniforms(module) {
|
|
2627
3323
|
return Boolean(module.uniformTypes && !isObjectEmpty(module.uniformTypes));
|
|
2628
3324
|
}
|
|
2629
|
-
function
|
|
3325
|
+
function getPlatformInfo2(device) {
|
|
2630
3326
|
return {
|
|
2631
3327
|
type: device.type,
|
|
2632
3328
|
shaderLanguage: device.info.shadingLanguage,
|
|
@@ -2644,8 +3340,8 @@ var __exports__ = (() => {
|
|
|
2644
3340
|
}
|
|
2645
3341
|
|
|
2646
3342
|
// src/compute/buffer-transform.ts
|
|
2647
|
-
var
|
|
2648
|
-
var
|
|
3343
|
+
var import_core13 = __toESM(require_core(), 1);
|
|
3344
|
+
var import_shadertools4 = __toESM(require_shadertools(), 1);
|
|
2649
3345
|
var _BufferTransform = class {
|
|
2650
3346
|
device;
|
|
2651
3347
|
model;
|
|
@@ -2660,7 +3356,7 @@ var __exports__ = (() => {
|
|
|
2660
3356
|
this.device = device;
|
|
2661
3357
|
this.model = new Model(this.device, {
|
|
2662
3358
|
id: props.id || "buffer-transform-model",
|
|
2663
|
-
fs: props.fs || (0,
|
|
3359
|
+
fs: props.fs || (0, import_shadertools4.getPassthroughFS)(),
|
|
2664
3360
|
topology: props.topology || "point-list",
|
|
2665
3361
|
varyings: props.outputs || props.varyings,
|
|
2666
3362
|
...props
|
|
@@ -2706,7 +3402,7 @@ var __exports__ = (() => {
|
|
|
2706
3402
|
if (!result) {
|
|
2707
3403
|
throw new Error("BufferTransform#getBuffer");
|
|
2708
3404
|
}
|
|
2709
|
-
if (result instanceof
|
|
3405
|
+
if (result instanceof import_core13.Buffer) {
|
|
2710
3406
|
return result.readAsync();
|
|
2711
3407
|
}
|
|
2712
3408
|
const { buffer, byteOffset = 0, byteLength = buffer.byteLength } = result;
|
|
@@ -2721,7 +3417,7 @@ var __exports__ = (() => {
|
|
|
2721
3417
|
});
|
|
2722
3418
|
|
|
2723
3419
|
// src/compute/texture-transform.ts
|
|
2724
|
-
var
|
|
3420
|
+
var import_shadertools5 = __toESM(require_shadertools(), 1);
|
|
2725
3421
|
var FS_OUTPUT_VARIABLE = "transform_output";
|
|
2726
3422
|
var TextureTransform = class {
|
|
2727
3423
|
device;
|
|
@@ -2744,7 +3440,7 @@ var __exports__ = (() => {
|
|
|
2744
3440
|
});
|
|
2745
3441
|
this.model = new Model(this.device, {
|
|
2746
3442
|
id: props.id || uid("texture-transform-model"),
|
|
2747
|
-
fs: props.fs || (0,
|
|
3443
|
+
fs: props.fs || (0, import_shadertools5.getPassthroughFS)({
|
|
2748
3444
|
input: props.targetTextureVarying,
|
|
2749
3445
|
inputChannels: props.targetTextureChannels,
|
|
2750
3446
|
output: FS_OUTPUT_VARIABLE
|
|
@@ -5283,13 +5979,13 @@ void main(void) {
|
|
|
5283
5979
|
};
|
|
5284
5980
|
|
|
5285
5981
|
// src/scenegraph/group-node.ts
|
|
5286
|
-
var
|
|
5982
|
+
var import_core16 = __toESM(require_core(), 1);
|
|
5287
5983
|
var GroupNode = class extends ScenegraphNode {
|
|
5288
5984
|
children;
|
|
5289
5985
|
constructor(props = {}) {
|
|
5290
5986
|
props = Array.isArray(props) ? { children: props } : props;
|
|
5291
5987
|
const { children = [] } = props;
|
|
5292
|
-
|
|
5988
|
+
import_core16.log.assert(
|
|
5293
5989
|
children.every((child) => child instanceof ScenegraphNode),
|
|
5294
5990
|
"every child must an instance of ScenegraphNode"
|
|
5295
5991
|
);
|
|
@@ -6530,10 +7226,10 @@ void main(void) {
|
|
|
6530
7226
|
}
|
|
6531
7227
|
|
|
6532
7228
|
// src/passes/shader-pass-renderer.ts
|
|
6533
|
-
var
|
|
7229
|
+
var import_shadertools6 = __toESM(require_shadertools(), 1);
|
|
6534
7230
|
|
|
6535
7231
|
// src/compute/swap.ts
|
|
6536
|
-
var
|
|
7232
|
+
var import_core18 = __toESM(require_core(), 1);
|
|
6537
7233
|
var Swap = class {
|
|
6538
7234
|
id;
|
|
6539
7235
|
/** The current resource - usually the source for renders or computations */
|
|
@@ -6565,7 +7261,7 @@ void main(void) {
|
|
|
6565
7261
|
(colorAttachment) => typeof colorAttachment !== "string" ? colorAttachment : device.createTexture({
|
|
6566
7262
|
id: `${props.id}-texture-0`,
|
|
6567
7263
|
format: colorAttachment,
|
|
6568
|
-
usage:
|
|
7264
|
+
usage: import_core18.Texture.SAMPLE | import_core18.Texture.RENDER | import_core18.Texture.COPY_SRC | import_core18.Texture.COPY_DST,
|
|
6569
7265
|
width,
|
|
6570
7266
|
height
|
|
6571
7267
|
})
|
|
@@ -6575,7 +7271,7 @@ void main(void) {
|
|
|
6575
7271
|
(colorAttachment) => typeof colorAttachment !== "string" ? colorAttachment : device.createTexture({
|
|
6576
7272
|
id: `${props.id}-texture-1`,
|
|
6577
7273
|
format: colorAttachment,
|
|
6578
|
-
usage:
|
|
7274
|
+
usage: import_core18.Texture.SAMPLE | import_core18.Texture.RENDER | import_core18.Texture.COPY_SRC | import_core18.Texture.COPY_DST,
|
|
6579
7275
|
width,
|
|
6580
7276
|
height
|
|
6581
7277
|
})
|
|
@@ -6747,7 +7443,7 @@ void main() {
|
|
|
6747
7443
|
textureModel;
|
|
6748
7444
|
constructor(device, props) {
|
|
6749
7445
|
this.device = device;
|
|
6750
|
-
props.shaderPasses.map((shaderPass) => (0,
|
|
7446
|
+
props.shaderPasses.map((shaderPass) => (0, import_shadertools6.initializeShaderModule)(shaderPass));
|
|
6751
7447
|
const modules = props.shaderPasses.reduce(
|
|
6752
7448
|
(object, shaderPass) => ({ ...object, [shaderPass.name]: shaderPass }),
|
|
6753
7449
|
{}
|
|
@@ -6922,221 +7618,6 @@ void main() {
|
|
|
6922
7618
|
}
|
|
6923
7619
|
};
|
|
6924
7620
|
|
|
6925
|
-
// src/compute/computation.ts
|
|
6926
|
-
var import_core17 = __toESM(require_core(), 1);
|
|
6927
|
-
var import_shadertools6 = __toESM(require_shadertools(), 1);
|
|
6928
|
-
var LOG_DRAW_PRIORITY2 = 2;
|
|
6929
|
-
var LOG_DRAW_TIMEOUT2 = 1e4;
|
|
6930
|
-
var _Computation = class {
|
|
6931
|
-
device;
|
|
6932
|
-
id;
|
|
6933
|
-
pipelineFactory;
|
|
6934
|
-
shaderFactory;
|
|
6935
|
-
userData = {};
|
|
6936
|
-
/** Bindings (textures, samplers, uniform buffers) */
|
|
6937
|
-
bindings = {};
|
|
6938
|
-
/** The underlying GPU pipeline. */
|
|
6939
|
-
pipeline;
|
|
6940
|
-
/** Assembled compute shader source */
|
|
6941
|
-
source;
|
|
6942
|
-
/** the underlying compiled compute shader */
|
|
6943
|
-
// @ts-ignore Set in function called from constructor
|
|
6944
|
-
shader;
|
|
6945
|
-
/** ShaderInputs instance */
|
|
6946
|
-
shaderInputs;
|
|
6947
|
-
// @ts-ignore Set in function called from constructor
|
|
6948
|
-
_uniformStore;
|
|
6949
|
-
_pipelineNeedsUpdate = "newly created";
|
|
6950
|
-
_getModuleUniforms;
|
|
6951
|
-
props;
|
|
6952
|
-
_destroyed = false;
|
|
6953
|
-
constructor(device, props) {
|
|
6954
|
-
if (device.type !== "webgpu") {
|
|
6955
|
-
throw new Error("Computation is only supported in WebGPU");
|
|
6956
|
-
}
|
|
6957
|
-
this.props = { ..._Computation.defaultProps, ...props };
|
|
6958
|
-
props = this.props;
|
|
6959
|
-
this.id = props.id || uid("model");
|
|
6960
|
-
this.device = device;
|
|
6961
|
-
Object.assign(this.userData, props.userData);
|
|
6962
|
-
const moduleMap = Object.fromEntries(
|
|
6963
|
-
this.props.modules?.map((module) => [module.name, module]) || []
|
|
6964
|
-
);
|
|
6965
|
-
this.shaderInputs = props.shaderInputs || new ShaderInputs(moduleMap);
|
|
6966
|
-
this.setShaderInputs(this.shaderInputs);
|
|
6967
|
-
this.props.shaderLayout ||= device.getShaderLayout(this.props.source);
|
|
6968
|
-
const platformInfo = getPlatformInfo2(device);
|
|
6969
|
-
const modules = (this.props.modules?.length > 0 ? this.props.modules : this.shaderInputs?.getModules()) || [];
|
|
6970
|
-
this.pipelineFactory = props.pipelineFactory || PipelineFactory.getDefaultPipelineFactory(this.device);
|
|
6971
|
-
this.shaderFactory = props.shaderFactory || ShaderFactory.getDefaultShaderFactory(this.device);
|
|
6972
|
-
const { source: source3, getUniforms: getUniforms2 } = this.props.shaderAssembler.assembleWGSLShader({
|
|
6973
|
-
platformInfo,
|
|
6974
|
-
...this.props,
|
|
6975
|
-
modules
|
|
6976
|
-
});
|
|
6977
|
-
this.source = source3;
|
|
6978
|
-
this._getModuleUniforms = getUniforms2;
|
|
6979
|
-
this.pipeline = this._updatePipeline();
|
|
6980
|
-
if (props.bindings) {
|
|
6981
|
-
this.setBindings(props.bindings);
|
|
6982
|
-
}
|
|
6983
|
-
Object.seal(this);
|
|
6984
|
-
}
|
|
6985
|
-
destroy() {
|
|
6986
|
-
if (this._destroyed)
|
|
6987
|
-
return;
|
|
6988
|
-
this.pipelineFactory.release(this.pipeline);
|
|
6989
|
-
this.shaderFactory.release(this.shader);
|
|
6990
|
-
this._uniformStore.destroy();
|
|
6991
|
-
this._destroyed = true;
|
|
6992
|
-
}
|
|
6993
|
-
// Draw call
|
|
6994
|
-
predraw() {
|
|
6995
|
-
this.updateShaderInputs();
|
|
6996
|
-
}
|
|
6997
|
-
dispatch(computePass, x, y, z) {
|
|
6998
|
-
try {
|
|
6999
|
-
this._logDrawCallStart();
|
|
7000
|
-
this.pipeline = this._updatePipeline();
|
|
7001
|
-
this.pipeline.setBindings(this.bindings);
|
|
7002
|
-
computePass.setPipeline(this.pipeline);
|
|
7003
|
-
computePass.setBindings([]);
|
|
7004
|
-
computePass.dispatch(x, y, z);
|
|
7005
|
-
} finally {
|
|
7006
|
-
this._logDrawCallEnd();
|
|
7007
|
-
}
|
|
7008
|
-
}
|
|
7009
|
-
// Update fixed fields (can trigger pipeline rebuild)
|
|
7010
|
-
// Update dynamic fields
|
|
7011
|
-
/**
|
|
7012
|
-
* Updates the vertex count (used in draw calls)
|
|
7013
|
-
* @note Any attributes with stepMode=vertex need to be at least this big
|
|
7014
|
-
*/
|
|
7015
|
-
setVertexCount(vertexCount) {
|
|
7016
|
-
}
|
|
7017
|
-
/**
|
|
7018
|
-
* Updates the instance count (used in draw calls)
|
|
7019
|
-
* @note Any attributes with stepMode=instance need to be at least this big
|
|
7020
|
-
*/
|
|
7021
|
-
setInstanceCount(instanceCount) {
|
|
7022
|
-
}
|
|
7023
|
-
setShaderInputs(shaderInputs) {
|
|
7024
|
-
this.shaderInputs = shaderInputs;
|
|
7025
|
-
this._uniformStore = new import_core17.UniformStore(this.shaderInputs.modules);
|
|
7026
|
-
for (const moduleName of Object.keys(this.shaderInputs.modules)) {
|
|
7027
|
-
const uniformBuffer = this._uniformStore.getManagedUniformBuffer(this.device, moduleName);
|
|
7028
|
-
this.bindings[`${moduleName}Uniforms`] = uniformBuffer;
|
|
7029
|
-
}
|
|
7030
|
-
}
|
|
7031
|
-
/**
|
|
7032
|
-
* Updates shader module settings (which results in uniforms being set)
|
|
7033
|
-
*/
|
|
7034
|
-
setShaderModuleProps(props) {
|
|
7035
|
-
const uniforms = this._getModuleUniforms(props);
|
|
7036
|
-
const keys = Object.keys(uniforms).filter((k) => {
|
|
7037
|
-
const uniform = uniforms[k];
|
|
7038
|
-
return !isNumericArray(uniform) && typeof uniform !== "number" && typeof uniform !== "boolean";
|
|
7039
|
-
});
|
|
7040
|
-
const bindings = {};
|
|
7041
|
-
for (const k of keys) {
|
|
7042
|
-
bindings[k] = uniforms[k];
|
|
7043
|
-
delete uniforms[k];
|
|
7044
|
-
}
|
|
7045
|
-
}
|
|
7046
|
-
updateShaderInputs() {
|
|
7047
|
-
this._uniformStore.setUniforms(this.shaderInputs.getUniformValues());
|
|
7048
|
-
}
|
|
7049
|
-
/**
|
|
7050
|
-
* Sets bindings (textures, samplers, uniform buffers)
|
|
7051
|
-
*/
|
|
7052
|
-
setBindings(bindings) {
|
|
7053
|
-
Object.assign(this.bindings, bindings);
|
|
7054
|
-
}
|
|
7055
|
-
_setPipelineNeedsUpdate(reason) {
|
|
7056
|
-
this._pipelineNeedsUpdate = this._pipelineNeedsUpdate || reason;
|
|
7057
|
-
}
|
|
7058
|
-
_updatePipeline() {
|
|
7059
|
-
if (this._pipelineNeedsUpdate) {
|
|
7060
|
-
let prevShader = null;
|
|
7061
|
-
if (this.pipeline) {
|
|
7062
|
-
import_core17.log.log(
|
|
7063
|
-
1,
|
|
7064
|
-
`Model ${this.id}: Recreating pipeline because "${this._pipelineNeedsUpdate}".`
|
|
7065
|
-
)();
|
|
7066
|
-
prevShader = this.shader;
|
|
7067
|
-
}
|
|
7068
|
-
this._pipelineNeedsUpdate = false;
|
|
7069
|
-
this.shader = this.shaderFactory.createShader({
|
|
7070
|
-
id: `${this.id}-fragment`,
|
|
7071
|
-
stage: "compute",
|
|
7072
|
-
source: this.source,
|
|
7073
|
-
debugShaders: this.props.debugShaders
|
|
7074
|
-
});
|
|
7075
|
-
this.pipeline = this.pipelineFactory.createComputePipeline({
|
|
7076
|
-
...this.props,
|
|
7077
|
-
shader: this.shader
|
|
7078
|
-
});
|
|
7079
|
-
if (prevShader) {
|
|
7080
|
-
this.shaderFactory.release(prevShader);
|
|
7081
|
-
}
|
|
7082
|
-
}
|
|
7083
|
-
return this.pipeline;
|
|
7084
|
-
}
|
|
7085
|
-
/** Throttle draw call logging */
|
|
7086
|
-
_lastLogTime = 0;
|
|
7087
|
-
_logOpen = false;
|
|
7088
|
-
_logDrawCallStart() {
|
|
7089
|
-
const logDrawTimeout = import_core17.log.level > 3 ? 0 : LOG_DRAW_TIMEOUT2;
|
|
7090
|
-
if (import_core17.log.level < 2 || Date.now() - this._lastLogTime < logDrawTimeout) {
|
|
7091
|
-
return;
|
|
7092
|
-
}
|
|
7093
|
-
this._lastLogTime = Date.now();
|
|
7094
|
-
this._logOpen = true;
|
|
7095
|
-
import_core17.log.group(LOG_DRAW_PRIORITY2, `>>> DRAWING MODEL ${this.id}`, { collapsed: import_core17.log.level <= 2 })();
|
|
7096
|
-
}
|
|
7097
|
-
_logDrawCallEnd() {
|
|
7098
|
-
if (this._logOpen) {
|
|
7099
|
-
const uniformTable = this.shaderInputs.getDebugTable();
|
|
7100
|
-
import_core17.log.table(LOG_DRAW_PRIORITY2, uniformTable)();
|
|
7101
|
-
import_core17.log.groupEnd(LOG_DRAW_PRIORITY2)();
|
|
7102
|
-
this._logOpen = false;
|
|
7103
|
-
}
|
|
7104
|
-
}
|
|
7105
|
-
_drawCount = 0;
|
|
7106
|
-
// TODO - fix typing of luma data types
|
|
7107
|
-
_getBufferOrConstantValues(attribute, dataType) {
|
|
7108
|
-
const TypedArrayConstructor = (0, import_core17.getTypedArrayConstructor)(dataType);
|
|
7109
|
-
const typedArray = attribute instanceof import_core17.Buffer ? new TypedArrayConstructor(attribute.debugData) : attribute;
|
|
7110
|
-
return typedArray.toString();
|
|
7111
|
-
}
|
|
7112
|
-
};
|
|
7113
|
-
var Computation = _Computation;
|
|
7114
|
-
__publicField(Computation, "defaultProps", {
|
|
7115
|
-
...import_core17.ComputePipeline.defaultProps,
|
|
7116
|
-
id: "unnamed",
|
|
7117
|
-
handle: void 0,
|
|
7118
|
-
userData: {},
|
|
7119
|
-
source: "",
|
|
7120
|
-
modules: [],
|
|
7121
|
-
defines: {},
|
|
7122
|
-
bindings: void 0,
|
|
7123
|
-
shaderInputs: void 0,
|
|
7124
|
-
pipelineFactory: void 0,
|
|
7125
|
-
shaderFactory: void 0,
|
|
7126
|
-
shaderAssembler: import_shadertools6.ShaderAssembler.getDefaultShaderAssembler(),
|
|
7127
|
-
debugShaders: void 0
|
|
7128
|
-
});
|
|
7129
|
-
function getPlatformInfo2(device) {
|
|
7130
|
-
return {
|
|
7131
|
-
type: device.type,
|
|
7132
|
-
shaderLanguage: device.info.shadingLanguage,
|
|
7133
|
-
shaderLanguageVersion: device.info.shadingLanguageVersion,
|
|
7134
|
-
gpu: device.info.gpu,
|
|
7135
|
-
// HACK - we pretend that the DeviceFeatures is a Set, it has a similar API
|
|
7136
|
-
features: device.features
|
|
7137
|
-
};
|
|
7138
|
-
}
|
|
7139
|
-
|
|
7140
7621
|
// src/modules/picking/picking-uniforms.ts
|
|
7141
7622
|
var DEFAULT_HIGHLIGHT_COLOR = [0, 1, 1, 1];
|
|
7142
7623
|
var INVALID_INDEX = -1;
|