cables_dev/cables/src/core/cgp/cgp_binding.js
- import { Logger } from "cables-shared-client";
- import GPUBuffer from "./cgp_gpubuffer.js";
-
- export default class Binding
- {
- /**
- * Description
- * @param {any} cgp
- * @param {any} idx
- * @param {string} name
- * @param {any} options={}
- */
- constructor(cgp, name, options = {})
- {
- if (typeof options != "object") this._log.error("binding options is not an object");
- this._index = -1;
-
- this._name = name;
- this._cgp = cgp;
- this._log = new Logger("cgp_binding");
- this.uniforms = [];
- this.cGpuBuffers = [];
- this._options = options;
- this.shader = null;
- this.bindingInstances = [];
- this.stageStr = options.stage;
- this.bindingType = options.bindingType || "uniform"; // "uniform", "storage", "read-only-storage",
-
- if (this.stageStr == "frag") this.stage = GPUShaderStage.FRAGMENT;
- else this.stage = GPUShaderStage.VERTEX;
- if (options.hasOwnProperty("index")) this._index = options.index;
-
- if (options.shader) this.shader = options.shader;
-
- this._buffer = null;
- this.isValid = true;
- this.changed = 0;
-
- if (this.shader)
- {
- if (this.stageStr == "frag") this.shader.bindingsFrag.push(this);
- if (this.stageStr == "vert") this.shader.bindingsVert.push(this);
- if (this._index == -1) this._index = this.shader.getNewBindingIndex();
- }
-
- if (this._index == -1) this._log.warn("binding could not get an index", this._name);
-
- this._cgp.on("deviceChange", () =>
- {
- // this.reInit();
- });
- }
-
- isStruct()
- {
- if (this.uniforms.length == 0) return false;
-
- if (this.uniforms.length == 1)
- {
- if (this.uniforms[0].type == "t" || this.uniforms[0].type == "sampler") return false;
- if (this.bindingType != "uniform") return false;
- }
-
- return true;
- }
-
- copy(newShader)
- {
- console.log("copy binding...");
- const options = {};
-
- for (const i in this._options)
- options[i] = this._options[i];
-
- options.shader = newShader;
-
- let binding = new Binding(this._cgp, this._name, options);
-
- for (let i = 0; i < this.uniforms.length; i++)
- {
- binding.addUniform(newShader.getUniform(this.uniforms[i].name)); // .copy(newShader)
- }
-
-
-
-
- return binding;
- }
-
- addUniform(uni)
- {
- this.uniforms.push(uni);
- }
-
- getSizeBytes()
- {
- let size = 0;
- for (let i = 0; i < this.uniforms.length; i++)
- {
- // console.log("UNIFORM!!!", i, this.uniforms[i], this.uniforms[i].getSizeBytes());
- // console.log("getSizeBytes", this.uniforms[i], this.uniforms[i].getSizeBytes);
- size += this.uniforms[i].getSizeBytes();
- }
- // if (this.uniforms.length == 0)console.log("NO UNIFORMS!!!");
- return size;
- }
-
- getShaderHeaderCode()
- {
- let str = "";
-
- let typeStr = "strct_" + this._name;
- let name = this._name;
-
- if (this.uniforms.length === 0) return "// no uniforms in bindinggroup...?\n";
-
-
- str += "// " + this.uniforms.length + " uniforms\n";
-
- if (this.isStruct())
- {
- str += "struct " + typeStr + "\n";
- str += "{\n";
- for (let i = 0; i < this.uniforms.length; i++)
- {
- str += " " + this.uniforms[i].name + ": " + this.uniforms[i].getWgslTypeStr();
- if (i != this.uniforms.length - 1)str += ",";
- str += "\n";
- }
- str += "};\n";
- }
- else
- {
- typeStr = this.uniforms[0].getWgslTypeStr();
- name = this.uniforms[0].name;
- }
-
- str += "@group(0) ";
- str += "@binding(" + this._index + ") ";
-
- if (this.isStruct())
- {
- str += "var<" + this.bindingType + "> ";
- }
- else if (this.bindingType == "read-only-storage")str += "var<storage,read> ";
- else str += "var ";
-
- str += name + ": " + typeStr + ";\n";
-
- return str;
- }
-
-
- getBindingGroupLayoutEntry()
- {
- let label = "layout " + this._name + " [";
- for (let i = 0; i < this.uniforms.length; i++) label += this.uniforms[i].getName() + ",";
- label += "]";
-
- const o = {
- "label": label,
- "binding": this._index,
- "visibility": this.stage,
- "size": this.getSizeBytes()
- };
-
- if (this.uniforms.length == 1 && this.uniforms[0].getType() == "t")
- {
- o.texture = {};
- }
- else if (this.uniforms.length == 1 && this.uniforms[0].getType() == "sampler")
- {
- o.sampler = {};
- }
- else
- {
- o.buffer = {};
- o.buffer.type = this.bindingType;
- }
-
- return o;
- }
-
- getBindingGroupEntry(gpuDevice, inst)
- {
- this.isValid = false;
-
- const o = {
- "label": this._name + " binding",
- "binding": this._index,
- "size": this.getSizeBytes(),
- "visibility": this.stage,
- };
-
- if (this.uniforms.length == 0)
- {
- console.log("binding uniforms length 0");
- return;
- }
-
- if (this.uniforms.length == 1 && this.uniforms[0].getType() == "t")
- {
- if (this.uniforms[0].getValue() && this.uniforms[0].getValue().gpuTexture) o.resource = this.uniforms[0].getValue().gpuTexture.createView();
- else o.resource = this._cgp.getEmptyTexture().createView();// CABLES.emptyCglTexture.createView();
- }
- else if (this.uniforms.length == 1 && this.uniforms[0].getType() == "sampler")
- {
- let smplDesc = {
- "addressModeU": "mirror-repeat",
- "addressModeV": "mirror-repeat",
- "magFilter": "linear",
- "minFilter": "linear",
- "mipmapFilter": "linear",
- };
-
- if (this.uniforms[0].getValue()) smplDesc = this.uniforms[0].getValue().getSampler();
-
- const sampler = this.uniforms[0]._cgp.device.createSampler(smplDesc);
- o.resource = sampler;
- }
- else
- {
- this._createCgpuBuffer(inst);
-
- o.resource = {
- "buffer": this.cGpuBuffers[inst].gpuBuffer,
- "minBindingSize": this.getSizeBytes(),
- "hasDynamicOffset": 0
- };
- }
-
- this.isValid = true;
- this.bindingInstances[inst] = o;
-
- return o;
- }
-
- _createCgpuBuffer(inst)
- {
- let buffCfg = {
- "label": this._name,
- "size": this.getSizeBytes(),
- "usage": GPUBufferUsage.COPY_DST | GPUBufferUsage.UNIFORM,
- };
-
- if (this.bindingType == "read-only-storage" || this.bindingType == "storage") buffCfg.usage = GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST;
-
- if (this.cGpuBuffers[inst]) this.cGpuBuffers[inst].dispose();
- this.cGpuBuffers[inst] = new GPUBuffer(this._cgp, this._name + " buff", null, { "buffCfg": buffCfg });
-
- if (this.uniforms.length > 0 && this.uniforms[0].gpuBuffer) this.cGpuBuffers[inst] = this.uniforms[0].gpuBuffer;
- }
-
-
-
- update(cgp, inst)
- {
- let b = this.bindingInstances[inst];
- if (!b) b = this.getBindingGroupEntry(cgp.device, inst);
-
- if (this.uniforms.length == 1 && this.uniforms[0].gpuBuffer)
- {
- if (this.uniforms[0].gpuBuffer != this.cGpuBuffers[inst])
- {
- console.log("changed?!");
- this.shader._needsRecompile = true; // TODO this should actually just rebuild the bindinggroup i guess ?
- }
-
- if (this._cgp.frameStore.branchProfiler) this._cgp.frameStore.branchStack.push("extern uni bind", [this.uniforms[0].getName(), this.cGpuBuffers[inst].floatArr]);
- if (this._cgp.frameStore.branchProfiler) this._cgp.frameStore.branchStack.pop();
- }
- else
- if (this.uniforms.length == 1 && this.uniforms[0].getType() == "t")
- {
- if (this._cgp.frameStore.branchProfiler) this._cgp.frameStore.branchStack.push("uni texture");
- if (this.uniforms[0].getValue())
- if (this.uniforms[0].getValue().gpuTexture)
- {
- this.bindingInstances[inst] = this.getBindingGroupEntry(this.uniforms[0]._cgp.device, inst);
- }
- else
- {
- console.log("uni t has no gputexture");
- b.resource = this._cgp.getErrorTexture().createView();
- }
-
- if (this._cgp.frameStore.branchProfiler) this._cgp.frameStore.branchStack.pop();
- }
- else if (this.uniforms.length == 1 && this.uniforms[0].getType() == "sampler")
- {
- if (this._cgp.frameStore.branchProfiler) this._cgp.frameStore.branchStack.push("uni sampler");
- b.resource = this.uniforms[0].getValue();
- if (this._cgp.frameStore.branchProfiler) this._cgp.frameStore.branchStack.pop();
- }
- else
- {
- let info = ["stage " + this.stageStr + " / inst " + inst];
-
- // console.log("B",this.);
- // update uniform values to buffer
- const s = this.getSizeBytes() / 4;
-
- // if (!this.cGpuBuffers[inst])
- // this._createCgpuBuffer(inst);
- // this.cGpuBuffers[inst] = new GPUBuffer(this._cgp, "buff", null, { "buffCfg": buffCfg });
-
- this.cGpuBuffers[inst].setLength(s);
-
- let off = 0;
- for (let i = 0; i < this.uniforms.length; i++)
- {
- info.push(this.uniforms[i].getName() + " " + this.uniforms[i].getValue());
- this.uniforms[i].copyToBuffer(this.cGpuBuffers[inst].floatArr, off); // todo: check if uniform changed?
-
- // if (isNaN(this.cGpuBuffers[inst].floatArr[0]))
- // {
- // console.log("shitttttttt", this.cGpuBuffers[inst].floatArr[0], this.uniforms[i].getName(), this.cGpuBuffers[inst].name, this.uniforms[i]);
- // }
-
- off += this.uniforms[i].getSizeBytes() / 4;
- }
- if (this._cgp.frameStore.branchProfiler) this._cgp.frameStore.branchStack.push("uni buff", info);
-
- // console.log("upodate", inst);
-
- this.cGpuBuffers[inst].updateGpuBuffer();
- // todo: only if changed...
- // cgp.device.queue.writeBuffer(
- // b.resource.buffer,
- // 0,
- // this._buffer.buffer,
- // this._buffer.byteOffset,
- // this._buffer.byteLength
- // );
-
- if (this._cgp.frameStore.branchProfiler) this._cgp.frameStore.branchStack.pop();
- }
- }
- }