<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[242766] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/242766">242766</a></dd>
<dt>Author</dt> <dd>justin_fan@apple.com</dd>
<dt>Date</dt> <dd>2019-03-11 20:19:10 -0700 (Mon, 11 Mar 2019)</dd>
</dl>

<h3>Log Message</h3>
<pre>[Web GPU] BindGroups/Argument buffers: Move MTLBuffer creation from and GPUBindGroup validation to GPUDevice.createBindGroup
https://bugs.webkit.org/show_bug.cgi?id=195519
<rdar://problem/48781297>

Reviewed by Myles C. Maxfield.

Metal's Argument Buffers should not be tied directly to GPUBindGroupLayout; rather, create the MTLBuffer
in GPUBindGroup creation process.
Move GPUBindGroup validation out of setBindGroup and to GPUBindGroup creation for performance.

Covered by existing tests. No behavior change.

* Modules/webgpu/WebGPUDevice.cpp:
(WebCore::WebGPUDevice::createBindGroup const):
* Sources.txt:
* SourcesCocoa.txt:
* WebCore.xcodeproj/project.pbxproj:
* platform/graphics/gpu/GPUBindGroup.cpp: Removed.
* platform/graphics/gpu/GPUBindGroup.h:
(WebCore::GPUBindGroup::vertexArgsBuffer): A buffer that arguments will be encoded into during setBindGroup.
(WebCore::GPUBindGroup::fragmentArgsBuffer): Ditto.
(WebCore::GPUBindGroup::boundBuffers const): A list of resources that are bound by this GPUBindGroup.
(WebCore::GPUBindGroup::boundTextures const): Ditto.
(WebCore::GPUBindGroup::layout const): Deleted.
(WebCore::GPUBindGroup::bindings const): Deleted.
* platform/graphics/gpu/GPUBindGroupLayout.h: No longer creating and retaining MTLBuffers.
(WebCore::GPUBindGroupLayout::vertexEncoder const):
(WebCore::GPUBindGroupLayout::fragmentEncoder const):
(WebCore::GPUBindGroupLayout::computeEncoder const):
(WebCore::GPUBindGroupLayout::ArgumentEncoderBuffer::isValid const): Deleted.
(WebCore::GPUBindGroupLayout::vertexArguments const): Deleted.
(WebCore::GPUBindGroupLayout::fragmentArguments const): Deleted.
(WebCore::GPUBindGroupLayout::computeArguments const): Deleted.
* platform/graphics/gpu/GPUProgrammablePassEncoder.h:
* platform/graphics/gpu/cocoa/GPUBindGroupLayoutMetal.mm:
(WebCore::tryCreateMtlArgumentEncoder):
(WebCore::GPUBindGroupLayout::tryCreate):
(WebCore::GPUBindGroupLayout::GPUBindGroupLayout):
(WebCore::tryCreateArgumentEncoderAndBuffer): Deleted.
* platform/graphics/gpu/cocoa/GPUBindGroupMetal.mm: Added.
(WebCore::tryCreateArgumentBuffer): Create and associate the MTLBuffer that backs the MTLArgumentEncoder.
(WebCore::tryGetResourceAsBufferBinding): Validate a GPUBindingResource.
(WebCore::trySetBufferOnEncoder): Encodes a GPUBufferBinding's MTLBuffer on a MTLArgumentEncoder.
(WebCore::tryGetResourceAsSampler): Ditto, for GPUSamplers.
(WebCore::trySetSamplerOnEncoder):
(WebCore::tryGetResourceAsTexture): Ditto, for GPUTextures.
(WebCore::trySetTextureOnEncoder):
(WebCore::GPUBindGroup::tryCreate): Most setBindGroup validation moved here.
(WebCore::GPUBindGroup::GPUBindGroup): Retains the resource references needed for setBindGroup.
* platform/graphics/gpu/cocoa/GPUProgrammablePassEncoderMetal.mm:
(WebCore::GPUProgrammablePassEncoder::setBindGroup): Most validation moved to GPUBindGroup::tryCreate().
(WebCore::GPUProgrammablePassEncoder::setResourceAsBufferOnEncoder): Deleted.
(WebCore::GPUProgrammablePassEncoder::setResourceAsSamplerOnEncoder): Deleted.
(WebCore::GPUProgrammablePassEncoder::setResourceAsTextureOnEncoder): Deleted.
* platform/graphics/gpu/cocoa/GPURenderPassEncoderMetal.mm:
(WebCore::GPURenderPassEncoder::useResource):
(WebCore::GPURenderPassEncoder::setVertexBuffer):
(WebCore::GPURenderPassEncoder::setFragmentBuffer):

Misc:
* platform/graphics/gpu/GPUCommandBuffer.cpp/h: Move missing includes to header.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModuleswebgpuWebGPUDevicecpp">trunk/Source/WebCore/Modules/webgpu/WebGPUDevice.cpp</a></li>
<li><a href="#trunkSourceWebCoreSourcestxt">trunk/Source/WebCore/Sources.txt</a></li>
<li><a href="#trunkSourceWebCoreSourcesCocoatxt">trunk/Source/WebCore/SourcesCocoa.txt</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsgpuGPUBindGrouph">trunk/Source/WebCore/platform/graphics/gpu/GPUBindGroup.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsgpuGPUBindGroupLayouth">trunk/Source/WebCore/platform/graphics/gpu/GPUBindGroupLayout.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsgpuGPUProgrammablePassEncoderh">trunk/Source/WebCore/platform/graphics/gpu/GPUProgrammablePassEncoder.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsgpucocoaGPUBindGroupLayoutMetalmm">trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUBindGroupLayoutMetal.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsgpucocoaGPUProgrammablePassEncoderMetalmm">trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUProgrammablePassEncoderMetal.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsgpucocoaGPURenderPassEncoderMetalmm">trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPURenderPassEncoderMetal.mm</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreplatformgraphicsgpucocoaGPUBindGroupMetalmm">trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUBindGroupMetal.mm</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreplatformgraphicsgpuGPUBindGroupcpp">trunk/Source/WebCore/platform/graphics/gpu/GPUBindGroup.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (242765 => 242766)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2019-03-12 02:54:07 UTC (rev 242765)
+++ trunk/Source/WebCore/ChangeLog      2019-03-12 03:19:10 UTC (rev 242766)
</span><span class="lines">@@ -1,3 +1,67 @@
</span><ins>+2019-03-11  Justin Fan  <justin_fan@apple.com>
+
+        [Web GPU] BindGroups/Argument buffers: Move MTLBuffer creation from and GPUBindGroup validation to GPUDevice.createBindGroup
+        https://bugs.webkit.org/show_bug.cgi?id=195519
+        <rdar://problem/48781297>
+
+        Reviewed by Myles C. Maxfield.
+
+        Metal's Argument Buffers should not be tied directly to GPUBindGroupLayout; rather, create the MTLBuffer 
+        in GPUBindGroup creation process.
+        Move GPUBindGroup validation out of setBindGroup and to GPUBindGroup creation for performance.
+
+        Covered by existing tests. No behavior change.
+
+        * Modules/webgpu/WebGPUDevice.cpp:
+        (WebCore::WebGPUDevice::createBindGroup const):
+        * Sources.txt:
+        * SourcesCocoa.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * platform/graphics/gpu/GPUBindGroup.cpp: Removed.
+        * platform/graphics/gpu/GPUBindGroup.h:
+        (WebCore::GPUBindGroup::vertexArgsBuffer): A buffer that arguments will be encoded into during setBindGroup.
+        (WebCore::GPUBindGroup::fragmentArgsBuffer): Ditto.
+        (WebCore::GPUBindGroup::boundBuffers const): A list of resources that are bound by this GPUBindGroup.
+        (WebCore::GPUBindGroup::boundTextures const): Ditto.
+        (WebCore::GPUBindGroup::layout const): Deleted.
+        (WebCore::GPUBindGroup::bindings const): Deleted.
+        * platform/graphics/gpu/GPUBindGroupLayout.h: No longer creating and retaining MTLBuffers.
+        (WebCore::GPUBindGroupLayout::vertexEncoder const):
+        (WebCore::GPUBindGroupLayout::fragmentEncoder const):
+        (WebCore::GPUBindGroupLayout::computeEncoder const):
+        (WebCore::GPUBindGroupLayout::ArgumentEncoderBuffer::isValid const): Deleted.
+        (WebCore::GPUBindGroupLayout::vertexArguments const): Deleted.
+        (WebCore::GPUBindGroupLayout::fragmentArguments const): Deleted.
+        (WebCore::GPUBindGroupLayout::computeArguments const): Deleted.
+        * platform/graphics/gpu/GPUProgrammablePassEncoder.h:
+        * platform/graphics/gpu/cocoa/GPUBindGroupLayoutMetal.mm:
+        (WebCore::tryCreateMtlArgumentEncoder):
+        (WebCore::GPUBindGroupLayout::tryCreate):
+        (WebCore::GPUBindGroupLayout::GPUBindGroupLayout):
+        (WebCore::tryCreateArgumentEncoderAndBuffer): Deleted.
+        * platform/graphics/gpu/cocoa/GPUBindGroupMetal.mm: Added.
+        (WebCore::tryCreateArgumentBuffer): Create and associate the MTLBuffer that backs the MTLArgumentEncoder.
+        (WebCore::tryGetResourceAsBufferBinding): Validate a GPUBindingResource.
+        (WebCore::trySetBufferOnEncoder): Encodes a GPUBufferBinding's MTLBuffer on a MTLArgumentEncoder.
+        (WebCore::tryGetResourceAsSampler): Ditto, for GPUSamplers.
+        (WebCore::trySetSamplerOnEncoder):
+        (WebCore::tryGetResourceAsTexture): Ditto, for GPUTextures.
+        (WebCore::trySetTextureOnEncoder):
+        (WebCore::GPUBindGroup::tryCreate): Most setBindGroup validation moved here.
+        (WebCore::GPUBindGroup::GPUBindGroup): Retains the resource references needed for setBindGroup. 
+        * platform/graphics/gpu/cocoa/GPUProgrammablePassEncoderMetal.mm:
+        (WebCore::GPUProgrammablePassEncoder::setBindGroup): Most validation moved to GPUBindGroup::tryCreate().
+        (WebCore::GPUProgrammablePassEncoder::setResourceAsBufferOnEncoder): Deleted.
+        (WebCore::GPUProgrammablePassEncoder::setResourceAsSamplerOnEncoder): Deleted.
+        (WebCore::GPUProgrammablePassEncoder::setResourceAsTextureOnEncoder): Deleted.
+        * platform/graphics/gpu/cocoa/GPURenderPassEncoderMetal.mm:
+        (WebCore::GPURenderPassEncoder::useResource):
+        (WebCore::GPURenderPassEncoder::setVertexBuffer):
+        (WebCore::GPURenderPassEncoder::setFragmentBuffer):
+
+        Misc:
+        * platform/graphics/gpu/GPUCommandBuffer.cpp/h: Move missing includes to header.
+
</ins><span class="cx"> 2019-03-11  Zalan Bujtas  <zalan@apple.com>
</span><span class="cx"> 
</span><span class="cx">         [Synthetic Click] Dispatch mouseout soon after mouseup
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebgpuWebGPUDevicecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webgpu/WebGPUDevice.cpp (242765 => 242766)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webgpu/WebGPUDevice.cpp     2019-03-12 02:54:07 UTC (rev 242765)
+++ trunk/Source/WebCore/Modules/webgpu/WebGPUDevice.cpp        2019-03-12 03:19:10 UTC (rev 242766)
</span><span class="lines">@@ -116,7 +116,7 @@
</span><span class="cx">     if (!gpuDescriptor)
</span><span class="cx">         return WebGPUBindGroup::create(nullptr);
</span><span class="cx"> 
</span><del>-    auto bindGroup = GPUBindGroup::create(WTFMove(*gpuDescriptor));
</del><ins>+    auto bindGroup = GPUBindGroup::tryCreate(*gpuDescriptor);
</ins><span class="cx">     return WebGPUBindGroup::create(WTFMove(bindGroup));
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreSourcestxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Sources.txt (242765 => 242766)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Sources.txt 2019-03-12 02:54:07 UTC (rev 242765)
+++ trunk/Source/WebCore/Sources.txt    2019-03-12 03:19:10 UTC (rev 242766)
</span><span class="lines">@@ -1813,7 +1813,6 @@
</span><span class="cx"> platform/graphics/filters/SourceGraphic.cpp
</span><span class="cx"> platform/graphics/filters/SpotLightSource.cpp
</span><span class="cx"> 
</span><del>-platform/graphics/gpu/GPUBindGroup.cpp
</del><span class="cx"> platform/graphics/gpu/GPUDevice.cpp
</span><span class="cx"> platform/graphics/gpu/GPUPipelineLayout.cpp
</span><span class="cx"> platform/graphics/gpu/GPUProgrammablePassEncoder.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreSourcesCocoatxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/SourcesCocoa.txt (242765 => 242766)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/SourcesCocoa.txt    2019-03-12 02:54:07 UTC (rev 242765)
+++ trunk/Source/WebCore/SourcesCocoa.txt       2019-03-12 03:19:10 UTC (rev 242766)
</span><span class="lines">@@ -317,6 +317,7 @@
</span><span class="cx"> platform/graphics/cv/TextureCacheCV.mm
</span><span class="cx"> platform/graphics/cv/VideoTextureCopierCV.cpp
</span><span class="cx"> 
</span><ins>+platform/graphics/gpu/cocoa/GPUBindGroupMetal.mm
</ins><span class="cx"> platform/graphics/gpu/cocoa/GPUBindGroupLayoutMetal.mm
</span><span class="cx"> platform/graphics/gpu/cocoa/GPUBufferMetal.mm
</span><span class="cx"> platform/graphics/gpu/cocoa/GPUCommandBufferMetal.mm
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (242765 => 242766)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj   2019-03-12 02:54:07 UTC (rev 242765)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj      2019-03-12 03:19:10 UTC (rev 242766)
</span><span class="lines">@@ -14094,6 +14094,7 @@
</span><span class="cx">          D084033D221E186400007205 /* WebGPUBindGroupDescriptor.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WebGPUBindGroupDescriptor.cpp; sourceTree = "<group>"; };
</span><span class="cx">          D0843A4A20FEBE3D00FE860E /* GraphicsContext3DManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GraphicsContext3DManager.h; sourceTree = "<group>"; };
</span><span class="cx">          D0843A4C20FEC16500FE860E /* GraphicsContext3DManager.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = GraphicsContext3DManager.cpp; sourceTree = "<group>"; };
</span><ins>+               D085E64A2236DEAE00C3E1E2 /* GPUBindGroupMetal.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = GPUBindGroupMetal.mm; sourceTree = "<group>"; };
</ins><span class="cx">           D086FE9609D53AAB005BC74D /* UnlinkCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnlinkCommand.h; sourceTree = "<group>"; };
</span><span class="cx">          D086FE9709D53AAB005BC74D /* UnlinkCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UnlinkCommand.cpp; sourceTree = "<group>"; };
</span><span class="cx">          D087CE3821ACA94200BDE174 /* GPUCommandBufferMetal.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = GPUCommandBufferMetal.mm; sourceTree = "<group>"; };
</span><span class="lines">@@ -14142,7 +14143,6 @@
</span><span class="cx">          D0BE105221E6AA0D00E42A89 /* WebGPUBindGroupDescriptor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebGPUBindGroupDescriptor.h; sourceTree = "<group>"; };
</span><span class="cx">          D0BE105321E6AA0D00E42A89 /* WebGPUBindGroupDescriptor.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = WebGPUBindGroupDescriptor.idl; sourceTree = "<group>"; };
</span><span class="cx">          D0BE105E21E6BAD300E42A89 /* GPUBindGroup.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPUBindGroup.h; sourceTree = "<group>"; };
</span><del>-               D0BE105F21E6BAD300E42A89 /* GPUBindGroup.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = GPUBindGroup.cpp; sourceTree = "<group>"; };
</del><span class="cx">           D0BE106021E6C0EB00E42A89 /* WebGPUBindGroup.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebGPUBindGroup.h; sourceTree = "<group>"; };
</span><span class="cx">          D0BE106121E6C0EB00E42A89 /* WebGPUBindGroup.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WebGPUBindGroup.cpp; sourceTree = "<group>"; };
</span><span class="cx">          D0BE106221E6C0EB00E42A89 /* WebGPUBindGroup.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = WebGPUBindGroup.idl; sourceTree = "<group>"; };
</span><span class="lines">@@ -18491,7 +18491,6 @@
</span><span class="cx">                  children = (
</span><span class="cx">                          D087CE3721ACA94200BDE174 /* cocoa */,
</span><span class="cx">                          312FF8CE21A4C33F00EB199D /* legacy */,
</span><del>-                               D0BE105F21E6BAD300E42A89 /* GPUBindGroup.cpp */,
</del><span class="cx">                           D0BE105E21E6BAD300E42A89 /* GPUBindGroup.h */,
</span><span class="cx">                          D0BE104E21E695E200E42A89 /* GPUBindGroupBinding.h */,
</span><span class="cx">                          D0BE105121E6A70E00E42A89 /* GPUBindGroupDescriptor.h */,
</span><span class="lines">@@ -26225,6 +26224,7 @@
</span><span class="cx">                  isa = PBXGroup;
</span><span class="cx">                  children = (
</span><span class="cx">                          D0232B5821CB49B7009483B9 /* GPUBindGroupLayoutMetal.mm */,
</span><ins>+                               D085E64A2236DEAE00C3E1E2 /* GPUBindGroupMetal.mm */,
</ins><span class="cx">                           D0D8649121B760C4003C983C /* GPUBufferMetal.mm */,
</span><span class="cx">                          D087CE3821ACA94200BDE174 /* GPUCommandBufferMetal.mm */,
</span><span class="cx">                          D087CE3C21ACA94200BDE174 /* GPUDeviceMetal.mm */,
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgpuGPUBindGroupcpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebCore/platform/graphics/gpu/GPUBindGroup.cpp (242765 => 242766)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gpu/GPUBindGroup.cpp      2019-03-12 02:54:07 UTC (rev 242765)
+++ trunk/Source/WebCore/platform/graphics/gpu/GPUBindGroup.cpp 2019-03-12 03:19:10 UTC (rev 242766)
</span><span class="lines">@@ -1,50 +0,0 @@
</span><del>-/*
- * 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 "GPUBindGroup.h"
-
-#if ENABLE(WEBGPU)
-
-#include "GPUBindGroupBinding.h"
-#include "GPUBindGroupDescriptor.h"
-
-namespace WebCore {
-
-Ref<GPUBindGroup> GPUBindGroup::create(GPUBindGroupDescriptor&& descriptor)
-{
-    // FIXME: Unfinished stub.
-    return adoptRef(*new GPUBindGroup(WTFMove(descriptor)));
-}
-
-GPUBindGroup::GPUBindGroup(GPUBindGroupDescriptor&& descriptor)
-    : m_layout(WTFMove(descriptor.layout))
-    , m_bindings(WTFMove(descriptor.bindings))
-{
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(WEBGPU)
</del></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgpuGPUBindGrouph"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/gpu/GPUBindGroup.h (242765 => 242766)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gpu/GPUBindGroup.h        2019-03-12 02:54:07 UTC (rev 242765)
+++ trunk/Source/WebCore/platform/graphics/gpu/GPUBindGroup.h   2019-03-12 03:19:10 UTC (rev 242766)
</span><span class="lines">@@ -27,28 +27,40 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(WEBGPU)
</span><span class="cx"> 
</span><del>-#include "GPUBindGroupBinding.h"
-#include "GPUBindGroupLayout.h"
-#include <wtf/Ref.h>
</del><span class="cx"> #include <wtf/RefCounted.h>
</span><ins>+#include <wtf/RefPtr.h>
+#include <wtf/RetainPtr.h>
</ins><span class="cx"> #include <wtf/Vector.h>
</span><span class="cx"> 
</span><ins>+OBJC_PROTOCOL(MTLBuffer);
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><ins>+class GPUBuffer;
+class GPUTexture;
+
</ins><span class="cx"> struct GPUBindGroupDescriptor;
</span><span class="cx"> 
</span><span class="cx"> class GPUBindGroup : public RefCounted<GPUBindGroup> {
</span><span class="cx"> public:
</span><del>-    static Ref<GPUBindGroup> create(GPUBindGroupDescriptor&&);
</del><ins>+    static RefPtr<GPUBindGroup> tryCreate(const GPUBindGroupDescriptor&);
+    
+#if USE(METAL)
+    MTLBuffer *vertexArgsBuffer() { return m_vertexArgsBuffer.get(); }
+    MTLBuffer *fragmentArgsBuffer() { return m_fragmentArgsBuffer.get(); }
+#endif
+    const Vector<Ref<GPUBuffer>>& boundBuffers() const { return m_boundBuffers; }
+    const Vector<Ref<GPUTexture>>& boundTextures() const { return m_boundTextures; }
</ins><span class="cx"> 
</span><del>-    const GPUBindGroupLayout& layout() const { return m_layout.get(); }
-    const Vector<GPUBindGroupBinding>& bindings() const { return m_bindings; }
-
</del><span class="cx"> private:
</span><del>-    explicit GPUBindGroup(GPUBindGroupDescriptor&&);
-
-    Ref<GPUBindGroupLayout> m_layout;
-    Vector<GPUBindGroupBinding> m_bindings;
</del><ins>+#if USE(METAL)
+    GPUBindGroup(RetainPtr<MTLBuffer>&& vertexBuffer, RetainPtr<MTLBuffer>&& fragmentBuffer, Vector<Ref<GPUBuffer>>&&, Vector<Ref<GPUTexture>>&&);
+    
+    RetainPtr<MTLBuffer> m_vertexArgsBuffer;
+    RetainPtr<MTLBuffer> m_fragmentArgsBuffer;
+#endif
+    Vector<Ref<GPUBuffer>> m_boundBuffers;
+    Vector<Ref<GPUTexture>> m_boundTextures;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgpuGPUBindGroupLayouth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/gpu/GPUBindGroupLayout.h (242765 => 242766)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gpu/GPUBindGroupLayout.h  2019-03-12 02:54:07 UTC (rev 242765)
+++ trunk/Source/WebCore/platform/graphics/gpu/GPUBindGroupLayout.h     2019-03-12 03:19:10 UTC (rev 242766)
</span><span class="lines">@@ -50,24 +50,18 @@
</span><span class="cx">     using BindingsMapType = HashMap<unsigned long long, GPUBindGroupLayoutBinding, WTF::IntHash<unsigned long long>, WTF::UnsignedWithZeroKeyHashTraits<unsigned long long>>;
</span><span class="cx">     const BindingsMapType& bindingsMap() const { return m_bindingsMap; }
</span><span class="cx"> #if USE(METAL)
</span><del>-    struct ArgumentEncoderBuffer {
-        RetainPtr<MTLArgumentEncoder> encoder;
-        RetainPtr<MTLBuffer> buffer;
-
-        bool isValid() const { return encoder && buffer; }
-    };
-    const ArgumentEncoderBuffer& vertexArguments() const { return m_vertexArguments; }
-    const ArgumentEncoderBuffer& fragmentArguments() const { return m_fragmentArguments; }
-    const ArgumentEncoderBuffer& computeArguments() const { return m_computeArguments; }
</del><ins>+    MTLArgumentEncoder *vertexEncoder() const { return m_vertexEncoder.get(); }
+    MTLArgumentEncoder *fragmentEncoder() const { return m_fragmentEncoder.get(); }
+    MTLArgumentEncoder *computeEncoder() const { return m_computeEncoder.get(); }
</ins><span class="cx"> #endif // USE(METAL)
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx"> #if USE(METAL)
</span><del>-    GPUBindGroupLayout(BindingsMapType&&, ArgumentEncoderBuffer&& vertex, ArgumentEncoderBuffer&& fragment, ArgumentEncoderBuffer&& compute);
</del><ins>+    GPUBindGroupLayout(BindingsMapType&&, RetainPtr<MTLArgumentEncoder>&& vertex, RetainPtr<MTLArgumentEncoder>&& fragment, RetainPtr<MTLArgumentEncoder>&& compute);
</ins><span class="cx"> 
</span><del>-    ArgumentEncoderBuffer m_vertexArguments;
-    ArgumentEncoderBuffer m_fragmentArguments;
-    ArgumentEncoderBuffer m_computeArguments;
</del><ins>+    RetainPtr<MTLArgumentEncoder> m_vertexEncoder;
+    RetainPtr<MTLArgumentEncoder> m_fragmentEncoder;
+    RetainPtr<MTLArgumentEncoder> m_computeEncoder;
</ins><span class="cx"> #endif // USE(METAL)
</span><span class="cx">     const BindingsMapType m_bindingsMap;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgpuGPUProgrammablePassEncoderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/gpu/GPUProgrammablePassEncoder.h (242765 => 242766)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gpu/GPUProgrammablePassEncoder.h  2019-03-12 02:54:07 UTC (rev 242765)
+++ trunk/Source/WebCore/platform/graphics/gpu/GPUProgrammablePassEncoder.h     2019-03-12 03:19:10 UTC (rev 242766)
</span><span class="lines">@@ -30,12 +30,11 @@
</span><span class="cx"> #include "GPUBindGroupBinding.h"
</span><span class="cx"> #include <wtf/RefCounted.h>
</span><span class="cx"> 
</span><del>-OBJC_PROTOCOL(MTLArgumentEncoder);
</del><span class="cx"> #if USE(METAL)
</span><span class="cx"> OBJC_PROTOCOL(MTLBuffer);
</span><span class="cx"> OBJC_PROTOCOL(MTLCommandEncoder);
</span><span class="cx"> OBJC_PROTOCOL(MTLResource);
</span><del>-#endif // USE(METAL)
</del><ins>+#endif
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="lines">@@ -61,9 +60,6 @@
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx"> #if USE(METAL)
</span><del>-    void setResourceAsBufferOnEncoder(MTLArgumentEncoder *, const GPUBindGroupBinding&, const char* const);
-    void setResourceAsSamplerOnEncoder(MTLArgumentEncoder *, const GPUBindGroupBinding&, const char* const);
-    void setResourceAsTextureOnEncoder(MTLArgumentEncoder *, const GPUBindGroupBinding&, const char* const);
</del><span class="cx">     virtual void useResource(MTLResource *, unsigned) = 0;
</span><span class="cx"> 
</span><span class="cx">     // Render command encoder methods.
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgpucocoaGPUBindGroupLayoutMetalmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUBindGroupLayoutMetal.mm (242765 => 242766)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUBindGroupLayoutMetal.mm      2019-03-12 02:54:07 UTC (rev 242765)
+++ trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUBindGroupLayoutMetal.mm 2019-03-12 03:19:10 UTC (rev 242766)
</span><span class="lines">@@ -63,28 +63,18 @@
</span><span class="cx">     END_BLOCK_OBJC_EXCEPTIONS;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static GPUBindGroupLayout::ArgumentEncoderBuffer tryCreateArgumentEncoderAndBuffer(const GPUDevice& device, ArgumentArray array)
</del><ins>+static RetainPtr<MTLArgumentEncoder> tryCreateMtlArgumentEncoder(const GPUDevice& device, ArgumentArray array)
</ins><span class="cx"> {
</span><del>-    GPUBindGroupLayout::ArgumentEncoderBuffer args;
</del><ins>+    RetainPtr<MTLArgumentEncoder> encoder;
</ins><span class="cx"> 
</span><span class="cx">     BEGIN_BLOCK_OBJC_EXCEPTIONS;
</span><del>-    args.encoder = adoptNS([device.platformDevice() newArgumentEncoderWithArguments:array.get()]);
</del><ins>+    encoder = adoptNS([device.platformDevice() newArgumentEncoderWithArguments:array.get()]);
</ins><span class="cx">     END_BLOCK_OBJC_EXCEPTIONS;
</span><del>-    if (!args.encoder) {
</del><ins>+    if (!encoder) {
</ins><span class="cx">         LOG(WebGPU, "GPUBindGroupLayout::tryCreate(): Unable to create MTLArgumentEncoder!");
</span><del>-        return { };
</del><ins>+        return nullptr;
</ins><span class="cx">     }
</span><del>-
-    BEGIN_BLOCK_OBJC_EXCEPTIONS;
-    args.buffer = adoptNS([device.platformDevice() newBufferWithLength:args.encoder.get().encodedLength options:0]);
-    [args.encoder setArgumentBuffer:args.buffer.get() offset:0];
-    END_BLOCK_OBJC_EXCEPTIONS;
-    if (!args.buffer) {
-        LOG(WebGPU, "GPUBindGroupLayout::tryCreate(): Unable to create MTLBuffer from MTLArgumentEncoder!");
-        return { };
-    }
-
-    return args;
</del><ins>+    return encoder;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> RefPtr<GPUBindGroupLayout> GPUBindGroupLayout::tryCreate(const GPUDevice& device, const GPUBindGroupLayoutDescriptor& descriptor)
</span><span class="lines">@@ -108,14 +98,13 @@
</span><span class="cx">         BEGIN_BLOCK_OBJC_EXCEPTIONS;
</span><span class="cx">         mtlArgument = adoptNS([MTLArgumentDescriptor new]);
</span><span class="cx">         END_BLOCK_OBJC_EXCEPTIONS;
</span><del>-
</del><span class="cx">         if (!mtlArgument) {
</span><span class="cx">             LOG(WebGPU, "GPUBindGroupLayout::tryCreate(): Unable to create MTLArgumentDescriptor for binding %lu!", binding.binding);
</span><span class="cx">             return nullptr;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        mtlArgument.get().dataType = MTLDataTypeForBindingType(binding.type);
-        mtlArgument.get().index = binding.binding;
</del><ins>+        [mtlArgument setDataType:MTLDataTypeForBindingType(binding.type)];
+        [mtlArgument setIndex:binding.binding];
</ins><span class="cx"> 
</span><span class="cx">         if (binding.visibility & GPUShaderStageBit::Flags::Vertex)
</span><span class="cx">             appendArgumentToArray(vertexArgsArray, mtlArgument);
</span><span class="lines">@@ -125,18 +114,18 @@
</span><span class="cx">             appendArgumentToArray(computeArgsArray, mtlArgument);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    ArgumentEncoderBuffer vertex, fragment, compute;
</del><ins>+    RetainPtr<MTLArgumentEncoder> vertex, fragment, compute;
</ins><span class="cx"> 
</span><span class="cx">     if (vertexArgsArray) {
</span><del>-        if (!(vertex = tryCreateArgumentEncoderAndBuffer(device, vertexArgsArray)).isValid())
</del><ins>+        if (!(vertex = tryCreateMtlArgumentEncoder(device, vertexArgsArray)))
</ins><span class="cx">             return nullptr;
</span><span class="cx">     }
</span><span class="cx">     if (fragmentArgsArray) {
</span><del>-        if (!(fragment = tryCreateArgumentEncoderAndBuffer(device, fragmentArgsArray)).isValid())
</del><ins>+        if (!(fragment = tryCreateMtlArgumentEncoder(device, fragmentArgsArray)))
</ins><span class="cx">             return nullptr;
</span><span class="cx">     }
</span><span class="cx">     if (computeArgsArray) {
</span><del>-        if (!(compute = tryCreateArgumentEncoderAndBuffer(device, computeArgsArray)).isValid())
</del><ins>+        if (!(compute = tryCreateMtlArgumentEncoder(device, computeArgsArray)))
</ins><span class="cx">             return nullptr;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -143,10 +132,10 @@
</span><span class="cx">     return adoptRef(new GPUBindGroupLayout(WTFMove(bindingsMap), WTFMove(vertex), WTFMove(fragment), WTFMove(compute)));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-GPUBindGroupLayout::GPUBindGroupLayout(BindingsMapType&& bindingsMap, ArgumentEncoderBuffer&& vertex, ArgumentEncoderBuffer&& fragment, ArgumentEncoderBuffer&& compute)
-    : m_vertexArguments(WTFMove(vertex))
-    , m_fragmentArguments(WTFMove(fragment))
-    , m_computeArguments(WTFMove(compute))
</del><ins>+GPUBindGroupLayout::GPUBindGroupLayout(BindingsMapType&& bindingsMap, RetainPtr<MTLArgumentEncoder>&& vertex, RetainPtr<MTLArgumentEncoder>&& fragment, RetainPtr<MTLArgumentEncoder>&& compute)
+    : m_vertexEncoder(WTFMove(vertex))
+    , m_fragmentEncoder(WTFMove(fragment))
+    , m_computeEncoder(WTFMove(compute))
</ins><span class="cx">     , m_bindingsMap(WTFMove(bindingsMap))
</span><span class="cx"> {
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgpucocoaGPUBindGroupMetalmm"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUBindGroupMetal.mm (0 => 242766)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUBindGroupMetal.mm                            (rev 0)
+++ trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUBindGroupMetal.mm       2019-03-12 03:19:10 UTC (rev 242766)
</span><span class="lines">@@ -0,0 +1,227 @@
</span><ins>+/*
+ * 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.
+ */
+
+#import "config.h"
+#import "GPUBindGroup.h"
+
+#if ENABLE(WEBGPU)
+
+#import "GPUBindGroupBinding.h"
+#import "GPUBindGroupDescriptor.h"
+#import "GPUBindGroupLayout.h"
+#import "GPUBuffer.h"
+#import "GPUSampler.h"
+#import "GPUTexture.h"
+#import "Logging.h"
+#import <wtf/BlockObjCExceptions.h>
+#import <wtf/Optional.h>
+
+namespace WebCore {
+
+static RetainPtr<MTLBuffer> tryCreateArgumentBuffer(MTLArgumentEncoder *encoder)
+{
+    RetainPtr<MTLBuffer> buffer;
+    BEGIN_BLOCK_OBJC_EXCEPTIONS;
+    buffer = adoptNS([encoder.device newBufferWithLength:encoder.encodedLength options:0]);
+    [encoder setArgumentBuffer:buffer.get() offset:0];
+    END_BLOCK_OBJC_EXCEPTIONS;
+    return buffer;
+}
+    
+static Optional<GPUBufferBinding> tryGetResourceAsBufferBinding(const GPUBindingResource& resource, const char* const functionName)
+{
+#if LOG_DISABLED
+    UNUSED_PARAM(functionName);
+#endif
+    if (!WTF::holds_alternative<GPUBufferBinding>(resource)) {
+        LOG(WebGPU, "%s: Resource is not a buffer type!", functionName);
+        return WTF::nullopt;
+    }
+    auto& bufferBinding = WTF::get<GPUBufferBinding>(resource);
+    if (!bufferBinding.buffer->platformBuffer()) {
+        LOG(WebGPU, "%s: Invalid MTLBuffer in GPUBufferBinding!", functionName);
+        return WTF::nullopt;
+    }
+    return GPUBufferBinding { bufferBinding.buffer.copyRef(), bufferBinding.offset, bufferBinding.size };
+}
+
+static void setBufferOnEncoder(MTLArgumentEncoder *argumentEncoder, const GPUBufferBinding& bufferBinding, unsigned index)
+{
+    ASSERT(argumentEncoder && bufferBinding.buffer->platformBuffer());
+
+    BEGIN_BLOCK_OBJC_EXCEPTIONS;
+    [argumentEncoder setBuffer:bufferBinding.buffer->platformBuffer() offset:bufferBinding.offset atIndex:index];
+    END_BLOCK_OBJC_EXCEPTIONS;
+}
+    
+static RefPtr<GPUSampler> tryGetResourceAsSampler(const GPUBindingResource& resource, const char* const functionName)
+{
+#if LOG_DISABLED
+    UNUSED_PARAM(functionName);
+#endif
+    if (!WTF::holds_alternative<Ref<GPUSampler>>(resource)) {
+        LOG(WebGPU, "%s: Resource is not a GPUSampler!", functionName);
+        return nullptr;
+    }
+    auto& samplerRef = WTF::get<Ref<GPUSampler>>(resource);
+    if (!samplerRef->platformSampler()) {
+        LOG(WebGPU, "%s: Invalid MTLSamplerState in GPUSampler binding!", functionName);
+        return nullptr;
+    }
+    return samplerRef.copyRef();
+}
+
+static void setSamplerOnEncoder(MTLArgumentEncoder *argumentEncoder, MTLSamplerState *sampler, unsigned index)
+{
+    ASSERT(argumentEncoder && sampler);
+
+    BEGIN_BLOCK_OBJC_EXCEPTIONS;
+    [argumentEncoder setSamplerState:sampler atIndex:index];
+    END_BLOCK_OBJC_EXCEPTIONS;
+}
+
+static RefPtr<GPUTexture> tryGetResourceAsTexture(const GPUBindingResource& resource, const char* const functionName)
+    {
+#if LOG_DISABLED
+    UNUSED_PARAM(functionName);
+#endif
+    if (!WTF::holds_alternative<Ref<GPUTexture>>(resource)) {
+        LOG(WebGPU, "%s: Resource is not a GPUTextureView!", functionName);
+        return nullptr;
+    }
+    auto& textureRef = WTF::get<Ref<GPUTexture>>(resource);
+    if (!textureRef->platformTexture()) {
+        LOG(WebGPU, "%s: Invalid MTLTexture in GPUTextureView binding!", functionName);
+        return nullptr;
+    }
+    return textureRef.copyRef();
+}
+
+static void setTextureOnEncoder(MTLArgumentEncoder *argumentEncoder, MTLTexture *texture, unsigned index)
+{
+    ASSERT(argumentEncoder && texture);
+
+    BEGIN_BLOCK_OBJC_EXCEPTIONS;
+    [argumentEncoder setTexture:texture atIndex:index];
+    END_BLOCK_OBJC_EXCEPTIONS;
+}
+    
+RefPtr<GPUBindGroup> GPUBindGroup::tryCreate(const GPUBindGroupDescriptor& descriptor)
+{
+    const char* const functionName = "GPUBindGroup::tryCreate()";
+    
+    MTLArgumentEncoder *vertexEncoder = descriptor.layout->vertexEncoder();
+    MTLArgumentEncoder *fragmentEncoder = descriptor.layout->fragmentEncoder();
+    // FIXME: Finish support for compute.
+    
+    RetainPtr<MTLBuffer> vertexArgsBuffer;
+    if (vertexEncoder && !(vertexArgsBuffer = tryCreateArgumentBuffer(vertexEncoder))) {
+        LOG(WebGPU, "%s: Unable to create MTLBuffer for vertex argument buffer!", functionName);
+        return nullptr;
+    }
+    RetainPtr<MTLBuffer> fragmentArgsBuffer;
+    if (fragmentEncoder && !(fragmentArgsBuffer = tryCreateArgumentBuffer(fragmentEncoder))) {
+        LOG(WebGPU, "%s: Unable to create MTLBuffer for fragment argument buffer!", functionName);
+        return nullptr;
+    }
+    
+    Vector<Ref<GPUBuffer>> boundBuffers;
+    Vector<Ref<GPUTexture>> boundTextures;
+
+    // Set each resource on each MTLArgumentEncoder it should be visible on.
+    const auto& layoutBindingsMap = descriptor.layout->bindingsMap();
+    for (const auto& resourceBinding : descriptor.bindings) {
+        auto layoutIterator = layoutBindingsMap.find(resourceBinding.binding);
+        if (layoutIterator == layoutBindingsMap.end()) {
+            LOG(WebGPU, "%s: GPUBindGroupBinding %lu not found in GPUBindGroupLayout!", functionName, resourceBinding.binding);
+            return nullptr;
+        }
+        auto layoutBinding = layoutIterator->value;
+        if (layoutBinding.visibility == GPUShaderStageBit::Flags::None)
+            continue;
+        if ((layoutBinding.visibility & GPUShaderStageBit::Flags::Vertex) && !vertexEncoder) {
+            LOG(WebGPU, "%s: No vertex encoder found for binding %lu!", functionName, resourceBinding.binding);
+            return nullptr;
+        }
+        if ((layoutBinding.visibility & GPUShaderStageBit::Flags::Fragment) && !fragmentEncoder) {
+            LOG(WebGPU, "%s: No fragment encoder found for binding %lu!", functionName, resourceBinding.binding);
+            return nullptr;
+        }
+        
+        switch (layoutBinding.type) {
+        // FIXME: Support more resource types.
+        case GPUBindGroupLayoutBinding::BindingType::UniformBuffer:
+        case GPUBindGroupLayoutBinding::BindingType::StorageBuffer: {
+            auto bufferResource = tryGetResourceAsBufferBinding(resourceBinding.resource, functionName);
+            if (!bufferResource)
+                return nullptr;
+            if (layoutBinding.visibility & GPUShaderStageBit::Flags::Vertex)
+                setBufferOnEncoder(vertexEncoder, *bufferResource, resourceBinding.binding);
+            if (layoutBinding.visibility & GPUShaderStageBit::Flags::Fragment)
+                setBufferOnEncoder(fragmentEncoder, *bufferResource, resourceBinding.binding);
+            boundBuffers.append(bufferResource->buffer.copyRef());
+            break;
+        }
+        case GPUBindGroupLayoutBinding::BindingType::Sampler: {
+            auto samplerResource = tryGetResourceAsSampler(resourceBinding.resource, functionName);
+            if (!samplerResource)
+                return nullptr;
+            if (layoutBinding.visibility & GPUShaderStageBit::Flags::Vertex)
+                setSamplerOnEncoder(vertexEncoder, samplerResource->platformSampler(), resourceBinding.binding);
+            if (layoutBinding.visibility & GPUShaderStageBit::Flags::Fragment)
+                setSamplerOnEncoder(fragmentEncoder, samplerResource->platformSampler(), resourceBinding.binding);
+            break;
+        }
+        case GPUBindGroupLayoutBinding::BindingType::SampledTexture: {
+            auto textureResource = tryGetResourceAsTexture(resourceBinding.resource, functionName);
+            if (!textureResource)
+                return nullptr;
+            if (layoutBinding.visibility & GPUShaderStageBit::Flags::Vertex)
+                setTextureOnEncoder(vertexEncoder, textureResource->platformTexture(), resourceBinding.binding);
+            if (layoutBinding.visibility & GPUShaderStageBit::Flags::Fragment)
+                setTextureOnEncoder(fragmentEncoder, textureResource->platformTexture(), resourceBinding.binding);
+            boundTextures.append(textureResource.releaseNonNull());
+            break;
+        }
+        default:
+            LOG(WebGPU, "%s: Resource type not yet implemented.", functionName);
+            return nullptr;
+        }
+    }
+    
+    return adoptRef(new GPUBindGroup(WTFMove(vertexArgsBuffer), WTFMove(fragmentArgsBuffer), WTFMove(boundBuffers), WTFMove(boundTextures)));
+}
+    
+GPUBindGroup::GPUBindGroup(RetainPtr<MTLBuffer>&& vertexBuffer, RetainPtr<MTLBuffer>&& fragmentBuffer, Vector<Ref<GPUBuffer>>&& buffers, Vector<Ref<GPUTexture>>&& textures)
+    : m_vertexArgsBuffer(WTFMove(vertexBuffer))
+    , m_fragmentArgsBuffer(WTFMove(fragmentBuffer))
+    , m_boundBuffers(WTFMove(buffers))
+    , m_boundTextures(WTFMove(textures))
+{
+}
+    
+} // namespace WebCore
+
+#endif // ENABLE(WEBPGU)
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgpucocoaGPUProgrammablePassEncoderMetalmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUProgrammablePassEncoderMetal.mm (242765 => 242766)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUProgrammablePassEncoderMetal.mm      2019-03-12 02:54:07 UTC (rev 242765)
+++ trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUProgrammablePassEncoderMetal.mm 2019-03-12 03:19:10 UTC (rev 242766)
</span><span class="lines">@@ -29,7 +29,6 @@
</span><span class="cx"> #if ENABLE(WEBGPU)
</span><span class="cx"> 
</span><span class="cx"> #import "GPUBindGroup.h"
</span><del>-#import "GPUBindGroupLayoutBinding.h"
</del><span class="cx"> #import "GPUCommandBuffer.h"
</span><span class="cx"> #import "Logging.h"
</span><span class="cx"> #import <Metal/Metal.h>
</span><span class="lines">@@ -50,162 +49,26 @@
</span><span class="cx"> 
</span><span class="cx"> void GPUProgrammablePassEncoder::setBindGroup(unsigned index, GPUBindGroup& bindGroup)
</span><span class="cx"> {
</span><del>-    const char* const functionName = "GPUProgrammablePassEncoder::setBindGroup()";
-
</del><span class="cx">     if (!platformPassEncoder()) {
</span><del>-        LOG(WebGPU, "%s: Invalid operation: Encoding is ended!");
</del><ins>+        LOG(WebGPU, "GPUProgrammablePassEncoder::setBindGroup(): Invalid operation: Encoding is ended!");
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><ins>+    
+    if (bindGroup.vertexArgsBuffer())
+        setVertexBuffer(bindGroup.vertexArgsBuffer(), 0, index);
+    if (bindGroup.fragmentArgsBuffer())
+        setFragmentBuffer(bindGroup.fragmentArgsBuffer(), 0, index);
</ins><span class="cx"> 
</span><del>-    const auto& vertexArgs = bindGroup.layout().vertexArguments();
-    const auto& fragmentArgs = bindGroup.layout().fragmentArguments();
-    // FIXME: Finish support for compute.
-
-    BEGIN_BLOCK_OBJC_EXCEPTIONS;
-
-    if (vertexArgs.buffer)
-        setVertexBuffer(vertexArgs.buffer.get(), 0, index);
-    if (fragmentArgs.buffer)
-        setFragmentBuffer(fragmentArgs.buffer.get(), 0, index);
-
-    END_BLOCK_OBJC_EXCEPTIONS;
-
-    // Set each resource on each MTLArgumentEncoder it should be visible on.
-    const auto& layoutBindingsMap = bindGroup.layout().bindingsMap();
-    for (const auto& resourceBinding : bindGroup.bindings()) {
-        auto layoutIterator = layoutBindingsMap.find(resourceBinding.binding);
-        if (layoutIterator == layoutBindingsMap.end()) {
-            LOG(WebGPU, "%s: GPUBindGroupBinding %lu not found in GPUBindGroupLayout!", functionName, resourceBinding.binding);
-            return;
-        }
-        auto layoutBinding = layoutIterator->value;
-
-        switch (layoutBinding.type) {
-        // FIXME: Support more resource types.
-        case GPUBindGroupLayoutBinding::BindingType::UniformBuffer:
-        case GPUBindGroupLayoutBinding::BindingType::StorageBuffer: {
-            if (layoutBinding.visibility & GPUShaderStageBit::Flags::Vertex)
-                setResourceAsBufferOnEncoder(vertexArgs.encoder.get(), resourceBinding, functionName);
-            if (layoutBinding.visibility & GPUShaderStageBit::Flags::Fragment)
-                setResourceAsBufferOnEncoder(fragmentArgs.encoder.get(), resourceBinding, functionName);
-            break;
-        }
-        case GPUBindGroupLayoutBinding::BindingType::Sampler: {
-            if (layoutBinding.visibility & GPUShaderStageBit::Flags::Vertex)
-                setResourceAsSamplerOnEncoder(vertexArgs.encoder.get(), resourceBinding, functionName);
-            if (layoutBinding.visibility & GPUShaderStageBit::Flags::Fragment)
-                setResourceAsSamplerOnEncoder(fragmentArgs.encoder.get(), resourceBinding, functionName);
-            break;
-        }
-        case GPUBindGroupLayoutBinding::BindingType::SampledTexture: {
-            if (layoutBinding.visibility & GPUShaderStageBit::Flags::Vertex)
-                setResourceAsTextureOnEncoder(vertexArgs.encoder.get(), resourceBinding, functionName);
-            if (layoutBinding.visibility & GPUShaderStageBit::Flags::Fragment)
-                setResourceAsTextureOnEncoder(fragmentArgs.encoder.get(), resourceBinding, functionName);
-            break;
-        }
-        default:
-            LOG(WebGPU, "%s: Resource type not yet implemented.", functionName);
-            return;
-        }
</del><ins>+    for (auto& bufferRef : bindGroup.boundBuffers()) {
+        useResource(bufferRef->platformBuffer(), bufferRef->isReadOnly() ? MTLResourceUsageRead : MTLResourceUsageRead | MTLResourceUsageWrite);
+        m_commandBuffer->useBuffer(bufferRef.copyRef());
</ins><span class="cx">     }
</span><del>-}
-
-void GPUProgrammablePassEncoder::setResourceAsBufferOnEncoder(MTLArgumentEncoder *argumentEncoder, const GPUBindGroupBinding& binding, const char* const functionName)
-{
-#if LOG_DISABLED
-    UNUSED_PARAM(functionName);
-#endif
-    if (!argumentEncoder) {
-        LOG(WebGPU, "%s: No argument encoder for requested stage found!", functionName);
-        return;
</del><ins>+    for (auto& textureRef : bindGroup.boundTextures()) {
+        useResource(textureRef->platformTexture(), textureRef->isReadOnly() ? MTLResourceUsageRead : MTLResourceUsageRead | MTLResourceUsageWrite);
+        m_commandBuffer->useTexture(textureRef.copyRef());
</ins><span class="cx">     }
</span><del>-
-    if (!WTF::holds_alternative<GPUBufferBinding>(binding.resource)) {
-        LOG(WebGPU, "%s: Resource is not a buffer type!", functionName);
-        return;
-    }
-
-    auto& bufferBinding = WTF::get<GPUBufferBinding>(binding.resource);
-    auto& bufferRef = bufferBinding.buffer;
-    auto mtlBuffer = bufferRef->platformBuffer();
-
-    if (!mtlBuffer) {
-        LOG(WebGPU, "%s: Invalid MTLBuffer in GPUBufferBinding!", functionName);
-        return;
-    }
-
-    BEGIN_BLOCK_OBJC_EXCEPTIONS;
-
-    [argumentEncoder setBuffer:mtlBuffer offset:bufferBinding.offset atIndex:binding.binding];
-    useResource(mtlBuffer, bufferRef->isReadOnly() ? MTLResourceUsageRead : MTLResourceUsageRead | MTLResourceUsageWrite);
-
-    END_BLOCK_OBJC_EXCEPTIONS;
-
-    m_commandBuffer->useBuffer(bufferRef.copyRef());
</del><span class="cx"> }
</span><span class="cx"> 
</span><del>-void GPUProgrammablePassEncoder::setResourceAsSamplerOnEncoder(MTLArgumentEncoder *argumentEncoder, const GPUBindGroupBinding& binding, const char *const functionName)
-{
-#if LOG_DISABLED
-    UNUSED_PARAM(functionName);
-#endif
-    if (!argumentEncoder) {
-        LOG(WebGPU, "%s: No argument encoder for requested stage found!", functionName);
-        return;
-    }
-
-    if (!WTF::holds_alternative<Ref<GPUSampler>>(binding.resource)) {
-        LOG(WebGPU, "%s: Resource is not a GPUSampler!", functionName);
-        return;
-    }
-
-    auto& samplerRef = WTF::get<Ref<GPUSampler>>(binding.resource);
-    auto mtlSampler = samplerRef->platformSampler();
-
-    if (!mtlSampler) {
-        LOG(WebGPU, "%s: Invalid MTLSamplerState in GPUSampler binding!", functionName);
-        return;
-    }
-
-    BEGIN_BLOCK_OBJC_EXCEPTIONS;
-    [argumentEncoder setSamplerState:mtlSampler atIndex:binding.binding];
-    END_BLOCK_OBJC_EXCEPTIONS;
-}
-
-void GPUProgrammablePassEncoder::setResourceAsTextureOnEncoder(MTLArgumentEncoder *argumentEncoder, const GPUBindGroupBinding& binding, const char* const functionName)
-{
-#if LOG_DISABLED
-    UNUSED_PARAM(functionName);
-#endif
-    if (!argumentEncoder) {
-        LOG(WebGPU, "%s: No argument encoder for requested stage found!", functionName);
-        return;
-    }
-
-    if (!WTF::holds_alternative<Ref<GPUTexture>>(binding.resource)) {
-        LOG(WebGPU, "%s: Resource is not a GPUTextureView!", functionName);
-        return;
-    }
-
-    auto& textureRef = WTF::get<Ref<GPUTexture>>(binding.resource);
-    auto mtlTexture = textureRef->platformTexture();
-
-    if (!mtlTexture) {
-        LOG(WebGPU, "%s: Invalid MTLTexture in GPUTextureView binding!", functionName);
-        return;
-    }
-
-    BEGIN_BLOCK_OBJC_EXCEPTIONS;
-
-    [argumentEncoder setTexture:mtlTexture atIndex:binding.binding];
-    useResource(mtlTexture, textureRef->isReadOnly() ? MTLResourceUsageRead : MTLResourceUsageRead | MTLResourceUsageWrite);
-
-    END_BLOCK_OBJC_EXCEPTIONS;
-
-    m_commandBuffer->useTexture(textureRef.copyRef());
-}
-
</del><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(WEBGPU)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgpucocoaGPURenderPassEncoderMetalmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPURenderPassEncoderMetal.mm (242765 => 242766)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPURenderPassEncoderMetal.mm    2019-03-12 02:54:07 UTC (rev 242765)
+++ trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPURenderPassEncoderMetal.mm       2019-03-12 03:19:10 UTC (rev 242766)
</span><span class="lines">@@ -277,8 +277,9 @@
</span><span class="cx">         LOG(WebGPU, "GPURenderPassEncoder: Invalid operation: Encoding is ended!");
</span><span class="cx">         return;
</span><span class="cx">     }
</span><del>-
</del><ins>+    BEGIN_BLOCK_OBJC_EXCEPTIONS;
</ins><span class="cx">     [m_platformRenderPassEncoder useResource:resource usage:usage];
</span><ins>+    END_BLOCK_OBJC_EXCEPTIONS;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void GPURenderPassEncoder::setVertexBuffer(MTLBuffer *buffer, unsigned offset, unsigned index)
</span><span class="lines">@@ -287,8 +288,9 @@
</span><span class="cx">         LOG(WebGPU, "GPURenderPassEncoder: Invalid operation: Encoding is ended!");
</span><span class="cx">         return;
</span><span class="cx">     }
</span><del>-
</del><ins>+    BEGIN_BLOCK_OBJC_EXCEPTIONS;
</ins><span class="cx">     [m_platformRenderPassEncoder setVertexBuffer:buffer offset:offset atIndex:index];
</span><ins>+    END_BLOCK_OBJC_EXCEPTIONS;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void GPURenderPassEncoder::setFragmentBuffer(MTLBuffer *buffer, unsigned offset, unsigned index)
</span><span class="lines">@@ -297,8 +299,9 @@
</span><span class="cx">         LOG(WebGPU, "GPURenderPassEncoder: Invalid operation: Encoding is ended!");
</span><span class="cx">         return;
</span><span class="cx">     }
</span><del>-
</del><ins>+    BEGIN_BLOCK_OBJC_EXCEPTIONS;
</ins><span class="cx">     [m_platformRenderPassEncoder setFragmentBuffer:buffer offset:offset atIndex:index];
</span><ins>+    END_BLOCK_OBJC_EXCEPTIONS;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #endif // USE(METAL)
</span></span></pre>
</div>
</div>

</body>
</html>