فهرست منبع

More UBO managing redesign - using an updateList to sync the buffers

Popov72 4 سال پیش
والد
کامیت
d9d7134233
3فایلهای تغییر یافته به همراه37 افزوده شده و 6 حذف شده
  1. 35 5
      src/Materials/uniformBuffer.ts
  2. 1 0
      src/Shaders/ShadersInclude/sceneUboDeclaration.fx
  3. 1 1
      src/scene.ts

+ 35 - 5
src/Materials/uniformBuffer.ts

@@ -43,6 +43,7 @@ export class UniformBuffer {
     private _currentEffectName: string;
     private _name: string;
     private _currentFrameId: number;
+    private _updateList: Array<[number, number, string?]>;
 
     /** @hidden */
     public _alreadyBound = false;
@@ -181,6 +182,7 @@ export class UniformBuffer {
             this._bufferIndex = -1;
             this._createBufferOnWrite = false;
             this._currentFrameId = 0;
+            this._updateList = [];
         }
 
         if (this._noUBO) {
@@ -521,13 +523,29 @@ export class UniformBuffer {
         this._createBufferOnWrite = ThinEngine.Features.trackUbosInFrame;
     }
 
-    private _createNewBuffer(): boolean {
+    private _createNewBuffer(excludedLocation: number): boolean {
         if (this._bufferIndex + 1 < this._buffers.length) {
+            const currentBufferData = this._bufferData;
             this._bufferIndex++;
             this._buffer = this._buffers[this._bufferIndex][0];
             this._bufferData = this._buffers[this._bufferIndex][1];
             this._valueCache = this._buffers[this._bufferIndex][2];
             this._createBufferOnWrite = false;
+            for (let i = 0; i < this._updateList.length; ++i) {
+                let [location, size, name] = this._updateList[i];
+                if (location === excludedLocation) {
+                    continue;
+                } else if (location < 0) {
+                    this._valueCache[name!] = size;
+                } else {
+                    while (size--) {
+                        if (this._bufferData[location + size] !== currentBufferData[location + size]) {
+                            this._bufferData[location + size] = currentBufferData[location + size];
+                            this._needSync = true;
+                        }
+                    }
+                }
+            }
             if (this._currentEffect && this._buffer) {
                 this._currentEffect.bindUniformBuffer(this._buffer, this._currentEffectName);
             }
@@ -547,6 +565,7 @@ export class UniformBuffer {
         if (ThinEngine.Features.trackUbosInFrame && this._currentFrameId !== this._engine.frameId) {
             this._currentFrameId = this._engine.frameId;
             this._createBufferOnWrite = false;
+            this._updateList.length = 0;
             if (this._buffers && this._buffers.length > 0) {
                 this._bufferIndex = 0;
                 this._buffer = this._buffers[this._bufferIndex][0];
@@ -593,7 +612,7 @@ export class UniformBuffer {
                 if ((size === 16 && !ThinEngine.Features.uniformBufferHardCheckMatrix) || this._bufferData[location + i] !== data[i]) {
                     changed = true;
                     if (this._createBufferOnWrite) {
-                        if (!this._createNewBuffer()) {
+                        if (!this._createNewBuffer(location)) {
                             // we didn't create a new buffer but advanced to the next one: retry the update, chances are that the new buffer already has the right data for uniformName so we won't set needSync to true
                             this.updateUniform(uniformName, data, size);
                             return;
@@ -603,11 +622,15 @@ export class UniformBuffer {
                 }
             }
 
+            if (changed && ThinEngine.Features.trackUbosInFrame) {
+                this._updateList[this._updateList.length] = [location, size];
+            }
+
             this._needSync = this._needSync || changed;
         } else {
             // No cache for dynamic
             if (this._createBufferOnWrite) {
-                this._createNewBuffer();
+                this._createNewBuffer(-1);
             }
             for (var i = 0; i < size; i++) {
                 this._bufferData[location + i] = data[i];
@@ -644,7 +667,7 @@ export class UniformBuffer {
             for (var i = 0; i < size; i++) {
                 if (this._bufferData[location + baseStride * 4 + countToFour] !== data[i]) {
                     changed = true;
-                    if (!this._createNewBuffer()) {
+                    if (!this._createNewBuffer(location)) {
                         // we didn't create a new buffer but advanced to the next one: retry the update, chances are that the new buffer already has the right data for uniformName so we won't set needSync to true
                         this.updateUniformArray(uniformName, data, size);
                         return;
@@ -661,11 +684,15 @@ export class UniformBuffer {
                 }
             }
 
+            if (changed && ThinEngine.Features.trackUbosInFrame) {
+                this._updateList[this._updateList.length] = [location, baseStride * 4];
+            }
+
             this._needSync = this._needSync || changed;
         } else {
             // No cache for dynamic
             if (this._createBufferOnWrite) {
-                this._createNewBuffer();
+                this._createNewBuffer(-1);
             }
             for (var i = 0; i < size; i++) {
                 this._bufferData[location + i] = data[i];
@@ -685,6 +712,9 @@ export class UniformBuffer {
         }
 
         this._valueCache[name] = flag;
+        if (ThinEngine.Features.trackUbosInFrame) {
+            this._updateList[this._updateList.length] = [-1, flag, name];
+        }
 
         return true;
     }

+ 1 - 0
src/Shaders/ShadersInclude/sceneUboDeclaration.fx

@@ -6,6 +6,7 @@ uniform Scene {
 	mat4 viewProjectionR;
 #endif 
 	mat4 view;
+	mat4 projection;
     vec4 viewPosition;
 };
 

+ 1 - 1
src/scene.ts

@@ -1656,7 +1656,7 @@ export class Scene extends AbstractScene implements IAnimatable, IClipPlanesHold
     }
 
     private _createUbo(): void {
-        this._sceneUbo = new UniformBuffer(this._engine, undefined, !ThinEngine.Features.trackUbosInFrame, "scene");
+        this._sceneUbo = new UniformBuffer(this._engine, undefined, false, "scene");
         this._sceneUbo.addUniform("viewProjection", 16);
         this._sceneUbo.addUniform("view", 16);
         this._sceneUbo.addUniform("projection", 16);