UNPKG

@awayjs/stage

Version:
154 lines (153 loc) 6.2 kB
import { ShaderRegisterElement } from './ShaderRegisterElement'; /** * RegisterPool is used by the shader compilers process to keep track of which registers of a certain type are * currently used and should not be allowed to be written to. Either entire registers can be requested and locked, * or single components (x, y, z, w) of a single register. * It is used by ShaderRegisterCache to track usages of individual register types. * * @see away.materials.ShaderRegisterCache */ var RegisterPool = /** @class */ (function () { /** * Creates a new RegisterPool object. * @param regName The base name of the register type ("ft" for fragment temporaries, "vc" for vertex constants, etc) * @param regCount The amount of available registers of this type. * @param persistent Whether or not registers, once reserved, can be freed again. For example, temporaries are not persistent, but constants are. */ function RegisterPool(regName, regCount, persistent) { if (persistent === void 0) { persistent = true; } this._regName = regName; this._regCount = regCount; this._persistent = persistent; this.initRegisters(regName, regCount); } /** * Retrieve an entire vector register that's still available. */ RegisterPool.prototype.requestFreeVectorReg = function () { for (var i = 0; i < this._regCount; ++i) { if (!this.isRegisterUsed(i)) { if (this._persistent) this._usedVectorCount[i]++; return this._vectorRegisters[i]; } } throw new Error('Register overflow!'); }; /** * Retrieve a single vector component that's still available. */ RegisterPool.prototype.requestFreeRegComponent = function () { for (var i = 0; i < this._regCount; ++i) { if (this._usedVectorCount[i] > 0) continue; for (var j = 0; j < 4; ++j) { if (this._usedSingleCount[j][i] == 0) { if (this._persistent) this._usedSingleCount[j][i]++; return this._registerComponents[j][i]; } } } throw new Error('Register overflow!'); }; /** * Marks a register as used, so it cannot be retrieved. The register won't be able to be used until removeUsage * has been called usageCount times again. * @param register The register to mark as used. * @param usageCount The amount of usages to add. */ RegisterPool.prototype.addUsage = function (register, usageCount) { if (register._component > -1) this._usedSingleCount[register._component][register.index] += usageCount; else this._usedVectorCount[register.index] += usageCount; }; /** * Removes a usage from a register. When usages reach 0, the register is freed again. * @param register The register for which to remove a usage. */ RegisterPool.prototype.removeUsage = function (register) { if (register._component > -1) { if (--this._usedSingleCount[register._component][register.index] < 0) throw new Error('More usages removed than exist!'); } else { if (--this._usedVectorCount[register.index] < 0) throw new Error('More usages removed than exist!'); } }; /** * Disposes any resources used by the current RegisterPool object. */ RegisterPool.prototype.dispose = function () { this._vectorRegisters = null; this._registerComponents = null; this._usedSingleCount = null; this._usedVectorCount = null; }; /** * Indicates whether or not any registers are in use. */ RegisterPool.prototype.hasRegisteredRegs = function () { for (var i = 0; i < this._regCount; ++i) if (this.isRegisterUsed(i)) return true; return false; }; /** * Initializes all registers. */ RegisterPool.prototype.initRegisters = function (regName, regCount) { var hash = RegisterPool._initPool(regName, regCount); this._vectorRegisters = RegisterPool._regPool[hash]; this._registerComponents = RegisterPool._regCompsPool[hash]; this._usedVectorCount = this._initArray(Array(regCount), 0); this._usedSingleCount = new Array(4); this._usedSingleCount[0] = this._initArray(new Array(regCount), 0); this._usedSingleCount[1] = this._initArray(new Array(regCount), 0); this._usedSingleCount[2] = this._initArray(new Array(regCount), 0); this._usedSingleCount[3] = this._initArray(new Array(regCount), 0); }; RegisterPool._initPool = function (regName, regCount) { var hash = regName + regCount; if (RegisterPool._regPool[hash] != undefined) return hash; var vectorRegisters = new Array(regCount); RegisterPool._regPool[hash] = vectorRegisters; var registerComponents = [ [], [], [], [] ]; RegisterPool._regCompsPool[hash] = registerComponents; for (var i = 0; i < regCount; ++i) { vectorRegisters[i] = new ShaderRegisterElement(regName, i); for (var j = 0; j < 4; ++j) registerComponents[j][i] = new ShaderRegisterElement(regName, i, j); } return hash; }; /** * Check if the temp register is either used for single or vector use */ RegisterPool.prototype.isRegisterUsed = function (index) { if (this._usedVectorCount[index] > 0) return true; for (var i = 0; i < 4; ++i) if (this._usedSingleCount[i][index] > 0) return true; return false; }; RegisterPool.prototype._initArray = function (a, val) { var l = a.length; for (var c = 0; c < l; c++) a[c] = val; return a; }; RegisterPool._regPool = new Object(); RegisterPool._regCompsPool = new Object(); return RegisterPool; }()); export { RegisterPool };