blob: 21d5aaf80a3948cdefb5429e26d587df505bf72e [file] [log] [blame]
Austin Eng11982702019-02-14 18:47:07 +00001// Copyright 2019 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 "tests/unittests/wire/WireTest.h"
16
17#include "common/Constants.h"
18
Corentin Wallez8dfc5932019-05-29 13:16:06 +000019#include <array>
20
Austin Eng11982702019-02-14 18:47:07 +000021using namespace testing;
22using namespace dawn_wire;
23
24class WireArgumentTests : public WireTest {
25 public:
Corentin Wallez0ae00a12019-03-28 17:12:47 +000026 WireArgumentTests() {
Austin Eng11982702019-02-14 18:47:07 +000027 }
28 ~WireArgumentTests() override = default;
29};
30
31// Test that the wire is able to send numerical values
32TEST_F(WireArgumentTests, ValueArgument) {
Corentin Wallez45b51f52019-10-28 22:15:47 +000033 WGPUCommandEncoder encoder = wgpuDeviceCreateCommandEncoder(device, nullptr);
34 WGPUComputePassEncoder pass = wgpuCommandEncoderBeginComputePass(encoder, nullptr);
35 wgpuComputePassEncoderDispatch(pass, 1, 2, 3);
Austin Eng11982702019-02-14 18:47:07 +000036
Corentin Wallez45b51f52019-10-28 22:15:47 +000037 WGPUCommandEncoder apiEncoder = api.GetNewCommandEncoder();
Corentin Wallez4b90c472019-07-10 20:43:13 +000038 EXPECT_CALL(api, DeviceCreateCommandEncoder(apiDevice, nullptr)).WillOnce(Return(apiEncoder));
Austin Eng11982702019-02-14 18:47:07 +000039
Corentin Wallez45b51f52019-10-28 22:15:47 +000040 WGPUComputePassEncoder apiPass = api.GetNewComputePassEncoder();
Corentin Wallez4b90c472019-07-10 20:43:13 +000041 EXPECT_CALL(api, CommandEncoderBeginComputePass(apiEncoder, nullptr)).WillOnce(Return(apiPass));
Austin Eng11982702019-02-14 18:47:07 +000042
43 EXPECT_CALL(api, ComputePassEncoderDispatch(apiPass, 1, 2, 3)).Times(1);
44
Austin Eng11982702019-02-14 18:47:07 +000045 FlushClient();
46}
47
48// Test that the wire is able to send arrays of numerical values
Austin Eng11982702019-02-14 18:47:07 +000049TEST_F(WireArgumentTests, ValueArrayArgument) {
Corentin Wallez8dfc5932019-05-29 13:16:06 +000050 // Create a bindgroup.
Austin Eng3ded65e2020-02-28 22:29:15 +000051 WGPUBindGroupLayoutDescriptor bglDescriptor = {};
Corentin Wallez8dfc5932019-05-29 13:16:06 +000052 bglDescriptor.bindingCount = 0;
53 bglDescriptor.bindings = nullptr;
54
Corentin Wallez45b51f52019-10-28 22:15:47 +000055 WGPUBindGroupLayout bgl = wgpuDeviceCreateBindGroupLayout(device, &bglDescriptor);
56 WGPUBindGroupLayout apiBgl = api.GetNewBindGroupLayout();
Corentin Wallez8dfc5932019-05-29 13:16:06 +000057 EXPECT_CALL(api, DeviceCreateBindGroupLayout(apiDevice, _)).WillOnce(Return(apiBgl));
58
Austin Eng3ded65e2020-02-28 22:29:15 +000059 WGPUBindGroupDescriptor bindGroupDescriptor = {};
Corentin Wallez8dfc5932019-05-29 13:16:06 +000060 bindGroupDescriptor.layout = bgl;
61 bindGroupDescriptor.bindingCount = 0;
62 bindGroupDescriptor.bindings = nullptr;
63
Corentin Wallez45b51f52019-10-28 22:15:47 +000064 WGPUBindGroup bindGroup = wgpuDeviceCreateBindGroup(device, &bindGroupDescriptor);
65 WGPUBindGroup apiBindGroup = api.GetNewBindGroup();
Corentin Wallez8dfc5932019-05-29 13:16:06 +000066 EXPECT_CALL(api, DeviceCreateBindGroup(apiDevice, _)).WillOnce(Return(apiBindGroup));
67
68 // Use the bindgroup in SetBindGroup that takes an array of value offsets.
Corentin Wallez45b51f52019-10-28 22:15:47 +000069 WGPUCommandEncoder encoder = wgpuDeviceCreateCommandEncoder(device, nullptr);
70 WGPUComputePassEncoder pass = wgpuCommandEncoderBeginComputePass(encoder, nullptr);
Corentin Wallez8dfc5932019-05-29 13:16:06 +000071
Austin Eng314fd352019-11-01 15:51:01 +000072 std::array<uint32_t, 4> testOffsets = {0, 42, 0xDEAD'BEEFu, 0xFFFF'FFFFu};
Corentin Wallez45b51f52019-10-28 22:15:47 +000073 wgpuComputePassEncoderSetBindGroup(pass, 0, bindGroup, testOffsets.size(), testOffsets.data());
Austin Eng11982702019-02-14 18:47:07 +000074
Corentin Wallez45b51f52019-10-28 22:15:47 +000075 WGPUCommandEncoder apiEncoder = api.GetNewCommandEncoder();
Corentin Wallez4b90c472019-07-10 20:43:13 +000076 EXPECT_CALL(api, DeviceCreateCommandEncoder(apiDevice, nullptr)).WillOnce(Return(apiEncoder));
Austin Eng11982702019-02-14 18:47:07 +000077
Corentin Wallez45b51f52019-10-28 22:15:47 +000078 WGPUComputePassEncoder apiPass = api.GetNewComputePassEncoder();
Corentin Wallez4b90c472019-07-10 20:43:13 +000079 EXPECT_CALL(api, CommandEncoderBeginComputePass(apiEncoder, nullptr)).WillOnce(Return(apiPass));
Austin Eng11982702019-02-14 18:47:07 +000080
Corentin Wallez8dfc5932019-05-29 13:16:06 +000081 EXPECT_CALL(api, ComputePassEncoderSetBindGroup(
82 apiPass, 0, apiBindGroup, testOffsets.size(),
Austin Eng314fd352019-11-01 15:51:01 +000083 MatchesLambda([testOffsets](const uint32_t* offsets) -> bool {
Corentin Wallez8dfc5932019-05-29 13:16:06 +000084 for (size_t i = 0; i < testOffsets.size(); i++) {
85 if (offsets[i] != testOffsets[i]) {
86 return false;
87 }
88 }
89 return true;
90 })));
Austin Eng11982702019-02-14 18:47:07 +000091
92 FlushClient();
93}
94
95// Test that the wire is able to send C strings
96TEST_F(WireArgumentTests, CStringArgument) {
97 // Create shader module
Austin Eng3ded65e2020-02-28 22:29:15 +000098 WGPUShaderModuleDescriptor vertexDescriptor = {};
Austin Eng11982702019-02-14 18:47:07 +000099 vertexDescriptor.codeSize = 0;
Corentin Wallez45b51f52019-10-28 22:15:47 +0000100 WGPUShaderModule vsModule = wgpuDeviceCreateShaderModule(device, &vertexDescriptor);
101 WGPUShaderModule apiVsModule = api.GetNewShaderModule();
Austin Eng11982702019-02-14 18:47:07 +0000102 EXPECT_CALL(api, DeviceCreateShaderModule(apiDevice, _)).WillOnce(Return(apiVsModule));
103
Yunchao He108bcbd2019-02-15 02:20:57 +0000104 // Create the color state descriptor
Austin Eng3ded65e2020-02-28 22:29:15 +0000105 WGPUBlendDescriptor blendDescriptor = {};
Corentin Wallez45b51f52019-10-28 22:15:47 +0000106 blendDescriptor.operation = WGPUBlendOperation_Add;
107 blendDescriptor.srcFactor = WGPUBlendFactor_One;
108 blendDescriptor.dstFactor = WGPUBlendFactor_One;
Austin Eng3ded65e2020-02-28 22:29:15 +0000109 WGPUColorStateDescriptor colorStateDescriptor = {};
Corentin Wallez45b51f52019-10-28 22:15:47 +0000110 colorStateDescriptor.format = WGPUTextureFormat_RGBA8Unorm;
Yunchao He108bcbd2019-02-15 02:20:57 +0000111 colorStateDescriptor.alphaBlend = blendDescriptor;
112 colorStateDescriptor.colorBlend = blendDescriptor;
Corentin Wallez45b51f52019-10-28 22:15:47 +0000113 colorStateDescriptor.writeMask = WGPUColorWriteMask_All;
Austin Eng11982702019-02-14 18:47:07 +0000114
115 // Create the input state
Austin Eng3ded65e2020-02-28 22:29:15 +0000116 WGPUVertexStateDescriptor vertexState = {};
Kai Ninomiyaae1f25f2019-11-07 22:23:29 +0000117 vertexState.indexFormat = WGPUIndexFormat_Uint32;
118 vertexState.vertexBufferCount = 0;
119 vertexState.vertexBuffers = nullptr;
Austin Eng11982702019-02-14 18:47:07 +0000120
Yunchao Hec33a8c12019-04-11 18:46:54 +0000121 // Create the rasterization state
Austin Eng3ded65e2020-02-28 22:29:15 +0000122 WGPURasterizationStateDescriptor rasterizationState = {};
Corentin Wallez45b51f52019-10-28 22:15:47 +0000123 rasterizationState.frontFace = WGPUFrontFace_CCW;
124 rasterizationState.cullMode = WGPUCullMode_None;
Yunchao Hec33a8c12019-04-11 18:46:54 +0000125 rasterizationState.depthBias = 0;
126 rasterizationState.depthBiasSlopeScale = 0.0;
127 rasterizationState.depthBiasClamp = 0.0;
128
Austin Eng11982702019-02-14 18:47:07 +0000129 // Create the depth-stencil state
Austin Eng3ded65e2020-02-28 22:29:15 +0000130 WGPUStencilStateFaceDescriptor stencilFace = {};
Corentin Wallez45b51f52019-10-28 22:15:47 +0000131 stencilFace.compare = WGPUCompareFunction_Always;
132 stencilFace.failOp = WGPUStencilOperation_Keep;
133 stencilFace.depthFailOp = WGPUStencilOperation_Keep;
134 stencilFace.passOp = WGPUStencilOperation_Keep;
Austin Eng11982702019-02-14 18:47:07 +0000135
Austin Eng3ded65e2020-02-28 22:29:15 +0000136 WGPUDepthStencilStateDescriptor depthStencilState = {};
Corentin Wallez45b51f52019-10-28 22:15:47 +0000137 depthStencilState.format = WGPUTextureFormat_Depth24PlusStencil8;
Austin Eng11982702019-02-14 18:47:07 +0000138 depthStencilState.depthWriteEnabled = false;
Corentin Wallez45b51f52019-10-28 22:15:47 +0000139 depthStencilState.depthCompare = WGPUCompareFunction_Always;
Austin Eng11982702019-02-14 18:47:07 +0000140 depthStencilState.stencilBack = stencilFace;
141 depthStencilState.stencilFront = stencilFace;
142 depthStencilState.stencilReadMask = 0xff;
143 depthStencilState.stencilWriteMask = 0xff;
144
145 // Create the pipeline layout
Austin Eng3ded65e2020-02-28 22:29:15 +0000146 WGPUPipelineLayoutDescriptor layoutDescriptor = {};
Jiawei Shao20301662019-02-21 00:45:19 +0000147 layoutDescriptor.bindGroupLayoutCount = 0;
Austin Eng11982702019-02-14 18:47:07 +0000148 layoutDescriptor.bindGroupLayouts = nullptr;
Corentin Wallez45b51f52019-10-28 22:15:47 +0000149 WGPUPipelineLayout layout = wgpuDeviceCreatePipelineLayout(device, &layoutDescriptor);
150 WGPUPipelineLayout apiLayout = api.GetNewPipelineLayout();
Austin Eng11982702019-02-14 18:47:07 +0000151 EXPECT_CALL(api, DeviceCreatePipelineLayout(apiDevice, _)).WillOnce(Return(apiLayout));
152
153 // Create pipeline
Austin Eng3ded65e2020-02-28 22:29:15 +0000154 WGPURenderPipelineDescriptor pipelineDescriptor = {};
Austin Eng11982702019-02-14 18:47:07 +0000155
Corentin Wallezc6c7a422019-09-05 09:35:07 +0000156 pipelineDescriptor.vertexStage.module = vsModule;
157 pipelineDescriptor.vertexStage.entryPoint = "main";
Austin Eng11982702019-02-14 18:47:07 +0000158
Austin Eng3ded65e2020-02-28 22:29:15 +0000159 WGPUProgrammableStageDescriptor fragmentStage = {};
Austin Eng11982702019-02-14 18:47:07 +0000160 fragmentStage.module = vsModule;
161 fragmentStage.entryPoint = "main";
162 pipelineDescriptor.fragmentStage = &fragmentStage;
163
Jiawei Shao20301662019-02-21 00:45:19 +0000164 pipelineDescriptor.colorStateCount = 1;
Corentin Wallezc81a7172019-09-20 23:22:27 +0000165 pipelineDescriptor.colorStates = &colorStateDescriptor;
Austin Eng11982702019-02-14 18:47:07 +0000166
167 pipelineDescriptor.sampleCount = 1;
Corentin Wallezf07e85c2019-07-15 20:47:56 +0000168 pipelineDescriptor.sampleMask = 0xFFFFFFFF;
169 pipelineDescriptor.alphaToCoverageEnabled = false;
Austin Eng11982702019-02-14 18:47:07 +0000170 pipelineDescriptor.layout = layout;
Kai Ninomiyaae1f25f2019-11-07 22:23:29 +0000171 pipelineDescriptor.vertexState = &vertexState;
Corentin Wallez45b51f52019-10-28 22:15:47 +0000172 pipelineDescriptor.primitiveTopology = WGPUPrimitiveTopology_TriangleList;
Yunchao Hec33a8c12019-04-11 18:46:54 +0000173 pipelineDescriptor.rasterizationState = &rasterizationState;
Austin Eng11982702019-02-14 18:47:07 +0000174 pipelineDescriptor.depthStencilState = &depthStencilState;
175
Corentin Wallez45b51f52019-10-28 22:15:47 +0000176 wgpuDeviceCreateRenderPipeline(device, &pipelineDescriptor);
Corentin Wallezcb2c64f2019-04-01 21:04:17 +0000177
Corentin Wallez45b51f52019-10-28 22:15:47 +0000178 WGPURenderPipeline apiDummyPipeline = api.GetNewRenderPipeline();
Austin Eng11982702019-02-14 18:47:07 +0000179 EXPECT_CALL(api,
180 DeviceCreateRenderPipeline(
Corentin Wallez45b51f52019-10-28 22:15:47 +0000181 apiDevice, MatchesLambda([](const WGPURenderPipelineDescriptor* desc) -> bool {
Corentin Wallezc6c7a422019-09-05 09:35:07 +0000182 return desc->vertexStage.entryPoint == std::string("main");
Austin Eng11982702019-02-14 18:47:07 +0000183 })))
Corentin Wallezcb2c64f2019-04-01 21:04:17 +0000184 .WillOnce(Return(apiDummyPipeline));
Austin Eng11982702019-02-14 18:47:07 +0000185
186 FlushClient();
187}
188
Jiawei Shaob2c50232019-02-27 09:21:56 +0000189
Austin Eng11982702019-02-14 18:47:07 +0000190// Test that the wire is able to send objects as value arguments
191TEST_F(WireArgumentTests, ObjectAsValueArgument) {
Corentin Wallez45b51f52019-10-28 22:15:47 +0000192 WGPUCommandEncoder cmdBufEncoder = wgpuDeviceCreateCommandEncoder(device, nullptr);
193 WGPUCommandEncoder apiEncoder = api.GetNewCommandEncoder();
Corentin Wallez4b90c472019-07-10 20:43:13 +0000194 EXPECT_CALL(api, DeviceCreateCommandEncoder(apiDevice, nullptr)).WillOnce(Return(apiEncoder));
Austin Eng11982702019-02-14 18:47:07 +0000195
Austin Eng3ded65e2020-02-28 22:29:15 +0000196 WGPUBufferDescriptor descriptor = {};
Jiawei Shaob2c50232019-02-27 09:21:56 +0000197 descriptor.size = 8;
Corentin Wallez9e9e29f2019-08-27 08:21:39 +0000198 descriptor.usage =
Corentin Wallez45b51f52019-10-28 22:15:47 +0000199 static_cast<WGPUBufferUsage>(WGPUBufferUsage_CopySrc | WGPUBufferUsage_CopyDst);
Austin Eng11982702019-02-14 18:47:07 +0000200
Corentin Wallez45b51f52019-10-28 22:15:47 +0000201 WGPUBuffer buffer = wgpuDeviceCreateBuffer(device, &descriptor);
202 WGPUBuffer apiBuffer = api.GetNewBuffer();
Jiawei Shaob2c50232019-02-27 09:21:56 +0000203 EXPECT_CALL(api, DeviceCreateBuffer(apiDevice, _))
204 .WillOnce(Return(apiBuffer))
205 .RetiresOnSaturation();
Austin Eng11982702019-02-14 18:47:07 +0000206
Corentin Wallez45b51f52019-10-28 22:15:47 +0000207 wgpuCommandEncoderCopyBufferToBuffer(cmdBufEncoder, buffer, 0, buffer, 4, 4);
Jiawei Shaob2c50232019-02-27 09:21:56 +0000208 EXPECT_CALL(api, CommandEncoderCopyBufferToBuffer(apiEncoder, apiBuffer, 0, apiBuffer, 4, 4));
209
Austin Eng11982702019-02-14 18:47:07 +0000210 FlushClient();
211}
212
213// Test that the wire is able to send array of objects
214TEST_F(WireArgumentTests, ObjectsAsPointerArgument) {
Corentin Wallez45b51f52019-10-28 22:15:47 +0000215 WGPUCommandBuffer cmdBufs[2];
216 WGPUCommandBuffer apiCmdBufs[2];
Austin Eng11982702019-02-14 18:47:07 +0000217
218 // Create two command buffers we need to use a GMock sequence otherwise the order of the
Corentin Wallez37b715d2019-02-18 09:42:03 +0000219 // CreateCommandEncoder might be swapped since they are equivalent in term of matchers
Austin Eng11982702019-02-14 18:47:07 +0000220 Sequence s;
221 for (int i = 0; i < 2; ++i) {
Corentin Wallez45b51f52019-10-28 22:15:47 +0000222 WGPUCommandEncoder cmdBufEncoder = wgpuDeviceCreateCommandEncoder(device, nullptr);
223 cmdBufs[i] = wgpuCommandEncoderFinish(cmdBufEncoder, nullptr);
Austin Eng11982702019-02-14 18:47:07 +0000224
Corentin Wallez45b51f52019-10-28 22:15:47 +0000225 WGPUCommandEncoder apiCmdBufEncoder = api.GetNewCommandEncoder();
Corentin Wallez4b90c472019-07-10 20:43:13 +0000226 EXPECT_CALL(api, DeviceCreateCommandEncoder(apiDevice, nullptr))
Austin Eng11982702019-02-14 18:47:07 +0000227 .InSequence(s)
Corentin Wallez37b715d2019-02-18 09:42:03 +0000228 .WillOnce(Return(apiCmdBufEncoder));
Austin Eng11982702019-02-14 18:47:07 +0000229
230 apiCmdBufs[i] = api.GetNewCommandBuffer();
Corentin Wallez4b90c472019-07-10 20:43:13 +0000231 EXPECT_CALL(api, CommandEncoderFinish(apiCmdBufEncoder, nullptr))
Austin Eng11982702019-02-14 18:47:07 +0000232 .WillOnce(Return(apiCmdBufs[i]));
Austin Eng11982702019-02-14 18:47:07 +0000233 }
234
235 // Create queue
Corentin Wallez45b51f52019-10-28 22:15:47 +0000236 WGPUQueue queue = wgpuDeviceCreateQueue(device);
237 WGPUQueue apiQueue = api.GetNewQueue();
Austin Eng11982702019-02-14 18:47:07 +0000238 EXPECT_CALL(api, DeviceCreateQueue(apiDevice)).WillOnce(Return(apiQueue));
239
240 // Submit command buffer and check we got a call with both API-side command buffers
Corentin Wallez45b51f52019-10-28 22:15:47 +0000241 wgpuQueueSubmit(queue, 2, cmdBufs);
Austin Eng11982702019-02-14 18:47:07 +0000242
243 EXPECT_CALL(
Corentin Wallez45b51f52019-10-28 22:15:47 +0000244 api, QueueSubmit(apiQueue, 2, MatchesLambda([=](const WGPUCommandBuffer* cmdBufs) -> bool {
Austin Eng11982702019-02-14 18:47:07 +0000245 return cmdBufs[0] == apiCmdBufs[0] && cmdBufs[1] == apiCmdBufs[1];
246 })));
247
Austin Eng11982702019-02-14 18:47:07 +0000248 FlushClient();
249}
250
251// Test that the wire is able to send structures that contain pure values (non-objects)
252TEST_F(WireArgumentTests, StructureOfValuesArgument) {
Austin Eng3ded65e2020-02-28 22:29:15 +0000253 WGPUSamplerDescriptor descriptor = {};
Corentin Wallez45b51f52019-10-28 22:15:47 +0000254 descriptor.magFilter = WGPUFilterMode_Linear;
255 descriptor.minFilter = WGPUFilterMode_Nearest;
256 descriptor.mipmapFilter = WGPUFilterMode_Linear;
257 descriptor.addressModeU = WGPUAddressMode_ClampToEdge;
258 descriptor.addressModeV = WGPUAddressMode_Repeat;
259 descriptor.addressModeW = WGPUAddressMode_MirrorRepeat;
Austin Eng11982702019-02-14 18:47:07 +0000260 descriptor.lodMinClamp = kLodMin;
261 descriptor.lodMaxClamp = kLodMax;
Corentin Wallez45b51f52019-10-28 22:15:47 +0000262 descriptor.compare = WGPUCompareFunction_Never;
Austin Eng11982702019-02-14 18:47:07 +0000263
Corentin Wallez45b51f52019-10-28 22:15:47 +0000264 wgpuDeviceCreateSampler(device, &descriptor);
Corentin Wallezcb2c64f2019-04-01 21:04:17 +0000265
Corentin Wallez45b51f52019-10-28 22:15:47 +0000266 WGPUSampler apiDummySampler = api.GetNewSampler();
Austin Eng11982702019-02-14 18:47:07 +0000267 EXPECT_CALL(api, DeviceCreateSampler(
Corentin Wallez45b51f52019-10-28 22:15:47 +0000268 apiDevice, MatchesLambda([](const WGPUSamplerDescriptor* desc) -> bool {
Austin Eng11982702019-02-14 18:47:07 +0000269 return desc->nextInChain == nullptr &&
Corentin Wallez45b51f52019-10-28 22:15:47 +0000270 desc->magFilter == WGPUFilterMode_Linear &&
271 desc->minFilter == WGPUFilterMode_Nearest &&
272 desc->mipmapFilter == WGPUFilterMode_Linear &&
273 desc->addressModeU == WGPUAddressMode_ClampToEdge &&
274 desc->addressModeV == WGPUAddressMode_Repeat &&
275 desc->addressModeW == WGPUAddressMode_MirrorRepeat &&
276 desc->compare == WGPUCompareFunction_Never &&
Austin Eng11982702019-02-14 18:47:07 +0000277 desc->lodMinClamp == kLodMin && desc->lodMaxClamp == kLodMax;
278 })))
Corentin Wallezcb2c64f2019-04-01 21:04:17 +0000279 .WillOnce(Return(apiDummySampler));
Austin Eng11982702019-02-14 18:47:07 +0000280
281 FlushClient();
282}
283
284// Test that the wire is able to send structures that contain objects
285TEST_F(WireArgumentTests, StructureOfObjectArrayArgument) {
Austin Eng3ded65e2020-02-28 22:29:15 +0000286 WGPUBindGroupLayoutDescriptor bglDescriptor = {};
Jiawei Shao20301662019-02-21 00:45:19 +0000287 bglDescriptor.bindingCount = 0;
Austin Eng11982702019-02-14 18:47:07 +0000288 bglDescriptor.bindings = nullptr;
289
Corentin Wallez45b51f52019-10-28 22:15:47 +0000290 WGPUBindGroupLayout bgl = wgpuDeviceCreateBindGroupLayout(device, &bglDescriptor);
291 WGPUBindGroupLayout apiBgl = api.GetNewBindGroupLayout();
Austin Eng11982702019-02-14 18:47:07 +0000292 EXPECT_CALL(api, DeviceCreateBindGroupLayout(apiDevice, _)).WillOnce(Return(apiBgl));
293
Austin Eng3ded65e2020-02-28 22:29:15 +0000294 WGPUPipelineLayoutDescriptor descriptor = {};
Jiawei Shao20301662019-02-21 00:45:19 +0000295 descriptor.bindGroupLayoutCount = 1;
Austin Eng11982702019-02-14 18:47:07 +0000296 descriptor.bindGroupLayouts = &bgl;
297
Corentin Wallez45b51f52019-10-28 22:15:47 +0000298 wgpuDeviceCreatePipelineLayout(device, &descriptor);
Corentin Wallezcb2c64f2019-04-01 21:04:17 +0000299
Corentin Wallez45b51f52019-10-28 22:15:47 +0000300 WGPUPipelineLayout apiDummyLayout = api.GetNewPipelineLayout();
Austin Eng11982702019-02-14 18:47:07 +0000301 EXPECT_CALL(api, DeviceCreatePipelineLayout(
302 apiDevice,
Corentin Wallez45b51f52019-10-28 22:15:47 +0000303 MatchesLambda([apiBgl](const WGPUPipelineLayoutDescriptor* desc) -> bool {
Austin Eng11982702019-02-14 18:47:07 +0000304 return desc->nextInChain == nullptr &&
Jiawei Shao20301662019-02-21 00:45:19 +0000305 desc->bindGroupLayoutCount == 1 &&
Austin Eng11982702019-02-14 18:47:07 +0000306 desc->bindGroupLayouts[0] == apiBgl;
307 })))
Corentin Wallezcb2c64f2019-04-01 21:04:17 +0000308 .WillOnce(Return(apiDummyLayout));
Austin Eng11982702019-02-14 18:47:07 +0000309
Austin Eng11982702019-02-14 18:47:07 +0000310 FlushClient();
311}
312
313// Test that the wire is able to send structures that contain objects
314TEST_F(WireArgumentTests, StructureOfStructureArrayArgument) {
315 static constexpr int NUM_BINDINGS = 3;
Corentin Wallez45b51f52019-10-28 22:15:47 +0000316 WGPUBindGroupLayoutBinding bindings[NUM_BINDINGS]{
317 {0, WGPUShaderStage_Vertex, WGPUBindingType_Sampler, false, false,
318 WGPUTextureViewDimension_2D, WGPUTextureComponentType_Float},
319 {1, WGPUShaderStage_Vertex, WGPUBindingType_SampledTexture, false, false,
320 WGPUTextureViewDimension_2D, WGPUTextureComponentType_Float},
321 {2, static_cast<WGPUShaderStage>(WGPUShaderStage_Vertex | WGPUShaderStage_Fragment),
322 WGPUBindingType_UniformBuffer, false, false, WGPUTextureViewDimension_2D,
323 WGPUTextureComponentType_Float},
Austin Eng11982702019-02-14 18:47:07 +0000324 };
Austin Eng3ded65e2020-02-28 22:29:15 +0000325 WGPUBindGroupLayoutDescriptor bglDescriptor = {};
Jiawei Shao20301662019-02-21 00:45:19 +0000326 bglDescriptor.bindingCount = NUM_BINDINGS;
Austin Eng11982702019-02-14 18:47:07 +0000327 bglDescriptor.bindings = bindings;
328
Corentin Wallez45b51f52019-10-28 22:15:47 +0000329 wgpuDeviceCreateBindGroupLayout(device, &bglDescriptor);
330 WGPUBindGroupLayout apiBgl = api.GetNewBindGroupLayout();
Austin Eng11982702019-02-14 18:47:07 +0000331 EXPECT_CALL(
332 api,
333 DeviceCreateBindGroupLayout(
Corentin Wallez45b51f52019-10-28 22:15:47 +0000334 apiDevice, MatchesLambda([bindings](const WGPUBindGroupLayoutDescriptor* desc) -> bool {
Austin Eng11982702019-02-14 18:47:07 +0000335 for (int i = 0; i < NUM_BINDINGS; ++i) {
336 const auto& a = desc->bindings[i];
337 const auto& b = bindings[i];
338 if (a.binding != b.binding || a.visibility != b.visibility ||
339 a.type != b.type) {
340 return false;
341 }
342 }
Jiawei Shao20301662019-02-21 00:45:19 +0000343 return desc->nextInChain == nullptr && desc->bindingCount == 3;
Austin Eng11982702019-02-14 18:47:07 +0000344 })))
345 .WillOnce(Return(apiBgl));
346
Austin Eng11982702019-02-14 18:47:07 +0000347 FlushClient();
348}
349
350// Test passing nullptr instead of objects - array of objects version
351TEST_F(WireArgumentTests, DISABLED_NullptrInArray) {
Corentin Wallez45b51f52019-10-28 22:15:47 +0000352 WGPUBindGroupLayout nullBGL = nullptr;
Austin Eng11982702019-02-14 18:47:07 +0000353
Austin Eng3ded65e2020-02-28 22:29:15 +0000354 WGPUPipelineLayoutDescriptor descriptor = {};
Jiawei Shao20301662019-02-21 00:45:19 +0000355 descriptor.bindGroupLayoutCount = 1;
Austin Eng11982702019-02-14 18:47:07 +0000356 descriptor.bindGroupLayouts = &nullBGL;
357
Corentin Wallez45b51f52019-10-28 22:15:47 +0000358 wgpuDeviceCreatePipelineLayout(device, &descriptor);
Austin Eng11982702019-02-14 18:47:07 +0000359 EXPECT_CALL(api,
360 DeviceCreatePipelineLayout(
Corentin Wallez45b51f52019-10-28 22:15:47 +0000361 apiDevice, MatchesLambda([](const WGPUPipelineLayoutDescriptor* desc) -> bool {
Jiawei Shao20301662019-02-21 00:45:19 +0000362 return desc->nextInChain == nullptr && desc->bindGroupLayoutCount == 1 &&
Austin Eng11982702019-02-14 18:47:07 +0000363 desc->bindGroupLayouts[0] == nullptr;
364 })))
365 .WillOnce(Return(nullptr));
366
367 FlushClient();
368}