Skip to content

Commit

Permalink
Merge 788b1e1 into 00ca9fb
Browse files Browse the repository at this point in the history
  • Loading branch information
ibgreen committed Mar 6, 2024
2 parents 00ca9fb + 788b1e1 commit 1a47848
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 24 deletions.
46 changes: 33 additions & 13 deletions modules/core/src/adapter/device.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import {isTextureFormatCompressed} from './type-utils/decode-texture-format';
*/
export type DeviceInfo = {
/** Type of device */
type: 'webgl' | 'webgpu';
type: 'webgl' | 'webgpu' | 'unknown';
/** Vendor (name of GPU vendor, Apple, nVidia etc */
vendor: string;
/** Renderer (usually driver name) */
Expand Down Expand Up @@ -116,17 +116,22 @@ export abstract class DeviceLimits {
/** Set-like class for features (lets apps check for WebGL / WebGPU extensions) */
export class DeviceFeatures {
protected features: Set<DeviceFeature>;
protected disabledFeatures?: Partial<Record<DeviceFeature, boolean>>;

constructor(features: DeviceFeature[] = []) {
constructor(
features: DeviceFeature[] = [],
disabledFeatures: Partial<Record<DeviceFeature, boolean>>
) {
this.features = new Set<DeviceFeature>(features);
this.disabledFeatures = disabledFeatures || {};
}

*[Symbol.iterator](): IterableIterator<DeviceFeature> {
yield* this.features;
}

has(feature: DeviceFeature): boolean {
return this.features.has(feature);
return !this.disabledFeatures[feature] && this.features.has(feature);
}
}

Expand Down Expand Up @@ -199,8 +204,8 @@ export type DeviceProps = {
width?: number /** width is only used when creating a new canvas */;
height?: number /** height is only used when creating a new canvas */;

/** Request a Device with the highest limits supported by platform. */
requestMaximalLimits?: boolean;
/** Request a Device with the highest limits supported by platform. WebGPU: devices can be created with minimal limits. */
requestMaxLimits?: boolean;

// WebGLContext PARAMETERS - Can only be set on context creation...
// alpha?: boolean; // Default render target has an alpha buffer.
Expand All @@ -211,17 +216,26 @@ export type DeviceProps = {
// preserveDrawingBuffer?: boolean; // Default render target buffers will not be automatically cleared and will preserve their values until cleared or overwritten
// failIfMajorPerformanceCaveat?: boolean; // Do not create if the system performance is low.

/** Error handling */
onError?: (error: Error) => unknown;
/** Instrument context (at the expense of performance) */

// DEBUG SETTINGS

/** WebGL: Instrument WebGL2RenderingContext (at the expense of performance) */
debug?: boolean;
/** Initialize the SpectorJS WebGL debugger */
/** Break on WebGL functions matching these strings */
break?: string[];
/** WebGL: Initialize the SpectorJS WebGL debugger */
spector?: boolean;
/** Initialize all features on startup */
initalizeFeatures?: boolean;
/** Disable specific features */
disabledFeatures?: Partial<Record<DeviceFeature, boolean>>;

// Unclear if these are still supported
manageState?: boolean; // Set to false to disable WebGL state management instrumentation
break?: string[]; // TODO: types
/** TODO- Unclear if still supported: Set to false to disable WebGL state management instrumentation */
manageState?: boolean;

// @deprecated Attach to existing context
// @deprecated Attach to existing context. Rename to handle? Use Device.attach?
gl?: WebGL2RenderingContext | null;
};

Expand All @@ -237,11 +251,17 @@ export abstract class Device {
width: 800, // width are height are only used by headless gl
height: 600,

requestMaximalLimits: true,
requestMaxLimits: true,
debug: Boolean(log.get('debug')), // Instrument context (at the expense of performance)
spector: Boolean(log.get('spector')), // Initialize the SpectorJS WebGL debugger
break: [],

// TODO - Change these after confirming things work as expected
initalizeFeatures: true,
disabledFeatures: {
'compilation-status-async-webgl': true
},

// alpha: undefined,
// depth: undefined,
// stencil: undefined,
Expand Down Expand Up @@ -270,7 +290,7 @@ export abstract class Device {
/** id of this device, primarily for debugging */
readonly id: string;
/** type of this device */
abstract readonly type: 'webgl' | 'webgpu';
abstract readonly type: 'webgl' | 'webgpu' | 'unknown';
/** A copy of the device props */
readonly props: Required<DeviceProps>;
/** Available for the application to store data on the device */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*/
export type PlatformInfo = {
/** Current Web GPU API backend */
type: 'webgl' | 'webgl2' | 'webgpu';
type: 'webgl' | 'webgpu' | 'unknown';
/** Which shader language is supported */
shaderLanguage: 'glsl' | 'wgsl';
/** Which shader language version is preferred */
Expand Down
8 changes: 3 additions & 5 deletions modules/test-utils/src/null-device/null-device.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,12 @@ import {NullQuerySet} from './resources/null-query-set';

/** Do-nothing device implementation for testing */
export class NullDevice extends Device {
static type: string = 'webgl';

static isSupported(): boolean {
return true;
}

readonly type = 'webgl';
features: DeviceFeatures = new DeviceFeatures();
static type: string = 'unknown';
readonly type = 'unknown';
features: DeviceFeatures = new DeviceFeatures([], this.props.disabledFeatures);
limits: NullDeviceLimits = new NullDeviceLimits();
readonly info = NullDeviceInfo;

Expand Down
24 changes: 22 additions & 2 deletions modules/webgl/src/adapter/device-helpers/webgl-device-features.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,12 @@ export class WebGLDeviceFeatures extends DeviceFeatures {
protected extensions: GLExtensions;
protected testedFeatures = new Set<DeviceFeature>();

constructor(gl: WebGL2RenderingContext, extensions: GLExtensions) {
super();
constructor(
gl: WebGL2RenderingContext,
extensions: GLExtensions,
disabledFeatures: Partial<Record<DeviceFeature, boolean>>
) {
super([], disabledFeatures);
this.gl = gl;
this.extensions = extensions;
// TODO - is this really needed?
Expand All @@ -71,6 +75,10 @@ export class WebGLDeviceFeatures extends DeviceFeatures {
}

override has(feature: DeviceFeature): boolean {
if (this.disabledFeatures[feature]) {
return false;
}

// We have already tested this feature
if (!this.testedFeatures.has(feature)) {
this.testedFeatures.add(feature);
Expand All @@ -87,6 +95,18 @@ export class WebGLDeviceFeatures extends DeviceFeatures {
return this.features.has(feature);
}

// FOR DEVICE

initializeFeatures() {
// @ts-expect-error
// eslint-disable-next-line @typescript-eslint/no-unused-vars
for (const feature of this) {
// WebGL extensions are initialized by requesting them
}
}

// IMPLEMENTATION

/** Extract all WebGL features */
protected getWebGLFeature(feature: DeviceFeature): boolean {
const featureInfo = WEBGL_FEATURES[feature];
Expand Down
5 changes: 4 additions & 1 deletion modules/webgl/src/adapter/webgl-device.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,11 @@ ${device.info.vendor}, ${device.info.renderer} for canvas: ${device.canvasContex

// luma Device fields
this.info = getDeviceInfo(this.gl, this._extensions);
this.features = new WebGLDeviceFeatures(this.gl, this._extensions);
this.limits = new WebGLDeviceLimits(this.gl);
this.features = new WebGLDeviceFeatures(this.gl, this._extensions, this.props.disabledFeatures);
if (this.props.initalizeFeatures) {
this.features.initializeFeatures();
}

this.canvasContext.resize();

Expand Down
4 changes: 2 additions & 2 deletions modules/webgpu/src/adapter/webgpu-device.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export class WebGPUDevice extends Device {
const requiredFeatures: GPUFeatureName[] = [];
const requiredLimits: Record<string, number> = {};

if (props.requestMaximalLimits) {
if (props.requestMaxLimits) {
requiredFeatures.push(...(Array.from(adapter.features) as GPUFeatureName[]));
for (const key in adapter.limits) {
requiredLimits[key] = adapter.limits[key];
Expand Down Expand Up @@ -332,7 +332,7 @@ export class WebGPUDevice extends Device {
features.add(feature);
}

return new DeviceFeatures(Array.from(features));
return new DeviceFeatures(Array.from(features), this.props.disabledFeatures);
}

copyExternalImageToTexture(options: {
Expand Down

0 comments on commit 1a47848

Please sign in to comment.