Skip to content

Commit

Permalink
[WebGPU] GPUCanvasContext.configure() should validate the GPUTextureD…
Browse files Browse the repository at this point in the history
…escriptor before creating the backing textures

https://bugs.webkit.org/show_bug.cgi?id=271404
rdar://125183118

Reviewed by Tadeu Zagallo.

The spec says we should validate the texture descriptor before
creating the texures in GPUCanvasContext.configure() and we
were not doing so.

Doing so avoids crashes createTextureView() as the returned
texture is invalid.

* Source/WebGPU/WebGPU/Device.h:
* Source/WebGPU/WebGPU/PresentationContextIOSurface.mm:
(WebGPU::PresentationContextIOSurface::configure):

Canonical link: https://commits.webkit.org/276648@main
  • Loading branch information
mwyrzykowski committed Mar 25, 2024
1 parent c33f546 commit 313a887
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 23 deletions.
2 changes: 1 addition & 1 deletion Source/WebGPU/WebGPU/Device.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ class Device : public WGPUDeviceImpl, public ThreadSafeRefCountedAndCanMakeThrea
id<MTLBuffer> placeholderBuffer() const;
id<MTLTexture> placeholderTexture() const;
bool isDestroyed() const;
NSString *errorValidatingTextureCreation(const WGPUTextureDescriptor&, const Vector<WGPUTextureFormat>& viewFormats);

private:
Device(id<MTLDevice>, id<MTLCommandQueue> defaultQueue, HardwareCapabilities&&, Adapter&);
Expand All @@ -143,7 +144,6 @@ class Device : public WGPUDeviceImpl, public ThreadSafeRefCountedAndCanMakeThrea
ErrorScope* currentErrorScope(WGPUErrorFilter);
std::optional<WGPUErrorType> validatePopErrorScope() const;
id<MTLBuffer> safeCreateBuffer(NSUInteger length, MTLStorageMode, MTLCPUCacheMode = MTLCPUCacheModeDefaultCache, MTLHazardTrackingMode = MTLHazardTrackingModeDefault) const;
NSString *errorValidatingTextureCreation(const WGPUTextureDescriptor&, const Vector<WGPUTextureFormat>& viewFormats);
bool validateCreateIOSurfaceBackedTexture(const WGPUTextureDescriptor&, const Vector<WGPUTextureFormat>& viewFormats, IOSurfaceRef backing);

bool validateRenderPipeline(const WGPURenderPipelineDescriptor&);
Expand Down
51 changes: 29 additions & 22 deletions Source/WebGPU/WebGPU/PresentationContextIOSurface.mm
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,35 @@
if (iosurface.height != static_cast<NSInteger>(height) || iosurface.width != static_cast<NSInteger>(width))
return device.generateAValidationError("Invalid surface size"_s);
}

if (!allowedFormat(descriptor.format)) {
device.generateAValidationError([NSString stringWithFormat:@"Requested texture format %s is not a valid context format", Texture::formatToString(descriptor.format)]);
return;
}

if (descriptor.width > limits.maxTextureDimension2D || descriptor.height > limits.maxTextureDimension2D) {
device.generateAValidationError("Requested canvas width and/or height are too large"_s);
return;
}

for (auto viewFormat : descriptor.viewFormats) {
if (!allowedViewFormat(viewFormat)) {
device.generateAValidationError("Requested texture view format BGRA8UnormStorage is not enabled"_s);
return;
}
}

Vector viewFormats(std::span { wgpuTextureDescriptor.viewFormats, wgpuTextureDescriptor.viewFormatCount });
if (NSString *error = device.errorValidatingTextureCreation(wgpuTextureDescriptor, viewFormats)) {
device.generateAValidationError(error);
return;
}

if ((descriptor.usage & WGPUTextureUsage_StorageBinding) && !device.hasFeature(WGPUFeatureName_BGRA8UnormStorage)) {
device.generateAValidationError("Requested storage format but BGRA8UnormStorage is not enabled"_s);
return;
}

for (IOSurface *iosurface in m_ioSurfaces) {
RefPtr<Texture> parentLuminanceClampTexture;
if (textureDescriptor.pixelFormat == MTLPixelFormatRGBA16Float) {
Expand All @@ -154,28 +183,6 @@
}
ASSERT(m_ioSurfaces.count == m_renderBuffers.size());

if (!allowedFormat(descriptor.format)) {
device.generateAValidationError([NSString stringWithFormat:@"Requested texture format %s is not a valid context format", Texture::formatToString(descriptor.format)]);
return;
}

if (descriptor.width > limits.maxTextureDimension2D || descriptor.height > limits.maxTextureDimension2D) {
device.generateAValidationError("Requested canvas width and/or height are too large"_s);
return;
}

for (auto viewFormat : descriptor.viewFormats) {
if (!allowedViewFormat(viewFormat)) {
device.generateAValidationError("Requested texture view format BGRA8UnormStorage is not enabled"_s);
return;
}
}

if ((descriptor.usage & WGPUTextureUsage_StorageBinding) && !device.hasFeature(WGPUFeatureName_BGRA8UnormStorage)) {
device.generateAValidationError("Requested storage format but BGRA8UnormStorage is not enabled"_s);
return;
}

if (needsLuminanceClampFunction) {
NSError *error = nil;
MTLCompileOptions* options = [MTLCompileOptions new];
Expand Down

0 comments on commit 313a887

Please sign in to comment.