blob: 93fcc66c21d210f29298ba990e2707c6ae338bf5 [file] [log] [blame] [edit]
/*
* Copyright (c) 2023 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. ``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
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <CoreFoundation/CoreFoundation.h>
#include <WebGPU/WebGPU.h>
#include <dispatch/dispatch.h>
#include <wtf/darwin/DispatchExtras.h>
#define UNUSED_PARAM(variable) (void)variable
int main()
{
WGPUInstanceCocoaDescriptor instanceCocoaDescriptor = {
{
NULL,
(WGPUSType)WGPUSTypeExtended_InstanceCocoaDescriptor,
},
^(WGPUWorkItem workItem)
{
dispatch_async(mainDispatchQueueSingleton(), workItem);
},
};
WGPUInstanceDescriptor instanceDescriptor = {
&instanceCocoaDescriptor.chain,
};
WGPUInstance instance = wgpuCreateInstance(&instanceDescriptor);
WGPURequestAdapterOptions requestAdapterOptions = {
NULL,
NULL,
WGPUPowerPreference_Undefined,
false,
};
// FIXME: Update this when adapter creation is actually asynchronous
__block WGPUAdapter adapter = NULL;
wgpuInstanceRequestAdapterWithBlock(instance, &requestAdapterOptions, ^(WGPURequestAdapterStatus status, WGPUAdapter localAdapter, const char* message) {
assert(status == WGPURequestAdapterStatus_Success);
UNUSED_PARAM(message);
adapter = localAdapter;
});
WGPUDeviceDescriptor deviceDescriptor = {
NULL,
NULL,
0,
NULL,
NULL,
};
// FIXME: Update this when device creation is actually asynchronous
__block WGPUDevice device = NULL;
wgpuAdapterRequestDeviceWithBlock(adapter, &deviceDescriptor, ^(WGPURequestDeviceStatus status, WGPUDevice localDevice, const char* message) {
assert(status == WGPURequestAdapterStatus_Success);
UNUSED_PARAM(message);
device = localDevice;
});
wgpuDevicePushErrorScope(device, WGPUErrorFilter_Validation);
WGPUBufferDescriptor uploadBufferDescriptor = {
NULL,
NULL,
WGPUBufferUsage_MapWrite | WGPUBufferUsage_CopySrc,
sizeof(int32_t),
false,
};
WGPUBuffer uploadBuffer = wgpuDeviceCreateBuffer(device, &uploadBufferDescriptor);
WGPUBufferDescriptor downloadBufferDescriptor = {
NULL,
NULL,
WGPUBufferUsage_MapRead | WGPUBufferUsage_CopyDst,
sizeof(int32_t),
false,
};
WGPUBuffer downloadBuffer = wgpuDeviceCreateBuffer(device, &downloadBufferDescriptor);
wgpuBufferMapAsyncWithBlock(uploadBuffer, WGPUMapMode_Write, 0, sizeof(int32_t), ^(WGPUBufferMapAsyncStatus status) {
assert(status == WGPUQueueWorkDoneStatus_Success);
int32_t * writePointer = wgpuBufferGetMappedRange(uploadBuffer, 0, sizeof(int32_t));
writePointer[0] = 17;
wgpuBufferUnmap(uploadBuffer);
WGPUCommandEncoderDescriptor commandEncoderDescriptor = {
NULL,
NULL,
};
WGPUCommandEncoder commandEncoder = wgpuDeviceCreateCommandEncoder(device, &commandEncoderDescriptor);
wgpuCommandEncoderCopyBufferToBuffer(commandEncoder, uploadBuffer, 0, downloadBuffer, 0, sizeof(uint32_t));
WGPUCommandBufferDescriptor commandBufferDescriptor = {
NULL,
NULL,
};
WGPUCommandBuffer commandBuffer = wgpuCommandEncoderFinish(commandEncoder, &commandBufferDescriptor);
WGPUCommandBuffer commands[] = { commandBuffer };
wgpuQueueSubmit(wgpuDeviceGetQueue(device), sizeof(commands) / sizeof(commands[0]), commands);
wgpuQueueOnSubmittedWorkDoneWithBlock(wgpuDeviceGetQueue(device), 0, ^(WGPUQueueWorkDoneStatus status) {
assert(status == WGPUQueueWorkDoneStatus_Success);
wgpuBufferMapAsyncWithBlock(downloadBuffer, WGPUMapMode_Read, 0, sizeof(int32_t), ^(WGPUBufferMapAsyncStatus status) {
assert(status == WGPUBufferMapAsyncStatus_Success);
int32_t * readPointer = wgpuBufferGetMappedRange(downloadBuffer, 0, sizeof(int32_t));
printf("Result: %" PRId32 "\n", readPointer[0]);
wgpuBufferUnmap(downloadBuffer);
wgpuDevicePopErrorScopeWithBlock(device, ^(WGPUErrorType type, const char* message) {
if (type != WGPUErrorType_NoError) {
if (message != nil)
printf("Message: %s\n", message);
else
printf("Empty message.\n");
} else
printf("Success!\n");
CFRunLoopStop(CFRunLoopGetMain());
wgpuCommandBufferRelease(commandBuffer);
wgpuCommandEncoderRelease(commandEncoder);
});
});
});
});
CFRunLoopRun();
wgpuBufferRelease(downloadBuffer);
wgpuBufferRelease(uploadBuffer);
wgpuDeviceRelease(device);
wgpuAdapterRelease(adapter);
wgpuInstanceRelease(instance);
return 0;
}