Diff
Modified: trunk/LayoutTests/ChangeLog (249182 => 249183)
--- trunk/LayoutTests/ChangeLog 2019-08-27 22:43:06 UTC (rev 249182)
+++ trunk/LayoutTests/ChangeLog 2019-08-27 23:39:38 UTC (rev 249183)
@@ -1,3 +1,15 @@
+2019-08-27 Justin Fan <justin_...@apple.com>
+
+ [WebGPU] Implement GPUErrors for and relax GPUBuffer validation rules
+ https://bugs.webkit.org/show_bug.cgi?id=200852
+
+ Reviewed by Dean Jackson.
+
+ Add a test to ensure GPUBuffer errors are generated properly.
+
+ * webgpu/buffer-errors-expected.txt: Added.
+ * webgpu/buffer-errors.html: Added.
+
2019-08-27 Russell Epstein <repst...@apple.com>
Test Gardening for scrollingcoordinator/ios/scroll-position-after-reattach.html
Added: trunk/LayoutTests/webgpu/buffer-errors-expected.txt (0 => 249183)
--- trunk/LayoutTests/webgpu/buffer-errors-expected.txt (rev 0)
+++ trunk/LayoutTests/webgpu/buffer-errors-expected.txt 2019-08-27 23:39:38 UTC (rev 249183)
@@ -0,0 +1,13 @@
+
+PASS GPUBuffers can be created with both read-only and STORAGE usages.
+PASS unmap on already unmapped, mappable GPUBuffer should not generate error.
+PASS GPUBuffer created via createBufferMapped cannot be remapped.
+PASS GPUBufferDescriptor with both MAP_READ and MAP_WRITE usage should fail.
+PASS Too-large GPUBufferDescriptor size should fail with out-of-memory error.
+PASS mapReadAsync on non-MAP_READ GPUBuffer should fail.
+PASS mapWriteAsync on non-MAP_WRITE GPUBuffer should fail.
+PASS unmap on non-mappable GPUBuffer should fail.
+PASS createBufferMapped: non-4-byte-aligned GPUBufferDesriptor size should fail.
+PASS Any method call on an invalid GPUBuffer should fail.
+PASS Any method call on a destroyed GPUBuffer should fail.
+
Added: trunk/LayoutTests/webgpu/buffer-errors.html (0 => 249183)
--- trunk/LayoutTests/webgpu/buffer-errors.html (rev 0)
+++ trunk/LayoutTests/webgpu/buffer-errors.html 2019-08-27 23:39:38 UTC (rev 249183)
@@ -0,0 +1,158 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Test GPUBuffer Errors.</title>
+<body>
+<script src=""
+<script src=""
+<script src=""
+<script>
+let tests = {};
+
+tests["GPUBuffers can be created with both read-only and STORAGE usages."] = async device => {
+ device.pushErrorScope("validation");
+ device.createBuffer({
+ size: 4,
+ usage: GPUBufferUsage.VERTEX | GPUBufferUsage.INDEX | GPUBufferUsage.TRANSFER_SRC | GPUBufferUsage.UNIFORM | GPUBufferUsage.STORAGE
+ });
+ return popNullError(device);
+};
+
+tests["unmap on already unmapped, mappable GPUBuffer should not generate error."] = async device => {
+ const buffer = device.createBuffer({
+ size: 4,
+ usage: GPUBufferUsage.MAP_READ |
+ GPUBufferUsage.TRANSFER_SRC |
+ GPUBufferUsage.TRANSFER_DST |
+ GPUBufferUsage.VERTEX |
+ GPUBufferUsage.INDEX |
+ GPUBufferUsage.UNIFORM |
+ GPUBufferUsage.STORAGE
+ });
+
+ device.pushErrorScope("validation");
+ buffer.unmap();
+ return popNullError(device);
+};
+
+tests["GPUBuffer created via createBufferMapped cannot be remapped."] = async device => {
+ device.pushErrorScope("validation");
+ const [buffer, _] = device.createBufferMapped({ size: 4, usage: 0 });
+ // Should not fail.
+ buffer.unmap();
+ await popNullError(device);
+
+ device.pushErrorScope("validation");
+ // Should fail.
+ buffer.unmap();
+ await popValidationError(device);
+
+ device.pushErrorScope("validation");
+ // Should fail.
+ buffer.mapReadAsync().then(() => { assert_unreached(); }).catch(e => {});
+ return popValidationError(device);
+};
+
+tests["GPUBufferDescriptor with both MAP_READ and MAP_WRITE usage should fail."] = async device => {
+ device.pushErrorScope("validation");
+ device.createBuffer({ size: 4, usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.MAP_WRITE });
+ return popValidationError(device);
+};
+
+tests["Too-large GPUBufferDescriptor size should fail with out-of-memory error."] = async device => {
+ device.pushErrorScope("out-of-memory");
+ device.createBuffer({ size: 99999999999, usage: GPUBufferUsage.NONE });
+ return popMemoryError(device);
+};
+
+tests["mapReadAsync on non-MAP_READ GPUBuffer should fail."] = async device => {
+ const buffer = device.createBuffer({
+ size: 4,
+ usage: GPUBufferUsage.MAP_WRITE |
+ GPUBufferUsage.TRANSFER_SRC |
+ GPUBufferUsage.TRANSFER_DST |
+ GPUBufferUsage.VERTEX |
+ GPUBufferUsage.INDEX |
+ GPUBufferUsage.UNIFORM |
+ GPUBufferUsage.STORAGE
+ });
+
+ device.pushErrorScope("validation");
+ buffer.mapReadAsync().then(() => { assert_unreached(); }).catch(e => {});
+ return popValidationError(device);
+};
+
+tests["mapWriteAsync on non-MAP_WRITE GPUBuffer should fail."] = async device => {
+ const buffer = device.createBuffer({
+ size: 4,
+ usage: GPUBufferUsage.MAP_READ |
+ GPUBufferUsage.TRANSFER_SRC |
+ GPUBufferUsage.TRANSFER_DST |
+ GPUBufferUsage.VERTEX |
+ GPUBufferUsage.INDEX |
+ GPUBufferUsage.UNIFORM |
+ GPUBufferUsage.STORAGE
+ });
+
+ device.pushErrorScope("validation");
+ buffer.mapWriteAsync().then(() => { assert_unreached(); }).catch(e => {});
+ return popValidationError(device);
+};
+
+tests["unmap on non-mappable GPUBuffer should fail."] = async device => {
+ const buffer = device.createBuffer({
+ size: 4,
+ usage: GPUBufferUsage.TRANSFER_SRC |
+ GPUBufferUsage.TRANSFER_DST |
+ GPUBufferUsage.VERTEX |
+ GPUBufferUsage.INDEX |
+ GPUBufferUsage.UNIFORM |
+ GPUBufferUsage.STORAGE
+ });
+
+ device.pushErrorScope("validation");
+ buffer.unmap();
+ return popValidationError(device);
+};
+
+tests["createBufferMapped: non-4-byte-aligned GPUBufferDesriptor size should fail."] = async device => {
+ device.pushErrorScope("validation");
+ device.createBufferMapped({ size: 5, usage: 0 });
+ return popValidationError(device);
+};
+
+tests["Any method call on an invalid GPUBuffer should fail."] = async device => {
+ const buffer = device.createBuffer({ size: 4, usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.MAP_WRITE });
+ return assertAllBufferMethodsFail(device, buffer);
+};
+
+tests["Any method call on a destroyed GPUBuffer should fail."] = async device => {
+ const buffer = device.createBuffer({ size: 4, usage: GPUBufferUsage.MAP_READ });
+
+ device.pushErrorScope("validation");
+ buffer.destroy();
+ await popNullError(device);
+
+ return assertAllBufferMethodsFail(device, buffer);
+};
+
+const assertAllBufferMethodsFail = async (device, buffer) => {
+ device.pushErrorScope("validation");
+ buffer.mapReadAsync().then(() => { assert_unreached(); }).catch(e => {});
+ await popValidationError(device);
+
+ device.pushErrorScope("validation");
+ buffer.mapWriteAsync().then(() => { assert_unreached(); }).catch(e => {});
+ await popValidationError(device);
+
+ device.pushErrorScope("validation");
+ buffer.unmap();
+ await popValidationError(device);
+
+ device.pushErrorScope("validation");
+ buffer.destroy();
+ return popValidationError(device);
+};
+
+runTestsWithDevice(tests);
+</script>
+</body>
\ No newline at end of file
Modified: trunk/Source/WebCore/ChangeLog (249182 => 249183)
--- trunk/Source/WebCore/ChangeLog 2019-08-27 22:43:06 UTC (rev 249182)
+++ trunk/Source/WebCore/ChangeLog 2019-08-27 23:39:38 UTC (rev 249183)
@@ -1,3 +1,39 @@
+2019-08-27 Justin Fan <justin_...@apple.com>
+
+ [WebGPU] Implement GPUErrors for and relax GPUBuffer validation rules
+ https://bugs.webkit.org/show_bug.cgi?id=200852
+
+ Reviewed by Dean Jackson.
+
+ Fix incorrect usage validation during GPUBuffer creation.
+ Implement GPUError reporting for GPUBuffer creation and methods.
+
+ Test: webgpu/buffer-errors.html
+
+ * Modules/webgpu/WebGPUBuffer.cpp:
+ (WebCore::WebGPUBuffer::create):
+ (WebCore::WebGPUBuffer::WebGPUBuffer):
+ (WebCore::WebGPUBuffer::unmap):
+ (WebCore::WebGPUBuffer::destroy):
+ (WebCore::WebGPUBuffer::rejectOrRegisterPromiseCallback):
+ * Modules/webgpu/WebGPUBuffer.h: Now inherits from GPUObjectBase.
+ * Modules/webgpu/WebGPUDevice.cpp:
+ (WebCore::WebGPUDevice::createBuffer const):
+ (WebCore::WebGPUDevice::createBufferMapped const):
+ * platform/graphics/gpu/GPUBuffer.h: No longer inherits from GPUObjectBase.
+ * platform/graphics/gpu/GPUObjectBase.h:
+ (WebCore::GPUObjectBase::errorScopes):
+ (WebCore::GPUObjectBase::generateError): Deleted.
+ * platform/graphics/gpu/cocoa/GPUBufferMetal.mm:
+ (WebCore::GPUBuffer::validateBufferUsage):
+ (WebCore::GPUBuffer::tryCreate): Alignment issue should be general WebGPU requirement.
+ (WebCore::GPUBuffer::GPUBuffer):
+ (WebCore::GPUBuffer::~GPUBuffer): Must do cleanup without generating errors.
+ (WebCore::GPUBuffer::registerMappingCallback):
+ (WebCore::GPUBuffer::copyStagingBufferToGPU):
+ (WebCore::GPUBuffer::unmap):
+ (WebCore::GPUBuffer::destroy):
+
2019-08-27 Zalan Bujtas <za...@apple.com>
[LFC][TFC] Layout and position the cell boxes
Modified: trunk/Source/WebCore/Modules/webgpu/WebGPUBuffer.cpp (249182 => 249183)
--- trunk/Source/WebCore/Modules/webgpu/WebGPUBuffer.cpp 2019-08-27 22:43:06 UTC (rev 249182)
+++ trunk/Source/WebCore/Modules/webgpu/WebGPUBuffer.cpp 2019-08-27 23:39:38 UTC (rev 249183)
@@ -28,17 +28,19 @@
#if ENABLE(WEBGPU)
-#include "Logging.h"
+#include "GPUErrorScopes.h"
+#include <wtf/text/StringConcatenate.h>
namespace WebCore {
-Ref<WebGPUBuffer> WebGPUBuffer::create(RefPtr<GPUBuffer>&& buffer)
+Ref<WebGPUBuffer> WebGPUBuffer::create(RefPtr<GPUBuffer>&& buffer, GPUErrorScopes& errorScopes)
{
- return adoptRef(*new WebGPUBuffer(WTFMove(buffer)));
+ return adoptRef(*new WebGPUBuffer(WTFMove(buffer), errorScopes));
}
-WebGPUBuffer::WebGPUBuffer(RefPtr<GPUBuffer>&& buffer)
- : m_buffer(WTFMove(buffer))
+WebGPUBuffer::WebGPUBuffer(RefPtr<GPUBuffer>&& buffer, GPUErrorScopes& errorScopes)
+ : GPUObjectBase(makeRef(errorScopes))
+ , m_buffer(WTFMove(buffer))
{
}
@@ -54,18 +56,22 @@
void WebGPUBuffer::unmap()
{
+ errorScopes().setErrorPrefix("GPUBuffer.unmap(): ");
+
if (!m_buffer)
- LOG(WebGPU, "GPUBuffer::unmap(): Invalid operation!");
+ errorScopes().generatePrefixedError("Invalid operation: invalid GPUBuffer!");
else
- m_buffer->unmap();
+ m_buffer->unmap(&errorScopes());
}
void WebGPUBuffer::destroy()
{
+ errorScopes().setErrorPrefix("GPUBuffer.destroy(): ");
+
if (!m_buffer)
- LOG(WebGPU, "GPUBuffer::destroy(): Invalid operation!");
+ errorScopes().generatePrefixedError("Invalid operation!");
else {
- m_buffer->destroy();
+ m_buffer->destroy(&errorScopes());
m_buffer = nullptr;
}
}
@@ -72,18 +78,22 @@
void WebGPUBuffer::rejectOrRegisterPromiseCallback(BufferMappingPromise&& promise, bool isRead)
{
+ errorScopes().setErrorPrefix(makeString("GPUBuffer.map", isRead ? "Read" : "Write", "Async(): "));
+
if (!m_buffer) {
- LOG(WebGPU, "GPUBuffer::map%sAsync(): Invalid operation!", isRead ? "Read" : "Write");
+ errorScopes().generatePrefixedError("Invalid operation: invalid GPUBuffer!");
promise.reject();
return;
}
- m_buffer->registerMappingCallback([promise = WTFMove(promise)] (JSC::ArrayBuffer* arrayBuffer) mutable {
+ m_buffer->registerMappingCallback([promise = WTFMove(promise), protectedErrorScopes = makeRef(errorScopes())] (JSC::ArrayBuffer* arrayBuffer) mutable {
if (arrayBuffer)
promise.resolve(*arrayBuffer);
- else
+ else {
+ protectedErrorScopes->generateError("", GPUErrorFilter::OutOfMemory);
promise.reject();
- }, isRead);
+ }
+ }, isRead, errorScopes());
}
} // namespace WebCore
Modified: trunk/Source/WebCore/Modules/webgpu/WebGPUBuffer.h (249182 => 249183)
--- trunk/Source/WebCore/Modules/webgpu/WebGPUBuffer.h 2019-08-27 22:43:06 UTC (rev 249182)
+++ trunk/Source/WebCore/Modules/webgpu/WebGPUBuffer.h 2019-08-27 23:39:38 UTC (rev 249183)
@@ -29,8 +29,8 @@
#include "GPUBuffer.h"
#include "GPUBufferUsage.h"
+#include "GPUObjectBase.h"
#include "JSDOMPromiseDeferred.h"
-#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
namespace JSC {
@@ -41,9 +41,9 @@
struct GPUBufferDescriptor;
-class WebGPUBuffer : public RefCounted<WebGPUBuffer> {
+class WebGPUBuffer : public GPUObjectBase {
public:
- static Ref<WebGPUBuffer> create(RefPtr<GPUBuffer>&&);
+ static Ref<WebGPUBuffer> create(RefPtr<GPUBuffer>&&, GPUErrorScopes&);
GPUBuffer* buffer() { return m_buffer.get(); }
const GPUBuffer* buffer() const { return m_buffer.get(); }
@@ -55,7 +55,7 @@
void destroy();
private:
- explicit WebGPUBuffer(RefPtr<GPUBuffer>&&);
+ explicit WebGPUBuffer(RefPtr<GPUBuffer>&&, GPUErrorScopes&);
void rejectOrRegisterPromiseCallback(BufferMappingPromise&&, bool);
Modified: trunk/Source/WebCore/Modules/webgpu/WebGPUDevice.cpp (249182 => 249183)
--- trunk/Source/WebCore/Modules/webgpu/WebGPUDevice.cpp 2019-08-27 22:43:06 UTC (rev 249182)
+++ trunk/Source/WebCore/Modules/webgpu/WebGPUDevice.cpp 2019-08-27 23:39:38 UTC (rev 249183)
@@ -91,7 +91,7 @@
m_errorScopes->setErrorPrefix("GPUDevice.createBuffer(): ");
auto buffer = m_device->tryCreateBuffer(descriptor, GPUBufferMappedOption::NotMapped, m_errorScopes);
- return WebGPUBuffer::create(WTFMove(buffer));
+ return WebGPUBuffer::create(WTFMove(buffer), m_errorScopes);
}
Vector<JSC::JSValue> WebGPUDevice::createBufferMapped(JSC::ExecState& state, const GPUBufferDescriptor& descriptor) const
@@ -106,7 +106,7 @@
wrappedArrayBuffer = toJS(&state, JSC::jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject()), arrayBuffer);
}
- auto webBuffer = WebGPUBuffer::create(WTFMove(buffer));
+ auto webBuffer = WebGPUBuffer::create(WTFMove(buffer), m_errorScopes);
auto wrappedWebBuffer = toJS(&state, JSC::jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject()), webBuffer);
return { wrappedWebBuffer, wrappedArrayBuffer };
Modified: trunk/Source/WebCore/platform/graphics/gpu/GPUBuffer.h (249182 => 249183)
--- trunk/Source/WebCore/platform/graphics/gpu/GPUBuffer.h 2019-08-27 22:43:06 UTC (rev 249182)
+++ trunk/Source/WebCore/platform/graphics/gpu/GPUBuffer.h 2019-08-27 23:39:38 UTC (rev 249183)
@@ -29,7 +29,6 @@
#include "DeferrableTask.h"
#include "GPUBufferUsage.h"
-#include "GPUObjectBase.h"
#include <wtf/Function.h>
#include <wtf/OptionSet.h>
#include <wtf/Ref.h>
@@ -49,6 +48,7 @@
namespace WebCore {
class GPUDevice;
+class GPUErrorScopes;
struct GPUBufferDescriptor;
@@ -61,7 +61,7 @@
#endif
using PlatformBufferSmartPtr = RetainPtr<PlatformBuffer>;
-class GPUBuffer : public GPUObjectBase {
+class GPUBuffer : public RefCounted<GPUBuffer> {
public:
enum class State {
Mapped,
@@ -94,9 +94,9 @@
#endif
using MappingCallback = WTF::Function<void(JSC::ArrayBuffer*)>;
- void registerMappingCallback(MappingCallback&&, bool);
- void unmap();
- void destroy();
+ void registerMappingCallback(MappingCallback&&, bool, GPUErrorScopes&);
+ void unmap(GPUErrorScopes*);
+ void destroy(GPUErrorScopes*);
private:
struct PendingMappingCallback : public RefCounted<PendingMappingCallback> {
@@ -111,13 +111,13 @@
PendingMappingCallback(MappingCallback&&);
};
- GPUBuffer(PlatformBufferSmartPtr&&, GPUDevice&, size_t, OptionSet<GPUBufferUsage::Flags>, GPUBufferMappedOption, GPUErrorScopes&);
+ GPUBuffer(PlatformBufferSmartPtr&&, GPUDevice&, size_t, OptionSet<GPUBufferUsage::Flags>, GPUBufferMappedOption);
static bool validateBufferUsage(const GPUDevice&, OptionSet<GPUBufferUsage::Flags>, GPUErrorScopes&);
JSC::ArrayBuffer* stagingBufferForRead();
JSC::ArrayBuffer* stagingBufferForWrite();
void runMappingCallback();
- void copyStagingBufferToGPU();
+ void copyStagingBufferToGPU(GPUErrorScopes*);
bool isMapWrite() const { return m_usage.contains(GPUBufferUsage::Flags::MapWrite); }
bool isMapRead() const { return m_usage.contains(GPUBufferUsage::Flags::MapRead); }
Modified: trunk/Source/WebCore/platform/graphics/gpu/GPUObjectBase.h (249182 => 249183)
--- trunk/Source/WebCore/platform/graphics/gpu/GPUObjectBase.h 2019-08-27 22:43:06 UTC (rev 249182)
+++ trunk/Source/WebCore/platform/graphics/gpu/GPUObjectBase.h 2019-08-27 23:39:38 UTC (rev 249183)
@@ -33,16 +33,12 @@
namespace WebCore {
class GPUObjectBase : public RefCounted<GPUObjectBase> {
-public:
- void generateError(const String& message, GPUErrorFilter filter = GPUErrorFilter::Validation)
- {
- m_errorScopes->generateError(message, filter);
- }
-
protected:
GPUObjectBase(Ref<GPUErrorScopes>&& reporter)
: m_errorScopes(WTFMove(reporter)) { }
+ GPUErrorScopes& errorScopes() { return m_errorScopes; }
+
private:
Ref<GPUErrorScopes> m_errorScopes;
};
Modified: trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUBufferMetal.mm (249182 => 249183)
--- trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUBufferMetal.mm 2019-08-27 22:43:06 UTC (rev 249182)
+++ trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUBufferMetal.mm 2019-08-27 23:39:38 UTC (rev 249183)
@@ -30,7 +30,7 @@
#import "GPUBufferDescriptor.h"
#import "GPUDevice.h"
-#import "Logging.h"
+#import "GPUErrorScopes.h"
#import <_javascript_Core/ArrayBuffer.h>
#import <Metal/Metal.h>
#import <wtf/BlockObjCExceptions.h>
@@ -46,7 +46,7 @@
bool GPUBuffer::validateBufferUsage(const GPUDevice& device, OptionSet<GPUBufferUsage::Flags> usage, GPUErrorScopes& errorScopes)
{
if (!device.platformDevice()) {
- LOG(WebGPU, "GPUBuffer::tryCreate(): Invalid GPUDevice!");
+ errorScopes.generatePrefixedError("Invalid GPUDevice!");
return false;
}
@@ -55,11 +55,6 @@
return false;
}
- if (usage.containsAny(readOnlyFlags) && (usage & GPUBufferUsage::Flags::Storage)) {
- LOG(WebGPU, "GPUBuffer::tryCreate(): Buffer cannot have both STORAGE and a read-only usage!");
- return false;
- }
-
return true;
}
@@ -76,16 +71,14 @@
if (!validateBufferUsage(device, usage, errorScopes))
return nullptr;
-#if PLATFORM(MAC)
// copyBufferToBuffer calls require 4-byte alignment. "Unmapping" a mapped-on-creation GPUBuffer
// that is otherwise unmappable requires such a copy to upload data.
if (isMapped == GPUBufferMappedOption::IsMapped
&& !usage.containsAny({ GPUBufferUsage::Flags::MapWrite, GPUBufferUsage::Flags::MapRead })
&& descriptor.size % 4) {
- LOG(WebGPU, "GPUBuffer::tryCreate(): Data must be aligned to a multiple of 4 bytes!");
+ errorScopes.generatePrefixedError("Data must be aligned to a multiple of 4 bytes!");
return nullptr;
}
-#endif
// 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.
@@ -107,12 +100,11 @@
return nullptr;
}
- return adoptRef(*new GPUBuffer(WTFMove(mtlBuffer), device, size, usage, isMapped, errorScopes));
+ return adoptRef(*new GPUBuffer(WTFMove(mtlBuffer), device, size, usage, isMapped));
}
-GPUBuffer::GPUBuffer(RetainPtr<MTLBuffer>&& buffer, GPUDevice& device, size_t size, OptionSet<GPUBufferUsage::Flags> usage, GPUBufferMappedOption isMapped, GPUErrorScopes& errorScopes)
- : GPUObjectBase(makeRef(errorScopes))
- , m_platformBuffer(WTFMove(buffer))
+GPUBuffer::GPUBuffer(RetainPtr<MTLBuffer>&& buffer, GPUDevice& device, size_t size, OptionSet<GPUBufferUsage::Flags> usage, GPUBufferMappedOption isMapped)
+ : m_platformBuffer(WTFMove(buffer))
, m_device(makeRef(device))
, m_byteLength(size)
, m_usage(usage)
@@ -125,7 +117,7 @@
GPUBuffer::~GPUBuffer()
{
- destroy();
+ destroy(nullptr);
}
bool GPUBuffer::isReadOnly() const
@@ -177,16 +169,16 @@
}
#endif // USE(METAL)
-void GPUBuffer::registerMappingCallback(MappingCallback&& callback, bool isRead)
+void GPUBuffer::registerMappingCallback(MappingCallback&& callback, bool isRead, GPUErrorScopes& errorScopes)
{
// Reject if request is invalid.
if (isRead && !isMapReadable()) {
- LOG(WebGPU, "GPUBuffer::mapReadAsync(): Invalid operation!");
+ errorScopes.generatePrefixedError("Invalid operation!");
callback(nullptr);
return;
}
if (!isRead && !isMapWriteable()) {
- LOG(WebGPU, "GPUBuffer::mapWriteAsync(): Invalid operation!");
+ errorScopes.generatePrefixedError("Invalid operation!");
callback(nullptr);
return;
}
@@ -226,7 +218,7 @@
return m_stagingBuffer.get();
}
-void GPUBuffer::copyStagingBufferToGPU()
+void GPUBuffer::copyStagingBufferToGPU(GPUErrorScopes* errorScopes)
{
MTLCommandQueue *queue;
if (!m_device->tryGetQueue() || !(queue = m_device->tryGetQueue()->platformQueue()))
@@ -239,8 +231,8 @@
stagingMtlBuffer = adoptNS([m_device->platformDevice() newBufferWithLength:static_cast<NSUInteger>(m_byteLength) options:MTLResourceCPUCacheModeDefaultCache]);
END_BLOCK_OBJC_EXCEPTIONS;
- if (!stagingMtlBuffer) {
- LOG(WebGPU, "GPUBuffer::unmap(): Unable to create staging buffer!");
+ if (!stagingMtlBuffer && errorScopes) {
+ errorScopes->generateError("", GPUErrorFilter::OutOfMemory);
return;
}
@@ -258,10 +250,10 @@
END_BLOCK_OBJC_EXCEPTIONS;
}
-void GPUBuffer::unmap()
+void GPUBuffer::unmap(GPUErrorScopes* errorScopes)
{
- if (!m_isMappedFromCreation && !isMappable()) {
- LOG(WebGPU, "GPUBuffer::unmap(): Invalid operation: buffer is not mappable!");
+ if (!m_isMappedFromCreation && !isMappable() && errorScopes) {
+ errorScopes->generatePrefixedError("Invalid operation: GPUBuffer is not mappable!");
return;
}
@@ -271,7 +263,7 @@
ASSERT(m_platformBuffer && m_platformBuffer.get().contents);
memcpy(m_platformBuffer.get().contents, m_stagingBuffer->data(), m_byteLength);
} else if (m_isMappedFromCreation)
- copyStagingBufferToGPU();
+ copyStagingBufferToGPU(errorScopes);
m_isMappedFromCreation = false;
m_stagingBuffer = nullptr;
@@ -284,10 +276,10 @@
}
}
-void GPUBuffer::destroy()
+void GPUBuffer::destroy(GPUErrorScopes* errorScopes)
{
if (state() == State::Mapped)
- unmap();
+ unmap(errorScopes);
m_platformBuffer = nullptr;
}