node: Implement Compute/RenderPassTimestampWrites

Bug: dawn:1250
Change-Id: Iccd9123b3af7347d7586b998df5b11ab15608bb1
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/112424
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Ben Clayton <bclayton@google.com>
Reviewed-by: Austin Eng <enga@chromium.org>
diff --git a/src/dawn/node/binding/Converter.cpp b/src/dawn/node/binding/Converter.cpp
index f06a6af..6ec7778 100644
--- a/src/dawn/node/binding/Converter.cpp
+++ b/src/dawn/node/binding/Converter.cpp
@@ -16,6 +16,7 @@
 
 #include "src/dawn/node/binding/GPUBuffer.h"
 #include "src/dawn/node/binding/GPUPipelineLayout.h"
+#include "src/dawn/node/binding/GPUQuerySet.h"
 #include "src/dawn/node/binding/GPUSampler.h"
 #include "src/dawn/node/binding/GPUShaderModule.h"
 #include "src/dawn/node/binding/GPUTexture.h"
@@ -1297,6 +1298,30 @@
            Convert(out.stencilReadOnly, in.stencilReadOnly);
 }
 
+bool Converter::Convert(wgpu::RenderPassTimestampWrite& out,
+                        const interop::GPURenderPassTimestampWrite& in) {
+    out = {};
+    return Convert(out.querySet, in.querySet) &&      //
+           Convert(out.queryIndex, in.queryIndex) &&  //
+           Convert(out.location, in.location);
+}
+
+bool Converter::Convert(wgpu::RenderPassTimestampLocation& out,
+                        const interop::GPURenderPassTimestampLocation& in) {
+    out = wgpu::RenderPassTimestampLocation::Beginning;
+    switch (in) {
+        case interop::GPURenderPassTimestampLocation::kBeginning:
+            out = wgpu::RenderPassTimestampLocation::Beginning;
+            return true;
+        case interop::GPURenderPassTimestampLocation::kEnd:
+            out = wgpu::RenderPassTimestampLocation::End;
+            return true;
+    }
+    Napi::Error::New(env, "invalid value for GPURenderPassTimestampLocation")
+        .ThrowAsJavaScriptException();
+    return false;
+}
+
 bool Converter::Convert(wgpu::LoadOp& out, const interop::GPULoadOp& in) {
     out = wgpu::LoadOp::Clear;
     switch (in) {
@@ -1325,6 +1350,30 @@
     return false;
 }
 
+bool Converter::Convert(wgpu::ComputePassTimestampWrite& out,
+                        const interop::GPUComputePassTimestampWrite& in) {
+    out = {};
+    return Convert(out.querySet, in.querySet) &&      //
+           Convert(out.queryIndex, in.queryIndex) &&  //
+           Convert(out.location, in.location);
+}
+
+bool Converter::Convert(wgpu::ComputePassTimestampLocation& out,
+                        const interop::GPUComputePassTimestampLocation& in) {
+    out = wgpu::ComputePassTimestampLocation::Beginning;
+    switch (in) {
+        case interop::GPUComputePassTimestampLocation::kBeginning:
+            out = wgpu::ComputePassTimestampLocation::Beginning;
+            return true;
+        case interop::GPUComputePassTimestampLocation::kEnd:
+            out = wgpu::ComputePassTimestampLocation::End;
+            return true;
+    }
+    Napi::Error::New(env, "invalid value for GPUComputePassTimestampLocation")
+        .ThrowAsJavaScriptException();
+    return false;
+}
+
 bool Converter::Convert(wgpu::BindGroupEntry& out, const interop::GPUBindGroupEntry& in) {
     out = {};
     if (!Convert(out.binding, in.binding)) {
diff --git a/src/dawn/node/binding/Converter.h b/src/dawn/node/binding/Converter.h
index 0c8a232..452cc2e 100644
--- a/src/dawn/node/binding/Converter.h
+++ b/src/dawn/node/binding/Converter.h
@@ -196,10 +196,22 @@
     [[nodiscard]] bool Convert(wgpu::RenderPassDepthStencilAttachment& out,
                                const interop::GPURenderPassDepthStencilAttachment& in);
 
+    [[nodiscard]] bool Convert(wgpu::RenderPassTimestampWrite& out,
+                               const interop::GPURenderPassTimestampWrite& in);
+
+    [[nodiscard]] bool Convert(wgpu::RenderPassTimestampLocation& out,
+                               const interop::GPURenderPassTimestampLocation& in);
+
     [[nodiscard]] bool Convert(wgpu::LoadOp& out, const interop::GPULoadOp& in);
 
     [[nodiscard]] bool Convert(wgpu::StoreOp& out, const interop::GPUStoreOp& in);
 
+    [[nodiscard]] bool Convert(wgpu::ComputePassTimestampWrite& out,
+                               const interop::GPUComputePassTimestampWrite& in);
+
+    [[nodiscard]] bool Convert(wgpu::ComputePassTimestampLocation& out,
+                               const interop::GPUComputePassTimestampLocation& in);
+
     [[nodiscard]] bool Convert(wgpu::BindGroupEntry& out, const interop::GPUBindGroupEntry& in);
 
     [[nodiscard]] bool Convert(wgpu::BindGroupLayoutEntry& out,
diff --git a/src/dawn/node/binding/GPUCommandEncoder.cpp b/src/dawn/node/binding/GPUCommandEncoder.cpp
index fcc9dce..e5ffa14 100644
--- a/src/dawn/node/binding/GPUCommandEncoder.cpp
+++ b/src/dawn/node/binding/GPUCommandEncoder.cpp
@@ -42,11 +42,11 @@
     wgpu::RenderPassDescriptorMaxDrawCount maxDrawCountDesc{};
     desc.nextInChain = &maxDrawCountDesc;
 
-    // TODO(dawn:1250) handle timestampWrites
     if (!conv(desc.colorAttachments, desc.colorAttachmentCount, descriptor.colorAttachments) ||
         !conv(desc.depthStencilAttachment, descriptor.depthStencilAttachment) ||
         !conv(desc.label, descriptor.label) ||
         !conv(desc.occlusionQuerySet, descriptor.occlusionQuerySet) ||
+        !conv(desc.timestampWrites, desc.timestampWriteCount, descriptor.timestampWrites) ||
         !conv(maxDrawCountDesc.maxDrawCount, descriptor.maxDrawCount)) {
         return {};
     }
@@ -58,8 +58,13 @@
 interop::Interface<interop::GPUComputePassEncoder> GPUCommandEncoder::beginComputePass(
     Napi::Env env,
     interop::GPUComputePassDescriptor descriptor) {
+    Converter conv(env);
+
     wgpu::ComputePassDescriptor desc{};
-    // TODO(dawn:1250) handle timestampWrites
+    if (!conv(desc.timestampWrites, desc.timestampWriteCount, descriptor.timestampWrites)) {
+        return {};
+    }
+
     return interop::GPUComputePassEncoder::Create<GPUComputePassEncoder>(
         env, enc_.BeginComputePass(&desc));
 }