Sitelet https://github.com/WebKit/WebKit/pull/5785
Skip to content

Bringup red triangle - #5785

Merged
webkit-commit-queue merged 1 commit into
WebKit:mainfrom
mwyrzykowski:eng/Bringup-red-triangle
Nov 7, 2022
Merged

webkit-commit-queue merged 1 commit into
WebKit:mainfrom
mwyrzykowski:eng/Bringup-red-triangle

Conversation

@mwyrzykowski

@mwyrzykowski mwyrzykowski commented Oct 25, 2022 •

Copy link
Copy Markdown
Contributor

2c1db24

Bringup red triangle
https://bugs.webkit.org/show_bug.cgi?id=247017
<radar://101514401>

Implement necessary interfaces to show a red triangle when WebGPU is enabled.

Reviewed by Myles C. Maxfield.

* Source/WTF/Scripts/Preferences/WebPreferences.yaml:
Place WebGPU enablement behind a local define.

* Source/WebCore/Modules/WebGPU/GPUCanvasContext.cpp:
(WebCore::getCanvasSizeAsIntSize):
(WebCore::platformSupportsWebGPUSurface):
(WebCore::GPUCanvasContext::create):
(WebCore::GPUCanvasContext::GPUCanvasContext):
(WebCore::GPUCanvasContext::reshape):
(WebCore::GPUCanvasContext::canvas):
(WebCore::GPUCanvasContext::configure):
(WebCore::GPUCanvasContext::getCurrentTexture):
(WebCore::GPUCanvasContext::pixelFormat const):
(WebCore::GPUCanvasContext::unconfigure):
(WebCore::GPUCanvasContext::colorSpace const):
(WebCore::GPUCanvasContext::layerContentsDisplayDelegate):
(WebCore::GPUCanvasContext::prepareForDisplay):
(WebCore::GPUCanvasContext::markContextChangedAndNotifyCanvasObservers):
Stub out implementation of GPUCanvasContext.

* Source/WebCore/Modules/WebGPU/GPUCanvasContext.h:
(WebCore::GPUCanvasContext::create): Deleted.
Renamed.

* Source/WebCore/Modules/WebGPU/GPUCanvasContext.idl:
Add ActiveDOMObject.

* Source/WebCore/PAL/pal/graphics/WebGPU/Impl/WebGPUBufferImpl.cpp:
(PAL::WebGPU::BufferImpl::getMappedRange):
Use the size of the buffer and not WGPU_WHOLE_MAP_SIZE, otherwise the
returned buffer size does not match what the client expects.

* Source/WebCore/dom/Document.cpp:
(WebCore::Document::getCSSCanvasContext):
Return gpu canvas if needed.

* Source/WebCore/dom/Document.h:
* Source/WebCore/dom/Document.idl:
Add support for GPUCanvas.

* Source/WebCore/html/HTMLCanvasElement.cpp:
(WebCore::HTMLCanvasElement::getContext):
(WebCore::HTMLCanvasElement::isWebGPUType):
(WebCore::HTMLCanvasElement::createContextWebGPU):
(WebCore::HTMLCanvasElement::getContextWebGPU):
* Source/WebCore/html/HTMLCanvasElement.h:
* Source/WebCore/html/HTMLCanvasElement.idl:
* Source/WebCore/html/canvas/CanvasRenderingContext.h:
(WebCore::CanvasRenderingContext::isWebGPU const):
Add support for gpu canvas.

* Source/WebCore/platform/graphics/cocoa/IOSurface.mm:
(WebCore::IOSurface::createFromSurface):
Return nullptr if surface is 0.

* Source/WebCore/rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::shouldSetContentsDisplayDelegate const):
(WebCore::RenderLayerBacking::updateConfiguration):
* Source/WebCore/rendering/RenderLayerBacking.h:
Add support for gpu canvas.

* Source/WebGPU/WebGPU/Buffer.mm:
(wgpuBufferGetSize):
Comes from the WebGPU repo.

* Source/WebGPU/WebGPU/CommandEncoder.h:
* Source/WebGPU/WebGPU/CommandEncoder.mm:
(WebGPU::loadAction):
(WebGPU::storeAction):
(WebGPU::CommandEncoder::validateRenderPassDescriptor const):
(WebGPU::CommandEncoder::beginRenderPass):
* Source/WebGPU/WebGPU/Device.h:
Add some basic validation for beginning the render pass.

* Source/WebGPU/WebGPU/RenderPassEncoder.h:
* Source/WebGPU/WebGPU/RenderPassEncoder.mm:
(WebGPU::RenderPassEncoder::~RenderPassEncoder):
(WebGPU::RenderPassEncoder::draw):
(WebGPU::RenderPassEncoder::endPass):
(WebGPU::RenderPassEncoder::setPipeline):
Setup the pipeline and make the call to draw a number of
primitives.

* Source/WebGPU/WebGPU/RenderPipeline.h:
(WebGPU::RenderPipeline::create):
(WebGPU::RenderPipeline::primitiveType const):
(WebGPU::RenderPipeline::maybeIndexType const):
(WebGPU::RenderPipeline::frontFace const):
(WebGPU::RenderPipeline::cullMode const):
* Source/WebGPU/WebGPU/RenderPipeline.mm:
(WebGPU::blendOperation):
(WebGPU::blendFactor):
(WebGPU::colorWriteMask):
(WebGPU::frontFace):
(WebGPU::cullMode):
(WebGPU::primitiveType):
(WebGPU::indexType):
(WebGPU::Device::validateRenderPipeline):
(WebGPU::Device::createRenderPipeline):
(WebGPU::RenderPipeline::RenderPipeline):
Add some basic pipeline support and validation.

* Source/WebGPU/WebGPU/ShaderModule.h:
* Source/WebGPU/WebGPU/ShaderModule.mm:
(WebGPU::earlyCompileShaderModule):
Fallback to the MSL string if the shader length is 0.

(WebGPU::ShaderModule::getNamedFunction const):
Lookup the function from the metal library.

* Source/WebGPU/WebGPU/Texture.h:
* Source/WebGPU/WebGPU/Texture.mm:
(WebGPU::Texture::pixelFormat):
(WebGPU::Texture::depthOnlyAspectMetalFormat):
(WebGPU::Texture::stencilOnlyAspectMetalFormat):
(WebGPU::Device::createTexture):
(WebGPU::Texture::resolveTextureViewDescriptorDefaults const):
(WebGPU::Texture::resolveTextureFormat):
(WebGPU::Texture::validateCreateView const):
(WebGPU::Texture::createView):
(WebGPU::pixelFormat): Deleted.
(WebGPU::depthOnlyAspectMetalFormat): Deleted.
(WebGPU::stencilOnlyAspectMetalFormat): Deleted.
Add support for some additional texture formats.

* Source/WebGPU/WebGPU/WebGPU.h:
wgpuBufferGetSize is in the public header.

* Source/WebGPU/WebGPU/WebGPUExt.h:
IOSurface support.

* Source/WebKit/GPUProcess/graphics/WebGPU/RemoteAdapter.cpp:
(WebKit::RemoteAdapter::RemoteAdapter):

* Source/WebKit/GPUProcess/graphics/WebGPU/RemoteBuffer.cpp:
(WebKit::RemoteBuffer::mapAsync):
Mapping the buffer for writing was not providing a buffer of the correct length.

(WebKit::RemoteDevice::createIOSurfaceBackedTexture):
* Source/WebKit/GPUProcess/graphics/WebGPU/RemoteDevice.h:
* Source/WebKit/GPUProcess/graphics/WebGPU/RemoteDevice.messages.in:
Create IOSurface backed texture.

* Source/WebKit/Platform/IPC/StreamClientConnection.h:
(IPC::StreamClientConnection::trySendSyncStream):
WebGPU sends a SetStreamDestinationID message which would previously
trigger an assertion here.

* Source/WebKit/Shared/WebGPU/WebGPURenderPassColorAttachment.cpp:
(WebKit::WebGPU::ConvertToBackingContext::convertToBacking):
(WebKit::WebGPU::ConvertFromBackingContext::convertFromBacking):
* Source/WebKit/Shared/WebGPU/WebGPURenderPassColorAttachment.h:
* Source/WebKit/Shared/WebGPU/WebGPURenderPassColorAttachment.serialization.in:
* Source/WebKit/Shared/WebGPU/WebGPURenderPassDescriptor.cpp:
(WebKit::WebGPU::ConvertToBackingContext::convertToBacking):
(WebKit::WebGPU::ConvertFromBackingContext::convertFromBacking):
* Source/WebKit/Shared/WebGPU/WebGPURenderPassDescriptor.h:
* Source/WebKit/Shared/WebGPU/WebGPURenderPassDescriptor.serialization.in:
Use optional values for resolveTargets and occlusionQuerySets as they
do not need to be specified.

* Source/WebKit/WebProcess/GPU/graphics/WebGPU/RemoteQueueProxy.h:
adoptRef was not getting called on m_parent leading to crashes, but
its not appearent why it was a Ref<> in the first place.

* Websites/webkit.org/demos/webgpu/scripts/hello-triangle.js:
(async helloTriangle):
Update javascript to new syntax.

* Source/WebCore/html/canvas/GPUCanvasContext.cpp:
* Source/WebCore/html/canvas/PlaceholderRenderingContext.cpp:
* Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h:
* Source/WebCore/platform/graphics/cocoa/GraphicsContextGLCocoa.h:
* Source/WebCore/platform/graphics/cocoa/GraphicsContextGLCocoa.mm:
* Source/WebCore/platform/graphics/cocoa/WebProcessGraphicsContextGLCocoa.mm:
Add missing includes and forward declarations.

Canonical link: https://commits.webkit.org/256411@main

04c221c

Misc iOS, tvOS & watchOS macOS Linux Windows
✅ 🧪 style ✅ 🛠 ios ✅ 🛠 mac ✅ 🛠 wpe ✅ 🛠 🧪 win
✅ 🧪 bindings ✅ 🛠 ios-sim ✅ 🛠 mac-debug ✅ 🛠 gtk ✅ 🛠 wincairo
✅ 🧪 webkitperl   🧪 ios-wk2 ✅ 🛠 mac-AS-debug ✅ 🧪 gtk-wk2
  🧪 api-ios ✅ 🧪 api-mac ✅ 🧪 api-gtk
✅ 🛠 🧪 jsc ✅ 🛠 tv   🧪 mac-wk1 ✅ 🛠 jsc-armv7
✅ 🛠 tv-sim ✅ 🧪 mac-wk2 ✅ 🧪 jsc-armv7-tests
✅ 🛠 🧪 merge ✅ 🛠 watch   🧪 mac-AS-debug-wk2 ✅ 🛠 jsc-mips
✅ 🛠 watch-sim ✅ 🧪 mac-wk2-stress ✅ 🧪 jsc-mips-tests

@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Oct 26, 2022

@djg djg left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with nits.

Comment thread Source/WebGPU/WebGPU/Buffer.mm Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the removal of WGPUBufferUsage_CopyDst & WGPUBufferUsage_MapRead constraints?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previous validation didn't allow for MapWrite | Vertex or other valid
combinations. I relaxed restrictions to only prevent buffers mapped as both
read and write which is invalid according to the specification.

I couldn't find where in the spec it says Read is only valid with CopyDst, does that exist? And if so, how would the buffers get bound as vertex / index / uniform / etc buffers?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://gpuweb.github.io/gpuweb/#buffer-usage

If descriptor.usage contains MAP_READ: descriptor.usage contains no other flags except COPY_DST.

If descriptor.usage contains MAP_WRITE: descriptor.usage contains no other flags except COPY_SRC.

The idea is that authors have to copy data in/out of all mappable buffers. I've tried many times to relax this restriction.

gpuweb/gpuweb#2926 (comment)

gpuweb/gpuweb#2388

Comment thread Source/WebGPU/WebGPU/Buffer.mm Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

Comment thread Source/WebGPU/WebGPU/CommandEncoder.mm Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

`Fully' is redundant.

Comment thread Source/WebGPU/WebGPU/RenderPipeline.mm Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

`Fully' is redundant.

Comment thread Source/WebGPU/WebGPU/ShaderModule.mm Outdated
Comment on lines 86 to 91

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use C++ raw string literal?

return String::fromUTF8(R"(
#include <metal_stdlib>
using namespace metal;
struct Vertex {
    float4 position [[position]];
    float4 color;
    ...
)");

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh that is much nicer, I'll do that, thank you

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The linter did not like that:

ERROR: Source/WebGPU/WebGPU/ShaderModule.mm:86:  Multi-line string ("...") found.  This lint script doesn't do well with such strings, and may give bogus warnings.  They're ugly and unnecessary, and you should use concatenation instead".  [readability/multiline_string] [5]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not reviewing these very closely. Someone that knows GPUProcess should review these.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kkinnunen-apple is this a reasonable approach or should I do something else? These constructors get called on the WebGPU work queue but startReceivingMessages needs to be called from the main queue at the moment, right?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the surface level this looks incorrect.
If this is the intention, this class of changes look like they could perhaps be submitted separately.
Submitting to main runloop is done with callOnMainRunLoop, but this really doesn't look like the correct approach.

IIRC the WebGPU, like WebGL is using the "main" IPC::Connection as their out of stream connection.
If I understand correctly, you are running into an assertion? I think the solution is to start using the "dedicated connection", similar to what RemoteRenderingBackend uses. This change could be submitted separately.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wgslSource

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@litherum not sure if this change is correct / i.e., lifetime is guaranteed to be ok. But the RemoteDeviceProxy instance which is passed to RemoteQueueProxy's constructor comes from RemoteDeviceProxy.cpp:56 and there is no call to adoptRef(...) so using Ref<...> here crashes.

But based on RemoteDeviceProxy's usage of RemoteQueueProxy here it seems like the lifetime is ok

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can actually just delete this member. It doesn't appear to be used for anything, and the ownership model of queues is a bit tricky.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to remove m_parent but it seems to be used in a few places via these member functions in the header:

    RemoteDeviceProxy& parent() { return m_parent; }
    RemoteGPUProxy& root() { return m_parent.root(); }

@litherum litherum left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review-in-progress. There's a lot here.

Comment on lines 1949 to 1960

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should not do this until it's ready for people to play around with. I don't think the implementation is at a point where it's good for it to show up in the experimental features menu.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WebGPU (no space)

Comment on lines 85 to 86

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this is a silly question, but why does the abstraction layer need to be at the WebGPU layer? Why not just have WebGPUSurface (not WebGPUSurfaceCocoa) and have the objects inside it be platform-specific? I believe this is the design we use for compositing IIRC.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reasoning from Kiet was to allow non-Apple platforms have a platform specific implementation of WebGPUSurface that uses something other than IOSurfaces.

Do you think it is worth keeping that abstraction or should the platform specific objects be placed inside WebGPUSurface allowing WebGPUSurfaceCocoa to be removed?

@litherum litherum Oct 31, 2022 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better to keep all the #PLATFORM(COCOA) yuckiness contained inside a single file, rather than sprayed around to all the callers who need to use surfaces.

Another option could be something like

#if PLATFORM(COCOA)
using WebGPUSurface = WebGPUSurfaceCocoa;
#else
using WebGPUSurface = WebGPUNullSurface;
#endif

if all the functions will have the same signatures (which seems likely?)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why copy?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the intent is to copy into m_currentConfiguration. This should probably be an r-value reference instead for clarity, I will change it, however it will probably end up having the same effect:

so:

void GPUCanvasContext::configure(GPUCanvasConfiguration&&)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worth adding a comment to indicate in which situations this statement would be reached.

Comment thread Source/WebGPU/WebGPU/CommandEncoder.mm Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(ditto)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order to better be able to reason about object lifetime, I think we should pull out the data we need from the render pipeline and retain that, instead of retaining the render pipeline itself.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Completely agree. I'll change that

Comment thread Source/WebGPU/WebGPU/RenderPipeline.h Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: The "maybe" is already indicated by the return type

Comment thread Source/WebGPU/WebGPU/RenderPipeline.h Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kind of think the getters shouldn't get internal Metal types, but instead should get the WebGPU type, and we can add a helper in a utilities file to convert. Returning Metal types feels kind of like a layering violation.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is easy for primitiveType, frontFace, and cullMode, but I don't know if its so simple for renderPipelineState which is used in the RenderPassEncoder.

Do you see a feasible way to achieve this for renderPipelineState? I will also see if I can break the coupling somehow between RenderPipeline and RenderPassEncoder

Comment thread Source/WebGPU/WebGPU/ShaderModule.mm Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we not actually commit this? How harmful would it be to maintain this in a local checkout until we get something better?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Certainly not harmful, just nothing will show on the screen until the compiler outputs a basic shader like this one

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the surface level this looks like some sort of corruption.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm investigating why this is occurring. It occurs during the call to RemoteGPUProxy::RequestAdapter:

auto sendResult = sendSync(Messages::RemoteGPU::RequestAdapter(*convertedOptions, identifier));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the surface level this looks incorrect.
If this is the intention, this class of changes look like they could perhaps be submitted separately.
Submitting to main runloop is done with callOnMainRunLoop, but this really doesn't look like the correct approach.

IIRC the WebGPU, like WebGL is using the "main" IPC::Connection as their out of stream connection.
If I understand correctly, you are running into an assertion? I think the solution is to start using the "dedicated connection", similar to what RemoteRenderingBackend uses. This change could be submitted separately.

@mwyrzykowski mwyrzykowski removed the merging-blocked Applied to prevent a change from being merged label Oct 26, 2022
@mwyrzykowski
mwyrzykowski force-pushed the eng/Bringup-red-triangle branch from 0975095 to 51a6401 Compare October 26, 2022 22:22

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@litherum would it be acceptable to keep the flag in WebPreferences but behind an otherwise undefined variable that I can add to my LocalOverrides.xcconfig? This avoid some recompilation since for some reason modifying WebPreferences.yaml triggers a rebuild of a large number of files

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this solves the problem nicely.

@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Oct 27, 2022
@mwyrzykowski mwyrzykowski removed the merging-blocked Applied to prevent a change from being merged label Oct 28, 2022
@mwyrzykowski
mwyrzykowski force-pushed the eng/Bringup-red-triangle branch from 51a6401 to f9df0e3 Compare October 28, 2022 21:14
Comment thread Source/WebGPU/WebGPU/ShaderModule.mm Outdated

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@litherum are you ok with this to avoid checking in the metal source file?

Even once we have the compiler outputting a basic shader, it is likely there will be disconnects between the pipeline and compiler where the pipeline may want to test features not available in the compiler. Having an option to use custom metal source allows development on the pipeline to continue in parallel with the compiler.

@litherum litherum Oct 31, 2022 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little sad that this is necessary, but I do see the rationale why it is significantly helpful for development.

I don't quite understand the ENABLE(WEBGPU) check, because this is inside WebGPU.framework. It doesn't make a lot of sense to say "build WebGPU.framework but disable WebGPU inside it"

Can we at least use something like

#define TEMPORARY_MSL_HACK_PLEASE_DELETE_ONCE_WGSL_COMPILER_IS_HOOKED_UP 1

or something?

@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Oct 28, 2022

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Can we use WebCore::IOSurface instead of a raw IOSurfaceRef?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could use WebCore::IOSurface but createIOSurfaceBackedTexture creates a WGPUTextureDescriptorIOSurfaceBacking which is defined in WebGPUExt.h and also cast to a WGPUChainedStruct so I believe we could not use unique_ptr inside the WGPUTextureDescriptorIOSurfaceBacking as WebGPUExt.h is a C-header.

Should we use WebCore::IOSurface in this function even though we need to retain the IOSurfaceRef longer than the lifetime of the WebCore::IOSurface object?

Comment on lines 46 to 48

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: final

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's already a final class: class WebGPUSurfaceCocoa final: public WebGPUSurface {

do we place final on the member function for redundancy / in case the class is changed from no longer being final? Since final on a member function of a final class does not change anything as far as I know, right?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, yeah, that makes sense. https://webkit.org/code-style-guidelines/#override-methods seems a little ambiguous here. Maybe this is worth a webkit-dev email about style?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this will work with IOKit sandboxing. This code is expected to run in the Web process, right? I don't think the web process is allowed to create IOSurfaces.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be likely created by the GPU process, right?

@litherum litherum Oct 31, 2022 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a UAF. m_configuration doesn't retain the device. (Nor should it! I'm not sure this is the right design, but I need to gather my thoughts before making a more conclusive comment.)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm also not super sure this is the right design. I kind of feel:

  1. The Surface is conceptually the equivalent of a CAMetalLayer. It shouldn't need to retain anything WebGPU-specific inside it.
  2. The Surface owns 3 IOSurfaces, so that part matches CAMetalLayer. So that's good
  3. But the 3 IOSurfaces are created lazily, and sent to the GPU Process one-by-one, which I don't think makes a lot of sense. I think it's a better design to package up all 3 IOSurfaces and send them in a single package to the GPUP (perhaps inside GPUCanvasContext.configure(), or maybe perhaps earlier).
  4. I'm also not sure that this belongs in platform/. This class is about interfacing between canvas, the compositor, and webgpu.
  5. I'm also not sure if the name is right. I'm considering the possibility that we may want to build browser features with WebGPU in the future (like a compositor, or filters). Those wouldn't be tied to canvas, and presumably would instead have their own subclass of WebGPUSurface, right? Both subclasses would be compiled on Cocoa, though.
  6. Is it really right that there's no concept of swap chain here? The GPUP doesn't seem to have any notion of this Surface object either, which I think is kind of contrary to the API design of WebGPU.framework. I kind of think we should try to have WebGPU.framework have a single usage pattern here for both CAMetalLayer and for WebKit, and try to make them as conceptually similar as possible. The current patch seems to be sidestepping this design by creating a new API-exposed WGPUTextureDescriptorIOSurfaceBacking object to create a texture directly from an IOSurface, without using the Surface/Swapchain machinery. I kind of think that's backwards.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to break this part out into a separate PR

Comment on lines 83 to 85

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand how this causes the rendered results to be presented to the screen. Is that really what this function is trying to do?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this is setting up WebGPUSurfaceCocoa::display() to perform the present next time it's called. But surely present() needs to do some invalidation logic to make sure it gets called soon?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do we know the GPU is done rendering the frame at this point? I don't see any back pressure from the GPUP to the Web process.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll take a look at this

@mwyrzykowski mwyrzykowski Nov 1, 2022 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct void WebGPUSurfaceCocoa::display(PlatformCALayer& layer) causes the contents to appear on the screen.

which on macOS is called from -[WebSimpleLayer display] and then GraphicsLayerCA::platformCALayerLayerDisplay

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the invalidation logic is handled by GPUCanvasContext::m_compositingResultsNeedsUpdating

@mwyrzykowski mwyrzykowski removed the merging-blocked Applied to prevent a change from being merged label Nov 2, 2022
@mwyrzykowski mwyrzykowski removed the merging-blocked Applied to prevent a change from being merged label Nov 5, 2022
@mwyrzykowski
mwyrzykowski force-pushed the eng/Bringup-red-triangle branch from 0fa42a2 to 811033a Compare November 5, 2022 16:49
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Nov 5, 2022
@mwyrzykowski mwyrzykowski removed the merging-blocked Applied to prevent a change from being merged label Nov 5, 2022
@mwyrzykowski
mwyrzykowski force-pushed the eng/Bringup-red-triangle branch from 811033a to d904f6f Compare November 5, 2022 21:25
@mwyrzykowski
mwyrzykowski force-pushed the eng/Bringup-red-triangle branch from d904f6f to e0cc817 Compare November 6, 2022 16:50
@mwyrzykowski mwyrzykowski added the merge-queue Applied to send a pull request to merge-queue label Nov 6, 2022
@webkit-commit-queue

Copy link
Copy Markdown
Collaborator

Commit message contains (OOPS!) and no reviewer found, blocking PR #5785

@webkit-commit-queue webkit-commit-queue added merging-blocked Applied to prevent a change from being merged and removed merge-queue Applied to send a pull request to merge-queue labels Nov 6, 2022
@mwyrzykowski mwyrzykowski removed the merging-blocked Applied to prevent a change from being merged label Nov 6, 2022
@mwyrzykowski
mwyrzykowski force-pushed the eng/Bringup-red-triangle branch from e0cc817 to 97eb7f5 Compare November 6, 2022 22:35
@mwyrzykowski
mwyrzykowski force-pushed the eng/Bringup-red-triangle branch from 97eb7f5 to b9638b3 Compare November 7, 2022 05:34
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label Nov 7, 2022
@mwyrzykowski mwyrzykowski removed the merging-blocked Applied to prevent a change from being merged label Nov 7, 2022
@mwyrzykowski
mwyrzykowski force-pushed the eng/Bringup-red-triangle branch from b9638b3 to 04c221c Compare November 7, 2022 15:02
@mwyrzykowski mwyrzykowski added the merge-queue Applied to send a pull request to merge-queue label Nov 7, 2022
https://bugs.webkit.org/show_bug.cgi?id=247017
<radar://101514401>

Implement necessary interfaces to show a red triangle when WebGPU is enabled.

Reviewed by Myles C. Maxfield.

* Source/WTF/Scripts/Preferences/WebPreferences.yaml:
Place WebGPU enablement behind a local define.

* Source/WebCore/Modules/WebGPU/GPUCanvasContext.cpp:
(WebCore::getCanvasSizeAsIntSize):
(WebCore::platformSupportsWebGPUSurface):
(WebCore::GPUCanvasContext::create):
(WebCore::GPUCanvasContext::GPUCanvasContext):
(WebCore::GPUCanvasContext::reshape):
(WebCore::GPUCanvasContext::canvas):
(WebCore::GPUCanvasContext::configure):
(WebCore::GPUCanvasContext::getCurrentTexture):
(WebCore::GPUCanvasContext::pixelFormat const):
(WebCore::GPUCanvasContext::unconfigure):
(WebCore::GPUCanvasContext::colorSpace const):
(WebCore::GPUCanvasContext::layerContentsDisplayDelegate):
(WebCore::GPUCanvasContext::prepareForDisplay):
(WebCore::GPUCanvasContext::markContextChangedAndNotifyCanvasObservers):
Stub out implementation of GPUCanvasContext.

* Source/WebCore/Modules/WebGPU/GPUCanvasContext.h:
(WebCore::GPUCanvasContext::create): Deleted.
Renamed.

* Source/WebCore/Modules/WebGPU/GPUCanvasContext.idl:
Add ActiveDOMObject.

* Source/WebCore/PAL/pal/graphics/WebGPU/Impl/WebGPUBufferImpl.cpp:
(PAL::WebGPU::BufferImpl::getMappedRange):
Use the size of the buffer and not WGPU_WHOLE_MAP_SIZE, otherwise the
returned buffer size does not match what the client expects.

* Source/WebCore/dom/Document.cpp:
(WebCore::Document::getCSSCanvasContext):
Return gpu canvas if needed.

* Source/WebCore/dom/Document.h:
* Source/WebCore/dom/Document.idl:
Add support for GPUCanvas.

* Source/WebCore/html/HTMLCanvasElement.cpp:
(WebCore::HTMLCanvasElement::getContext):
(WebCore::HTMLCanvasElement::isWebGPUType):
(WebCore::HTMLCanvasElement::createContextWebGPU):
(WebCore::HTMLCanvasElement::getContextWebGPU):
* Source/WebCore/html/HTMLCanvasElement.h:
* Source/WebCore/html/HTMLCanvasElement.idl:
* Source/WebCore/html/canvas/CanvasRenderingContext.h:
(WebCore::CanvasRenderingContext::isWebGPU const):
Add support for gpu canvas.

* Source/WebCore/platform/graphics/cocoa/IOSurface.mm:
(WebCore::IOSurface::createFromSurface):
Return nullptr if surface is 0.

* Source/WebCore/rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::shouldSetContentsDisplayDelegate const):
(WebCore::RenderLayerBacking::updateConfiguration):
* Source/WebCore/rendering/RenderLayerBacking.h:
Add support for gpu canvas.

* Source/WebGPU/WebGPU/Buffer.mm:
(wgpuBufferGetSize):
Comes from the WebGPU repo.

* Source/WebGPU/WebGPU/CommandEncoder.h:
* Source/WebGPU/WebGPU/CommandEncoder.mm:
(WebGPU::loadAction):
(WebGPU::storeAction):
(WebGPU::CommandEncoder::validateRenderPassDescriptor const):
(WebGPU::CommandEncoder::beginRenderPass):
* Source/WebGPU/WebGPU/Device.h:
Add some basic validation for beginning the render pass.

* Source/WebGPU/WebGPU/RenderPassEncoder.h:
* Source/WebGPU/WebGPU/RenderPassEncoder.mm:
(WebGPU::RenderPassEncoder::~RenderPassEncoder):
(WebGPU::RenderPassEncoder::draw):
(WebGPU::RenderPassEncoder::endPass):
(WebGPU::RenderPassEncoder::setPipeline):
Setup the pipeline and make the call to draw a number of
primitives.

* Source/WebGPU/WebGPU/RenderPipeline.h:
(WebGPU::RenderPipeline::create):
(WebGPU::RenderPipeline::primitiveType const):
(WebGPU::RenderPipeline::maybeIndexType const):
(WebGPU::RenderPipeline::frontFace const):
(WebGPU::RenderPipeline::cullMode const):
* Source/WebGPU/WebGPU/RenderPipeline.mm:
(WebGPU::blendOperation):
(WebGPU::blendFactor):
(WebGPU::colorWriteMask):
(WebGPU::frontFace):
(WebGPU::cullMode):
(WebGPU::primitiveType):
(WebGPU::indexType):
(WebGPU::Device::validateRenderPipeline):
(WebGPU::Device::createRenderPipeline):
(WebGPU::RenderPipeline::RenderPipeline):
Add some basic pipeline support and validation.

* Source/WebGPU/WebGPU/ShaderModule.h:
* Source/WebGPU/WebGPU/ShaderModule.mm:
(WebGPU::earlyCompileShaderModule):
Fallback to the MSL string if the shader length is 0.

(WebGPU::ShaderModule::getNamedFunction const):
Lookup the function from the metal library.

* Source/WebGPU/WebGPU/Texture.h:
* Source/WebGPU/WebGPU/Texture.mm:
(WebGPU::Texture::pixelFormat):
(WebGPU::Texture::depthOnlyAspectMetalFormat):
(WebGPU::Texture::stencilOnlyAspectMetalFormat):
(WebGPU::Device::createTexture):
(WebGPU::Texture::resolveTextureViewDescriptorDefaults const):
(WebGPU::Texture::resolveTextureFormat):
(WebGPU::Texture::validateCreateView const):
(WebGPU::Texture::createView):
(WebGPU::pixelFormat): Deleted.
(WebGPU::depthOnlyAspectMetalFormat): Deleted.
(WebGPU::stencilOnlyAspectMetalFormat): Deleted.
Add support for some additional texture formats.

* Source/WebGPU/WebGPU/WebGPU.h:
wgpuBufferGetSize is in the public header.

* Source/WebGPU/WebGPU/WebGPUExt.h:
IOSurface support.

* Source/WebKit/GPUProcess/graphics/WebGPU/RemoteAdapter.cpp:
(WebKit::RemoteAdapter::RemoteAdapter):

* Source/WebKit/GPUProcess/graphics/WebGPU/RemoteBuffer.cpp:
(WebKit::RemoteBuffer::mapAsync):
Mapping the buffer for writing was not providing a buffer of the correct length.

(WebKit::RemoteDevice::createIOSurfaceBackedTexture):
* Source/WebKit/GPUProcess/graphics/WebGPU/RemoteDevice.h:
* Source/WebKit/GPUProcess/graphics/WebGPU/RemoteDevice.messages.in:
Create IOSurface backed texture.

* Source/WebKit/Platform/IPC/StreamClientConnection.h:
(IPC::StreamClientConnection::trySendSyncStream):
WebGPU sends a SetStreamDestinationID message which would previously
trigger an assertion here.

* Source/WebKit/Shared/WebGPU/WebGPURenderPassColorAttachment.cpp:
(WebKit::WebGPU::ConvertToBackingContext::convertToBacking):
(WebKit::WebGPU::ConvertFromBackingContext::convertFromBacking):
* Source/WebKit/Shared/WebGPU/WebGPURenderPassColorAttachment.h:
* Source/WebKit/Shared/WebGPU/WebGPURenderPassColorAttachment.serialization.in:
* Source/WebKit/Shared/WebGPU/WebGPURenderPassDescriptor.cpp:
(WebKit::WebGPU::ConvertToBackingContext::convertToBacking):
(WebKit::WebGPU::ConvertFromBackingContext::convertFromBacking):
* Source/WebKit/Shared/WebGPU/WebGPURenderPassDescriptor.h:
* Source/WebKit/Shared/WebGPU/WebGPURenderPassDescriptor.serialization.in:
Use optional values for resolveTargets and occlusionQuerySets as they
do not need to be specified.

* Source/WebKit/WebProcess/GPU/graphics/WebGPU/RemoteQueueProxy.h:
adoptRef was not getting called on m_parent leading to crashes, but
its not appearent why it was a Ref<> in the first place.

* Websites/webkit.org/demos/webgpu/scripts/hello-triangle.js:
(async helloTriangle):
Update javascript to new syntax.

* Source/WebCore/html/canvas/GPUCanvasContext.cpp:
* Source/WebCore/html/canvas/PlaceholderRenderingContext.cpp:
* Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h:
* Source/WebCore/platform/graphics/cocoa/GraphicsContextGLCocoa.h:
* Source/WebCore/platform/graphics/cocoa/GraphicsContextGLCocoa.mm:
* Source/WebCore/platform/graphics/cocoa/WebProcessGraphicsContextGLCocoa.mm:
Add missing includes and forward declarations.

Canonical link: https://commits.webkit.org/256411@main
@webkit-commit-queue

Copy link
Copy Markdown
Collaborator

Committed 256411@main (2c1db24): https://commits.webkit.org/256411@main

Reviewed commits have been landed. Closing PR #5785 and removing active labels.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

WebGPU For bugs in WebGPU

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants