CommandAllocator: Default initalize allocated data.

BUG=dawn:21

Change-Id: I98499385d7397ab431e1bbe00add7ef01941cca6
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/7160
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn_native/CommandAllocator.h b/src/dawn_native/CommandAllocator.h
index ecede3c..504ba7a 100644
--- a/src/dawn_native/CommandAllocator.h
+++ b/src/dawn_native/CommandAllocator.h
@@ -113,14 +113,26 @@
             static_assert(sizeof(E) == sizeof(uint32_t), "");
             static_assert(alignof(E) == alignof(uint32_t), "");
             static_assert(alignof(T) <= kMaxSupportedAlignment, "");
-            return reinterpret_cast<T*>(
+            T* result = reinterpret_cast<T*>(
                 Allocate(static_cast<uint32_t>(commandId), sizeof(T), alignof(T)));
+            if (!result) {
+                return nullptr;
+            }
+            new (result) T;
+            return result;
         }
 
         template <typename T>
         T* AllocateData(size_t count) {
             static_assert(alignof(T) <= kMaxSupportedAlignment, "");
-            return reinterpret_cast<T*>(AllocateData(sizeof(T) * count, alignof(T)));
+            T* result = reinterpret_cast<T*>(AllocateData(sizeof(T) * count, alignof(T)));
+            if (!result) {
+                return nullptr;
+            }
+            for (size_t i = 0; i < count; i++) {
+                new (result + i) T;
+            }
+            return result;
         }
 
       private:
diff --git a/src/dawn_native/CommandEncoder.cpp b/src/dawn_native/CommandEncoder.cpp
index 7b50777..cc13ec2 100644
--- a/src/dawn_native/CommandEncoder.cpp
+++ b/src/dawn_native/CommandEncoder.cpp
@@ -643,7 +643,6 @@
         mEncodingState = EncodingState::RenderPass;
 
         BeginRenderPassCmd* cmd = mAllocator.Allocate<BeginRenderPassCmd>(Command::BeginRenderPass);
-        new (cmd) BeginRenderPassCmd;
 
         for (uint32_t i = 0; i < info->colorAttachmentCount; ++i) {
             if (info->colorAttachments[i] != nullptr) {
@@ -695,7 +694,6 @@
 
         CopyBufferToBufferCmd* copy =
             mAllocator.Allocate<CopyBufferToBufferCmd>(Command::CopyBufferToBuffer);
-        new (copy) CopyBufferToBufferCmd;
         copy->source.buffer = source;
         copy->source.offset = sourceOffset;
         copy->destination.buffer = destination;
@@ -720,7 +718,6 @@
 
         CopyBufferToTextureCmd* copy =
             mAllocator.Allocate<CopyBufferToTextureCmd>(Command::CopyBufferToTexture);
-        new (copy) CopyBufferToTextureCmd;
         copy->source.buffer = source->buffer;
         copy->source.offset = source->offset;
         copy->destination.texture = destination->texture;
@@ -757,7 +754,6 @@
 
         CopyTextureToBufferCmd* copy =
             mAllocator.Allocate<CopyTextureToBufferCmd>(Command::CopyTextureToBuffer);
-        new (copy) CopyTextureToBufferCmd;
         copy->source.texture = source->texture;
         copy->source.origin = source->origin;
         copy->copySize = *copySize;
@@ -794,7 +790,6 @@
 
         CopyTextureToTextureCmd* copy =
             mAllocator.Allocate<CopyTextureToTextureCmd>(Command::CopyTextureToTexture);
-        new (copy) CopyTextureToTextureCmd;
         copy->source.texture = source->texture;
         copy->source.origin = source->origin;
         copy->source.level = source->level;
diff --git a/src/dawn_native/ComputePassEncoder.cpp b/src/dawn_native/ComputePassEncoder.cpp
index 406a656..1217b92 100644
--- a/src/dawn_native/ComputePassEncoder.cpp
+++ b/src/dawn_native/ComputePassEncoder.cpp
@@ -44,7 +44,6 @@
         }
 
         DispatchCmd* dispatch = mAllocator->Allocate<DispatchCmd>(Command::Dispatch);
-        new (dispatch) DispatchCmd;
         dispatch->x = x;
         dispatch->y = y;
         dispatch->z = z;
@@ -58,7 +57,6 @@
 
         SetComputePipelineCmd* cmd =
             mAllocator->Allocate<SetComputePipelineCmd>(Command::SetComputePipeline);
-        new (cmd) SetComputePipelineCmd;
         cmd->pipeline = pipeline;
     }
 
diff --git a/src/dawn_native/ProgrammablePassEncoder.cpp b/src/dawn_native/ProgrammablePassEncoder.cpp
index 3c2b53a..bf9c451 100644
--- a/src/dawn_native/ProgrammablePassEncoder.cpp
+++ b/src/dawn_native/ProgrammablePassEncoder.cpp
@@ -53,7 +53,6 @@
 
         InsertDebugMarkerCmd* cmd =
             mAllocator->Allocate<InsertDebugMarkerCmd>(Command::InsertDebugMarker);
-        new (cmd) InsertDebugMarkerCmd;
         cmd->length = strlen(groupLabel);
 
         char* label = mAllocator->AllocateData<char>(cmd->length + 1);
@@ -65,8 +64,7 @@
             return;
         }
 
-        PopDebugGroupCmd* cmd = mAllocator->Allocate<PopDebugGroupCmd>(Command::PopDebugGroup);
-        new (cmd) PopDebugGroupCmd;
+        mAllocator->Allocate<PopDebugGroupCmd>(Command::PopDebugGroup);
     }
 
     void ProgrammablePassEncoder::PushDebugGroup(const char* groupLabel) {
@@ -75,7 +73,6 @@
         }
 
         PushDebugGroupCmd* cmd = mAllocator->Allocate<PushDebugGroupCmd>(Command::PushDebugGroup);
-        new (cmd) PushDebugGroupCmd;
         cmd->length = strlen(groupLabel);
 
         char* label = mAllocator->AllocateData<char>(cmd->length + 1);
@@ -103,7 +100,6 @@
         }
 
         SetBindGroupCmd* cmd = mAllocator->Allocate<SetBindGroupCmd>(Command::SetBindGroup);
-        new (cmd) SetBindGroupCmd;
         cmd->index = groupIndex;
         cmd->group = group;
     }
@@ -128,7 +124,6 @@
 
         SetPushConstantsCmd* cmd =
             mAllocator->Allocate<SetPushConstantsCmd>(Command::SetPushConstants);
-        new (cmd) SetPushConstantsCmd;
         cmd->stages = stages;
         cmd->offset = offset;
         cmd->count = count;
diff --git a/src/dawn_native/RenderPassEncoder.cpp b/src/dawn_native/RenderPassEncoder.cpp
index 7470063..c83666b 100644
--- a/src/dawn_native/RenderPassEncoder.cpp
+++ b/src/dawn_native/RenderPassEncoder.cpp
@@ -50,7 +50,6 @@
         }
 
         DrawCmd* draw = mAllocator->Allocate<DrawCmd>(Command::Draw);
-        new (draw) DrawCmd;
         draw->vertexCount = vertexCount;
         draw->instanceCount = instanceCount;
         draw->firstVertex = firstVertex;
@@ -67,7 +66,6 @@
         }
 
         DrawIndexedCmd* draw = mAllocator->Allocate<DrawIndexedCmd>(Command::DrawIndexed);
-        new (draw) DrawIndexedCmd;
         draw->indexCount = indexCount;
         draw->instanceCount = instanceCount;
         draw->firstIndex = firstIndex;
@@ -83,7 +81,6 @@
 
         SetRenderPipelineCmd* cmd =
             mAllocator->Allocate<SetRenderPipelineCmd>(Command::SetRenderPipeline);
-        new (cmd) SetRenderPipelineCmd;
         cmd->pipeline = pipeline;
     }
 
@@ -94,7 +91,6 @@
 
         SetStencilReferenceCmd* cmd =
             mAllocator->Allocate<SetStencilReferenceCmd>(Command::SetStencilReference);
-        new (cmd) SetStencilReferenceCmd;
         cmd->reference = reference;
     }
 
@@ -104,7 +100,6 @@
         }
 
         SetBlendColorCmd* cmd = mAllocator->Allocate<SetBlendColorCmd>(Command::SetBlendColor);
-        new (cmd) SetBlendColorCmd;
         cmd->color = *color;
     }
 
@@ -121,7 +116,6 @@
         }
 
         SetScissorRectCmd* cmd = mAllocator->Allocate<SetScissorRectCmd>(Command::SetScissorRect);
-        new (cmd) SetScissorRectCmd;
         cmd->x = x;
         cmd->y = y;
         cmd->width = width;
@@ -135,7 +129,6 @@
         }
 
         SetIndexBufferCmd* cmd = mAllocator->Allocate<SetIndexBufferCmd>(Command::SetIndexBuffer);
-        new (cmd) SetIndexBufferCmd;
         cmd->buffer = buffer;
         cmd->offset = offset;
     }
@@ -156,13 +149,12 @@
 
         SetVertexBuffersCmd* cmd =
             mAllocator->Allocate<SetVertexBuffersCmd>(Command::SetVertexBuffers);
-        new (cmd) SetVertexBuffersCmd;
         cmd->startSlot = startSlot;
         cmd->count = count;
 
         Ref<BufferBase>* cmdBuffers = mAllocator->AllocateData<Ref<BufferBase>>(count);
         for (size_t i = 0; i < count; ++i) {
-            new (&cmdBuffers[i]) Ref<BufferBase>(buffers[i]);
+            cmdBuffers[i] = buffers[i];
         }
 
         uint64_t* cmdOffsets = mAllocator->AllocateData<uint64_t>(count);
diff --git a/src/tests/unittests/CommandAllocatorTests.cpp b/src/tests/unittests/CommandAllocatorTests.cpp
index 8e8b7a7..206261f 100644
--- a/src/tests/unittests/CommandAllocatorTests.cpp
+++ b/src/tests/unittests/CommandAllocatorTests.cpp
@@ -401,3 +401,48 @@
         allocator.AllocateData<AlignedStruct<8>>(std::numeric_limits<size_t>::max() / 8);
     ASSERT_EQ(data, nullptr);
 }
+
+template <int DefaultValue>
+struct IntWithDefault {
+    IntWithDefault() : value(DefaultValue) {
+    }
+
+    int value;
+};
+
+// Test that the allcator correctly defaults initalizes data for Allocate
+TEST(CommandAllocator, AllocateDefaultInitializes) {
+    CommandAllocator allocator;
+
+    IntWithDefault<42>* int42 = allocator.Allocate<IntWithDefault<42>>(CommandType::Draw);
+    ASSERT_EQ(int42->value, 42);
+
+    IntWithDefault<43>* int43 = allocator.Allocate<IntWithDefault<43>>(CommandType::Draw);
+    ASSERT_EQ(int43->value, 43);
+
+    IntWithDefault<44>* int44 = allocator.Allocate<IntWithDefault<44>>(CommandType::Draw);
+    ASSERT_EQ(int44->value, 44);
+
+    CommandIterator iterator(std::move(allocator));
+    iterator.DataWasDestroyed();
+}
+
+// Test that the allcator correctly defaults initalizes data for AllocateData
+TEST(CommandAllocator, AllocateDataDefaultInitializes) {
+    CommandAllocator allocator;
+
+    IntWithDefault<33>* int33 = allocator.AllocateData<IntWithDefault<33>>(1);
+    ASSERT_EQ(int33[0].value, 33);
+
+    IntWithDefault<34>* int34 = allocator.AllocateData<IntWithDefault<34>>(2);
+    ASSERT_EQ(int34[0].value, 34);
+    ASSERT_EQ(int34[0].value, 34);
+
+    IntWithDefault<35>* int35 = allocator.AllocateData<IntWithDefault<35>>(3);
+    ASSERT_EQ(int35[0].value, 35);
+    ASSERT_EQ(int35[1].value, 35);
+    ASSERT_EQ(int35[2].value, 35);
+
+    CommandIterator iterator(std::move(allocator));
+    iterator.DataWasDestroyed();
+}