WebKit Bugzilla
Attachment 371561 Details for
Bug 198644
: [WHLSL] Hook up compute
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
WIP
file.txt (text/plain), 33.42 KB, created by
Myles C. Maxfield
on 2019-06-06 22:19:44 PDT
(
hide
)
Description:
WIP
Filename:
MIME Type:
Creator:
Myles C. Maxfield
Created:
2019-06-06 22:19:44 PDT
Size:
33.42 KB
patch
obsolete
>commit 6163be9dc5cda76fa2a2cbaaf17cbba5d36418f4 >Author: Myles C. Maxfield <mmaxfield@apple.com> >Date: Fri Jun 7 01:18:59 2019 -0400 > > compute > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLComputeDimensions.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLComputeDimensions.cpp >new file mode 100644 >index 00000000000..e7de4c6532c >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLComputeDimensions.cpp >@@ -0,0 +1,91 @@ >+/* >+ * Copyright (C) 2019 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "WHLSLComputeDimensions.h" >+ >+#if ENABLE(WEBGPU) >+ >+#include "WHLSLFunctionDeclaration.h" >+#include "WHLSLPrepare.h" >+#include "WHLSLProgram.h" >+#include <wtf/Optional.h> >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+class ComputeDimensionsVisitor : public Visitor { >+public: >+ ComputeDimensionsVisitor(AST::FunctionDefinition& entryPoint) >+ : m_entryPoint(entryPoint) >+ { >+ } >+ >+ virtual ~ComputeDimensionsVisitor() = default; >+ >+ Optional<ComputeDimensions> computeDimensions() const { return m_computeDimensions; } >+ >+private: >+ void visit(AST::FunctionDeclaration& functionDeclaration) override >+ { >+ Visitor::visit(functionDeclaration); >+ bool foundNumThreadsFunctionAttribute = false; >+ for (auto& functionAttribute : functionDeclaration.attributeBlock()) { >+ auto success = WTF::visit(WTF::makeVisitor([&](AST::NumThreadsFunctionAttribute& numThreadsFunctionAttribute) { >+ if (foundNumThreadsFunctionAttribute) >+ return false; >+ foundNumThreadsFunctionAttribute = true; >+ if (&functionDeclaration == &m_entryPoint) { >+ ASSERT(!m_computeDimensions); >+ m_computeDimensions = {{ numThreadsFunctionAttribute.width(), numThreadsFunctionAttribute.height(), numThreadsFunctionAttribute.depth() }}; >+ } >+ return true; >+ }), functionAttribute); >+ if (!success) { >+ setError(); >+ return; >+ } >+ } >+ } >+ >+ AST::FunctionDefinition& m_entryPoint; >+ Optional<ComputeDimensions> m_computeDimensions; >+}; >+ >+Optional<ComputeDimensions> computeDimensions(Program& program, AST::FunctionDefinition& entryPoint) >+{ >+ ComputeDimensionsVisitor computeDimensions(entryPoint); >+ computeDimensions.Visitor::visit(program); >+ if (computeDimensions.error()) >+ return WTF::nullopt; >+ return computeDimensions.computeDimensions(); >+} >+ >+} // namespace WHLSL >+ >+} // namespace WebCore >+ >+#endif // ENABLE(WEBGPU) >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLComputeDimensions.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLComputeDimensions.h >new file mode 100644 >index 00000000000..de450813a58 >--- /dev/null >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLComputeDimensions.h >@@ -0,0 +1,44 @@ >+/* >+ * Copyright (C) 2019 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#if ENABLE(WEBGPU) >+ >+#include "WHLSLPrepare.h" >+ >+namespace WebCore { >+ >+namespace WHLSL { >+ >+class Program; >+ >+Optional<ComputeDimensions> computeDimensions(Program&, AST::FunctionDefinition&); >+ >+} >+ >+} >+ >+#endif >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.cpp >index 56fb36546ac..93e022afaee 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.cpp >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.cpp >@@ -31,6 +31,7 @@ > #include "WHLSLASTDumper.h" > #include "WHLSLCheckDuplicateFunctions.h" > #include "WHLSLChecker.h" >+#include "WHLSLComputeDimensions.h" > #include "WHLSLFunctionStageChecker.h" > #include "WHLSLHighZombieFinder.h" > #include "WHLSLLiteralTypeChecker.h" >@@ -168,12 +169,16 @@ Optional<ComputePrepareResult> prepare(String& whlslSource, ComputePipelineDescr > auto matchedSemantics = matchSemantics(*program, computePipelineDescriptor); > if (!matchedSemantics) > return WTF::nullopt; >+ auto computeDimensions = WHLSL::computeDimensions(*program, *matchedSemantics->shader); >+ if (!computeDimensions) >+ return WTF::nullopt; > > auto generatedCode = Metal::generateMetalCode(*program, WTFMove(*matchedSemantics), computePipelineDescriptor.layout); > > ComputePrepareResult result; > result.metalSource = WTFMove(generatedCode.metalSource); > result.mangledEntryPointName = WTFMove(generatedCode.mangledEntryPointName); >+ result.computeDimensions = WTFMove(*computeDimensions); > return result; > } > >diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.h >index 5bd6df06dc6..eb2021b7ca2 100644 >--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.h >+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.h >@@ -42,9 +42,16 @@ struct RenderPrepareResult { > }; > Optional<RenderPrepareResult> prepare(String& whlslSource, RenderPipelineDescriptor&); > >+struct ComputeDimensions { >+ unsigned width; >+ unsigned height; >+ unsigned depth; >+}; >+ > struct ComputePrepareResult { > String metalSource; > String mangledEntryPointName; >+ ComputeDimensions computeDimensions; > }; > Optional<ComputePrepareResult> prepare(String& whlslSource, ComputePipelineDescriptor&); > >diff --git a/Source/WebCore/Sources.txt b/Source/WebCore/Sources.txt >index a8bbbf9f795..8d50e63ad40 100644 >--- a/Source/WebCore/Sources.txt >+++ b/Source/WebCore/Sources.txt >@@ -306,6 +306,7 @@ Modules/websockets/WorkerThreadableWebSocketChannel.cpp > > Modules/webgpu/GPUCanvasContext.cpp > Modules/webgpu/NavigatorGPU.cpp >+Modules/webgpu/WHLSL/WHLSLComputeDimensions.cpp > Modules/webgpu/WHLSL/WHLSLASTDumper.cpp > Modules/webgpu/WHLSL/WHLSLInferTypes.cpp > Modules/webgpu/WHLSL/WHLSLLexer.cpp >diff --git a/Source/WebCore/SourcesCocoa.txt b/Source/WebCore/SourcesCocoa.txt >index bd29e5b48cb..b3f351a6ed2 100644 >--- a/Source/WebCore/SourcesCocoa.txt >+++ b/Source/WebCore/SourcesCocoa.txt >@@ -326,6 +326,7 @@ platform/graphics/gpu/cocoa/GPUCommandBufferMetal.mm > platform/graphics/gpu/cocoa/GPUComputePassEncoderMetal.mm > platform/graphics/gpu/cocoa/GPUComputePipelineMetal.mm > platform/graphics/gpu/cocoa/GPUDeviceMetal.mm >+platform/graphics/gpu/cocoa/GPUPipelineMetalConvertLayout.cpp > platform/graphics/gpu/cocoa/GPUProgrammablePassEncoderMetal.mm > platform/graphics/gpu/cocoa/GPUQueueMetal.mm > platform/graphics/gpu/cocoa/GPURenderPassEncoderMetal.mm >diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >index f87491eb108..eecdaa472c5 100644 >--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj >+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj >@@ -6392,6 +6392,10 @@ > 1C840B9921EC400800D0500D /* WHLSLGatherEntryPointItems.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLGatherEntryPointItems.cpp; sourceTree = "<group>"; }; > 1C840B9A21EC400900D0500D /* WHLSLGatherEntryPointItems.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLGatherEntryPointItems.h; sourceTree = "<group>"; }; > 1C840B9B21EC400900D0500D /* WHLSLChecker.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLChecker.cpp; sourceTree = "<group>"; }; >+ 1C86CA4B22AA19FF001BF961 /* WHLSLComputeDimensions.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLComputeDimensions.cpp; sourceTree = "<group>"; }; >+ 1C86CA4C22AA19FF001BF961 /* WHLSLComputeDimensions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLComputeDimensions.h; sourceTree = "<group>"; }; >+ 1C86CA4E22AA23C9001BF961 /* GPUPipelineMetalConvertLayout.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = GPUPipelineMetalConvertLayout.cpp; sourceTree = "<group>"; }; >+ 1C86CA4F22AA23C9001BF961 /* GPUPipelineMetalConvertLayout.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPUPipelineMetalConvertLayout.h; sourceTree = "<group>"; }; > 1C904DF90BA9D2C80081E9D0 /* Version.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Version.xcconfig; sourceTree = "<group>"; }; > 1C9AE5CA21ED9DF50069D5F2 /* WHLSLHighZombieFinder.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLHighZombieFinder.cpp; sourceTree = "<group>"; }; > 1C9AE5CB21ED9DF50069D5F2 /* WHLSLHighZombieFinder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLHighZombieFinder.h; sourceTree = "<group>"; }; >@@ -25492,6 +25496,8 @@ > C234A9B521E92C23003C984D /* WHLSLSynthesizeStructureAccessors.h */, > C234A98521E886A9003C984D /* WHLSLVisitor.cpp */, > C234A98721E886AD003C984D /* WHLSLVisitor.h */, >+ 1C86CA4B22AA19FF001BF961 /* WHLSLComputeDimensions.cpp */, >+ 1C86CA4C22AA19FF001BF961 /* WHLSLComputeDimensions.h */, > ); > path = WHLSL; > sourceTree = "<group>"; >@@ -25989,6 +25995,8 @@ > D087CE3E21ACA94200BDE174 /* GPUSwapChainMetal.mm */, > D087CE3F21ACA94200BDE174 /* GPUTextureMetal.mm */, > D06EF553220BA26A0018724E /* GPUUtilsMetal.mm */, >+ 1C86CA4E22AA23C9001BF961 /* GPUPipelineMetalConvertLayout.cpp */, >+ 1C86CA4F22AA23C9001BF961 /* GPUPipelineMetalConvertLayout.h */, > ); > path = cocoa; > sourceTree = "<group>"; >diff --git a/Source/WebCore/platform/graphics/gpu/GPUComputePipeline.h b/Source/WebCore/platform/graphics/gpu/GPUComputePipeline.h >index 0359f29bed0..65367c9d934 100644 >--- a/Source/WebCore/platform/graphics/gpu/GPUComputePipeline.h >+++ b/Source/WebCore/platform/graphics/gpu/GPUComputePipeline.h >@@ -27,6 +27,7 @@ > > #if ENABLE(WEBGPU) > >+#include "WHLSLPrepare.h" > #include <wtf/RefCounted.h> > #include <wtf/RefPtr.h> > #include <wtf/RetainPtr.h> >@@ -48,10 +49,13 @@ public: > > const PlatformComputePipeline* platformComputePipeline() const { return m_platformComputePipeline.get(); } > >+ WHLSL::ComputeDimensions computeDimensions() const { return m_computeDimensions; } >+ > private: >- GPUComputePipeline(PlatformComputePipelineSmartPtr&&); >+ GPUComputePipeline(PlatformComputePipelineSmartPtr&&, WHLSL::ComputeDimensions); > > PlatformComputePipelineSmartPtr m_platformComputePipeline; >+ WHLSL::ComputeDimensions m_computeDimensions { 0, 0, 0 }; > }; > > } // namespace WebCore >diff --git a/Source/WebCore/platform/graphics/gpu/cocoa/GPUComputePassEncoderMetal.mm b/Source/WebCore/platform/graphics/gpu/cocoa/GPUComputePassEncoderMetal.mm >index 713c1b79107..6bd28f70170 100644 >--- a/Source/WebCore/platform/graphics/gpu/cocoa/GPUComputePassEncoderMetal.mm >+++ b/Source/WebCore/platform/graphics/gpu/cocoa/GPUComputePassEncoderMetal.mm >@@ -97,11 +97,7 @@ void GPUComputePassEncoder::dispatch(unsigned x, unsigned y, unsigned z) > > BEGIN_BLOCK_OBJC_EXCEPTIONS; > >- auto w = pipelineState.threadExecutionWidth; >- auto h = pipelineState.maxTotalThreadsPerThreadgroup / w; >- >- // FIXME: This should be gleaned from the shader if not using MSL. For now, use the docs' example calculation. >- auto threadsPerThreadgroup = MTLSizeMake(w, h, 1); >+ auto threadsPerThreadgroup = MTLSizeMake(m_pipeline->computeDimensions().width, m_pipeline->computeDimensions().height, m_pipeline->computeDimensions().depth); > > auto threadgroupsPerGrid = MTLSizeMake(x, y, z); > >diff --git a/Source/WebCore/platform/graphics/gpu/cocoa/GPUComputePipelineMetal.mm b/Source/WebCore/platform/graphics/gpu/cocoa/GPUComputePipelineMetal.mm >index fbe43f441c8..e8368c63f3e 100644 >--- a/Source/WebCore/platform/graphics/gpu/cocoa/GPUComputePipelineMetal.mm >+++ b/Source/WebCore/platform/graphics/gpu/cocoa/GPUComputePipelineMetal.mm >@@ -30,68 +30,174 @@ > > #import "GPUComputePipelineDescriptor.h" > #import "GPUDevice.h" >+#import "GPUPipelineMetalConvertLayout.h" > #import "Logging.h" >+#import "WHLSLPrepare.h" > #import <Metal/Metal.h> > #import <wtf/BlockObjCExceptions.h> > >-OBJC_PROTOCOL(MTLFunction); >- > namespace WebCore { > >-static RetainPtr<MTLFunction> tryCreateMtlComputeFunction(const GPUPipelineStageDescriptor& stage) >+static bool trySetMetalFunctions(const char* const functionName, MTLLibrary *computeMetalLibrary, MTLComputePipelineDescriptor *mtlDescriptor, const String& computeEntryPointName) > { >- if (!stage.module->platformShaderModule() || stage.entryPoint.isNull()) { >- LOG(WebGPU, "GPUComputePipeline::tryCreate(): Invalid GPUShaderModule!"); >- return nullptr; >+#if LOG_DISABLED >+ UNUSED_PARAM(functionName); >+#endif >+ >+ BEGIN_BLOCK_OBJC_EXCEPTIONS; >+ >+ if (!computeMetalLibrary) { >+ LOG(WebGPU, "%s: MTLLibrary for compute stage does not exist!", functionName); >+ return false; >+ } >+ >+ auto function = adoptNS([computeMetalLibrary newFunctionWithName:computeEntryPointName]); >+ if (!function) { >+ LOG(WebGPU, "%s: Cannot create compute MTLFunction \"%s\"!", functionName, computeEntryPointName.utf8().data()); >+ return false; > } > >- RetainPtr<MTLFunction> function; >+ [mtlDescriptor setComputeFunction:function.get()]; >+ return true; >+ >+ END_BLOCK_OBJC_EXCEPTIONS; >+ >+ return false; >+} >+ >+static Optional<WHLSL::ComputeDimensions> trySetFunctions(const char* const functionName, const GPUPipelineStageDescriptor& computeStage, const GPUDevice& device, MTLComputePipelineDescriptor* mtlDescriptor, Optional<WHLSL::ComputePipelineDescriptor>& whlslDescriptor) >+{ >+#if LOG_DISABLED >+ UNUSED_PARAM(functionName); >+#endif >+ RetainPtr<MTLLibrary> computeLibrary; >+ String computeEntryPoint; >+ >+ WHLSL::ComputeDimensions computeDimensions { 1, 1, 1 }; >+ >+ if (whlslDescriptor) { >+ // WHLSL functions are compiled to MSL first. >+ String whlslSource = computeStage.module->whlslSource(); >+ ASSERT(!whlslSource.isNull()); >+ >+ whlslDescriptor->entryPointName = computeStage.entryPoint; >+ >+ auto whlslCompileResult = WHLSL::prepare(whlslSource, *whlslDescriptor); >+ if (!whlslCompileResult) >+ return WTF::nullopt; >+ computeDimensions = whlslCompileResult->computeDimensions; >+ >+ WTFLogAlways("Metal Source: %s", whlslCompileResult->metalSource.utf8().data()); >+ >+ NSError *error = nil; >+ >+ BEGIN_BLOCK_OBJC_EXCEPTIONS; >+ computeLibrary = adoptNS([device.platformDevice() newLibraryWithSource:whlslCompileResult->metalSource options:nil error:&error]); >+ END_BLOCK_OBJC_EXCEPTIONS; >+ >+ ASSERT(computeLibrary); >+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195771 Once we zero-fill variables, there should be no warnings, so we should be able to ASSERT(!error) here. >+ >+ computeEntryPoint = whlslCompileResult->mangledEntryPointName; >+ } else { >+ computeLibrary = computeStage.module->platformShaderModule(); >+ computeEntryPoint = computeStage.entryPoint; >+ } >+ >+ if (trySetMetalFunctions(functionName, computeLibrary.get(), mtlDescriptor, computeEntryPoint)) >+ return computeDimensions; >+ return WTF::nullopt; >+} >+ >+struct ConvertResult { >+ RetainPtr<MTLComputePipelineDescriptor> pipelineDescriptor; >+ WHLSL::ComputeDimensions computeDimensions; >+}; >+static Optional<ConvertResult> convertComputePipelineDescriptor(const char* const functionName, const GPUComputePipelineDescriptor& descriptor, const GPUDevice& device) >+{ >+ RetainPtr<MTLComputePipelineDescriptor> mtlDescriptor; > > BEGIN_BLOCK_OBJC_EXCEPTIONS; >- function = adoptNS([stage.module->platformShaderModule() newFunctionWithName:stage.entryPoint]); >+ >+ mtlDescriptor = adoptNS([MTLComputePipelineDescriptor new]); >+ > END_BLOCK_OBJC_EXCEPTIONS; > >- if (!function) >- LOG(WebGPU, "GPUComputePipeline::tryCreate(): Cannot create compute MTLFunction \"%s\"!", stage.entryPoint.utf8().data()); >+ if (!mtlDescriptor) { >+ LOG(WebGPU, "%s: Error creating MTLDescriptor!", functionName); >+ return WTF::nullopt; >+ } >+ >+ const auto& computeStage = descriptor.computeStage; >+ >+ bool isWhlsl = !computeStage.module->whlslSource().isNull(); >+ >+ Optional<WHLSL::ComputePipelineDescriptor> whlslDescriptor; >+ if (isWhlsl) >+ whlslDescriptor = WHLSL::ComputePipelineDescriptor(); >+ >+ if (descriptor.layout && whlslDescriptor) { >+ if (auto layout = convertLayout(*descriptor.layout)) >+ whlslDescriptor->layout = WTFMove(*layout); >+ else { >+ LOG(WebGPU, "%s: Error converting GPUPipelineLayout!", functionName); >+ return WTF::nullopt; >+ } >+ } >+ >+ if (auto computeDimensions = trySetFunctions(functionName, computeStage, device, mtlDescriptor.get(), whlslDescriptor)) >+ return {{ mtlDescriptor, *computeDimensions }}; > >- return function; >+ return WTF::nullopt; > } > >-static RetainPtr<MTLComputePipelineState> tryCreateMTLComputePipelineState(const GPUDevice& device, const GPUComputePipelineDescriptor& descriptor) >+struct CreateResult { >+ RetainPtr<MTLComputePipelineState> pipelineState; >+ WHLSL::ComputeDimensions computeDimensions; >+}; >+static Optional<CreateResult> tryCreateMTLComputePipelineState(const char* const functionName, const GPUDevice& device, const GPUComputePipelineDescriptor& descriptor) > { > if (!device.platformDevice()) { > LOG(WebGPU, "GPUComputePipeline::tryCreate(): Invalid GPUDevice!"); >- return nullptr; >+ return WTF::nullopt; > } > >- auto computeFunction = tryCreateMtlComputeFunction(descriptor.computeStage); >- if (!computeFunction) >- return nullptr; >+ auto convertResult = convertComputePipelineDescriptor(functionName, descriptor, device); >+ if (!convertResult) >+ return WTF::nullopt; >+ ASSERT(convertResult->pipelineDescriptor); >+ auto mtlDescriptor = convertResult->pipelineDescriptor; > >- RetainPtr<MTLComputePipelineState> pipelineState; >- NSError *error = nil; >+ RetainPtr<MTLComputePipelineState> pipeline; > > BEGIN_BLOCK_OBJC_EXCEPTIONS; >- pipelineState = adoptNS([device.platformDevice() newComputePipelineStateWithFunction:computeFunction.get() error:&error]); >- END_BLOCK_OBJC_EXCEPTIONS; > >- if (!pipelineState) >+ NSError *error = nil; >+ pipeline = adoptNS([device.platformDevice() newComputePipelineStateWithDescriptor:mtlDescriptor.get() options:MTLPipelineOptionNone reflection:nil error:&error]); >+ if (!pipeline) { > LOG(WebGPU, "GPUComputePipeline::tryCreate(): %s!", error ? error.localizedDescription.UTF8String : "Unable to create MTLComputePipelineState!"); >+ return WTF::nullopt; >+ } > >- return pipelineState; >+ END_BLOCK_OBJC_EXCEPTIONS; >+ >+ return {{ pipeline, convertResult->computeDimensions }}; > } > > RefPtr<GPUComputePipeline> GPUComputePipeline::tryCreate(const GPUDevice& device, const GPUComputePipelineDescriptor& descriptor) > { >- auto mtlPipeline = tryCreateMTLComputePipelineState(device, descriptor); >- if (!mtlPipeline) >+ const char* const functionName = "GPURenderPipeline::create()"; >+ >+ auto createResult = tryCreateMTLComputePipelineState(functionName, device, descriptor); >+ if (!createResult) > return nullptr; > >- return adoptRef(new GPUComputePipeline(WTFMove(mtlPipeline))); >+ return adoptRef(new GPUComputePipeline(WTFMove(createResult->pipelineState), createResult->computeDimensions)); > } > >-GPUComputePipeline::GPUComputePipeline(RetainPtr<MTLComputePipelineState>&& pipeline) >+GPUComputePipeline::GPUComputePipeline(RetainPtr<MTLComputePipelineState>&& pipeline, WHLSL::ComputeDimensions computeDimensions) > : m_platformComputePipeline(WTFMove(pipeline)) >+ , m_computeDimensions(computeDimensions) > { > } > >diff --git a/Source/WebCore/platform/graphics/gpu/cocoa/GPUPipelineMetalConvertLayout.cpp b/Source/WebCore/platform/graphics/gpu/cocoa/GPUPipelineMetalConvertLayout.cpp >new file mode 100644 >index 00000000000..bd57688f5be >--- /dev/null >+++ b/Source/WebCore/platform/graphics/gpu/cocoa/GPUPipelineMetalConvertLayout.cpp >@@ -0,0 +1,94 @@ >+/* >+ * Copyright (C) 2019 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "GPUPipelineMetalConvertLayout.h" >+ >+#include "GPUPipelineLayout.h" >+ >+#if ENABLE(WEBGPU) >+ >+namespace WebCore { >+ >+static OptionSet<WHLSL::ShaderStage> convertShaderStageFlags(GPUShaderStageFlags flags) >+{ >+ OptionSet<WHLSL::ShaderStage> result; >+ if (flags & GPUShaderStageBit::Flags::Vertex) >+ result.add(WHLSL::ShaderStage::Vertex); >+ if (flags & GPUShaderStageBit::Flags::Fragment) >+ result.add(WHLSL::ShaderStage::Fragment); >+ if (flags & GPUShaderStageBit::Flags::Compute) >+ result.add(WHLSL::ShaderStage::Compute); >+ return result; >+} >+ >+static Optional<WHLSL::Binding::BindingDetails> convertBindingType(GPUBindGroupLayout::InternalBindingDetails internalBindingDetails) >+{ >+ return WTF::visit(WTF::makeVisitor([&](GPUBindGroupLayout::UniformBuffer uniformBuffer) -> Optional<WHLSL::Binding::BindingDetails> { >+ return { WHLSL::UniformBufferBinding { uniformBuffer.internalLengthName } }; >+ }, [&](GPUBindGroupLayout::DynamicUniformBuffer) -> Optional<WHLSL::Binding::BindingDetails> { >+ return WTF::nullopt; >+ }, [&](GPUBindGroupLayout::Sampler) -> Optional<WHLSL::Binding::BindingDetails> { >+ return { WHLSL::SamplerBinding { } }; >+ }, [&](GPUBindGroupLayout::SampledTexture) -> Optional<WHLSL::Binding::BindingDetails> { >+ return { WHLSL::TextureBinding { } }; >+ }, [&](GPUBindGroupLayout::StorageBuffer storageBuffer) -> Optional<WHLSL::Binding::BindingDetails> { >+ return { WHLSL::StorageBufferBinding { storageBuffer.internalLengthName } }; >+ }, [&](GPUBindGroupLayout::DynamicStorageBuffer) -> Optional<WHLSL::Binding::BindingDetails> { >+ return WTF::nullopt; >+ }), internalBindingDetails); >+} >+ >+Optional<WHLSL::Layout> convertLayout(const GPUPipelineLayout& layout) >+{ >+ WHLSL::Layout result; >+ if (layout.bindGroupLayouts().size() > std::numeric_limits<unsigned>::max()) >+ return WTF::nullopt; >+ for (size_t i = 0; i < layout.bindGroupLayouts().size(); ++i) { >+ const auto& bindGroupLayout = layout.bindGroupLayouts()[i]; >+ WHLSL::BindGroup bindGroup; >+ bindGroup.name = static_cast<unsigned>(i); >+ for (const auto& keyValuePair : bindGroupLayout->bindingsMap()) { >+ const auto& bindingDetails = keyValuePair.value; >+ WHLSL::Binding binding; >+ binding.visibility = convertShaderStageFlags(bindingDetails.externalBinding.visibility); >+ if (auto bindingType = convertBindingType(bindingDetails.internalBindingDetails)) >+ binding.binding = *bindingType; >+ else >+ return WTF::nullopt; >+ if (bindingDetails.externalBinding.binding > std::numeric_limits<unsigned>::max()) >+ return WTF::nullopt; >+ binding.externalName = bindingDetails.externalBinding.binding; >+ binding.internalName = bindingDetails.internalName; >+ bindGroup.bindings.append(WTFMove(binding)); >+ } >+ result.append(WTFMove(bindGroup)); >+ } >+ return result; >+} >+ >+} // namespace WebCore >+ >+#endif // ENABLE(WEBGPU) >diff --git a/Source/WebCore/platform/graphics/gpu/cocoa/GPUPipelineMetalConvertLayout.h b/Source/WebCore/platform/graphics/gpu/cocoa/GPUPipelineMetalConvertLayout.h >new file mode 100644 >index 00000000000..8e29d93af02 >--- /dev/null >+++ b/Source/WebCore/platform/graphics/gpu/cocoa/GPUPipelineMetalConvertLayout.h >@@ -0,0 +1,41 @@ >+/* >+ * Copyright (C) 2019 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#if ENABLE(WEBGPU) >+ >+#include "WHLSLPipelineDescriptor.h" >+#include <wtf/Optional.h> >+ >+namespace WebCore { >+ >+class GPUPipelineLayout; >+ >+Optional<WHLSL::Layout> convertLayout(const GPUPipelineLayout&); >+ >+} >+ >+#endif >diff --git a/Source/WebCore/platform/graphics/gpu/cocoa/GPURenderPipelineMetal.mm b/Source/WebCore/platform/graphics/gpu/cocoa/GPURenderPipelineMetal.mm >index 4a9eebbe130..5768d07e782 100644 >--- a/Source/WebCore/platform/graphics/gpu/cocoa/GPURenderPipelineMetal.mm >+++ b/Source/WebCore/platform/graphics/gpu/cocoa/GPURenderPipelineMetal.mm >@@ -30,6 +30,7 @@ > > #import "GPUDevice.h" > #import "GPULimits.h" >+#import "GPUPipelineMetalConvertLayout.h" > #import "GPUUtils.h" > #import "Logging.h" > #import "WHLSLPrepare.h" >@@ -98,35 +99,6 @@ static WHLSL::VertexFormat convertVertexFormat(GPUVertexFormat vertexFormat) > } > } > >-static OptionSet<WHLSL::ShaderStage> convertShaderStageFlags(GPUShaderStageFlags flags) >-{ >- OptionSet<WHLSL::ShaderStage> result; >- if (flags & GPUShaderStageBit::Flags::Vertex) >- result.add(WHLSL::ShaderStage::Vertex); >- if (flags & GPUShaderStageBit::Flags::Fragment) >- result.add(WHLSL::ShaderStage::Fragment); >- if (flags & GPUShaderStageBit::Flags::Compute) >- result.add(WHLSL::ShaderStage::Compute); >- return result; >-} >- >-static Optional<WHLSL::Binding::BindingDetails> convertBindingType(GPUBindGroupLayout::InternalBindingDetails internalBindingDetails) >-{ >- return WTF::visit(WTF::makeVisitor([&](GPUBindGroupLayout::UniformBuffer uniformBuffer) -> Optional<WHLSL::Binding::BindingDetails> { >- return { WHLSL::UniformBufferBinding { uniformBuffer.internalLengthName } }; >- }, [&](GPUBindGroupLayout::DynamicUniformBuffer) -> Optional<WHLSL::Binding::BindingDetails> { >- return WTF::nullopt; >- }, [&](GPUBindGroupLayout::Sampler) -> Optional<WHLSL::Binding::BindingDetails> { >- return { WHLSL::SamplerBinding { } }; >- }, [&](GPUBindGroupLayout::SampledTexture) -> Optional<WHLSL::Binding::BindingDetails> { >- return { WHLSL::TextureBinding { } }; >- }, [&](GPUBindGroupLayout::StorageBuffer storageBuffer) -> Optional<WHLSL::Binding::BindingDetails> { >- return { WHLSL::StorageBufferBinding { storageBuffer.internalLengthName } }; >- }, [&](GPUBindGroupLayout::DynamicStorageBuffer) -> Optional<WHLSL::Binding::BindingDetails> { >- return WTF::nullopt; >- }), internalBindingDetails); >-} >- > static Optional<WHLSL::TextureFormat> convertTextureFormat(GPUTextureFormat format) > { > switch (format) { >@@ -368,34 +340,6 @@ static bool trySetColorStates(const char* const functionName, const Vector<GPUCo > return true; > } > >-static Optional<WHLSL::Layout> convertLayout(const GPUPipelineLayout& layout) >-{ >- WHLSL::Layout result; >- if (layout.bindGroupLayouts().size() > std::numeric_limits<unsigned>::max()) >- return WTF::nullopt; >- for (size_t i = 0; i < layout.bindGroupLayouts().size(); ++i) { >- const auto& bindGroupLayout = layout.bindGroupLayouts()[i]; >- WHLSL::BindGroup bindGroup; >- bindGroup.name = static_cast<unsigned>(i); >- for (const auto& keyValuePair : bindGroupLayout->bindingsMap()) { >- const auto& bindingDetails = keyValuePair.value; >- WHLSL::Binding binding; >- binding.visibility = convertShaderStageFlags(bindingDetails.externalBinding.visibility); >- if (auto bindingType = convertBindingType(bindingDetails.internalBindingDetails)) >- binding.binding = *bindingType; >- else >- return WTF::nullopt; >- if (bindingDetails.externalBinding.binding > std::numeric_limits<unsigned>::max()) >- return WTF::nullopt; >- binding.externalName = bindingDetails.externalBinding.binding; >- binding.internalName = bindingDetails.internalName; >- bindGroup.bindings.append(WTFMove(binding)); >- } >- result.append(WTFMove(bindGroup)); >- } >- return result; >-} >- > static bool trySetMetalFunctions(const char* const functionName, MTLLibrary *vertexMetalLibrary, MTLLibrary *fragmentMetalLibrary, MTLRenderPipelineDescriptor *mtlDescriptor, const String& vertexEntryPointName, const String& fragmentEntryPointName) > { > #if LOG_DISABLED >@@ -542,6 +486,11 @@ static RetainPtr<MTLRenderPipelineDescriptor> convertRenderPipelineDescriptor(co > > static RetainPtr<MTLRenderPipelineState> tryCreateMtlRenderPipelineState(const char* const functionName, const GPURenderPipelineDescriptor& descriptor, const GPUDevice& device) > { >+ if (!device.platformDevice()) { >+ LOG(WebGPU, "GPUComputePipeline::tryCreate(): Invalid GPUDevice!"); >+ return nullptr; >+ } >+ > auto mtlDescriptor = convertRenderPipelineDescriptor(functionName, descriptor, device); > if (!mtlDescriptor) > return nullptr; >@@ -550,7 +499,7 @@ static RetainPtr<MTLRenderPipelineState> tryCreateMtlRenderPipelineState(const c > > BEGIN_BLOCK_OBJC_EXCEPTIONS; > >- NSError *error = [NSError errorWithDomain:@"com.apple.WebKit.GPU" code:1 userInfo:nil]; >+ NSError *error = nil; > pipeline = adoptNS([device.platformDevice() newRenderPipelineStateWithDescriptor:mtlDescriptor.get() error:&error]); > if (!pipeline) > LOG(WebGPU, "%s: %s!", functionName, error.localizedDescription.UTF8String);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 198644
:
371561
|
371612