Skip to content
2 changes: 1 addition & 1 deletion packages/dev/core/src/Engines/Native/nativeInterfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export interface INativeEngine {
updateDynamicVertexBuffer(vertexBuffer: NativeData, bytes: ArrayBuffer, byteOffset: number, byteLength: number): void;

createProgram(vertexShader: string, fragmentShader: string): NativeProgram;
createProgramAsync(vertexShader: string, fragmentShader: string, onSuccess: () => void, onError: () => void): NativeProgram;
createProgramAsync(vertexShader: string, fragmentShader: string, onSuccess: () => void, onError: (error: Error) => void): NativeProgram;
getUniforms(shaderProgram: NativeProgram, uniformsNames: string[]): WebGLUniformLocation[];
getAttributes(shaderProgram: NativeProgram, attributeNames: string[]): number[];

Expand Down
15 changes: 13 additions & 2 deletions packages/dev/core/src/Engines/Native/nativePipelineContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,27 @@ import type { IMatrixLike, IVector2Like, IVector3Like, IVector4Like, IColor3Like
import type { IPipelineContext } from "../IPipelineContext";
import type { NativeEngine } from "../nativeEngine";

export enum CompilationState {
uncompiled,
compiled,
error,
}

export class NativePipelineContext implements IPipelineContext {
public isParallelCompiled: boolean = true;
public isCompilationComplete: boolean = false;
public compilationState: CompilationState = CompilationState.uncompiled;
public compilationError?: Error;

public get isAsync(): boolean {
return this.isParallelCompiled;
}

public get isReady(): boolean {
return this.isCompilationComplete;
if (this.compilationState === CompilationState.error) {
const message = this.compilationError?.message;
throw new Error("SHADER ERROR" + (typeof message === "string" ? "\n" + message : ""));
}
return this.compilationState === CompilationState.compiled;
}

public onCompiled?: () => void;
Expand Down
20 changes: 14 additions & 6 deletions packages/dev/core/src/Engines/nativeEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import type { NativeData } from "./Native/nativeDataStream";
import { NativeDataStream } from "./Native/nativeDataStream";
import type { INative, INativeCamera, INativeEngine, NativeFramebuffer, NativeProgram, NativeTexture, NativeUniform, NativeVertexArrayObject } from "./Native/nativeInterfaces";
import { RuntimeError, ErrorCodes } from "../Misc/error";
import { NativePipelineContext } from "./Native/nativePipelineContext";
import { CompilationState, NativePipelineContext } from "./Native/nativePipelineContext";
import { NativeRenderTargetWrapper } from "./Native/nativeRenderTargetWrapper";
import { NativeHardwareTexture } from "./Native/nativeHardwareTexture";
import type { HardwareTextureWrapper } from "../Materials/Textures/hardwareTextureWrapper";
Expand Down Expand Up @@ -698,17 +698,25 @@ export class NativeEngine extends Engine {
fragmentCode = ThinEngine._ConcatenateShader(fragmentCode, defines);

const onSuccess = () => {
nativePipelineContext.isCompilationComplete = true;
nativePipelineContext.compilationState = CompilationState.compiled;
nativePipelineContext.onCompiled?.();
this.onAfterShaderCompilationObservable.notifyObservers(this);
};

if (this.isAsync(pipelineContext)) {
return this._engine.createProgramAsync(vertexCode, fragmentCode, onSuccess, () => {}) as WebGLProgram;
return this._engine.createProgramAsync(vertexCode, fragmentCode, onSuccess, (error: Error) => {
nativePipelineContext.compilationState = CompilationState.error;
nativePipelineContext.compilationError = error;
}) as WebGLProgram;
} else {
const program = (nativePipelineContext.nativeProgram = this._engine.createProgram(vertexCode, fragmentCode));
onSuccess();
return program as WebGLProgram;
try {
const program = (nativePipelineContext.nativeProgram = this._engine.createProgram(vertexCode, fragmentCode));
onSuccess();
return program as WebGLProgram;
} catch (e: any) {
const message = e?.message;
throw new Error("SHADER ERROR" + (typeof message === "string" ? "\n" + message : ""));
}
}
}

Expand Down