WebKit Bugzilla
Attachment 362189 Details for
Bug 194665
: [Web GPU] Buffer updates part 1: async mapping functions, unmap, and destroy
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-194665-20190215171020.patch (text/plain), 29.90 KB, created by
Justin Fan
on 2019-02-15 17:10:20 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Justin Fan
Created:
2019-02-15 17:10:20 PST
Size:
29.90 KB
patch
obsolete
>Subversion Revision: 241328 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index a420326f3b772cf5f430abd161844c239e15fbd0..9f00a1075f25a2ebc027cdd8b745750bedac8c51 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,52 @@ >+2019-02-14 Justin Fan <justin_fan@apple.com> >+ >+ [WebGPU] (WIP) Buffer updates part 1: async mapping functions, unmap, and destroy >+ https://bugs.webkit.org/show_bug.cgi?id=194665 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ buffers.html updated to test all new functionality. Other tests updated to match new API. >+ >+ * Modules/webgpu/WebGPUBuffer.cpp: >+ (WebCore::WebGPUBuffer::create): >+ (WebCore::WebGPUBuffer::WebGPUBuffer): >+ (WebCore::WebGPUBuffer::mapReadAsync): >+ (WebCore::WebGPUBuffer::mapWriteAsync): >+ (WebCore::WebGPUBuffer::unmap): >+ (WebCore::WebGPUBuffer::destroy): >+ * Modules/webgpu/WebGPUBuffer.h: >+ (WebCore::WebGPUBuffer::buffer const): >+ (WebCore::WebGPUBuffer::mapping const): Deleted. >+ (WebCore::WebGPUBuffer::unmap): Deleted. >+ (WebCore::WebGPUBuffer::destroy): Deleted. >+ * Modules/webgpu/WebGPUBuffer.idl: >+ * Modules/webgpu/WebGPUDevice.cpp: >+ (WebCore::WebGPUDevice::createBuffer const): >+ (WebCore::WebGPUDevice::createBindGroup const): >+ * Modules/webgpu/WebGPUDevice.h: >+ * Modules/webgpu/WebGPURenderPassEncoder.cpp: >+ (WebCore::WebGPURenderPassEncoder::setVertexBuffers): >+ * platform/graphics/gpu/GPUBuffer.h: >+ (WebCore::GPUBuffer::isMappable const): >+ (WebCore::GPUBuffer::isMapWriteable const): >+ (WebCore::GPUBuffer::isMapReadable const): >+ (WebCore::GPUBuffer::mapping const): Deleted. >+ * platform/graphics/gpu/GPUBufferUsage.h: >+ * platform/graphics/gpu/GPUDevice.cpp: >+ (WebCore::GPUDevice::tryCreateBuffer const): >+ (WebCore::GPUDevice::createBuffer const): Deleted. >+ * platform/graphics/gpu/GPUDevice.h: >+ * platform/graphics/gpu/cocoa/GPUBufferMetal.mm: >+ (WebCore::GPUBuffer::tryCreateMappableBuffer): >+ (WebCore::GPUBuffer::tryCreate): >+ (WebCore::GPUBuffer::GPUBuffer): >+ (WebCore::GPUBuffer::~GPUBuffer): >+ (WebCore::GPUBuffer::resolveMappingPromise): >+ (WebCore::GPUBuffer::mapReadAsync): >+ (WebCore::GPUBuffer::mapWriteAsync): >+ (WebCore::GPUBuffer::unmap): >+ (WebCore::GPUBuffer::create): Deleted. >+ > 2019-02-12 Justin Fan <justin_fan@apple.com> > > [WebGPU] Remove WebGPUBufferDescriptor/Usage and use GPU versions >diff --git a/Source/WebCore/Modules/webgpu/WebGPUBuffer.cpp b/Source/WebCore/Modules/webgpu/WebGPUBuffer.cpp >index 909a5c7642f24af64248d999dc31c4e420f40861..0dc42edb47d1e844b92db316fe554c92bcdbb3ee 100644 >--- a/Source/WebCore/Modules/webgpu/WebGPUBuffer.cpp >+++ b/Source/WebCore/Modules/webgpu/WebGPUBuffer.cpp >@@ -28,18 +28,65 @@ > > #if ENABLE(WEBGPU) > >+#include "Logging.h" >+#include "Microtasks.h" >+ > namespace WebCore { > >-Ref<WebGPUBuffer> WebGPUBuffer::create(Ref<GPUBuffer>&& buffer) >+Ref<WebGPUBuffer> WebGPUBuffer::create(RefPtr<GPUBuffer>&& buffer) > { > return adoptRef(*new WebGPUBuffer(WTFMove(buffer))); > } > >-WebGPUBuffer::WebGPUBuffer(Ref<GPUBuffer>&& buffer) >+WebGPUBuffer::WebGPUBuffer(RefPtr<GPUBuffer>&& buffer) > : m_buffer(WTFMove(buffer)) > { > } > >+void WebGPUBuffer::mapReadAsync(ArrayBufferPromise&& promise) >+{ >+ rejectOrPendMappingPromise(WTFMove(promise), GPUBufferUsage::MapRead); >+} >+ >+void WebGPUBuffer::mapWriteAsync(ArrayBufferPromise&& promise) >+{ >+ rejectOrPendMappingPromise(WTFMove(promise), GPUBufferUsage::MapWrite); >+} >+ >+void WebGPUBuffer::unmap() >+{ >+ if (m_buffer) >+ m_buffer->unmap(); >+} >+ >+void WebGPUBuffer::destroy() >+{ >+ m_buffer = nullptr; >+} >+ >+void WebGPUBuffer::rejectOrPendMappingPromise(ArrayBufferPromise&& promise, GPUBufferUsageFlags usage) >+{ >+ const char* const type = (usage == GPUBufferUsage::MapRead) ? "Read" : "Write"; >+ >+ if (!m_buffer) { >+ LOG(WebGPU, "WebGPUBuffer::map%sAsync(): Invalid operation!", type); >+ promise.reject(); >+ return; >+ } >+ >+ MicrotaskQueue::mainThreadQueue().append(std::make_unique<VoidMicrotask>([this, protectedThis = makeRef(*this), pendingPromise = WTFMove(promise), usage, type] () mutable { >+#if LOG_DISABLED >+ UNUSED_PARAM(type); >+#endif >+ if (m_buffer) >+ (usage == GPUBufferUsage::MapRead) ? m_buffer->mapReadAsync(WTFMove(pendingPromise)) : m_buffer->mapWriteAsync(WTFMove(pendingPromise)); >+ else { >+ LOG(WebGPU, "WebGPUBuffer::map%sAsync(): Invalid operation!", type); >+ pendingPromise.reject(); >+ } >+ })); >+} >+ > } // namespace WebCore > > #endif // ENABLE(WEBGPU) >diff --git a/Source/WebCore/Modules/webgpu/WebGPUBuffer.h b/Source/WebCore/Modules/webgpu/WebGPUBuffer.h >index 51aebf2e2a785a19da3b0db6868adacd7cbcb248..aace0a96cca4d9606134a50f328f96f0e22a4ea6 100644 >--- a/Source/WebCore/Modules/webgpu/WebGPUBuffer.h >+++ b/Source/WebCore/Modules/webgpu/WebGPUBuffer.h >@@ -28,26 +28,35 @@ > #if ENABLE(WEBGPU) > > #include "GPUBuffer.h" >- >+#include "GPUBufferUsage.h" > #include <wtf/RefCounted.h> > #include <wtf/RefPtr.h> > >+namespace JSC { >+class ArrayBuffer; >+} >+ > namespace WebCore { > >+struct GPUBufferDescriptor; >+ > class WebGPUBuffer : public RefCounted<WebGPUBuffer> { > public: >- static Ref<WebGPUBuffer> create(Ref<GPUBuffer>&&); >+ static Ref<WebGPUBuffer> create(RefPtr<GPUBuffer>&&); > >- const GPUBuffer& buffer() const { return m_buffer.get(); } >+ RefPtr<const GPUBuffer> buffer() const { return m_buffer; } > >- JSC::ArrayBuffer* mapping() const { return m_buffer->mapping(); } >- void unmap() { /* FIXME: Unimplemented stub. */ } >- void destroy() { /* FIXME: Unimplemented stub. */ } >+ void mapReadAsync(ArrayBufferPromise&&); >+ void mapWriteAsync(ArrayBufferPromise&&); >+ void unmap(); >+ void destroy(); > > private: >- explicit WebGPUBuffer(Ref<GPUBuffer>&&); >+ explicit WebGPUBuffer(RefPtr<GPUBuffer>&&); >+ >+ void rejectOrPendMappingPromise(ArrayBufferPromise&&, GPUBufferUsageFlags); > >- Ref<GPUBuffer> m_buffer; >+ RefPtr<GPUBuffer> m_buffer; > }; > > } // namespace WebCore >diff --git a/Source/WebCore/Modules/webgpu/WebGPUBuffer.idl b/Source/WebCore/Modules/webgpu/WebGPUBuffer.idl >index 308667ef4355de1d259c68a30d50a258ace88486..752ae7456e9207636f36d616f507759f94167ea6 100644 >--- a/Source/WebCore/Modules/webgpu/WebGPUBuffer.idl >+++ b/Source/WebCore/Modules/webgpu/WebGPUBuffer.idl >@@ -28,7 +28,10 @@ > EnabledAtRuntime=WebGPU, > ImplementationLacksVTable > ] interface WebGPUBuffer { >- readonly attribute ArrayBuffer? mapping; >+ //void setSubData(u32 offset, ArrayBuffer data); >+ >+ Promise<ArrayBuffer> mapReadAsync(); >+ Promise<ArrayBuffer> mapWriteAsync(); > void unmap(); > > void destroy(); >diff --git a/Source/WebCore/Modules/webgpu/WebGPUDevice.cpp b/Source/WebCore/Modules/webgpu/WebGPUDevice.cpp >index ea3b3c7a39ad15e93b256a405a54ec5847a5b727..767c27eb4b2e3b425f8a428fd20f9fc1b5ec4420 100644 >--- a/Source/WebCore/Modules/webgpu/WebGPUDevice.cpp >+++ b/Source/WebCore/Modules/webgpu/WebGPUDevice.cpp >@@ -73,11 +73,10 @@ WebGPUDevice::WebGPUDevice(Ref<WebGPUAdapter>&& adapter, Ref<GPUDevice>&& device > UNUSED_PARAM(m_adapter); > } > >-RefPtr<WebGPUBuffer> WebGPUDevice::createBuffer(GPUBufferDescriptor&& descriptor) const >+Ref<WebGPUBuffer> WebGPUDevice::createBuffer(GPUBufferDescriptor&& descriptor) const > { >- if (auto buffer = m_device->createBuffer(WTFMove(descriptor))) >- return WebGPUBuffer::create(buffer.releaseNonNull()); >- return nullptr; >+ auto buffer = m_device->tryCreateBuffer(WTFMove(descriptor)); >+ return WebGPUBuffer::create(WTFMove(buffer)); > } > > Ref<WebGPUTexture> WebGPUDevice::createTexture(GPUTextureDescriptor&& descriptor) const >@@ -119,8 +118,8 @@ Ref<WebGPUBindGroup> WebGPUDevice::createBindGroup(WebGPUBindGroupDescriptor&& d > return static_cast<GPUBindingResource>(view->texture()); > return WTF::nullopt; > }, [] (const WebGPUBufferBinding& binding) -> Optional<GPUBindingResource> { >- if (binding.buffer) >- return static_cast<GPUBindingResource>(GPUBufferBinding { binding.buffer->buffer(), binding.offset, binding.size }); >+ if (binding.buffer && binding.buffer->buffer()) >+ return static_cast<GPUBindingResource>(GPUBufferBinding { binding.buffer->buffer().releaseNonNull(), binding.offset, binding.size }); > return WTF::nullopt; > }); > >diff --git a/Source/WebCore/Modules/webgpu/WebGPUDevice.h b/Source/WebCore/Modules/webgpu/WebGPUDevice.h >index a97485f8a2e5f0aeed26eacb6913d7d0c9a9ec9a..059825ac57dd00da60bba2d3521d86a15e092769 100644 >--- a/Source/WebCore/Modules/webgpu/WebGPUDevice.h >+++ b/Source/WebCore/Modules/webgpu/WebGPUDevice.h >@@ -62,7 +62,7 @@ public: > const WebGPUAdapter& adapter() const { return m_adapter.get(); } > const GPUDevice& device() const { return m_device.get(); } > >- RefPtr<WebGPUBuffer> createBuffer(GPUBufferDescriptor&&) const; >+ Ref<WebGPUBuffer> createBuffer(GPUBufferDescriptor&&) const; > Ref<WebGPUTexture> createTexture(GPUTextureDescriptor&&) const; > > Ref<WebGPUBindGroupLayout> createBindGroupLayout(WebGPUBindGroupLayoutDescriptor&&) const; >diff --git a/Source/WebCore/Modules/webgpu/WebGPURenderPassEncoder.cpp b/Source/WebCore/Modules/webgpu/WebGPURenderPassEncoder.cpp >index 03fb31bbc39cbb00f14b0c8a696df5fa6a3d3790..f9f6c8e5483896d241991eefebd87fefa354f305 100644 >--- a/Source/WebCore/Modules/webgpu/WebGPURenderPassEncoder.cpp >+++ b/Source/WebCore/Modules/webgpu/WebGPURenderPassEncoder.cpp >@@ -50,18 +50,26 @@ WebGPURenderPassEncoder::WebGPURenderPassEncoder(Ref<WebGPUCommandBuffer>&& crea > void WebGPURenderPassEncoder::setVertexBuffers(unsigned long startSlot, Vector<RefPtr<WebGPUBuffer>>&& buffers, Vector<unsigned long long>&& offsets) > { > if (buffers.isEmpty() || buffers.size() != offsets.size()) { >- LOG(WebGPU, "WebGPURenderPassEncoder::setVertexBuffers: Invalid number of buffers or offsets!"); >+ LOG(WebGPU, "WebGPURenderPassEncoder::setVertexBuffers(): Invalid number of buffers or offsets!"); > return; > } > > if (startSlot + buffers.size() > maxVertexBuffers) { >- LOG(WebGPU, "WebGPURenderPassEncoder::setVertexBuffers: Invalid startSlot %lu for %lu buffers!", startSlot, buffers.size()); >+ LOG(WebGPU, "WebGPURenderPassEncoder::setVertexBuffers(): Invalid startSlot %lu for %lu buffers!", startSlot, buffers.size()); > return; > } > >- auto gpuBuffers = buffers.map([] (const auto& buffer) -> Ref<const GPUBuffer> { >- return buffer->buffer(); >- }); >+ Vector<Ref<const GPUBuffer>> gpuBuffers; >+ gpuBuffers.reserveCapacity(buffers.size()); >+ >+ for (const auto& buffer : buffers) { >+ if (!buffer || !buffer->buffer()) { >+ LOG(WebGPU, "WebGPURenderPassEncoder::setVertexBuffers(): Invalid or destroyed buffer in list!"); >+ return; >+ } >+ >+ gpuBuffers.uncheckedAppend(buffer->buffer().releaseNonNull()); >+ } > > m_passEncoder->setVertexBuffers(startSlot, WTFMove(gpuBuffers), WTFMove(offsets)); > } >diff --git a/Source/WebCore/platform/graphics/gpu/GPUBuffer.h b/Source/WebCore/platform/graphics/gpu/GPUBuffer.h >index deb583dc86a9da3832e5920e0590e32e18cfeafd..81e0ce3678641d65b10db66340eb9dfed4f54ef1 100644 >--- a/Source/WebCore/platform/graphics/gpu/GPUBuffer.h >+++ b/Source/WebCore/platform/graphics/gpu/GPUBuffer.h >@@ -27,6 +27,8 @@ > > #if ENABLE(WEBGPU) > >+#include "GPUBufferUsage.h" >+#include "JSDOMPromiseDeferred.h" > #include <wtf/Ref.h> > #include <wtf/RefCounted.h> > #include <wtf/RetainPtr.h> >@@ -43,6 +45,7 @@ class GPUDevice; > > struct GPUBufferDescriptor; > >+using ArrayBufferPromise = DOMPromiseDeferred<IDLInterface<JSC::ArrayBuffer*>>; > using PlatformBuffer = MTLBuffer; > using PlatformBufferSmartPtr = RetainPtr<MTLBuffer>; > >@@ -50,17 +53,29 @@ class GPUBuffer : public RefCounted<GPUBuffer> { > public: > ~GPUBuffer(); > >- static RefPtr<GPUBuffer> create(const GPUDevice&, GPUBufferDescriptor&&); >+ static RefPtr<GPUBuffer> tryCreate(const GPUDevice&, GPUBufferDescriptor&&); > > PlatformBuffer *platformBuffer() const { return m_platformBuffer.get(); } > >- JSC::ArrayBuffer* mapping() const { return m_mapping.get(); } >+ void mapReadAsync(ArrayBufferPromise&&); >+ void mapWriteAsync(ArrayBufferPromise&&); >+ void unmap(); > > private: >- explicit GPUBuffer(PlatformBufferSmartPtr&&, RefPtr<JSC::ArrayBuffer>&&); >+ GPUBuffer(PlatformBufferSmartPtr&&, RefPtr<JSC::ArrayBuffer>&&, GPUBufferUsageFlags); >+ >+ static RefPtr<GPUBuffer> tryCreateMappableBuffer(const GPUDevice&, const GPUBufferDescriptor&); >+ void resolveMappingPromise(ArrayBufferPromise&&); >+ >+ bool isMappable() const { return m_isMapWriteable || m_isMapReadable; } >+ bool isMapWriteable() const { return m_isMapWriteable && !m_isMapped; } >+ bool isMapReadable() const { return m_isMapReadable && !m_isMapped; } > > PlatformBufferSmartPtr m_platformBuffer; > RefPtr<JSC::ArrayBuffer> m_mapping; >+ bool m_isMapWriteable; >+ bool m_isMapReadable; >+ bool m_isMapped = false; > }; > > } // namespace WebCore >diff --git a/Source/WebCore/platform/graphics/gpu/GPUBufferUsage.h b/Source/WebCore/platform/graphics/gpu/GPUBufferUsage.h >index 5ab4024a1325405a5b1cf7e8dbb3998d8c2cd194..d2c4a67b07e6e7c255ddb4ebf52290f65801d44c 100644 >--- a/Source/WebCore/platform/graphics/gpu/GPUBufferUsage.h >+++ b/Source/WebCore/platform/graphics/gpu/GPUBufferUsage.h >@@ -35,7 +35,7 @@ using GPUBufferUsageFlags = unsigned long; > > class GPUBufferUsage : public RefCounted<GPUBufferUsage> { > public: >- enum class Flags : GPUBufferUsageFlags { >+ enum Flags : GPUBufferUsageFlags { > None = 0, > MapRead = 1, > MapWrite = 2, >diff --git a/Source/WebCore/platform/graphics/gpu/GPUDevice.cpp b/Source/WebCore/platform/graphics/gpu/GPUDevice.cpp >index 16351e80fe7cdcad4abd434f16d9665a24690335..c6ad216e4e711a61ab460bf1724340f54900084f 100644 >--- a/Source/WebCore/platform/graphics/gpu/GPUDevice.cpp >+++ b/Source/WebCore/platform/graphics/gpu/GPUDevice.cpp >@@ -44,9 +44,9 @@ > > namespace WebCore { > >-RefPtr<GPUBuffer> GPUDevice::createBuffer(GPUBufferDescriptor&& descriptor) const >+RefPtr<GPUBuffer> GPUDevice::tryCreateBuffer(GPUBufferDescriptor&& descriptor) const > { >- return GPUBuffer::create(*this, WTFMove(descriptor)); >+ return GPUBuffer::tryCreate(*this, WTFMove(descriptor)); > } > > RefPtr<GPUTexture> GPUDevice::tryCreateTexture(GPUTextureDescriptor&& descriptor) const >diff --git a/Source/WebCore/platform/graphics/gpu/GPUDevice.h b/Source/WebCore/platform/graphics/gpu/GPUDevice.h >index 456eb8455dd4e564c4532bd3b2c3fd6271b59b49..7fce8f483e5e448af24eb063d4fac5b70de62f17 100644 >--- a/Source/WebCore/platform/graphics/gpu/GPUDevice.h >+++ b/Source/WebCore/platform/graphics/gpu/GPUDevice.h >@@ -60,7 +60,7 @@ class GPUDevice : public RefCounted<GPUDevice> { > public: > static RefPtr<GPUDevice> create(Optional<GPURequestAdapterOptions>&&); > >- RefPtr<GPUBuffer> createBuffer(GPUBufferDescriptor&&) const; >+ RefPtr<GPUBuffer> tryCreateBuffer(GPUBufferDescriptor&&) const; > RefPtr<GPUTexture> tryCreateTexture(GPUTextureDescriptor&&) const; > > RefPtr<GPUBindGroupLayout> tryCreateBindGroupLayout(GPUBindGroupLayoutDescriptor&&) const; >diff --git a/Source/WebCore/platform/graphics/gpu/cocoa/GPUBufferMetal.mm b/Source/WebCore/platform/graphics/gpu/cocoa/GPUBufferMetal.mm >index fcc276dbe14295381b43325c0cc26dfd48534ae7..5250b09b8245f1a6202baab4615b2aa62de1a847 100644 >--- a/Source/WebCore/platform/graphics/gpu/cocoa/GPUBufferMetal.mm >+++ b/Source/WebCore/platform/graphics/gpu/cocoa/GPUBufferMetal.mm >@@ -31,8 +31,6 @@ > #import "GPUBufferDescriptor.h" > #import "GPUDevice.h" > #import "Logging.h" >- >-#import <Foundation/NSRange.h> > #import <JavaScriptCore/ArrayBuffer.h> > #import <Metal/Metal.h> > #import <wtf/Gigacage.h> >@@ -40,13 +38,8 @@ > > namespace WebCore { > >-RefPtr<GPUBuffer> GPUBuffer::create(const GPUDevice& device, GPUBufferDescriptor&& descriptor) >+RefPtr<GPUBuffer> GPUBuffer::tryCreateMappableBuffer(const GPUDevice& device, const GPUBufferDescriptor& descriptor) > { >- if (!device.platformDevice()) { >- LOG(WebGPU, "GPUBuffer::create(): Invalid GPUDevice!"); >- return nullptr; >- } >- > size_t pageSize = WTF::pageSize(); > size_t pageAlignedSize = roundUpToMultipleOf(pageSize, descriptor.size); > void* pageAlignedCopy = Gigacage::tryAlignedMalloc(Gigacage::Primitive, pageSize, pageAlignedSize); >@@ -75,12 +68,30 @@ RefPtr<GPUBuffer> GPUBuffer::create(const GPUDevice& device, GPUBufferDescriptor > return nullptr; > } > >- return adoptRef(*new GPUBuffer(WTFMove(mtlBuffer), WTFMove(arrayBuffer))); >+ return adoptRef(*new GPUBuffer(WTFMove(mtlBuffer), WTFMove(arrayBuffer), descriptor.usage)); >+} >+ >+RefPtr<GPUBuffer> GPUBuffer::tryCreate(const GPUDevice& device, GPUBufferDescriptor&& descriptor) >+{ >+ if (!device.platformDevice()) { >+ LOG(WebGPU, "GPUBuffer::create(): Invalid GPUDevice!"); >+ return nullptr; >+ } >+ >+ // FIXME: Validate combinations of GPUBufferUsageFlags as restrictions are specified. >+ >+ // Mappable buffers need shared storage allocation. >+ if (descriptor.usage & (GPUBufferUsage::Flags::MapWrite | GPUBufferUsage::Flags::MapRead)) >+ return tryCreateMappableBuffer(device, descriptor); >+ >+ return nullptr; > } > >-GPUBuffer::GPUBuffer(PlatformBufferSmartPtr&& platformBuffer, RefPtr<ArrayBuffer>&& arrayBuffer) >+GPUBuffer::GPUBuffer(PlatformBufferSmartPtr&& platformBuffer, RefPtr<ArrayBuffer>&& arrayBuffer, GPUBufferUsageFlags usage) > : m_platformBuffer(WTFMove(platformBuffer)) > , m_mapping(WTFMove(arrayBuffer)) >+ , m_isMapWriteable(usage & GPUBufferUsage::Flags::MapWrite) >+ , m_isMapReadable(usage & GPUBufferUsage::Flags::MapRead) > { > } > >@@ -92,6 +103,44 @@ GPUBuffer::~GPUBuffer() > } > } > >+void GPUBuffer::resolveMappingPromise(ArrayBufferPromise&& promise) >+{ >+ m_isMapped = true; >+ auto mappingPtr = m_mapping.get(); >+ promise.resolve(mappingPtr); >+} >+ >+void GPUBuffer::mapReadAsync(ArrayBufferPromise&& promise) >+{ >+ if (isMapReadable()) { >+ ASSERT(m_mapping); >+ >+ resolveMappingPromise(WTFMove(promise)); >+ } else { >+ promise.reject(); >+ LOG(WebGPU, "GPUBuffer::mapReadAsync(): Invalid operation!"); >+ } >+} >+ >+void GPUBuffer::mapWriteAsync(ArrayBufferPromise&& promise) >+{ >+ if (isMapWriteable()) { >+ ASSERT(m_mapping); >+ >+ // FIXME: memset(m_mapping->data(), 0, m_mapping->byteLength())? This often happens in the middle of shader execution. >+ resolveMappingPromise(WTFMove(promise)); >+ } else { >+ promise.reject(); >+ LOG(WebGPU, "GPUBuffer::mapWriteAsync(): Invalid operation!"); >+ } >+} >+ >+void GPUBuffer::unmap() >+{ >+ if (isMappable()) >+ m_isMapped = false; >+} >+ > } // namespace WebCore > > #endif // ENABLE(WEBGPU) >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index c9dbfb9f9ba6b6504022268303ce463c16d91545..c1d9b756a909952864a7e630d5b676a1f41287de 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,13 @@ >+2019-02-14 Justin Fan <justin_fan@apple.com> >+ >+ [WebGPU] (WIP) Buffer updates part 1: async mapping functions, unmap, and destroy >+ https://bugs.webkit.org/show_bug.cgi?id=194665 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * webgpu/buffer-resource-triangles.html: >+ * webgpu/buffers.html: >+ > 2019-02-12 Justin Fan <justin_fan@apple.com> > > [WebGPU] Remove WebGPUBufferDescriptor/Usage and use GPU versions >diff --git a/LayoutTests/webgpu/buffer-resource-triangles.html b/LayoutTests/webgpu/buffer-resource-triangles.html >index 0f3a1473df1105dda9075a870986829e560fe74b..b4a2855a65d06f0c187acd26c2a82f2d8f2cb8ad 100644 >--- a/LayoutTests/webgpu/buffer-resource-triangles.html >+++ b/LayoutTests/webgpu/buffer-resource-triangles.html >@@ -79,34 +79,33 @@ function createUniformBufferBindGroupLayout(bindNum, stage = WebGPUShaderStageBi > > const vertexSize = 4 * 4; > const verticesBufferSize = vertexSize * 3; >+function createAndUploadVerticesBuffer(device, promises) { >+ const buffer = device.createBuffer({ size:verticesBufferSize, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE }); >+ >+ const promise = buffer.mapWriteAsync().then(mapping => { >+ const mappedArray = new Float32Array(mapping); >+ mappedArray.set([ >+ 0, 1, 0, 1, >+ -1, -1, 0, 1, >+ 1, -1, 0, 1 >+ ]); >+ buffer.unmap(); >+ }); > >-// FIXME: Keep up to date with buffer upload decisions. >-function createVerticesBuffer(device) { >- const buffer = device.createBuffer({ size:verticesBufferSize, usage: GPUBufferUsage.VERTEX }); >- >- const vertices = [ >- 0, 1, 0, 1, >- -1, -1, 0, 1, >- 1, -1, 0, 1 >- ]; >- >- const mappedArray = new Float32Array(buffer.mapping); >- mappedArray.set(vertices); >- >+ promises.push(promise); > return buffer; > } > >-function createFloat4Buffer(device, a, b) { >- const buffer = device.createBuffer({ size: vertexSize, usage: GPUBufferUsage.UNIFORM }); >- >- const arrayBuffer = buffer.mapping; >- const floatArray = new Float32Array(arrayBuffer); >+function createFloat4Buffer(device, a, b, promises) { >+ const buffer = device.createBuffer({ size: vertexSize, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.MAP_WRITE }); > >- floatArray[0] = a; >- floatArray[1] = b; >- floatArray[2] = 0; >- floatArray[3] = 1; >+ const promise = buffer.mapWriteAsync().then(mapping => { >+ const mappedArray = new Float32Array(mapping); >+ mappedArray.set([a, b, 0, 1]); >+ buffer.unmap(); >+ }); > >+ promises.push(promise); > return buffer; > } > >@@ -126,16 +125,18 @@ async function test() { > const shaderModule = device.createShaderModule({ code: shaderCode }); > > // Create vertex data WebGPUBuffers. >- const verticesBuffer = createVerticesBuffer(device); >+ let bufferPromises = []; > >- const upperLeft = createFloat4Buffer(device, -1, 1); >- const upperMiddle = createFloat4Buffer(device, 0, 1); >- const upperRight = createFloat4Buffer(device, 1, 1); >- const lowerLeft = createFloat4Buffer(device, -1, -1); >- const lowerRight = createFloat4Buffer(device, 1, -1); >+ const verticesBuffer = createAndUploadVerticesBuffer(device, bufferPromises); >+ >+ const upperLeft = createFloat4Buffer(device, -1, 1, bufferPromises); >+ const upperMiddle = createFloat4Buffer(device, 0, 1, bufferPromises); >+ const upperRight = createFloat4Buffer(device, 1, 1, bufferPromises); >+ const lowerLeft = createFloat4Buffer(device, -1, -1, bufferPromises); >+ const lowerRight = createFloat4Buffer(device, 1, -1, bufferPromises); > > // Color data buffer. >- const green = createFloat4Buffer(device, 0, 1); >+ const green = createFloat4Buffer(device, 0, 1, bufferPromises); > > // Create vertex input state. > const inputState = { >@@ -195,21 +196,23 @@ async function test() { > bindings: [bgBindingUR, bgBindingUM, bgBindingLR] > }); > >- const commandBuffer = device.createCommandBuffer(); >- const passEncoder = beginBasicRenderPass(context, commandBuffer); >- passEncoder.setPipeline(pipeline); >- >- // Vertex data for upper triangles. >- passEncoder.setBindGroup(0, leftTriangleBG); >- passEncoder.setBindGroup(1, rightTriangleBG); >- // Lower triangle. >- passEncoder.setVertexBuffers(0, [verticesBuffer], [0]); >- passEncoder.draw(9, 1, 0, 0); >- >- const endCommandBuffer = passEncoder.endPass(); >- const queue = device.getQueue(); >- queue.submit([endCommandBuffer]); >- context.present(); >+ Promise.all(bufferPromises).then(() => { >+ const commandBuffer = device.createCommandBuffer(); >+ const passEncoder = beginBasicRenderPass(context, commandBuffer); >+ passEncoder.setPipeline(pipeline); >+ >+ // Vertex data for upper triangles. >+ passEncoder.setBindGroup(0, leftTriangleBG); >+ passEncoder.setBindGroup(1, rightTriangleBG); >+ // Lower triangle. >+ passEncoder.setVertexBuffers(0, [verticesBuffer], [0]); >+ passEncoder.draw(9, 1, 0, 0); >+ >+ const endCommandBuffer = passEncoder.endPass(); >+ const queue = device.getQueue(); >+ queue.submit([endCommandBuffer]); >+ context.present(); >+ }); > } > > test(); >diff --git a/LayoutTests/webgpu/buffers.html b/LayoutTests/webgpu/buffers.html >index 6f70f4bbd733052fdb99618ee15da71d1966f6f6..005c94da459974dd67478b88395ae85e498ab788 100644 >--- a/LayoutTests/webgpu/buffers.html >+++ b/LayoutTests/webgpu/buffers.html >@@ -7,24 +7,48 @@ > <script src="../resources/js-test-pre.js"></script> > <script src="js/basic-webgpu-functions.js"></script> > <script> >-function createBuffer() { >+function mapWriteBuffer() { > const buffer = defaultDevice.createBuffer({ size: 16, usage: GPUBufferUsage.MAP_WRITE }); > assert_true(buffer instanceof WebGPUBuffer, "createBuffer returned a WebGPUBuffer"); > >- let arrayBuffer = buffer.mapping; >- let floatArray = new Float32Array(arrayBuffer); >- assert_equals(floatArray.length, 4); >+ // should queue pending promise to resolve after task boundary >+ buffer.mapWriteAsync().then(arrayBuffer => { >+ // buffer is now 'mapped' >+ let array = new Float32Array(arrayBuffer); >+ array.set([1, 2, 3, 4]); >+ }).catch(() => { >+ console.log("rejected"); // If line 42 is uncommented, should go here >+ }); > >- floatArray[0] = -1; >- floatArray[1] = 1; >- floatArray[2] = 0; >- floatArray[3] = 1; >+ buffer.unmap(); // should do nothing >+ >+ // should queue another pending promise, since the first one has not yet resolved >+ buffer.mapWriteAsync().then(arrayBuffer => { >+ console.log("resolved!"); >+ }) >+ .catch(() => { >+ // should go here >+ console.log("also rejected"); >+ buffer.unmap(); >+ >+ buffer.mapWriteAsync().then(arrayBuffer => { >+ let array = new Float32Array(arrayBuffer); >+ assert_true(array[0] == 0, "mapWriteAsync zeroed out storage"); >+ >+ buffer.destroy(); >+ }).catch(() => { >+ console.log("rejected again"); >+ }); >+ }); >+ >+ // What happens if you call this here? >+ buffer.destroy(); > } > > promise_test(async t => { > const canvas = document.createElement("canvas"); > await setUpContexts(canvas); >- createBuffer(); >+ mapWriteBuffer(); > }, "createBuffer() on WebGPUDevice."); > > </script> >diff --git a/LayoutTests/webgpu/depth-enabled-triangle-strip.html b/LayoutTests/webgpu/depth-enabled-triangle-strip.html >index 03e6a72f571715101c522a7b70e6b9adf947dc0f..fe6936587f4746cb9e82bb34b6bb794773854ce1 100644 >--- a/LayoutTests/webgpu/depth-enabled-triangle-strip.html >+++ b/LayoutTests/webgpu/depth-enabled-triangle-strip.html >@@ -44,21 +44,22 @@ fragment float4 fragment_main(VertexOut v [[stage_in]]) > } > ` > >-function createVertexBuffer(device) { >+async function createVertexBuffer(device) { > const bufferSize = 4 * 4 * 4; >- const buffer = device.createBuffer({ size: bufferSize, usage: GPUBufferUsage.MAP_WRITE }); >+ const buffer = device.createBuffer({ size: bufferSize, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE }); > > let floatArray = new Float32Array(buffer.mapping); >- >- const vertices = [ >- // float4 xyzw >- -1, 1, 0, 1, >- -1, -1, 0, 1, >- 1, 1, 0, 1, >- 1, -1, 0, 1 >- ]; >- >- floatArray.set(vertices); >+ buffer.mapWriteAsync().then(mapping => { >+ let mappedArray = new Float32Array(mapping); >+ mappedArray.set([ >+ // float4 xyzw >+ -1, 1, 0, 1, >+ -1, -1, 0, 1, >+ 1, 1, 0, 1, >+ 1, -1, 0, 1 >+ ]); >+ buffer.unmap(); >+ }); > > return buffer; > } >@@ -86,7 +87,7 @@ async function test() { > const context = createBasicContext(canvas, device); > // FIXME: Replace with non-MSL shaders. > const shaderModule = device.createShaderModule({ code: shaderCode }); >- const vertexBuffer = createVertexBuffer(device); >+ const vertexBuffer = await createVertexBuffer(device); > const inputStateDescriptor = createInputStateDescriptor(); > const depthStateDescriptor = createBasicDepthStateDescriptor(); > const pipeline = createBasicPipeline(shaderModule, device, null, inputStateDescriptor, depthStateDescriptor); >diff --git a/LayoutTests/webgpu/vertex-buffer-triangle-strip.html b/LayoutTests/webgpu/vertex-buffer-triangle-strip.html >index 86f923f49520a6775e36785edaec14c3cb9f7cb7..5090ad808f40aa6ac1b616f166fb1dd07e698f43 100644 >--- a/LayoutTests/webgpu/vertex-buffer-triangle-strip.html >+++ b/LayoutTests/webgpu/vertex-buffer-triangle-strip.html >@@ -38,23 +38,21 @@ fragment float4 fragment_main(VertexOut v [[stage_in]]) > } > ` > >-function createVertexBuffer(device) { >+async function createVertexBuffer(device) { > const bufferSize = 4 * 5 * 4; >- const buffer = device.createBuffer({ size: bufferSize, usage: GPUBufferUsage.MAP_WRITE }); >+ const buffer = device.createBuffer({ size: bufferSize, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE }); > >- let floatArray = new Float32Array(buffer.mapping); >- >- const vertices = [ >- // float4 xyzw, float g >- -1, 1, 0, 1, 1, >- -1, -1, 0, 1, 1, >- 1, 1, 0, 1, 1, >- 1, -1, 0, 1, 1 >- ]; >- >- for (let i = 0; i < vertices.length; ++i) { >- floatArray[i] = vertices[i]; >- } >+ buffer.mapWriteAsync().then(mapping => { >+ let mappedArray = new Float32Array(mapping); >+ mappedArray.set([ >+ // float4 xyzw, float g >+ -1, 1, 0, 1, 1, >+ -1, -1, 0, 1, 1, >+ 1, 1, 0, 1, 1, >+ 1, -1, 0, 1, 1 >+ ]); >+ buffer.unmap(); >+ }); > > return buffer; > } >@@ -87,7 +85,7 @@ async function test() { > const context = createBasicContext(canvas, device); > // FIXME: Replace with non-MSL shaders. > const shaderModule = device.createShaderModule({ code: shaderCode }); >- const vertexBuffer = createVertexBuffer(device); >+ const vertexBuffer = await createVertexBuffer(device); > const inputStateDescriptor = createInputStateDescriptor(); > const pipeline = createBasicPipeline(shaderModule, device, null, inputStateDescriptor); > const commandBuffer = device.createCommandBuffer();
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 194665
:
362052
|
362062
|
362185
|
362187
|
362189
|
362198
|
362572
|
362667
|
362786
|
362792
|
362836