Bringup red triangle - #5785
Bringup red triangle#5785
Conversation
|
EWS run on previous version of this PR (hash 0975095) Details |
There was a problem hiding this comment.
Why the removal of WGPUBufferUsage_CopyDst & WGPUBufferUsage_MapRead constraints?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Use C++ raw string literal?
return String::fromUTF8(R"(
#include <metal_stdlib>
using namespace metal;
struct Vertex {
float4 position [[position]];
float4 color;
...
)");
There was a problem hiding this comment.
oh that is much nicer, I'll do that, thank you
There was a problem hiding this comment.
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]
There was a problem hiding this comment.
I'm not reviewing these very closely. Someone that knows GPUProcess should review these.
There was a problem hiding this comment.
@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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
@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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
left a comment
There was a problem hiding this comment.
Review-in-progress. There's a lot here.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?)
There was a problem hiding this comment.
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&&)
There was a problem hiding this comment.
It might be worth adding a comment to indicate in which situations this statement would be reached.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Completely agree. I'll change that
There was a problem hiding this comment.
Nit: The "maybe" is already indicated by the return type
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Can we not actually commit this? How harmful would it be to maintain this in a local checkout until we get something better?
There was a problem hiding this comment.
Certainly not harmful, just nothing will show on the screen until the compiler outputs a basic shader like this one
There was a problem hiding this comment.
On the surface level this looks like some sort of corruption.
There was a problem hiding this comment.
I'm investigating why this is occurring. It occurs during the call to RemoteGPUProxy::RequestAdapter:
auto sendResult = sendSync(Messages::RemoteGPU::RequestAdapter(*convertedOptions, identifier));
There was a problem hiding this comment.
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.
0975095 to
51a6401
Compare
|
EWS run on previous version of this PR (hash 51a6401) Details |
There was a problem hiding this comment.
@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
There was a problem hiding this comment.
Yes, this solves the problem nicely.
51a6401 to
f9df0e3
Compare
|
EWS run on previous version of this PR (hash f9df0e3) Details |
There was a problem hiding this comment.
@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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Nit: Can we use WebCore::IOSurface instead of a raw IOSurfaceRef?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
This should be likely created by the GPU process, right?
There was a problem hiding this comment.
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.)
There was a problem hiding this comment.
I'm also not super sure this is the right design. I kind of feel:
- The Surface is conceptually the equivalent of a
CAMetalLayer. It shouldn't need to retain anything WebGPU-specific inside it. - The Surface owns 3 IOSurfaces, so that part matches CAMetalLayer. So that's good
- 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).
- I'm also not sure that this belongs in platform/. This class is about interfacing between canvas, the compositor, and webgpu.
- 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.
- 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.
There was a problem hiding this comment.
I'm going to break this part out into a separate PR
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
I'll take a look at this
There was a problem hiding this comment.
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
There was a problem hiding this comment.
I think the invalidation logic is handled by GPUCanvasContext::m_compositingResultsNeedsUpdating
0fa42a2 to
811033a
Compare
|
EWS run on previous version of this PR (hash 811033a) Details |
811033a to
d904f6f
Compare
|
EWS run on previous version of this PR (hash d904f6f) Details |
d904f6f to
e0cc817
Compare
|
EWS run on previous version of this PR (hash e0cc817) Details |
|
Commit message contains (OOPS!) and no reviewer found, blocking PR #5785 |
e0cc817 to
97eb7f5
Compare
|
EWS run on previous version of this PR (hash 97eb7f5) Details |
97eb7f5 to
b9638b3
Compare
|
EWS run on previous version of this PR (hash b9638b3) Details |
b9638b3 to
04c221c
Compare
|
EWS run on current version of this PR (hash 04c221c) Details |
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 to
2c1db24
Compare
|
Committed 256411@main (2c1db24): https://commits.webkit.org/256411@main Reviewed commits have been landed. Closing PR #5785 and removing active labels. |
2c1db24
04c221c
🧪 ios-wk2🧪 api-ios🧪 mac-wk1🧪 mac-AS-debug-wk2