|
@@ -67,6 +67,11 @@ export interface WebGPUEngineOptions extends GPURequestAdapterOptions {
|
|
|
* Defines the requested Swap Chain Format.
|
|
|
*/
|
|
|
swapChainFormat?: GPUTextureFormat;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Defines wether MSAA is enabled on the canvas.
|
|
|
+ */
|
|
|
+ antialiasing?: boolean;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -76,10 +81,9 @@ export class WebGPUEngine extends Engine {
|
|
|
// Page Life cycle and constants
|
|
|
private readonly _uploadEncoderDescriptor = { label: "upload" };
|
|
|
private readonly _renderEncoderDescriptor = { label: "render" };
|
|
|
- private readonly _blitDescriptor = { label: "upload" };
|
|
|
private readonly _clearDepthValue = 1;
|
|
|
private readonly _clearStencilValue = 0;
|
|
|
- private readonly _defaultSampleCount = 1;
|
|
|
+ private readonly _defaultSampleCount = 4; // Only supported value for now.
|
|
|
|
|
|
// Engine Life Cycle
|
|
|
private _canvas: HTMLCanvasElement;
|
|
@@ -89,13 +93,13 @@ export class WebGPUEngine extends Engine {
|
|
|
private _device: GPUDevice;
|
|
|
private _context: GPUCanvasContext;
|
|
|
private _swapChain: GPUSwapChain;
|
|
|
+ private _mainPassSampleCount: number;
|
|
|
|
|
|
// Some of the internal state might change during the render pass.
|
|
|
// This happens mainly during clear for the state
|
|
|
// And when the frame starts to swap the target texture from the swap chain
|
|
|
private _mainTexture: GPUTexture;
|
|
|
private _depthTexture: GPUTexture;
|
|
|
- private _mainTextureCopyView: GPUTextureCopyView;
|
|
|
private _mainColorAttachments: GPURenderPassColorAttachmentDescriptor[];
|
|
|
private _mainTextureExtends: GPUExtent3D;
|
|
|
private _mainDepthAttachment: GPURenderPassDepthStencilAttachmentDescriptor;
|
|
@@ -103,7 +107,6 @@ export class WebGPUEngine extends Engine {
|
|
|
// Frame Life Cycle (recreated each frame)
|
|
|
private _uploadEncoder: GPUCommandEncoder;
|
|
|
private _renderEncoder: GPUCommandEncoder;
|
|
|
- private _blitEncoder: GPUCommandEncoder;
|
|
|
|
|
|
private _commandBuffers: GPUCommandBuffer[] = [null as any, null as any];
|
|
|
|
|
@@ -159,6 +162,7 @@ export class WebGPUEngine extends Engine {
|
|
|
|
|
|
options.deviceDescriptor = options.deviceDescriptor || { };
|
|
|
options.swapChainFormat = options.swapChainFormat || WebGPUConstants.GPUTextureFormat_bgra8unorm;
|
|
|
+ options.antialiasing = options.antialiasing === undefined ? true : options.antialiasing;
|
|
|
|
|
|
this._decodeEngine.getCaps().textureFloat = false;
|
|
|
this._decodeEngine.getCaps().textureFloatRender = false;
|
|
@@ -194,8 +198,8 @@ export class WebGPUEngine extends Engine {
|
|
|
this._canvas = canvas;
|
|
|
this._options = options;
|
|
|
|
|
|
- // TODO WEBGPU. RESIZE and SCALING.
|
|
|
this._hardwareScalingLevel = 1;
|
|
|
+ this._mainPassSampleCount = options.antialiasing ? this._defaultSampleCount : 1;
|
|
|
|
|
|
this._sharedInit(canvas, !!options.doNotHandleTouchAction, options.audioEngine);
|
|
|
}
|
|
@@ -209,8 +213,7 @@ export class WebGPUEngine extends Engine {
|
|
|
* @param shadercOptions Defines the ShaderC compiler options if necessary
|
|
|
* @returns a promise notifying the readiness of the engine.
|
|
|
*/
|
|
|
- public initEngineAsync(shadercOptions: any = null): Promise<void> {
|
|
|
- // TODO WEBGPU. Rename to initAsync.
|
|
|
+ public initAsync(shadercOptions: any = null): Promise<void> {
|
|
|
return (window as any).Shaderc(shadercOptions)
|
|
|
.then((shaderc: any) => {
|
|
|
this._shaderc = shaderc;
|
|
@@ -290,12 +293,11 @@ export class WebGPUEngine extends Engine {
|
|
|
this._swapChain = this._context.configureSwapChain({
|
|
|
device: this._device,
|
|
|
format: this._options.swapChainFormat!,
|
|
|
- usage: WebGPUConstants.GPUTextureUsage_TRANSFER_DST,
|
|
|
+ usage: WebGPUConstants.GPUTextureUsage_OUTPUT_ATTACHMENT | WebGPUConstants.GPUTextureUsage_COPY_SRC,
|
|
|
});
|
|
|
}
|
|
|
|
|
|
// Set default values as WebGL with depth and stencil attachment for the broadest Compat.
|
|
|
- // TODO WEBGPU. Reinit on resize.
|
|
|
private _initializeMainAttachments(): void {
|
|
|
this._mainTextureExtends = {
|
|
|
width: this.getRenderWidth(),
|
|
@@ -303,46 +305,43 @@ export class WebGPUEngine extends Engine {
|
|
|
depth: 1
|
|
|
};
|
|
|
|
|
|
- const mainTextureDescriptor = {
|
|
|
- size: this._mainTextureExtends,
|
|
|
- arrayLayerCount: 1,
|
|
|
- mipLevelCount: 1,
|
|
|
- sampleCount: this._defaultSampleCount,
|
|
|
- dimension: WebGPUConstants.GPUTextureDimension_2d,
|
|
|
- format: WebGPUConstants.GPUTextureFormat_bgra8unorm,
|
|
|
- usage: WebGPUConstants.GPUTextureUsage_OUTPUT_ATTACHMENT | WebGPUConstants.GPUTextureUsage_TRANSFER_SRC,
|
|
|
- };
|
|
|
+ if (this._options.antialiasing) {
|
|
|
+ const mainTextureDescriptor = {
|
|
|
+ size: this._mainTextureExtends,
|
|
|
+ arrayLayerCount: 1,
|
|
|
+ mipLevelCount: 1,
|
|
|
+ sampleCount: this._mainPassSampleCount,
|
|
|
+ dimension: WebGPUConstants.GPUTextureDimension_2d,
|
|
|
+ format: WebGPUConstants.GPUTextureFormat_bgra8unorm,
|
|
|
+ usage: WebGPUConstants.GPUTextureUsage_OUTPUT_ATTACHMENT,
|
|
|
+ };
|
|
|
|
|
|
- if (this._mainTexture) {
|
|
|
- this._mainTexture.destroy();
|
|
|
+ if (this._mainTexture) {
|
|
|
+ this._mainTexture.destroy();
|
|
|
+ }
|
|
|
+ this._mainTexture = this._device.createTexture(mainTextureDescriptor);
|
|
|
+ this._mainColorAttachments = [{
|
|
|
+ attachment: this._mainTexture.createDefaultView(),
|
|
|
+ loadValue: new Color4(0, 0, 0, 1),
|
|
|
+ storeOp: WebGPUConstants.GPUStoreOp_store
|
|
|
+ }];
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ this._mainColorAttachments = [{
|
|
|
+ attachment: this._swapChain.getCurrentTexture().createDefaultView(),
|
|
|
+ loadValue: new Color4(0, 0, 0, 1),
|
|
|
+ storeOp: WebGPUConstants.GPUStoreOp_store
|
|
|
+ }];
|
|
|
}
|
|
|
- this._mainTexture = this._device.createTexture(mainTextureDescriptor);
|
|
|
- const mainTextureView = this._mainTexture.createDefaultView();
|
|
|
- this._mainTextureCopyView = {
|
|
|
- texture: this._mainTexture,
|
|
|
- origin: {
|
|
|
- x: 0,
|
|
|
- y: 0,
|
|
|
- z: 0
|
|
|
- },
|
|
|
- mipLevel: 0,
|
|
|
- arrayLayer: 0,
|
|
|
- };
|
|
|
-
|
|
|
- this._mainColorAttachments = [{
|
|
|
- attachment: mainTextureView,
|
|
|
- loadValue: new Color4(0, 0, 0, 1),
|
|
|
- storeOp: WebGPUConstants.GPUStoreOp_store
|
|
|
- }];
|
|
|
|
|
|
const depthTextureDescriptor = {
|
|
|
size: this._mainTextureExtends,
|
|
|
arrayLayerCount: 1,
|
|
|
mipLevelCount: 1,
|
|
|
- sampleCount: this._defaultSampleCount,
|
|
|
+ sampleCount: this._mainPassSampleCount,
|
|
|
dimension: WebGPUConstants.GPUTextureDimension_2d,
|
|
|
format: WebGPUConstants.GPUTextureFormat_depth24plusStencil8,
|
|
|
- usage: WebGPUConstants.GPUTextureUsage_OUTPUT_ATTACHMENT
|
|
|
+ usage: WebGPUConstants.GPUTextureUsage_OUTPUT_ATTACHMENT
|
|
|
};
|
|
|
|
|
|
if (this._depthTexture) {
|
|
@@ -1160,7 +1159,7 @@ export class WebGPUEngine extends Engine {
|
|
|
mipLevelCount: noMipmap ? 1 : mipMaps + 1,
|
|
|
sampleCount: 1,
|
|
|
size: textureExtent,
|
|
|
- usage: WebGPUConstants.GPUTextureUsage_TRANSFER_DST | WebGPUConstants.GPUTextureUsage_SAMPLED
|
|
|
+ usage: WebGPUConstants.GPUTextureUsage_COPY_DST | WebGPUConstants.GPUTextureUsage_SAMPLED
|
|
|
};
|
|
|
|
|
|
const gpuTexture = this._device.createTexture(textureDescriptor);
|
|
@@ -1239,7 +1238,7 @@ export class WebGPUEngine extends Engine {
|
|
|
mipLevelCount: noMipmap ? 1 : mipMaps + 1,
|
|
|
sampleCount: 1,
|
|
|
size: textureExtent,
|
|
|
- usage: WebGPUConstants.GPUTextureUsage_TRANSFER_DST | WebGPUConstants.GPUTextureUsage_SAMPLED
|
|
|
+ usage: WebGPUConstants.GPUTextureUsage_COPY_DST | WebGPUConstants.GPUTextureUsage_SAMPLED
|
|
|
};
|
|
|
|
|
|
const gpuTexture = this._device.createTexture(textureDescriptor);
|
|
@@ -1407,7 +1406,6 @@ export class WebGPUEngine extends Engine {
|
|
|
|
|
|
this._uploadEncoder = this._device.createCommandEncoder(this._uploadEncoderDescriptor);
|
|
|
this._renderEncoder = this._device.createCommandEncoder(this._renderEncoderDescriptor);
|
|
|
- this._blitEncoder = this._device.createCommandEncoder(this._blitDescriptor);
|
|
|
}
|
|
|
|
|
|
private _freezeCommands: boolean = false;
|
|
@@ -1438,20 +1436,6 @@ export class WebGPUEngine extends Engine {
|
|
|
this._frozenCommands[1] = this._commandBuffers[1];
|
|
|
}
|
|
|
|
|
|
- // TODO WEBGPU. GC.
|
|
|
- this._blitEncoder.copyTextureToTexture(this._mainTextureCopyView, {
|
|
|
- texture: this._swapChain.getCurrentTexture(),
|
|
|
- origin: {
|
|
|
- x: 0,
|
|
|
- y: 0,
|
|
|
- z: 0
|
|
|
- },
|
|
|
- mipLevel: 0,
|
|
|
- arrayLayer: 0,
|
|
|
- },
|
|
|
- this._mainTextureExtends);
|
|
|
- this._commandBuffers[2] = this._blitEncoder.finish();
|
|
|
-
|
|
|
this._device.getQueue().submit(this._commandBuffers);
|
|
|
|
|
|
super.endFrame();
|
|
@@ -1482,7 +1466,13 @@ export class WebGPUEngine extends Engine {
|
|
|
this._endRenderPass();
|
|
|
}
|
|
|
|
|
|
- // this._mainColorAttachments[0].attachment = this._swapChain.getCurrentTexture().createDefaultView();
|
|
|
+ // Resolve in case of MSAA
|
|
|
+ if (this._options.antialiasing) {
|
|
|
+ this._mainColorAttachments[0].resolveTarget = this._swapChain.getCurrentTexture().createDefaultView();
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ this._mainColorAttachments[0].attachment = this._swapChain.getCurrentTexture().createDefaultView();
|
|
|
+ }
|
|
|
|
|
|
this._currentRenderPass = this._renderEncoder.beginRenderPass({
|
|
|
colorAttachments: this._mainColorAttachments,
|
|
@@ -2061,7 +2051,6 @@ export class WebGPUEngine extends Engine {
|
|
|
}
|
|
|
|
|
|
// Unsupported at the moment but needs to be extracted from the MSAA param.
|
|
|
- const sampleCount = this._defaultSampleCount;
|
|
|
const topology = this._getTopology(fillMode);
|
|
|
const rasterizationStateDescriptor = this._getRasterizationStateDescriptor();
|
|
|
const depthStateDescriptor = this._getDepthStencilStateDescriptor();
|
|
@@ -2071,7 +2060,7 @@ export class WebGPUEngine extends Engine {
|
|
|
const pipelineLayout = this._getPipelineLayout();
|
|
|
|
|
|
gpuPipeline.renderPipeline = this._device.createRenderPipeline({
|
|
|
- sampleCount,
|
|
|
+ sampleCount: this._mainPassSampleCount,
|
|
|
primitiveTopology: topology,
|
|
|
rasterizationState: rasterizationStateDescriptor,
|
|
|
depthStencilState: depthStateDescriptor,
|