<!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>[242404] trunk</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/242404">242404</a></dd>
<dt>Author</dt> <dd>justin_fan@apple.com</dd>
<dt>Date</dt> <dd>2019-03-04 16:55:15 -0800 (Mon, 04 Mar 2019)</dd>
</dl>

<h3>Log Message</h3>
<pre>[Web GPU] Blitting function prototypes
https://bugs.webkit.org/show_bug.cgi?id=195224
<rdar://problem/48538902>

Reviewed by Dean Jackson.

Source/WebCore:

Implement barebones GPUCommandBuffer::copy* prototypes while rounding out GPUTexture implementation details.

Test: webgpu/blit-commands.html

* Modules/webgpu/GPUOrigin3D.h: Added.
* Modules/webgpu/GPUOrigin3D.idl: Added.
* Modules/webgpu/WebGPUCommandBuffer.cpp: Add copy view struct implementations.
(WebCore::WebGPUBufferCopyView::asGPUBufferCopyView const): Added.
(WebCore::WebGPUTextureCopyView::asGPUTextureCopyView const): Added.
(WebCore::WebGPUCommandBuffer::copyBufferToBuffer): Added.
(WebCore::WebGPUCommandBuffer::copyBufferToTexture): Added.
(WebCore::WebGPUCommandBuffer::copyTextureToBuffer): Added.
(WebCore::WebGPUCommandBuffer::copyTextureToTexture): Added.
* Modules/webgpu/WebGPUCommandBuffer.h: Add new functions and supporting structs.
* Modules/webgpu/WebGPUCommandBuffer.idl: Ditto.
* Modules/webgpu/WebGPURenderPassDescriptor.cpp: Refactor constructors to copy the entire base class.
(WebCore::GPURenderPassColorAttachmentDescriptor::GPURenderPassColorAttachmentDescriptor):
(WebCore::GPURenderPassDepthStencilAttachmentDescriptor::GPURenderPassDepthStencilAttachmentDescriptor):
(WebCore::WebGPURenderPassDescriptor::asGPURenderPassDescriptor const):
(WebCore::attachment): Deleted.
* Modules/webgpu/WebGPUTexture.h:
(WebCore::WebGPUTexture::texture const): Added.
* platform/graphics/gpu/GPUBuffer.h:
(WebCore::GPUBuffer::byteLength const): Added.
(WebCore::GPUBuffer::isTransferSource const): Added.
(WebCore::GPUBuffer::isTransferDestination const): Renamed from isTransferDst. Refactored for OptionSet API.
(WebCore::GPUBuffer::isVertex const): Ditto.
(WebCore::GPUBuffer::isUniform const): Ditto.
(WebCore::GPUBuffer::isStorage const): Ditto.
(WebCore::GPUBuffer::isMappable const): Ditto.
(WebCore::GPUBuffer::isMapWrite const): Ditto.
(WebCore::GPUBuffer::isMapRead const): Ditto.
* platform/graphics/gpu/GPUBufferUsage.h: Refactored for better bit flag style.
* platform/graphics/gpu/GPUCommandBuffer.h:
(WebCore::GPUCommandBuffer::blitEncoder const): Added.
* platform/graphics/gpu/GPURenderPassDescriptor.h:
* platform/graphics/gpu/GPUTexture.h: Cache usage flags for reference.
(WebCore::GPUTexture::isTransferSrc const): Added.
(WebCore::GPUTexture::isTransferDst const): Added.
(WebCore::GPUTexture::isOutputAttachment const): Added.
* platform/graphics/gpu/GPUTextureUsage.h: Refactor to match GPUBufferUsage.h.
* platform/graphics/gpu/cocoa/GPUBufferMetal.mm:
(WebCore::GPUBuffer::validateBufferUsage): Renamed from validateBufferCreate, refactored for OptionSet.
(WebCore::GPUBuffer::tryCreate):
(WebCore::GPUBuffer::GPUBuffer):
(WebCore::GPUBuffer::isReadOnly const):
(WebCore::GPUBuffer::setSubData): Add alignment check according to Metal docs.
* platform/graphics/gpu/cocoa/GPUCommandBufferMetal.mm:
(WebCore::GPUCommandBuffer::create): No need to use this alias here.
(WebCore::GPUCommandBuffer::GPUCommandBuffer): Ditto.
(WebCore::GPUCommandBuffer::copyBufferToBuffer): Added.
(WebCore::GPUCommandBuffer::copyBufferToTexture): Added.
(WebCore::GPUCommandBuffer::copyTextureToBuffer): Added.
(WebCore::GPUCommandBuffer::copyTextureToTexture): Added.
* platform/graphics/gpu/cocoa/GPUQueueMetal.mm:
(WebCore::GPUQueue::submit): End encoding on the MTLCommandBuffer's blitCommandEncoder if it was used.
* platform/graphics/gpu/cocoa/GPUSwapChainMetal.mm:
(WebCore::GPUSwapChain::getNextTexture): Now provide usage flags to texture creation.
* platform/graphics/gpu/cocoa/GPUTextureMetal.mm:
(WebCore::mtlTextureUsageForGPUTextureUsageFlags): Refactor validation.
(WebCore::tryCreateMtlTextureDescriptor): Ditto.
(WebCore::GPUTexture::tryCreate): Now provide usage flags to texture creation.
(WebCore::GPUTexture::create): Ditto.
(WebCore::GPUTexture::GPUTexture): Ditto.
(WebCore::GPUTexture::createDefaultTextureView): Ditto.

LayoutTests:

Add basic test to copy data with all new blitting functions and verify the result.

* webgpu/blit-commands-expected.html: Added.
* webgpu/blit-commands.html: Added.
* webgpu/buffer-command-buffer-races.html: Fixed typo.
* webgpu/resources/green-400.png: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestswebgpubuffercommandbufferraceshtml">trunk/LayoutTests/webgpu/buffer-command-buffer-races.html</a></li>
<li><a href="#trunkSourceWebCoreCMakeListstxt">trunk/Source/WebCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreDerivedSourcesinputxcfilelist">trunk/Source/WebCore/DerivedSources-input.xcfilelist</a></li>
<li><a href="#trunkSourceWebCoreDerivedSourcesoutputxcfilelist">trunk/Source/WebCore/DerivedSources-output.xcfilelist</a></li>
<li><a href="#trunkSourceWebCoreDerivedSourcesmake">trunk/Source/WebCore/DerivedSources.make</a></li>
<li><a href="#trunkSourceWebCoreModuleswebgpuWebGPUCommandBuffercpp">trunk/Source/WebCore/Modules/webgpu/WebGPUCommandBuffer.cpp</a></li>
<li><a href="#trunkSourceWebCoreModuleswebgpuWebGPUCommandBufferh">trunk/Source/WebCore/Modules/webgpu/WebGPUCommandBuffer.h</a></li>
<li><a href="#trunkSourceWebCoreModuleswebgpuWebGPUCommandBufferidl">trunk/Source/WebCore/Modules/webgpu/WebGPUCommandBuffer.idl</a></li>
<li><a href="#trunkSourceWebCoreModuleswebgpuWebGPURenderPassDescriptorcpp">trunk/Source/WebCore/Modules/webgpu/WebGPURenderPassDescriptor.cpp</a></li>
<li><a href="#trunkSourceWebCoreModuleswebgpuWebGPUTextureh">trunk/Source/WebCore/Modules/webgpu/WebGPUTexture.h</a></li>
<li><a href="#trunkSourceWebCoreSourcestxt">trunk/Source/WebCore/Sources.txt</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsgpuGPUBufferh">trunk/Source/WebCore/platform/graphics/gpu/GPUBuffer.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsgpuGPUBufferUsageh">trunk/Source/WebCore/platform/graphics/gpu/GPUBufferUsage.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsgpuGPUCommandBufferh">trunk/Source/WebCore/platform/graphics/gpu/GPUCommandBuffer.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsgpuGPURenderPassDescriptorh">trunk/Source/WebCore/platform/graphics/gpu/GPURenderPassDescriptor.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsgpuGPUTextureh">trunk/Source/WebCore/platform/graphics/gpu/GPUTexture.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsgpuGPUTextureUsageh">trunk/Source/WebCore/platform/graphics/gpu/GPUTextureUsage.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsgpucocoaGPUBufferMetalmm">trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUBufferMetal.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsgpucocoaGPUCommandBufferMetalmm">trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUCommandBufferMetal.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsgpucocoaGPUQueueMetalmm">trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUQueueMetal.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsgpucocoaGPUSwapChainMetalmm">trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUSwapChainMetal.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsgpucocoaGPUTextureMetalmm">trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUTextureMetal.mm</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestswebgpublitcommandsexpectedhtml">trunk/LayoutTests/webgpu/blit-commands-expected.html</a></li>
<li><a href="#trunkLayoutTestswebgpublitcommandshtml">trunk/LayoutTests/webgpu/blit-commands.html</a></li>
<li>trunk/LayoutTests/webgpu/resources/</li>
<li><a href="#trunkLayoutTestswebgpuresourcesgreen400png">trunk/LayoutTests/webgpu/resources/green-400.png</a></li>
<li><a href="#trunkSourceWebCoreModuleswebgpuGPUOrigin3Dh">trunk/Source/WebCore/Modules/webgpu/GPUOrigin3D.h</a></li>
<li><a href="#trunkSourceWebCoreModuleswebgpuGPUOrigin3Didl">trunk/Source/WebCore/Modules/webgpu/GPUOrigin3D.idl</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (242403 => 242404)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog      2019-03-05 00:43:41 UTC (rev 242403)
+++ trunk/LayoutTests/ChangeLog 2019-03-05 00:55:15 UTC (rev 242404)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2019-03-04  Justin Fan  <justin_fan@apple.com>
+
+        [Web GPU] Blitting function prototypes
+        https://bugs.webkit.org/show_bug.cgi?id=195224
+        <rdar://problem/48538902>
+
+        Reviewed by Dean Jackson.
+
+        Add basic test to copy data with all new blitting functions and verify the result.
+
+        * webgpu/blit-commands-expected.html: Added.
+        * webgpu/blit-commands.html: Added.
+        * webgpu/buffer-command-buffer-races.html: Fixed typo.
+        * webgpu/resources/green-400.png: Added.
+
</ins><span class="cx"> 2019-03-04  Zalan Bujtas  <zalan@apple.com>
</span><span class="cx"> 
</span><span class="cx">         [ContentChangeObserver] Introduce fixed duration content observation
</span></span></pre></div>
<a id="trunkLayoutTestswebgpublitcommandsexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/webgpu/blit-commands-expected.html (0 => 242404)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webgpu/blit-commands-expected.html                             (rev 0)
+++ trunk/LayoutTests/webgpu/blit-commands-expected.html        2019-03-05 00:55:15 UTC (rev 242404)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Reference File</title>
+<p>Pass if square canvas below is completely green.</p>
+<canvas width="400" height="400"></canvas>
+<script>
+const canvas = document.querySelector("canvas");
+const context = canvas.getContext('2d');
+
+context.fillStyle = 'rgb(0, 255, 0)';
+context.fillRect(0, 0, canvas.width, canvas.height);
+</script>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkLayoutTestswebgpublitcommandshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/webgpu/blit-commands.html (0 => 242404)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webgpu/blit-commands.html                              (rev 0)
+++ trunk/LayoutTests/webgpu/blit-commands.html 2019-03-05 00:55:15 UTC (rev 242404)
</span><span class="lines">@@ -0,0 +1,112 @@
</span><ins>+<!DOCTYPE html><!-- webkit-test-runner [ experimental:WebGPUEnabled=true ] -->
+<meta charset="utf-8">
+<title>Basic Blitting</title>
+<meta name="assert" content="Blit operations copy a green canvas.">
+<link rel="match" href="blit-commands-expected.html">
+<p>Pass if square canvas below is completely green.</p>
+<canvas width="400" height="400"></canvas>
+<body>
+<script src="js/webgpu-functions.js"></script>
+<script>
+if (window.testRunner)
+    testRunner.waitUntilDone();
+
+async function loadImage() {
+    const image = new Image();
+    image.src = "resources/green-400.png";
+    image.onload = () => { test(image); }
+}
+
+async function test(image) {
+    const device = await getBasicDevice();
+
+    const canvas2d = document.createElement('canvas');
+    canvas2d.width = image.width;
+    canvas2d.height = image.height;
+    const context2d = canvas2d.getContext('2d');
+    context2d.drawImage(image, 0, 0);
+
+    const imageData = context2d.getImageData(0, 0, image.width, image.height);
+
+    const bufferDescriptor = {
+        size: imageData.data.byteLength,
+        usage: GPUBufferUsage.TRANSFER_SRC | GPUBufferUsage.TRANSFER_DST
+    };
+    const bufferA = device.createBuffer(bufferDescriptor);
+    bufferA.setSubData(0, imageData.data.buffer);
+
+    const bufferB = device.createBuffer(bufferDescriptor);
+    const bufferViewB = {
+        buffer: bufferB,
+        offset: 0,
+        rowPitch: 0,
+        imageHeight: 0
+    };
+
+    const textureSize = {
+        width: image.width,
+        height: image.height,
+        depth: 1
+    };
+    const textureDescriptor = {
+        size: textureSize,
+        arrayLayerCount: 1,
+        mipLevelCount: 1,
+        sampleCount: 1,
+        dimension: "2d",
+        format: "r8g8b8a8-unorm",
+        usage: GPUTextureUsage.TRANSFER_SRC | GPUTextureUsage.TRANSFER_DST
+    };
+    const textureA = device.createTexture(textureDescriptor);
+    const textureViewA = {
+        texture: textureA,
+        mipLevel: 0,
+        arrayLayer: 0,
+        origin: { x: 0, y: 0, z: 0 }
+    };
+
+    const textureB = device.createTexture(textureDescriptor);
+    const textureViewB = {
+        texture: textureB,
+        mipLevel: 0,
+        arrayLayer: 0,
+        origin: { x: 0, y: 0, z: 0 }
+    };
+
+    const readBufferDescriptor = {
+        size: imageData.data.byteLength,
+        usage: GPUBufferUsage.TRANSFER_DST | GPUBufferUsage.MAP_READ
+    };
+    const readBuffer = device.createBuffer(readBufferDescriptor);
+    const readBufferView = {
+        buffer: readBuffer,
+        offset: 0,
+        rowPitch: 0,
+        imageHeight: 0
+    };
+
+    const commandBuffer = device.createCommandBuffer();
+    commandBuffer.copyBufferToBuffer(bufferA, 0, bufferB, 0, imageData.data.byteLength);
+    commandBuffer.copyBufferToTexture(bufferViewB, textureViewA, textureSize);
+    commandBuffer.copyTextureToTexture(textureViewA, textureViewB, textureSize);
+    commandBuffer.copyTextureToBuffer(textureViewB, readBufferView, textureSize);
+    device.getQueue().submit([commandBuffer]);
+
+    const resultContext = document.querySelector('canvas').getContext('2d');
+
+    await readBuffer.mapReadAsync().then(ab => {
+        const array = new Uint8ClampedArray(ab);
+        const resultImageData = new ImageData(array, image.width, image.height);
+
+        resultContext.putImageData(resultImageData, 0, 0);
+
+        readBuffer.unmap();
+    });
+
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+loadImage();
+</script>
+</body>
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkLayoutTestswebgpubuffercommandbufferraceshtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/webgpu/buffer-command-buffer-races.html (242403 => 242404)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webgpu/buffer-command-buffer-races.html        2019-03-05 00:43:41 UTC (rev 242403)
+++ trunk/LayoutTests/webgpu/buffer-command-buffer-races.html   2019-03-05 00:55:15 UTC (rev 242404)
</span><span class="lines">@@ -2,7 +2,7 @@
</span><span class="cx"> <meta charset="utf-8">
</span><span class="cx"> <title>WebGPU Hello Triangles</title>
</span><span class="cx"> <meta name="assert" content="WebGPU correctly renders a green canvas.">
</span><del>-<link rel="match" href="vertex-buffer-triangle-strip-expected.html">
</del><ins>+<link rel="match" href="buffer-command-buffer-races-expected.html">
</ins><span class="cx"> <p>Pass if square canvas below is completely green.</p>
</span><span class="cx"> <canvas width="400" height="400"></canvas>
</span><span class="cx"> <script src="js/webgpu-functions.js"></script>
</span></span></pre></div>
<a id="trunkLayoutTestswebgpuresourcesgreen400png"></a>
<div class="binary"><h4>Added: trunk/LayoutTests/webgpu/resources/green-400.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Index: trunk/LayoutTests/webgpu/resources/green-400.png
</span><span class="cx">===================================================================
</span><del>--- trunk/LayoutTests/webgpu/resources/green-400.png    2019-03-05 00:43:41 UTC (rev 242403)
</del><ins>+++ trunk/LayoutTests/webgpu/resources/green-400.png     2019-03-05 00:55:15 UTC (rev 242404)
</ins><span class="cx">Property changes on: trunk/LayoutTests/webgpu/resources/green-400.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<ins>+image/png
</ins><span class="cx">\ No newline at end of property
</span><a id="trunkSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/CMakeLists.txt (242403 => 242404)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/CMakeLists.txt      2019-03-05 00:43:41 UTC (rev 242403)
+++ trunk/Source/WebCore/CMakeLists.txt 2019-03-05 00:55:15 UTC (rev 242404)
</span><span class="lines">@@ -469,6 +469,7 @@
</span><span class="cx">     Modules/webgpu/GPUDepthStencilStateDescriptor.idl
</span><span class="cx">     Modules/webgpu/GPUExtent3D.idl
</span><span class="cx">     Modules/webgpu/GPULoadOp.idl
</span><ins>+    Modules/webgpu/GPUOrigin3D.idl
</ins><span class="cx">     Modules/webgpu/GPURequestAdapterOptions.idl
</span><span class="cx">     Modules/webgpu/GPUStoreOp.idl
</span><span class="cx">     Modules/webgpu/GPUTextureDescriptor.idl
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (242403 => 242404)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2019-03-05 00:43:41 UTC (rev 242403)
+++ trunk/Source/WebCore/ChangeLog      2019-03-05 00:55:15 UTC (rev 242404)
</span><span class="lines">@@ -1,3 +1,77 @@
</span><ins>+2019-03-04  Justin Fan  <justin_fan@apple.com>
+
+        [Web GPU] Blitting function prototypes
+        https://bugs.webkit.org/show_bug.cgi?id=195224
+        <rdar://problem/48538902>
+
+        Reviewed by Dean Jackson.
+
+        Implement barebones GPUCommandBuffer::copy* prototypes while rounding out GPUTexture implementation details.
+
+        Test: webgpu/blit-commands.html
+
+        * Modules/webgpu/GPUOrigin3D.h: Added.
+        * Modules/webgpu/GPUOrigin3D.idl: Added.
+        * Modules/webgpu/WebGPUCommandBuffer.cpp: Add copy view struct implementations.
+        (WebCore::WebGPUBufferCopyView::asGPUBufferCopyView const): Added.
+        (WebCore::WebGPUTextureCopyView::asGPUTextureCopyView const): Added.
+        (WebCore::WebGPUCommandBuffer::copyBufferToBuffer): Added.
+        (WebCore::WebGPUCommandBuffer::copyBufferToTexture): Added.
+        (WebCore::WebGPUCommandBuffer::copyTextureToBuffer): Added.
+        (WebCore::WebGPUCommandBuffer::copyTextureToTexture): Added.
+        * Modules/webgpu/WebGPUCommandBuffer.h: Add new functions and supporting structs.
+        * Modules/webgpu/WebGPUCommandBuffer.idl: Ditto.
+        * Modules/webgpu/WebGPURenderPassDescriptor.cpp: Refactor constructors to copy the entire base class.
+        (WebCore::GPURenderPassColorAttachmentDescriptor::GPURenderPassColorAttachmentDescriptor):
+        (WebCore::GPURenderPassDepthStencilAttachmentDescriptor::GPURenderPassDepthStencilAttachmentDescriptor):
+        (WebCore::WebGPURenderPassDescriptor::asGPURenderPassDescriptor const):
+        (WebCore::attachment): Deleted.
+        * Modules/webgpu/WebGPUTexture.h:
+        (WebCore::WebGPUTexture::texture const): Added.
+        * platform/graphics/gpu/GPUBuffer.h:
+        (WebCore::GPUBuffer::byteLength const): Added.
+        (WebCore::GPUBuffer::isTransferSource const): Added.
+        (WebCore::GPUBuffer::isTransferDestination const): Renamed from isTransferDst. Refactored for OptionSet API.
+        (WebCore::GPUBuffer::isVertex const): Ditto.
+        (WebCore::GPUBuffer::isUniform const): Ditto.
+        (WebCore::GPUBuffer::isStorage const): Ditto.
+        (WebCore::GPUBuffer::isMappable const): Ditto.
+        (WebCore::GPUBuffer::isMapWrite const): Ditto.
+        (WebCore::GPUBuffer::isMapRead const): Ditto.
+        * platform/graphics/gpu/GPUBufferUsage.h: Refactored for better bit flag style.
+        * platform/graphics/gpu/GPUCommandBuffer.h:
+        (WebCore::GPUCommandBuffer::blitEncoder const): Added.
+        * platform/graphics/gpu/GPURenderPassDescriptor.h: 
+        * platform/graphics/gpu/GPUTexture.h: Cache usage flags for reference.
+        (WebCore::GPUTexture::isTransferSrc const): Added.
+        (WebCore::GPUTexture::isTransferDst const): Added.
+        (WebCore::GPUTexture::isOutputAttachment const): Added.
+        * platform/graphics/gpu/GPUTextureUsage.h: Refactor to match GPUBufferUsage.h.
+        * platform/graphics/gpu/cocoa/GPUBufferMetal.mm:
+        (WebCore::GPUBuffer::validateBufferUsage): Renamed from validateBufferCreate, refactored for OptionSet.
+        (WebCore::GPUBuffer::tryCreate):
+        (WebCore::GPUBuffer::GPUBuffer):
+        (WebCore::GPUBuffer::isReadOnly const):
+        (WebCore::GPUBuffer::setSubData): Add alignment check according to Metal docs.
+        * platform/graphics/gpu/cocoa/GPUCommandBufferMetal.mm: 
+        (WebCore::GPUCommandBuffer::create): No need to use this alias here.
+        (WebCore::GPUCommandBuffer::GPUCommandBuffer): Ditto.
+        (WebCore::GPUCommandBuffer::copyBufferToBuffer): Added.
+        (WebCore::GPUCommandBuffer::copyBufferToTexture): Added.
+        (WebCore::GPUCommandBuffer::copyTextureToBuffer): Added. 
+        (WebCore::GPUCommandBuffer::copyTextureToTexture): Added. 
+        * platform/graphics/gpu/cocoa/GPUQueueMetal.mm:
+        (WebCore::GPUQueue::submit): End encoding on the MTLCommandBuffer's blitCommandEncoder if it was used.
+        * platform/graphics/gpu/cocoa/GPUSwapChainMetal.mm:
+        (WebCore::GPUSwapChain::getNextTexture): Now provide usage flags to texture creation.
+        * platform/graphics/gpu/cocoa/GPUTextureMetal.mm:
+        (WebCore::mtlTextureUsageForGPUTextureUsageFlags): Refactor validation.
+        (WebCore::tryCreateMtlTextureDescriptor): Ditto.
+        (WebCore::GPUTexture::tryCreate): Now provide usage flags to texture creation.
+        (WebCore::GPUTexture::create): Ditto.
+        (WebCore::GPUTexture::GPUTexture): Ditto.
+        (WebCore::GPUTexture::createDefaultTextureView): Ditto.
+
</ins><span class="cx"> 2019-03-04  Zalan Bujtas  <zalan@apple.com>
</span><span class="cx"> 
</span><span class="cx">         [ContentChangeObserver] Introduce fixed duration content observation
</span></span></pre></div>
<a id="trunkSourceWebCoreDerivedSourcesinputxcfilelist"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/DerivedSources-input.xcfilelist (242403 => 242404)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/DerivedSources-input.xcfilelist     2019-03-05 00:43:41 UTC (rev 242403)
+++ trunk/Source/WebCore/DerivedSources-input.xcfilelist        2019-03-05 00:55:15 UTC (rev 242404)
</span><span class="lines">@@ -321,13 +321,14 @@
</span><span class="cx"> $(PROJECT_DIR)/Modules/webdatabase/SQLTransactionErrorCallback.idl
</span><span class="cx"> $(PROJECT_DIR)/Modules/webdriver/NavigatorWebDriver.idl
</span><span class="cx"> $(PROJECT_DIR)/Modules/webgpu/DOMWindowWebGPU.idl
</span><del>-$(PROJECT_DIR)/Modules/webgpu/GPUColor.idl
</del><span class="cx"> $(PROJECT_DIR)/Modules/webgpu/GPUBufferDescriptor.idl
</span><span class="cx"> $(PROJECT_DIR)/Modules/webgpu/GPUBufferUsage.idl
</span><ins>+$(PROJECT_DIR)/Modules/webgpu/GPUColor.idl
</ins><span class="cx"> $(PROJECT_DIR)/Modules/webgpu/GPUCompareFunction.idl
</span><span class="cx"> $(PROJECT_DIR)/Modules/webgpu/GPUDepthStencilStateDescriptor.idl
</span><span class="cx"> $(PROJECT_DIR)/Modules/webgpu/GPUExtent3D.idl
</span><span class="cx"> $(PROJECT_DIR)/Modules/webgpu/GPULoadOp.idl
</span><ins>+$(PROJECT_DIR)/Modules/webgpu/GPUOrigin3D.idl
</ins><span class="cx"> $(PROJECT_DIR)/Modules/webgpu/GPURequestAdapterOptions.idl
</span><span class="cx"> $(PROJECT_DIR)/Modules/webgpu/GPUStoreOp.idl
</span><span class="cx"> $(PROJECT_DIR)/Modules/webgpu/GPUTextureDescriptor.idl
</span></span></pre></div>
<a id="trunkSourceWebCoreDerivedSourcesoutputxcfilelist"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/DerivedSources-output.xcfilelist (242403 => 242404)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/DerivedSources-output.xcfilelist    2019-03-05 00:43:41 UTC (rev 242403)
+++ trunk/Source/WebCore/DerivedSources-output.xcfilelist       2019-03-05 00:55:15 UTC (rev 242404)
</span><span class="lines">@@ -577,12 +577,12 @@
</span><span class="cx"> $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSFontFaceSet.h
</span><span class="cx"> $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGCObservation.cpp
</span><span class="cx"> $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGCObservation.h
</span><del>-$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPUColor.cpp
-$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPUColor.h
</del><span class="cx"> $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPUBufferDescriptor.cpp
</span><span class="cx"> $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPUBufferDescriptor.h
</span><span class="cx"> $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPUBufferUsage.cpp
</span><span class="cx"> $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPUBufferUsage.h
</span><ins>+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPUColor.cpp
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPUColor.h
</ins><span class="cx"> $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPUCompareFunction.cpp
</span><span class="cx"> $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPUCompareFunction.h
</span><span class="cx"> $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPUDepthStencilStateDescriptor.cpp
</span><span class="lines">@@ -591,6 +591,8 @@
</span><span class="cx"> $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPUExtent3D.h
</span><span class="cx"> $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPULoadOp.cpp
</span><span class="cx"> $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPULoadOp.h
</span><ins>+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPUOrigin3D.cpp
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPUOrigin3D.h
</ins><span class="cx"> $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPURequestAdapterOptions.cpp
</span><span class="cx"> $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPURequestAdapterOptions.h
</span><span class="cx"> $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/JSGPUStoreOp.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreDerivedSourcesmake"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/DerivedSources.make (242403 => 242404)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/DerivedSources.make 2019-03-05 00:43:41 UTC (rev 242403)
+++ trunk/Source/WebCore/DerivedSources.make    2019-03-05 00:55:15 UTC (rev 242404)
</span><span class="lines">@@ -379,6 +379,7 @@
</span><span class="cx">     $(WebCore)/Modules/webgpu/GPUDepthStencilStateDescriptor.idl \
</span><span class="cx">     $(WebCore)/Modules/webgpu/GPUExtent3D.idl \
</span><span class="cx">     $(WebCore)/Modules/webgpu/GPULoadOp.idl \
</span><ins>+    $(WebCore)/Modules/webgpu/GPUOrigin3D.idl \
</ins><span class="cx">     $(WebCore)/Modules/webgpu/GPURequestAdapterOptions.idl \
</span><span class="cx">     $(WebCore)/Modules/webgpu/GPUStoreOp.idl \
</span><span class="cx">     $(WebCore)/Modules/webgpu/GPUTextureDescriptor.idl \
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebgpuGPUOrigin3Dhfromrev242403trunkSourceWebCoreplatformgraphicsgpuGPUBufferUsageh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/Modules/webgpu/GPUOrigin3D.h (from rev 242403, trunk/Source/WebCore/platform/graphics/gpu/GPUBufferUsage.h) (0 => 242404)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webgpu/GPUOrigin3D.h                                (rev 0)
+++ trunk/Source/WebCore/Modules/webgpu/GPUOrigin3D.h   2019-03-05 00:55:15 UTC (rev 242404)
</span><span class="lines">@@ -0,0 +1,40 @@
</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.
+ */
+
+#pragma once
+
+#if ENABLE(WEBGPU)
+
+namespace WebCore {
+
+struct GPUOrigin3D {
+    unsigned x;
+    unsigned y;
+    unsigned z;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGPU)
</ins></span></pre></div>
<a id="trunkSourceWebCoreModuleswebgpuGPUOrigin3Didlfromrev242403trunkSourceWebCoreplatformgraphicsgpuGPUBufferUsageh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/Modules/webgpu/GPUOrigin3D.idl (from rev 242403, trunk/Source/WebCore/platform/graphics/gpu/GPUBufferUsage.h) (0 => 242404)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webgpu/GPUOrigin3D.idl                              (rev 0)
+++ trunk/Source/WebCore/Modules/webgpu/GPUOrigin3D.idl 2019-03-05 00:55:15 UTC (rev 242404)
</span><span class="lines">@@ -0,0 +1,36 @@
</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.
+ */
+// https://github.com/gpuweb/gpuweb/blob/master/design/sketch.webidl
+
+typedef unsigned long u32;
+
+[
+    Conditional=WEBGPU,
+    EnabledAtRuntime=WebGPU
+] dictionary GPUOrigin3D {
+    u32 x;
+    u32 y;
+    u32 z;
+};
</ins></span></pre></div>
<a id="trunkSourceWebCoreModuleswebgpuWebGPUCommandBuffercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webgpu/WebGPUCommandBuffer.cpp (242403 => 242404)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webgpu/WebGPUCommandBuffer.cpp      2019-03-05 00:43:41 UTC (rev 242403)
+++ trunk/Source/WebCore/Modules/webgpu/WebGPUCommandBuffer.cpp 2019-03-05 00:55:15 UTC (rev 242404)
</span><span class="lines">@@ -30,11 +30,37 @@
</span><span class="cx"> 
</span><span class="cx"> #include "GPURenderPassDescriptor.h"
</span><span class="cx"> #include "GPURenderPassEncoder.h"
</span><ins>+#include "WebGPUBuffer.h"
</ins><span class="cx"> #include "WebGPURenderPassDescriptor.h"
</span><span class="cx"> #include "WebGPURenderPassEncoder.h"
</span><ins>+#include "WebGPUTexture.h"
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><ins>+Optional<GPUBufferCopyView> WebGPUBufferCopyView::asGPUBufferCopyView() const
+{
+    if (!buffer || !buffer->buffer()) {
+        LOG(WebGPU, "GPUCommandEncoder: Invalid buffer for copy!");
+        return WTF::nullopt;
+    }
+
+    // FIXME: Add Web GPU validation.
+
+    return GPUBufferCopyView { buffer->buffer().releaseNonNull(), *this };
+}
+
+Optional<GPUTextureCopyView> WebGPUTextureCopyView::asGPUTextureCopyView() const
+{
+    if (!texture || !texture->texture()) {
+        LOG(WebGPU, "GPUCommandEncoder: Invalid texture for copy!");
+        return WTF::nullopt;
+    }
+
+    // FIXME: Add Web GPU validation.
+
+    return GPUTextureCopyView { texture->texture().releaseNonNull(), *this };
+}
+
</ins><span class="cx"> Ref<WebGPUCommandBuffer> WebGPUCommandBuffer::create(Ref<GPUCommandBuffer>&& buffer)
</span><span class="cx"> {
</span><span class="cx">     return adoptRef(*new WebGPUCommandBuffer(WTFMove(buffer)));
</span><span class="lines">@@ -56,6 +82,57 @@
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebGPUCommandBuffer::copyBufferToBuffer(const WebGPUBuffer& src, unsigned long srcOffset, const WebGPUBuffer& dst, unsigned long dstOffset, unsigned long size)
+{
+    if (!src.buffer() || !dst.buffer()) {
+        LOG(WebGPU, "GPUCommandBuffer::copyBufferToBuffer(): Invalid GPUBuffer!");
+        return;
+    }
+
+    // FIXME: Add Web GPU validation.
+
+    m_commandBuffer->copyBufferToBuffer(src.buffer().releaseNonNull(), srcOffset, dst.buffer().releaseNonNull(), dstOffset, size);
+}
+
+void WebGPUCommandBuffer::copyBufferToTexture(const WebGPUBufferCopyView& srcBuffer, const WebGPUTextureCopyView& dstTexture, const GPUExtent3D& size)
+{
+    auto gpuBufferView = srcBuffer.asGPUBufferCopyView();
+    auto gpuTextureView = dstTexture.asGPUTextureCopyView();
+
+    if (!gpuBufferView || !gpuTextureView)
+        return;
+
+    // FIXME: Add Web GPU validation.
+
+    m_commandBuffer->copyBufferToTexture(*gpuBufferView, *gpuTextureView, size);
+}
+
+void WebGPUCommandBuffer::copyTextureToBuffer(const WebGPUTextureCopyView& srcTexture, const WebGPUBufferCopyView& dstBuffer, const GPUExtent3D& size)
+{
+    auto gpuTextureView = srcTexture.asGPUTextureCopyView();
+    auto gpuBufferView = dstBuffer.asGPUBufferCopyView();
+
+    if (!gpuTextureView || !gpuBufferView)
+        return;
+
+    // FIXME: Add Web GPU validation.
+
+    m_commandBuffer->copyTextureToBuffer(*gpuTextureView, *gpuBufferView, size);
+}
+
+void WebGPUCommandBuffer::copyTextureToTexture(const WebGPUTextureCopyView& src, const WebGPUTextureCopyView& dst, const GPUExtent3D& size)
+{
+    auto gpuSrcView = src.asGPUTextureCopyView();
+    auto gpuDstView = dst.asGPUTextureCopyView();
+
+    if (!gpuSrcView || !gpuDstView)
+        return;
+
+    // FIXME: Add Web GPU validation.
+
+    m_commandBuffer->copyTextureToTexture(*gpuSrcView, *gpuDstView, size);
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(WEBGPU)
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebgpuWebGPUCommandBufferh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webgpu/WebGPUCommandBuffer.h (242403 => 242404)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webgpu/WebGPUCommandBuffer.h        2019-03-05 00:43:41 UTC (rev 242403)
+++ trunk/Source/WebCore/Modules/webgpu/WebGPUCommandBuffer.h   2019-03-05 00:55:15 UTC (rev 242404)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include "GPUCommandBuffer.h"
</span><span class="cx"> 
</span><ins>+#include <wtf/Optional.h>
</ins><span class="cx"> #include <wtf/Ref.h>
</span><span class="cx"> #include <wtf/RefCounted.h>
</span><span class="cx"> #include <wtf/RefPtr.h>
</span><span class="lines">@@ -35,10 +36,25 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><ins>+class WebGPUBuffer;
</ins><span class="cx"> class WebGPURenderPassEncoder;
</span><ins>+class WebGPUTexture;
</ins><span class="cx"> 
</span><ins>+struct GPUExtent3D;
</ins><span class="cx"> struct WebGPURenderPassDescriptor;
</span><span class="cx"> 
</span><ins>+struct WebGPUBufferCopyView : GPUBufferCopyViewBase {
+    Optional<GPUBufferCopyView> asGPUBufferCopyView() const;
+
+    RefPtr<WebGPUBuffer> buffer;
+};
+
+struct WebGPUTextureCopyView : GPUTextureCopyViewBase {
+    Optional<GPUTextureCopyView> asGPUTextureCopyView() const;
+
+    RefPtr<WebGPUTexture> texture;
+};
+
</ins><span class="cx"> class WebGPUCommandBuffer : public RefCounted<WebGPUCommandBuffer> {
</span><span class="cx"> public:
</span><span class="cx">     static Ref<WebGPUCommandBuffer> create(Ref<GPUCommandBuffer>&&);
</span><span class="lines">@@ -46,6 +62,10 @@
</span><span class="cx">     const GPUCommandBuffer& commandBuffer() const { return m_commandBuffer.get(); }
</span><span class="cx"> 
</span><span class="cx">     RefPtr<WebGPURenderPassEncoder> beginRenderPass(WebGPURenderPassDescriptor&&);
</span><ins>+    void copyBufferToBuffer(const WebGPUBuffer&, unsigned long srcOffset, const WebGPUBuffer&, unsigned long dstOffset, unsigned long size);
+    void copyBufferToTexture(const WebGPUBufferCopyView&, const WebGPUTextureCopyView&, const GPUExtent3D&);
+    void copyTextureToBuffer(const WebGPUTextureCopyView&, const WebGPUBufferCopyView&, const GPUExtent3D&);
+    void copyTextureToTexture(const WebGPUTextureCopyView&, const WebGPUTextureCopyView&, const GPUExtent3D&);
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     WebGPUCommandBuffer(Ref<GPUCommandBuffer>&&);
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebgpuWebGPUCommandBufferidl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webgpu/WebGPUCommandBuffer.idl (242403 => 242404)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webgpu/WebGPUCommandBuffer.idl      2019-03-05 00:43:41 UTC (rev 242403)
+++ trunk/Source/WebCore/Modules/webgpu/WebGPUCommandBuffer.idl 2019-03-05 00:55:15 UTC (rev 242404)
</span><span class="lines">@@ -24,18 +24,39 @@
</span><span class="cx">  */
</span><span class="cx"> // https://github.com/gpuweb/gpuweb/blob/master/design/sketch.webidl
</span><span class="cx"> 
</span><ins>+typedef unsigned long u32;
+typedef unsigned long long u64;
+
</ins><span class="cx"> [
</span><span class="cx">     Conditional=WEBGPU,
</span><span class="cx">     EnabledAtRuntime=WebGPU,
</span><ins>+    ImplementedAs=WebGPUBufferCopyView
+] dictionary GPUBufferCopyView {
+    WebGPUBuffer buffer;
+    u64 offset;
+    u64 rowPitch;
+    u32 imageHeight;
+};
+
+[
+    Conditional=WEBGPU,
+    EnabledAtRuntime=WebGPU,
+    ImplementedAs=WebGPUTextureCopyView
+] dictionary GPUTextureCopyView {
+    WebGPUTexture texture;
+    u32 mipLevel;
+    u32 arrayLayer;
+    GPUOrigin3D origin;
+};
+
+[
+    Conditional=WEBGPU,
+    EnabledAtRuntime=WebGPU,
</ins><span class="cx">     ImplementationLacksVTable
</span><span class="cx"> ] interface WebGPUCommandBuffer {
</span><span class="cx">     WebGPURenderPassEncoder beginRenderPass(WebGPURenderPassDescriptor descriptor);
</span><span class="cx"> 
</span><del>-/* Not Yet Implemented
-    WebGPUComputePassEncoder beginComputePass();
-
-    // Commands allowed outside of "passes"
-        void copyBufferToBuffer(
</del><ins>+    void copyBufferToBuffer(
</ins><span class="cx">         WebGPUBuffer src,
</span><span class="cx">         u64 srcOffset,
</span><span class="cx">         WebGPUBuffer dst,
</span><span class="lines">@@ -43,21 +64,20 @@
</span><span class="cx">         u64 size);
</span><span class="cx"> 
</span><span class="cx">     void copyBufferToTexture(
</span><del>-        WebGPUBufferCopyView source,
-        WebGPUTextureCopyView destination,
-        WebGPUExtent3D copySize);
</del><ins>+        GPUBufferCopyView source,
+        GPUTextureCopyView destination,
+        GPUExtent3D copySize);
</ins><span class="cx"> 
</span><span class="cx">     void copyTextureToBuffer(
</span><del>-        WebGPUTextureCopyView source,
-        WebGPUBufferCopyView destination,
-        WebGPUExtent3D copySize);
</del><ins>+        GPUTextureCopyView source,
+        GPUBufferCopyView destination,
+        GPUExtent3D copySize);
</ins><span class="cx"> 
</span><span class="cx">     void copyTextureToTexture(
</span><del>-        WebGPUTextureCopyView source,
-        WebGPUTextureCopyView destination,
-        WebGPUExtent3D copySize);
</del><ins>+        GPUTextureCopyView source,
+        GPUTextureCopyView destination,
+        GPUExtent3D copySize);
</ins><span class="cx"> 
</span><del>-    // TODO figure which other commands are needed
-    void blit();
-*/
</del><ins>+    // Not Yet Implemented
+    // WebGPUComputePassEncoder beginComputePass();
</ins><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebgpuWebGPURenderPassDescriptorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webgpu/WebGPURenderPassDescriptor.cpp (242403 => 242404)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webgpu/WebGPURenderPassDescriptor.cpp       2019-03-05 00:43:41 UTC (rev 242403)
+++ trunk/Source/WebCore/Modules/webgpu/WebGPURenderPassDescriptor.cpp  2019-03-05 00:55:15 UTC (rev 242404)
</span><span class="lines">@@ -33,14 +33,14 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-GPURenderPassColorAttachmentDescriptor::GPURenderPassColorAttachmentDescriptor(Ref<GPUTexture>&& texture, GPULoadOp load, GPUStoreOp store, GPUColor color)
-    : GPURenderPassColorAttachmentDescriptorBase { load, store, color }
</del><ins>+GPURenderPassColorAttachmentDescriptor::GPURenderPassColorAttachmentDescriptor(Ref<GPUTexture>&& texture, const GPURenderPassColorAttachmentDescriptorBase& base)
+    : GPURenderPassColorAttachmentDescriptorBase(base)
</ins><span class="cx">     , attachment(WTFMove(texture))
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-GPURenderPassDepthStencilAttachmentDescriptor::GPURenderPassDepthStencilAttachmentDescriptor(Ref<GPUTexture>&& texture, GPULoadOp load, GPUStoreOp store, float depth)
-    : GPURenderPassDepthStencilAttachmentDescriptorBase { load, store, depth }
</del><ins>+GPURenderPassDepthStencilAttachmentDescriptor::GPURenderPassDepthStencilAttachmentDescriptor(Ref<GPUTexture>&& texture, const GPURenderPassDepthStencilAttachmentDescriptorBase& base)
+    : GPURenderPassDepthStencilAttachmentDescriptorBase(base)
</ins><span class="cx">     , attachment(WTFMove(texture))
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="lines">@@ -56,21 +56,21 @@
</span><span class="cx">     Vector<GPURenderPassColorAttachmentDescriptor> gpuColorAttachments;
</span><span class="cx"> 
</span><span class="cx">     for (const auto& colorAttachment : colorAttachments) {
</span><del>-        if (!colorAttachment.attachment) {
</del><ins>+        if (!colorAttachment.attachment || !colorAttachment.attachment->texture()->isOutputAttachment()) {
</ins><span class="cx">             LOG(WebGPU, "GPURenderPassDescriptor: Invalid attachment in GPURenderPassColorAttachmentDescriptor!");
</span><span class="cx">             return WTF::nullopt;
</span><span class="cx">         }
</span><del>-        gpuColorAttachments.append(GPURenderPassColorAttachmentDescriptor(colorAttachment.attachment->texture(), colorAttachment.loadOp, colorAttachment.storeOp, colorAttachment.clearColor));
</del><ins>+        gpuColorAttachments.append(GPURenderPassColorAttachmentDescriptor { colorAttachment.attachment->texture(), colorAttachment });
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     Optional<GPURenderPassDepthStencilAttachmentDescriptor> gpuDepthAttachment;
</span><span class="cx"> 
</span><span class="cx">     if (depthStencilAttachment) {
</span><del>-        if (!depthStencilAttachment->attachment) {
</del><ins>+        if (!depthStencilAttachment->attachment || !depthStencilAttachment->attachment->texture()->isOutputAttachment()) {
</ins><span class="cx">             LOG(WebGPU, "GPURenderPassDescriptor: Invalid attachment in GPURenderPassDepthStencilAttachmentDescriptor!");
</span><span class="cx">             return WTF::nullopt;
</span><span class="cx">         }
</span><del>-        gpuDepthAttachment = GPURenderPassDepthStencilAttachmentDescriptor(depthStencilAttachment->attachment->texture(), depthStencilAttachment->depthLoadOp, depthStencilAttachment->depthStoreOp, depthStencilAttachment->clearDepth);
</del><ins>+        gpuDepthAttachment = GPURenderPassDepthStencilAttachmentDescriptor { depthStencilAttachment->attachment->texture(), *depthStencilAttachment };
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return GPURenderPassDescriptor { WTFMove(gpuColorAttachments), WTFMove(gpuDepthAttachment) };
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebgpuWebGPUTextureh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webgpu/WebGPUTexture.h (242403 => 242404)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webgpu/WebGPUTexture.h      2019-03-05 00:43:41 UTC (rev 242403)
+++ trunk/Source/WebCore/Modules/webgpu/WebGPUTexture.h 2019-03-05 00:55:15 UTC (rev 242404)
</span><span class="lines">@@ -40,6 +40,8 @@
</span><span class="cx"> public:
</span><span class="cx">     static Ref<WebGPUTexture> create(RefPtr<GPUTexture>&&);
</span><span class="cx"> 
</span><ins>+    RefPtr<GPUTexture> texture() const { return m_texture; }
+
</ins><span class="cx">     RefPtr<WebGPUTextureView> createDefaultTextureView();
</span><span class="cx"> 
</span><span class="cx"> private:
</span></span></pre></div>
<a id="trunkSourceWebCoreSourcestxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Sources.txt (242403 => 242404)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Sources.txt 2019-03-05 00:43:41 UTC (rev 242403)
+++ trunk/Source/WebCore/Sources.txt    2019-03-05 00:55:15 UTC (rev 242404)
</span><span class="lines">@@ -2775,6 +2775,7 @@
</span><span class="cx"> JSGPUDepthStencilStateDescriptor.cpp
</span><span class="cx"> JSGPUExtent3D.cpp
</span><span class="cx"> JSGPULoadOp.cpp
</span><ins>+JSGPUOrigin3D.cpp
</ins><span class="cx"> JSGPURequestAdapterOptions.cpp
</span><span class="cx"> JSGPUStoreOp.cpp
</span><span class="cx"> JSGPUTextureDescriptor.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (242403 => 242404)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj   2019-03-05 00:43:41 UTC (rev 242403)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj      2019-03-05 00:55:15 UTC (rev 242404)
</span><span class="lines">@@ -14136,6 +14136,8 @@
</span><span class="cx">          D0CAAE9C216824A7001C91C7 /* WebMetalComputeCommandEncoder.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WebMetalComputeCommandEncoder.cpp; sourceTree = "<group>"; };
</span><span class="cx">          D0CAAE9D216824A7001C91C7 /* WebMetalBuffer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebMetalBuffer.h; sourceTree = "<group>"; };
</span><span class="cx">          D0CAAE9E216824A8001C91C7 /* WebMetalCommandBuffer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WebMetalCommandBuffer.cpp; sourceTree = "<group>"; };
</span><ins>+               D0CCA94922299F97006979B6 /* GPUOrigin3D.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPUOrigin3D.h; sourceTree = "<group>"; };
+               D0CCA94A22299F97006979B6 /* GPUOrigin3D.idl */ = {isa = PBXFileReference; lastKnownFileType = text; path = GPUOrigin3D.idl; sourceTree = "<group>"; };
</ins><span class="cx">           D0D8648721B64CAA003C983C /* GPUBufferDescriptor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GPUBufferDescriptor.h; sourceTree = "<group>"; };
</span><span class="cx">          D0D8648C21B70676003C983C /* WebGPUBuffer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebGPUBuffer.h; sourceTree = "<group>"; };
</span><span class="cx">          D0D8648D21B70676003C983C /* WebGPUBuffer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WebGPUBuffer.cpp; sourceTree = "<group>"; };
</span><span class="lines">@@ -26073,6 +26075,8 @@
</span><span class="cx">                          D03C84A221FFD7230002227F /* GPUDepthStencilStateDescriptor.idl */,
</span><span class="cx">                          D026F480220A2B7000AC5F49 /* GPUExtent3D.idl */,
</span><span class="cx">                          D08AA02D220D0B9C0058C502 /* GPULoadOp.idl */,
</span><ins>+                               D0CCA94922299F97006979B6 /* GPUOrigin3D.h */,
+                               D0CCA94A22299F97006979B6 /* GPUOrigin3D.idl */,
</ins><span class="cx">                           D02C26922181416D00D818E4 /* GPURequestAdapterOptions.idl */,
</span><span class="cx">                          D08AA031220D0CE60058C502 /* GPUStoreOp.idl */,
</span><span class="cx">                          D026F48B220A5B0B00AC5F49 /* GPUTextureDescriptor.idl */,
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgpuGPUBufferh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/gpu/GPUBuffer.h (242403 => 242404)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gpu/GPUBuffer.h   2019-03-05 00:43:41 UTC (rev 242403)
+++ trunk/Source/WebCore/platform/graphics/gpu/GPUBuffer.h      2019-03-05 00:55:15 UTC (rev 242404)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> #include "DeferrableTask.h"
</span><span class="cx"> #include "GPUBufferUsage.h"
</span><span class="cx"> #include <wtf/Function.h>
</span><ins>+#include <wtf/OptionSet.h>
</ins><span class="cx"> #include <wtf/Ref.h>
</span><span class="cx"> #include <wtf/RefCounted.h>
</span><span class="cx"> #include <wtf/RetainPtr.h>
</span><span class="lines">@@ -70,12 +71,14 @@
</span><span class="cx">     static RefPtr<GPUBuffer> tryCreate(Ref<GPUDevice>&&, GPUBufferDescriptor&&);
</span><span class="cx"> 
</span><span class="cx">     PlatformBuffer *platformBuffer() const { return m_platformBuffer.get(); }
</span><del>-    bool isTransferDst() const { return m_usage & GPUBufferUsage::TransferDst; }
-    bool isVertex() const { return m_usage & GPUBufferUsage::Vertex; }
-    bool isUniform() const { return m_usage & GPUBufferUsage::Uniform; }
-    bool isStorage() const { return m_usage & GPUBufferUsage::Storage; }
</del><ins>+    unsigned long byteLength() const { return m_byteLength; }
+    bool isTransferSource() const { return m_usage.contains(GPUBufferUsage::Flags::TransferSource); }
+    bool isTransferDestination() const { return m_usage.contains(GPUBufferUsage::Flags::TransferDestination); }
+    bool isVertex() const { return m_usage.contains(GPUBufferUsage::Flags::Vertex); }
+    bool isUniform() const { return m_usage.contains(GPUBufferUsage::Flags::Uniform); }
+    bool isStorage() const { return m_usage.contains(GPUBufferUsage::Flags::Storage); }
</ins><span class="cx">     bool isReadOnly() const;
</span><del>-    bool isMappable() const { return m_usage & (GPUBufferUsage::MapWrite | GPUBufferUsage::MapRead); }
</del><ins>+    bool isMappable() const { return m_usage.containsAny({ GPUBufferUsage::Flags::MapWrite, GPUBufferUsage::Flags::MapRead }); }
</ins><span class="cx">     State state() const;
</span><span class="cx"> 
</span><span class="cx"> #if USE(METAL)
</span><span class="lines">@@ -104,16 +107,16 @@
</span><span class="cx">         PendingMappingCallback(MappingCallback&&);
</span><span class="cx">     };
</span><span class="cx"> 
</span><del>-    static bool validateBufferCreate(const GPUDevice&, const GPUBufferDescriptor&);
</del><ins>+    static bool validateBufferUsage(const GPUDevice&, OptionSet<GPUBufferUsage::Flags>);
</ins><span class="cx"> 
</span><del>-    GPUBuffer(PlatformBufferSmartPtr&&, const GPUBufferDescriptor&, Ref<GPUDevice>&&);
</del><ins>+    GPUBuffer(PlatformBufferSmartPtr&&, const GPUBufferDescriptor&, OptionSet<GPUBufferUsage::Flags>, Ref<GPUDevice>&&);
</ins><span class="cx"> 
</span><span class="cx">     JSC::ArrayBuffer* stagingBufferForRead();
</span><span class="cx">     JSC::ArrayBuffer* stagingBufferForWrite();
</span><span class="cx">     void runMappingCallback();
</span><span class="cx"> 
</span><del>-    bool isMapWrite() const { return m_usage & GPUBufferUsage::MapWrite; }
-    bool isMapRead() const { return m_usage & GPUBufferUsage::MapRead; }
</del><ins>+    bool isMapWrite() const { return m_usage.contains(GPUBufferUsage::Flags::MapWrite); }
+    bool isMapRead() const { return m_usage.contains(GPUBufferUsage::Flags::MapRead); }
</ins><span class="cx">     bool isMapWriteable() const { return isMapWrite() && state() == State::Unmapped; }
</span><span class="cx">     bool isMapReadable() const { return isMapRead() && state() == State::Unmapped; }
</span><span class="cx"> 
</span><span class="lines">@@ -129,7 +132,7 @@
</span><span class="cx">     DeferrableTask<Timer> m_mappingCallbackTask;
</span><span class="cx"> 
</span><span class="cx">     unsigned long m_byteLength;
</span><del>-    GPUBufferUsage::Flags m_usage;
</del><ins>+    OptionSet<GPUBufferUsage::Flags> m_usage;
</ins><span class="cx">     unsigned m_numScheduledCommandBuffers = 0;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgpuGPUBufferUsageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/gpu/GPUBufferUsage.h (242403 => 242404)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gpu/GPUBufferUsage.h      2019-03-05 00:43:41 UTC (rev 242403)
+++ trunk/Source/WebCore/platform/graphics/gpu/GPUBufferUsage.h 2019-03-05 00:55:15 UTC (rev 242404)
</span><span class="lines">@@ -31,20 +31,20 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-using GPUBufferUsageFlags = unsigned long;
</del><ins>+using GPUBufferUsageFlags = unsigned;
</ins><span class="cx"> 
</span><span class="cx"> class GPUBufferUsage : public RefCounted<GPUBufferUsage> {
</span><span class="cx"> public:
</span><del>-    enum Flags : GPUBufferUsageFlags {
</del><ins>+    enum class Flags : GPUBufferUsageFlags {
</ins><span class="cx">         None = 0,
</span><del>-        MapRead = 1,
-        MapWrite = 2,
-        TransferSrc = 4,
-        TransferDst = 8,
-        Index = 16,
-        Vertex = 32,
-        Uniform = 64,
-        Storage = 128
</del><ins>+        MapRead = 1 << 0,
+        MapWrite = 1 << 1,
+        TransferSource = 1 << 2,
+        TransferDestination = 1 << 3,
+        Index = 1 << 4,
+        Vertex = 1 << 5,
+        Uniform = 1 << 6,
+        Storage = 1 << 7,
</ins><span class="cx">     };
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgpuGPUCommandBufferh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/gpu/GPUCommandBuffer.h (242403 => 242404)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gpu/GPUCommandBuffer.h    2019-03-05 00:43:41 UTC (rev 242403)
+++ trunk/Source/WebCore/platform/graphics/gpu/GPUCommandBuffer.h       2019-03-05 00:55:15 UTC (rev 242404)
</span><span class="lines">@@ -27,11 +27,13 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(WEBGPU)
</span><span class="cx"> 
</span><ins>+#include "GPUOrigin3D.h"
</ins><span class="cx"> #include <wtf/RefCounted.h>
</span><span class="cx"> #include <wtf/RefPtr.h>
</span><span class="cx"> #include <wtf/RetainPtr.h>
</span><span class="cx"> #include <wtf/Vector.h>
</span><span class="cx"> 
</span><ins>+OBJC_PROTOCOL(MTLBlitCommandEncoder);
</ins><span class="cx"> OBJC_PROTOCOL(MTLCommandBuffer);
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -38,10 +40,45 @@
</span><span class="cx"> 
</span><span class="cx"> class GPUBuffer;
</span><span class="cx"> class GPUDevice;
</span><ins>+class GPUTexture;
</ins><span class="cx"> 
</span><ins>+struct GPUExtent3D;
+
</ins><span class="cx"> using PlatformCommandBuffer = MTLCommandBuffer;
</span><span class="cx"> using PlatformCommandBufferSmartPtr = RetainPtr<MTLCommandBuffer>;
</span><span class="cx"> 
</span><ins>+struct GPUBufferCopyViewBase {
+    unsigned long offset;
+    unsigned long rowPitch;
+    unsigned imageHeight;
+};
+
+struct GPUBufferCopyView final : GPUBufferCopyViewBase {
+    GPUBufferCopyView(Ref<GPUBuffer>&& bufferCopy, const GPUBufferCopyViewBase& base)
+        : GPUBufferCopyViewBase(base)
+        , buffer(WTFMove(bufferCopy))
+    {
+    }
+
+    Ref<GPUBuffer> buffer;
+};
+
+struct GPUTextureCopyViewBase {
+    unsigned mipLevel;
+    unsigned arrayLayer;
+    GPUOrigin3D origin;
+};
+
+struct GPUTextureCopyView final : GPUTextureCopyViewBase {
+    GPUTextureCopyView(Ref<GPUTexture>&& textureCopy, const GPUTextureCopyViewBase& base)
+        : GPUTextureCopyViewBase(base)
+        , texture(WTFMove(textureCopy))
+    {
+    }
+
+    Ref<GPUTexture> texture;
+};
+
</ins><span class="cx"> class GPUCommandBuffer : public RefCounted<GPUCommandBuffer> {
</span><span class="cx"> public:
</span><span class="cx">     static RefPtr<GPUCommandBuffer> create(GPUDevice&);
</span><span class="lines">@@ -48,7 +85,15 @@
</span><span class="cx"> 
</span><span class="cx">     PlatformCommandBuffer* platformCommandBuffer() const { return m_platformCommandBuffer.get(); }
</span><span class="cx">     const Vector<Ref<GPUBuffer>>& usedBuffers() const { return m_usedBuffers; }
</span><ins>+#if USE(METAL)
+    MTLBlitCommandEncoder *blitEncoder() const;
+#endif
</ins><span class="cx"> 
</span><ins>+    void copyBufferToBuffer(Ref<GPUBuffer>&&, unsigned long srcOffset, Ref<GPUBuffer>&&, unsigned long dstOffset, unsigned long size);
+    void copyBufferToTexture(const GPUBufferCopyView&, const GPUTextureCopyView&, const GPUExtent3D&);
+    void copyTextureToBuffer(const GPUTextureCopyView&, const GPUBufferCopyView&, const GPUExtent3D&);
+    void copyTextureToTexture(const GPUTextureCopyView&, const GPUTextureCopyView&, const GPUExtent3D&);
+
</ins><span class="cx">     void useBuffer(Ref<GPUBuffer>&& buffer) { m_usedBuffers.append(WTFMove(buffer)); }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="lines">@@ -56,6 +101,9 @@
</span><span class="cx"> 
</span><span class="cx">     PlatformCommandBufferSmartPtr m_platformCommandBuffer;
</span><span class="cx">     Vector<Ref<GPUBuffer>> m_usedBuffers;
</span><ins>+#if USE(METAL)
+    mutable RetainPtr<MTLBlitCommandEncoder> m_blitEncoder;
+#endif
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgpuGPURenderPassDescriptorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/gpu/GPURenderPassDescriptor.h (242403 => 242404)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gpu/GPURenderPassDescriptor.h     2019-03-05 00:43:41 UTC (rev 242403)
+++ trunk/Source/WebCore/platform/graphics/gpu/GPURenderPassDescriptor.h        2019-03-05 00:55:15 UTC (rev 242404)
</span><span class="lines">@@ -43,7 +43,7 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> struct GPURenderPassColorAttachmentDescriptor final : GPURenderPassColorAttachmentDescriptorBase {
</span><del>-    GPURenderPassColorAttachmentDescriptor(Ref<GPUTexture>&&, GPULoadOp, GPUStoreOp, GPUColor);
</del><ins>+    GPURenderPassColorAttachmentDescriptor(Ref<GPUTexture>&&, const GPURenderPassColorAttachmentDescriptorBase&);
</ins><span class="cx"> 
</span><span class="cx">     Ref<GPUTexture> attachment;
</span><span class="cx"> };
</span><span class="lines">@@ -57,7 +57,7 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> struct GPURenderPassDepthStencilAttachmentDescriptor final : GPURenderPassDepthStencilAttachmentDescriptorBase {
</span><del>-    GPURenderPassDepthStencilAttachmentDescriptor(Ref<GPUTexture>&&, GPULoadOp, GPUStoreOp, float);
</del><ins>+    GPURenderPassDepthStencilAttachmentDescriptor(Ref<GPUTexture>&&, const GPURenderPassDepthStencilAttachmentDescriptorBase&);
</ins><span class="cx"> 
</span><span class="cx">     Ref<GPUTexture> attachment;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgpuGPUTextureh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/gpu/GPUTexture.h (242403 => 242404)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gpu/GPUTexture.h  2019-03-05 00:43:41 UTC (rev 242403)
+++ trunk/Source/WebCore/platform/graphics/gpu/GPUTexture.h     2019-03-05 00:55:15 UTC (rev 242404)
</span><span class="lines">@@ -27,6 +27,8 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(WEBGPU)
</span><span class="cx"> 
</span><ins>+#include "GPUTextureUsage.h"
+#include <wtf/OptionSet.h>
</ins><span class="cx"> #include <wtf/RefCounted.h>
</span><span class="cx"> #include <wtf/RefPtr.h>
</span><span class="cx"> #include <wtf/RetainPtr.h>
</span><span class="lines">@@ -44,17 +46,22 @@
</span><span class="cx"> 
</span><span class="cx"> class GPUTexture : public RefCounted<GPUTexture> {
</span><span class="cx"> public:
</span><del>-    static RefPtr<GPUTexture> tryCreate(const GPUDevice&, GPUTextureDescriptor&&);
-    static Ref<GPUTexture> create(PlatformTextureSmartPtr&&);
</del><ins>+    static RefPtr<GPUTexture> tryCreate(const GPUDevice&, const GPUTextureDescriptor&);
+    static Ref<GPUTexture> create(PlatformTextureSmartPtr&&, OptionSet<GPUTextureUsage::Flags>);
</ins><span class="cx"> 
</span><span class="cx">     PlatformTexture *platformTexture() const { return m_platformTexture.get(); }
</span><ins>+    bool isTransferSource() const { return m_usage.contains(GPUTextureUsage::Flags::TransferSource); }
+    bool isTransferDestination() const { return m_usage.contains(GPUTextureUsage::Flags::TransferDestination); }
+    bool isOutputAttachment() const { return m_usage.contains(GPUTextureUsage::Flags::OutputAttachment); }
</ins><span class="cx"> 
</span><span class="cx">     RefPtr<GPUTexture> createDefaultTextureView();
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    explicit GPUTexture(PlatformTextureSmartPtr&&);
</del><ins>+    explicit GPUTexture(PlatformTextureSmartPtr&&, OptionSet<GPUTextureUsage::Flags>);
</ins><span class="cx"> 
</span><span class="cx">     PlatformTextureSmartPtr m_platformTexture;
</span><ins>+
+    OptionSet<GPUTextureUsage::Flags> m_usage;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgpuGPUTextureUsageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/gpu/GPUTextureUsage.h (242403 => 242404)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gpu/GPUTextureUsage.h     2019-03-05 00:43:41 UTC (rev 242403)
+++ trunk/Source/WebCore/platform/graphics/gpu/GPUTextureUsage.h        2019-03-05 00:55:15 UTC (rev 242404)
</span><span class="lines">@@ -31,16 +31,18 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx">     
</span><del>-using GPUTextureUsageFlags = unsigned long;
</del><ins>+using GPUTextureUsageFlags = unsigned;
</ins><span class="cx">     
</span><span class="cx"> class GPUTextureUsage : public RefCounted<GPUTextureUsage> {
</span><span class="cx"> public:
</span><del>-    static const GPUTextureUsageFlags None = 0;
-    static const GPUTextureUsageFlags TransferSrc = 1;
-    static const GPUTextureUsageFlags TransferDst = 2;
-    static const GPUTextureUsageFlags Sampled = 4;
-    static const GPUTextureUsageFlags Storage = 8;
-    static const GPUTextureUsageFlags OutputAttachment = 16;
</del><ins>+    enum class Flags : GPUTextureUsageFlags {
+        None = 0,
+        TransferSource = 1 << 0,
+        TransferDestination = 1 << 1,
+        Sampled = 1 << 2,
+        Storage = 1 << 3,
+        OutputAttachment = 1 << 4,
+    };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgpucocoaGPUBufferMetalmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUBufferMetal.mm (242403 => 242404)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUBufferMetal.mm       2019-03-05 00:43:41 UTC (rev 242403)
+++ trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUBufferMetal.mm  2019-03-05 00:55:15 UTC (rev 242404)
</span><span class="lines">@@ -39,10 +39,10 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-static const auto readOnlyMask = GPUBufferUsage::Index | GPUBufferUsage::Vertex | GPUBufferUsage::Uniform | GPUBufferUsage::TransferSrc;
</del><ins>+static const auto readOnlyFlags = OptionSet<GPUBufferUsage::Flags> { GPUBufferUsage::Flags::Index, GPUBufferUsage::Flags::Vertex, GPUBufferUsage::Flags::Uniform, GPUBufferUsage::Flags::TransferSource };
</ins><span class="cx"> 
</span><span class="cx"> 
</span><del>-bool GPUBuffer::validateBufferCreate(const GPUDevice& device, const GPUBufferDescriptor& descriptor)
</del><ins>+bool GPUBuffer::validateBufferUsage(const GPUDevice& device, OptionSet<GPUBufferUsage::Flags> usage)
</ins><span class="cx"> {
</span><span class="cx">     if (!device.platformDevice()) {
</span><span class="cx">         LOG(WebGPU, "GPUBuffer::create(): Invalid GPUDevice!");
</span><span class="lines">@@ -49,12 +49,12 @@
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if ((descriptor.usage & GPUBufferUsage::MapWrite) && (descriptor.usage & GPUBufferUsage::MapRead)) {
</del><ins>+    if (usage.containsAll({ GPUBufferUsage::Flags::MapWrite, GPUBufferUsage::Flags::MapRead })) {
</ins><span class="cx">         LOG(WebGPU, "GPUBuffer::create(): Buffer cannot have both MAP_READ and MAP_WRITE usage!");
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if ((descriptor.usage & readOnlyMask) && (descriptor.usage & GPUBufferUsage::Storage)) {
</del><ins>+    if (usage.containsAny(readOnlyFlags) && (usage & GPUBufferUsage::Flags::Storage)) {
</ins><span class="cx">         LOG(WebGPU, "GPUBuffer::create(): Buffer cannot have both STORAGE and a read-only usage!");
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="lines">@@ -64,7 +64,8 @@
</span><span class="cx"> 
</span><span class="cx"> RefPtr<GPUBuffer> GPUBuffer::tryCreate(Ref<GPUDevice>&& device, GPUBufferDescriptor&& descriptor)
</span><span class="cx"> {
</span><del>-    if (!validateBufferCreate(device.get(), descriptor))
</del><ins>+    auto usage = OptionSet<GPUBufferUsage::Flags>::fromRaw(descriptor.usage);
+    if (!validateBufferUsage(device.get(), usage))
</ins><span class="cx">         return nullptr;
</span><span class="cx"> 
</span><span class="cx">     // FIXME: Metal best practices: Read-only one-time-use data less than 4 KB should not allocate a MTLBuffer and be used in [MTLCommandEncoder set*Bytes] calls instead.
</span><span class="lines">@@ -72,7 +73,7 @@
</span><span class="cx">     MTLResourceOptions resourceOptions = MTLResourceCPUCacheModeDefaultCache;
</span><span class="cx"> 
</span><span class="cx">     // Mappable buffers use shared storage allocation.
</span><del>-    resourceOptions |= (descriptor.usage & (GPUBufferUsage::MapWrite | GPUBufferUsage::MapRead)) ? MTLResourceStorageModeShared : MTLResourceStorageModePrivate;
</del><ins>+    resourceOptions |= usage.containsAny({ GPUBufferUsage::Flags::MapWrite, GPUBufferUsage::Flags::MapRead }) ? MTLResourceStorageModeShared : MTLResourceStorageModePrivate;
</ins><span class="cx"> 
</span><span class="cx">     RetainPtr<MTLBuffer> mtlBuffer;
</span><span class="cx"> 
</span><span class="lines">@@ -87,14 +88,14 @@
</span><span class="cx">         return nullptr;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    return adoptRef(*new GPUBuffer(WTFMove(mtlBuffer), descriptor, WTFMove(device)));
</del><ins>+    return adoptRef(*new GPUBuffer(WTFMove(mtlBuffer), descriptor, usage, WTFMove(device)));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-GPUBuffer::GPUBuffer(RetainPtr<MTLBuffer>&& buffer, const GPUBufferDescriptor& descriptor, Ref<GPUDevice>&& device)
</del><ins>+GPUBuffer::GPUBuffer(RetainPtr<MTLBuffer>&& buffer, const GPUBufferDescriptor& descriptor, OptionSet<GPUBufferUsage::Flags> usage, Ref<GPUDevice>&& device)
</ins><span class="cx">     : m_platformBuffer(WTFMove(buffer))
</span><span class="cx">     , m_device(WTFMove(device))
</span><span class="cx">     , m_byteLength(descriptor.size)
</span><del>-    , m_usage(static_cast<GPUBufferUsage::Flags>(descriptor.usage))
</del><ins>+    , m_usage(usage)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -105,7 +106,7 @@
</span><span class="cx"> 
</span><span class="cx"> bool GPUBuffer::isReadOnly() const
</span><span class="cx"> {
</span><del>-    return m_usage & readOnlyMask;
</del><ins>+    return m_usage.containsAny(readOnlyFlags);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> GPUBuffer::State GPUBuffer::state() const
</span><span class="lines">@@ -120,10 +121,18 @@
</span><span class="cx"> 
</span><span class="cx"> void GPUBuffer::setSubData(unsigned long offset, const JSC::ArrayBuffer& data)
</span><span class="cx"> {
</span><del>-    if (!isTransferDst() || state() != State::Unmapped) {
</del><ins>+    if (!isTransferDestination() || state() != State::Unmapped) {
</ins><span class="cx">         LOG(WebGPU, "GPUBuffer::setSubData(): Invalid operation!");
</span><span class="cx">         return;
</span><span class="cx">     }
</span><ins>+
+#if PLATFORM(MAC)
+    if (offset % 4 || data.byteLength() % 4) {
+        LOG(WebGPU, "GPUBuffer::setSubData(): Data must be aligned to a multiple of 4 bytes!");
+        return;
+    }
+#endif
+
</ins><span class="cx">     auto subDataLength = checkedSum<unsigned long>(data.byteLength(), offset);
</span><span class="cx">     if (subDataLength.hasOverflowed() || subDataLength.unsafeGet() > m_byteLength) {
</span><span class="cx">         LOG(WebGPU, "GPUBuffer::setSubData(): Invalid offset or data size!");
</span><span class="lines">@@ -130,8 +139,6 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // FIXME: Add alignment checks once specified.
-
</del><span class="cx">     if (m_subDataBuffers.isEmpty()) {
</span><span class="cx">         BEGIN_BLOCK_OBJC_EXCEPTIONS;
</span><span class="cx">         m_subDataBuffers.append(adoptNS([m_platformBuffer.get().device newBufferWithLength:m_byteLength options:MTLResourceCPUCacheModeDefaultCache]));
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgpucocoaGPUCommandBufferMetalmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUCommandBufferMetal.mm (242403 => 242404)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUCommandBufferMetal.mm        2019-03-05 00:43:41 UTC (rev 242403)
+++ trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUCommandBufferMetal.mm   2019-03-05 00:55:15 UTC (rev 242404)
</span><span class="lines">@@ -28,12 +28,16 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(WEBGPU)
</span><span class="cx"> 
</span><ins>+#import "GPUBuffer.h"
</ins><span class="cx"> #import "GPUDevice.h"
</span><ins>+#import "GPUExtent3D.h"
</ins><span class="cx"> #import "GPUQueue.h"
</span><ins>+#import "GPUTexture.h"
</ins><span class="cx"> #import "Logging.h"
</span><span class="cx"> 
</span><span class="cx"> #import <Metal/Metal.h>
</span><span class="cx"> #import <wtf/BlockObjCExceptions.h>
</span><ins>+#import <wtf/CheckedArithmetic.h>
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="lines">@@ -50,7 +54,7 @@
</span><span class="cx"> 
</span><span class="cx">     auto mtlQueue = gpuCommandQueue->platformQueue();
</span><span class="cx"> 
</span><del>-    PlatformCommandBufferSmartPtr buffer;
</del><ins>+    RetainPtr<MTLCommandBuffer> buffer;
</ins><span class="cx"> 
</span><span class="cx">     BEGIN_BLOCK_OBJC_EXCEPTIONS;
</span><span class="cx"> 
</span><span class="lines">@@ -66,11 +70,142 @@
</span><span class="cx">     return adoptRef(new GPUCommandBuffer(WTFMove(buffer)));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-GPUCommandBuffer::GPUCommandBuffer(PlatformCommandBufferSmartPtr&& buffer)
</del><ins>+GPUCommandBuffer::GPUCommandBuffer(RetainPtr<MTLCommandBuffer>&& buffer)
</ins><span class="cx">     : m_platformCommandBuffer(WTFMove(buffer))
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+MTLBlitCommandEncoder *GPUCommandBuffer::blitEncoder() const
+{
+    return m_blitEncoder ? m_blitEncoder.get() : (m_blitEncoder = [m_platformCommandBuffer blitCommandEncoder]).get();
+}
+
+void GPUCommandBuffer::copyBufferToBuffer(Ref<GPUBuffer>&& src, unsigned long srcOffset, Ref<GPUBuffer>&& dst, unsigned long dstOffset, unsigned long size)
+{
+    if (!src->isTransferSource() || !dst->isTransferDestination()) {
+        LOG(WebGPU, "GPUCommandBuffer::copyBufferToBuffer(): Invalid operation!");
+        return;
+    }
+
+#if PLATFORM(MAC)
+    if (size % 4 || srcOffset % 4 || dstOffset % 4) {
+        LOG(WebGPU, "GPUCommandBuffer::copyBufferToBuffer(): Copy must be aligned to a multiple of 4 bytes!");
+        return;
+    }
+#endif
+
+    auto srcLength = checkedSum<unsigned long>(size, srcOffset);
+    auto dstLength = checkedSum<unsigned long>(size, dstOffset);
+    if (srcLength.hasOverflowed() || dstLength.hasOverflowed()
+        || srcLength.unsafeGet() > src->byteLength() || dstLength.unsafeGet() > dst->byteLength()) {
+        LOG(WebGPU, "GPUCommandBuffer::copyBufferToBuffer(): Invalid offset or copy size!");
+        return;
+    }
+
+    BEGIN_BLOCK_OBJC_EXCEPTIONS;
+
+    [blitEncoder()
+        copyFromBuffer:src->platformBuffer()
+        sourceOffset:srcOffset
+        toBuffer:dst->platformBuffer()
+        destinationOffset:dstOffset
+        size:size];
+
+    END_BLOCK_OBJC_EXCEPTIONS;
+
+    useBuffer(WTFMove(src));
+    useBuffer(WTFMove(dst));
+}
+
+void GPUCommandBuffer::copyBufferToTexture(const GPUBufferCopyView& srcBuffer, const GPUTextureCopyView& dstTexture, const GPUExtent3D& size)
+{
+    if (!srcBuffer.buffer->isTransferSource() || !dstTexture.texture->isTransferDestination()) {
+        LOG(WebGPU, "GPUComandBuffer::copyBufferToTexture(): Invalid operation!");
+        return;
+    }
+
+    // FIXME: Add Metal validation.
+
+    // GPUBufferCopyView::offset: The location must be aligned to the size of the destination texture's pixel format. The value must be a multiple of the destination texture's pixel size, in bytes.
+
+    // GPUBufferCopyView::rowPitch: The value must be a multiple of the destination texture's pixel size, in bytes. The value must be less than or equal to 32,767 multiplied by the destination texture’s pixel size.
+
+    // GPUBufferCopyView::imageHeight: The value must be a multiple of the destination texture's pixel size, in bytes.
+
+    // GPUExtent3D: When you copy to a 1D texture, height and depth must be 1. When you copy to a 2D texture, depth must be 1.
+
+    // GPUTextureCopyView::texture: The value must not be a framebufferOnly texture and must not have a PVRTC pixel format.
+
+    BEGIN_BLOCK_OBJC_EXCEPTIONS;
+
+    [blitEncoder()
+        copyFromBuffer:srcBuffer.buffer->platformBuffer()
+        sourceOffset:srcBuffer.offset
+        sourceBytesPerRow:srcBuffer.rowPitch
+        sourceBytesPerImage:srcBuffer.imageHeight
+        sourceSize:MTLSizeMake(size.width, size.height, size.depth)
+        toTexture:dstTexture.texture->platformTexture()
+        destinationSlice:dstTexture.arrayLayer
+        destinationLevel:dstTexture.mipLevel
+        destinationOrigin:MTLOriginMake(dstTexture.origin.x, dstTexture.origin.y, dstTexture.origin.z)];
+
+    END_BLOCK_OBJC_EXCEPTIONS;
+
+    useBuffer(srcBuffer.buffer.copyRef());
+}
+
+void GPUCommandBuffer::copyTextureToBuffer(const GPUTextureCopyView& srcTexture, const GPUBufferCopyView& dstBuffer, const GPUExtent3D& size)
+{
+    if (!srcTexture.texture->isTransferSource() || !dstBuffer.buffer->isTransferDestination()) {
+        LOG(WebGPU, "GPUCommandBuffer::copyTextureToBuffer(): Invalid operation!");
+        return;
+    }
+
+    // FIXME: Add Metal validation?
+
+    BEGIN_BLOCK_OBJC_EXCEPTIONS;
+
+    [blitEncoder()
+        copyFromTexture:srcTexture.texture->platformTexture()
+        sourceSlice:srcTexture.arrayLayer
+        sourceLevel:srcTexture.mipLevel
+        sourceOrigin:MTLOriginMake(srcTexture.origin.x, srcTexture.origin.y, srcTexture.origin.z)
+        sourceSize:MTLSizeMake(size.width, size.height, size.depth)
+        toBuffer:dstBuffer.buffer->platformBuffer()
+        destinationOffset:dstBuffer.offset
+        destinationBytesPerRow:dstBuffer.rowPitch
+        destinationBytesPerImage:dstBuffer.imageHeight];
+
+    END_BLOCK_OBJC_EXCEPTIONS;
+
+    useBuffer(dstBuffer.buffer.copyRef());
+}
+
+void GPUCommandBuffer::copyTextureToTexture(const GPUTextureCopyView& src, const GPUTextureCopyView& dst, const GPUExtent3D& size)
+{
+    if (!src.texture->isTransferSource() || !dst.texture->isTransferDestination()) {
+        LOG(WebGPU, "GPUCommandBuffer::copyTextureToTexture(): Invalid operation!");
+        return;
+    }
+
+    // FIXME: Add Metal validation?
+
+    BEGIN_BLOCK_OBJC_EXCEPTIONS;
+
+    [blitEncoder()
+        copyFromTexture:src.texture->platformTexture()
+        sourceSlice:src.arrayLayer
+        sourceLevel:src.mipLevel
+        sourceOrigin:MTLOriginMake(src.origin.x, src.origin.y, src.origin.z)
+        sourceSize:MTLSizeMake(size.width, size.height, size.depth)
+        toTexture:dst.texture->platformTexture()
+        destinationSlice:src.arrayLayer
+        destinationLevel:src.mipLevel
+        destinationOrigin:MTLOriginMake(dst.origin.x, dst.origin.y, dst.origin.z)];
+
+    END_BLOCK_OBJC_EXCEPTIONS;
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(WEBGPU)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgpucocoaGPUQueueMetalmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUQueueMetal.mm (242403 => 242404)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUQueueMetal.mm        2019-03-05 00:43:41 UTC (rev 242403)
+++ trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUQueueMetal.mm   2019-03-05 00:55:15 UTC (rev 242404)
</span><span class="lines">@@ -72,7 +72,11 @@
</span><span class="cx"> 
</span><span class="cx"> void GPUQueue::submit(Vector<Ref<const GPUCommandBuffer>>&& commandBuffers)
</span><span class="cx"> {
</span><ins>+    BEGIN_BLOCK_OBJC_EXCEPTIONS;
+
</ins><span class="cx">     for (auto& commandBuffer : commandBuffers) {
</span><ins>+        if (commandBuffer->blitEncoder())
+            [commandBuffer->blitEncoder() endEncoding];
</ins><span class="cx">         // Prevent any buffer mapping callbacks from executing until command buffer is complete.
</span><span class="cx">         for (auto& buffer : commandBuffer->usedBuffers()) {
</span><span class="cx">             if (buffer->state() != GPUBuffer::State::Unmapped) {
</span><span class="lines">@@ -84,6 +88,8 @@
</span><span class="cx"> 
</span><span class="cx">         [commandBuffer->platformCommandBuffer() commit];
</span><span class="cx">     }
</span><ins>+
+    END_BLOCK_OBJC_EXCEPTIONS;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> String GPUQueue::label() const
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgpucocoaGPUSwapChainMetalmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUSwapChainMetal.mm (242403 => 242404)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUSwapChainMetal.mm    2019-03-05 00:43:41 UTC (rev 242403)
+++ trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUSwapChainMetal.mm       2019-03-05 00:55:15 UTC (rev 242404)
</span><span class="lines">@@ -117,7 +117,7 @@
</span><span class="cx">         return nullptr;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    return GPUTexture::create(WTFMove(mtlTexture));
</del><ins>+    return GPUTexture::create(WTFMove(mtlTexture), GPUTextureUsage::Flags::OutputAttachment);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void GPUSwapChain::present()
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgpucocoaGPUTextureMetalmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUTextureMetal.mm (242403 => 242404)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUTextureMetal.mm      2019-03-05 00:43:41 UTC (rev 242403)
+++ trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUTextureMetal.mm 2019-03-05 00:55:15 UTC (rev 242404)
</span><span class="lines">@@ -54,25 +54,32 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static Optional<MTLTextureUsage> mtlTextureUsageForGPUTextureUsageFlags(GPUTextureUsageFlags flags)
</del><ins>+static Optional<MTLTextureUsage> mtlTextureUsageForGPUTextureUsageFlags(OptionSet<GPUTextureUsage::Flags> flags, const char* const functionName)
</ins><span class="cx"> {
</span><del>-    MTLTextureUsage usage = MTLTextureUsageUnknown;
</del><ins>+#if LOG_DISABLED
+    UNUSED_PARAM(functionName);
+#endif
+    if (flags.containsAny({ GPUTextureUsage::Flags::TransferSource, GPUTextureUsage::Flags::Sampled }) && (flags & GPUTextureUsage::Flags::Storage)) {
+        LOG(WebGPU, "%s: Texture cannot have both STORAGE and a read-only usage!", functionName);
+        return WTF::nullopt;
+    }
</ins><span class="cx"> 
</span><del>-    if (flags & GPUTextureUsage::Storage)
-        usage |= MTLTextureUsageShaderWrite | MTLTextureUsageShaderRead | MTLTextureUsagePixelFormatView;
-
-    if (flags & GPUTextureUsage::Sampled) {
-        // SAMPLED is a read-only usage.
-        if (flags & GPUTextureUsage::Storage)
</del><ins>+    if (flags & GPUTextureUsage::Flags::OutputAttachment) {
+        if (flags.containsAny({ GPUTextureUsage::Flags::Storage, GPUTextureUsage::Flags::Sampled })) {
+            LOG(WebGPU, "%s: Texture cannot have OUTPUT_ATTACHMENT usage with STORAGE or SAMPLED usages!", functionName);
</ins><span class="cx">             return WTF::nullopt;
</span><ins>+        }
</ins><span class="cx"> 
</span><del>-        usage |= MTLTextureUsageShaderRead | MTLTextureUsagePixelFormatView;
</del><ins>+        return MTLTextureUsageRenderTarget | MTLTextureUsagePixelFormatView;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (flags & GPUTextureUsage::OutputAttachment)
-        usage |= MTLTextureUsageRenderTarget;
</del><ins>+    if (flags & GPUTextureUsage::Flags::Storage)
+        return MTLTextureUsageShaderWrite | MTLTextureUsageShaderRead | MTLTextureUsagePixelFormatView;
</ins><span class="cx"> 
</span><del>-    return usage;
</del><ins>+    if (flags & GPUTextureUsage::Flags::Sampled)
+        return MTLTextureUsageShaderRead | MTLTextureUsagePixelFormatView;
+
+    return MTLTextureUsageUnknown;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static MTLStorageMode storageModeForPixelFormatAndSampleCount(MTLPixelFormat format, unsigned long samples)
</span><span class="lines">@@ -88,12 +95,8 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static RetainPtr<MTLTextureDescriptor> tryCreateMtlTextureDescriptor(const char* const functionName, const GPUTextureDescriptor&& descriptor)
</del><ins>+static RetainPtr<MTLTextureDescriptor> tryCreateMtlTextureDescriptor(const char* const functionName, const GPUTextureDescriptor& descriptor, OptionSet<GPUTextureUsage::Flags> usage)
</ins><span class="cx"> {
</span><del>-#if LOG_DISABLED
-    UNUSED_PARAM(functionName);
-#endif
-
</del><span class="cx">     RetainPtr<MTLTextureDescriptor> mtlDescriptor;
</span><span class="cx"> 
</span><span class="cx">     BEGIN_BLOCK_OBJC_EXCEPTIONS;
</span><span class="lines">@@ -110,11 +113,9 @@
</span><span class="cx">     // FIXME: Add more validation as constraints are added to spec.
</span><span class="cx">     auto pixelFormat = static_cast<MTLPixelFormat>(platformTextureFormatForGPUTextureFormat(descriptor.format));
</span><span class="cx"> 
</span><del>-    auto usage = mtlTextureUsageForGPUTextureUsageFlags(descriptor.usage);
-    if (!usage) {
-        LOG(WebGPU, "%s: Invalid GPUTextureUsageFlags!", functionName);
</del><ins>+    auto mtlUsage = mtlTextureUsageForGPUTextureUsageFlags(usage, functionName);
+    if (!mtlUsage)
</ins><span class="cx">         return nullptr;
</span><del>-    }
</del><span class="cx"> 
</span><span class="cx">     auto storageMode = storageModeForPixelFormatAndSampleCount(pixelFormat, descriptor.sampleCount);
</span><span class="cx"> 
</span><span class="lines">@@ -128,7 +129,7 @@
</span><span class="cx">     [mtlDescriptor setSampleCount:descriptor.sampleCount];
</span><span class="cx">     [mtlDescriptor setTextureType:mtlTextureTypeForGPUTextureDescriptor(descriptor)];
</span><span class="cx">     [mtlDescriptor setPixelFormat:pixelFormat];
</span><del>-    [mtlDescriptor setUsage:*usage];
</del><ins>+    [mtlDescriptor setUsage:*mtlUsage];
</ins><span class="cx"> 
</span><span class="cx">     [mtlDescriptor setStorageMode:storageMode];
</span><span class="cx"> 
</span><span class="lines">@@ -137,7 +138,7 @@
</span><span class="cx">     return mtlDescriptor;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RefPtr<GPUTexture> GPUTexture::tryCreate(const GPUDevice& device, GPUTextureDescriptor&& descriptor)
</del><ins>+RefPtr<GPUTexture> GPUTexture::tryCreate(const GPUDevice& device, const GPUTextureDescriptor& descriptor)
</ins><span class="cx"> {
</span><span class="cx">     const char* const functionName = "GPUTexture::tryCreate()";
</span><span class="cx"> 
</span><span class="lines">@@ -146,7 +147,8 @@
</span><span class="cx">         return nullptr;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    auto mtlDescriptor = tryCreateMtlTextureDescriptor(functionName, WTFMove(descriptor));
</del><ins>+    auto usage = OptionSet<GPUTextureUsage::Flags>::fromRaw(descriptor.usage);
+    auto mtlDescriptor = tryCreateMtlTextureDescriptor(functionName, descriptor, usage);
</ins><span class="cx">     if (!mtlDescriptor)
</span><span class="cx">         return nullptr;
</span><span class="cx"> 
</span><span class="lines">@@ -163,16 +165,17 @@
</span><span class="cx">         return nullptr;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    return adoptRef(new GPUTexture(WTFMove(mtlTexture)));
</del><ins>+    return adoptRef(new GPUTexture(WTFMove(mtlTexture), usage));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-Ref<GPUTexture> GPUTexture::create(PlatformTextureSmartPtr&& texture)
</del><ins>+Ref<GPUTexture> GPUTexture::create(PlatformTextureSmartPtr&& texture, OptionSet<GPUTextureUsage::Flags> usage)
</ins><span class="cx"> {
</span><del>-    return adoptRef(*new GPUTexture(WTFMove(texture)));
</del><ins>+    return adoptRef(*new GPUTexture(WTFMove(texture), usage));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-GPUTexture::GPUTexture(PlatformTextureSmartPtr&& texture)
</del><ins>+GPUTexture::GPUTexture(PlatformTextureSmartPtr&& texture, OptionSet<GPUTextureUsage::Flags> usage)
</ins><span class="cx">     : m_platformTexture(WTFMove(texture))
</span><ins>+    , m_usage(usage)
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -191,7 +194,7 @@
</span><span class="cx">         return nullptr;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    return GPUTexture::create(WTFMove(texture));
</del><ins>+    return GPUTexture::create(WTFMove(texture), m_usage);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre>
</div>
</div>

</body>
</html>