playcanvas
Version:
PlayCanvas WebGL game engine
129 lines (126 loc) • 4.77 kB
JavaScript
import { TEXTUREDIMENSION_2D, SAMPLETYPE_FLOAT, SHADERSTAGE_COMPUTE, PIXELFORMAT_RGBA8, SAMPLETYPE_UINT, SAMPLETYPE_INT, TEXTUREDIMENSION_CUBE, TEXTUREDIMENSION_3D, TEXTUREDIMENSION_2D_ARRAY } from './constants.js';
var id = 0;
var textureDimensionInfo = {
[TEXTUREDIMENSION_2D]: 'texture2D',
[TEXTUREDIMENSION_CUBE]: 'textureCube',
[TEXTUREDIMENSION_3D]: 'texture3D',
[TEXTUREDIMENSION_2D_ARRAY]: 'texture2DArray'
};
class BindBaseFormat {
constructor(name, visibility){
this.slot = -1;
this.scopeId = null;
this.name = name;
this.visibility = visibility;
}
}
class BindUniformBufferFormat extends BindBaseFormat {
}
class BindStorageBufferFormat extends BindBaseFormat {
constructor(name, visibility, readOnly = false){
super(name, visibility);
this.readOnly = readOnly;
}
}
class BindTextureFormat extends BindBaseFormat {
constructor(name, visibility, textureDimension = TEXTUREDIMENSION_2D, sampleType = SAMPLETYPE_FLOAT, hasSampler = true){
super(name, visibility);
this.textureDimension = textureDimension;
this.sampleType = sampleType;
this.hasSampler = hasSampler;
}
}
class BindStorageTextureFormat extends BindBaseFormat {
constructor(name, format = PIXELFORMAT_RGBA8, textureDimension = TEXTUREDIMENSION_2D, write = true, read = false){
super(name, SHADERSTAGE_COMPUTE);
this.format = format;
this.textureDimension = textureDimension;
this.write = write;
this.read = read;
}
}
class BindGroupFormat {
destroy() {
this.impl.destroy();
}
getTexture(name) {
var index = this.textureFormatsMap.get(name);
if (index !== undefined) {
return this.textureFormats[index];
}
return null;
}
getStorageTexture(name) {
var index = this.storageTextureFormatsMap.get(name);
if (index !== undefined) {
return this.storageTextureFormats[index];
}
return null;
}
getShaderDeclarationTextures(bindGroup) {
var code = '';
this.textureFormats.forEach((format)=>{
var textureType = textureDimensionInfo[format.textureDimension];
var isArray = textureType === 'texture2DArray';
var sampleTypePrefix = format.sampleType === SAMPLETYPE_UINT ? 'u' : format.sampleType === SAMPLETYPE_INT ? 'i' : '';
textureType = "" + sampleTypePrefix + textureType;
var namePostfix = '';
var extraCode = '';
if (isArray) {
namePostfix = '_texture';
extraCode = "#define " + format.name + " " + sampleTypePrefix + "sampler2DArray(" + format.name + namePostfix + ", " + format.name + "_sampler)\n";
}
code += "layout(set = " + bindGroup + ", binding = " + format.slot + ") uniform " + textureType + " " + format.name + namePostfix + ";\n";
if (format.hasSampler) {
code += "layout(set = " + bindGroup + ", binding = " + (format.slot + 1) + ") uniform sampler " + format.name + "_sampler;\n";
}
code += extraCode;
});
return code;
}
loseContext() {}
constructor(graphicsDevice, formats){
this.uniformBufferFormats = [];
this.textureFormats = [];
this.storageTextureFormats = [];
this.storageBufferFormats = [];
this.id = id++;
var slot = 0;
formats.forEach((format)=>{
format.slot = slot++;
if (format instanceof BindTextureFormat && format.hasSampler) {
slot++;
}
if (format instanceof BindUniformBufferFormat) {
this.uniformBufferFormats.push(format);
} else if (format instanceof BindTextureFormat) {
this.textureFormats.push(format);
} else if (format instanceof BindStorageTextureFormat) {
this.storageTextureFormats.push(format);
} else if (format instanceof BindStorageBufferFormat) {
this.storageBufferFormats.push(format);
} else ;
});
this.device = graphicsDevice;
var scope = graphicsDevice.scope;
this.bufferFormatsMap = new Map();
this.uniformBufferFormats.forEach((bf, i)=>this.bufferFormatsMap.set(bf.name, i));
this.textureFormatsMap = new Map();
this.textureFormats.forEach((tf, i)=>{
this.textureFormatsMap.set(tf.name, i);
tf.scopeId = scope.resolve(tf.name);
});
this.storageTextureFormatsMap = new Map();
this.storageTextureFormats.forEach((tf, i)=>{
this.storageTextureFormatsMap.set(tf.name, i);
tf.scopeId = scope.resolve(tf.name);
});
this.storageBufferFormatsMap = new Map();
this.storageBufferFormats.forEach((bf, i)=>{
this.storageBufferFormatsMap.set(bf.name, i);
bf.scopeId = scope.resolve(bf.name);
});
this.impl = graphicsDevice.createBindGroupFormatImpl(this);
}
}
export { BindGroupFormat, BindStorageBufferFormat, BindStorageTextureFormat, BindTextureFormat, BindUniformBufferFormat };