1 // Copyright 2021 The Dawn Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "src/dawn_node/binding/GPUQueue.h" 16 17 #include <memory> 18 19 #include "src/dawn_node/binding/Converter.h" 20 #include "src/dawn_node/binding/GPUBuffer.h" 21 #include "src/dawn_node/binding/GPUCommandBuffer.h" 22 #include "src/dawn_node/utils/Debug.h" 23 24 namespace wgpu { namespace binding { 25 26 //////////////////////////////////////////////////////////////////////////////// 27 // wgpu::bindings::GPUQueue 28 //////////////////////////////////////////////////////////////////////////////// GPUQueue(wgpu::Queue queue,std::shared_ptr<AsyncRunner> async)29 GPUQueue::GPUQueue(wgpu::Queue queue, std::shared_ptr<AsyncRunner> async) 30 : queue_(std::move(queue)), async_(std::move(async)) { 31 } 32 submit(Napi::Env env,std::vector<interop::Interface<interop::GPUCommandBuffer>> commandBuffers)33 void GPUQueue::submit( 34 Napi::Env env, 35 std::vector<interop::Interface<interop::GPUCommandBuffer>> commandBuffers) { 36 std::vector<wgpu::CommandBuffer> bufs(commandBuffers.size()); 37 for (size_t i = 0; i < commandBuffers.size(); i++) { 38 bufs[i] = *commandBuffers[i].As<GPUCommandBuffer>(); 39 } 40 Converter conv(env); 41 uint32_t bufs_size; 42 if (!conv(bufs_size, bufs.size())) { 43 return; 44 } 45 queue_.Submit(bufs_size, bufs.data()); 46 } 47 onSubmittedWorkDone(Napi::Env env)48 interop::Promise<void> GPUQueue::onSubmittedWorkDone(Napi::Env env) { 49 struct Context { 50 Napi::Env env; 51 interop::Promise<void> promise; 52 AsyncTask task; 53 }; 54 auto ctx = new Context{env, interop::Promise<void>(env, PROMISE_INFO), async_}; 55 auto promise = ctx->promise; 56 57 queue_.OnSubmittedWorkDone( 58 0, 59 [](WGPUQueueWorkDoneStatus status, void* userdata) { 60 auto c = std::unique_ptr<Context>(static_cast<Context*>(userdata)); 61 if (status != WGPUQueueWorkDoneStatus::WGPUQueueWorkDoneStatus_Success) { 62 Napi::Error::New(c->env, "onSubmittedWorkDone() failed") 63 .ThrowAsJavaScriptException(); 64 } 65 c->promise.Resolve(); 66 }, 67 ctx); 68 69 return promise; 70 } 71 writeBuffer(Napi::Env env,interop::Interface<interop::GPUBuffer> buffer,interop::GPUSize64 bufferOffset,interop::BufferSource data,interop::GPUSize64 dataOffset,std::optional<interop::GPUSize64> size)72 void GPUQueue::writeBuffer(Napi::Env env, 73 interop::Interface<interop::GPUBuffer> buffer, 74 interop::GPUSize64 bufferOffset, 75 interop::BufferSource data, 76 interop::GPUSize64 dataOffset, 77 std::optional<interop::GPUSize64> size) { 78 wgpu::Buffer buf = *buffer.As<GPUBuffer>(); 79 Converter::BufferSource src{}; 80 Converter conv(env); 81 if (!conv(src, data)) { 82 return; 83 } 84 85 // TODO(crbug.com/dawn/1132): Bounds check 86 if (src.data) { 87 src.data = reinterpret_cast<uint8_t*>(src.data) + dataOffset; 88 } 89 src.size -= dataOffset; 90 if (size.has_value()) { 91 src.size = size.value(); 92 } 93 94 queue_.WriteBuffer(buf, bufferOffset, src.data, src.size); 95 } 96 writeTexture(Napi::Env env,interop::GPUImageCopyTexture destination,interop::BufferSource data,interop::GPUImageDataLayout dataLayout,interop::GPUExtent3D size)97 void GPUQueue::writeTexture(Napi::Env env, 98 interop::GPUImageCopyTexture destination, 99 interop::BufferSource data, 100 interop::GPUImageDataLayout dataLayout, 101 interop::GPUExtent3D size) { 102 wgpu::ImageCopyTexture dst{}; 103 Converter::BufferSource src{}; 104 wgpu::TextureDataLayout layout{}; 105 wgpu::Extent3D sz{}; 106 Converter conv(env); 107 if (!conv(dst, destination) || // 108 !conv(src, data) || // 109 !conv(layout, dataLayout) || // 110 !conv(sz, size)) { 111 return; 112 } 113 114 queue_.WriteTexture(&dst, src.data, src.size, &layout, &sz); 115 } 116 copyExternalImageToTexture(Napi::Env,interop::GPUImageCopyExternalImage source,interop::GPUImageCopyTextureTagged destination,interop::GPUExtent3D copySize)117 void GPUQueue::copyExternalImageToTexture(Napi::Env, 118 interop::GPUImageCopyExternalImage source, 119 interop::GPUImageCopyTextureTagged destination, 120 interop::GPUExtent3D copySize) { 121 UNIMPLEMENTED(); 122 } 123 getLabel(Napi::Env)124 std::optional<std::string> GPUQueue::getLabel(Napi::Env) { 125 UNIMPLEMENTED(); 126 } 127 setLabel(Napi::Env,std::optional<std::string> value)128 void GPUQueue::setLabel(Napi::Env, std::optional<std::string> value) { 129 UNIMPLEMENTED(); 130 } 131 132 }} // namespace wgpu::binding 133