blob: 401f9b875be354bad63125789c095d7847ddfdfa [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 Wallez3966eb12020-04-21 07:36:30 +000052 bglDescriptor.entryCount = 0;
53 bglDescriptor.entries = nullptr;
Corentin Wallez8dfc5932019-05-29 13:16:06 +000054
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;
Corentin Wallez3966eb12020-04-21 07:36:30 +000061 bindGroupDescriptor.entryCount = 0;
62 bindGroupDescriptor.entries = nullptr;
Corentin Wallez8dfc5932019-05-29 13:16:06 +000063
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 = {};
Corentin Wallez45b51f52019-10-28 22:15:47 +000099 WGPUShaderModule vsModule = wgpuDeviceCreateShaderModule(device, &vertexDescriptor);
100 WGPUShaderModule apiVsModule = api.GetNewShaderModule();
Austin Eng11982702019-02-14 18:47:07 +0000101 EXPECT_CALL(api, DeviceCreateShaderModule(apiDevice, _)).WillOnce(Return(apiVsModule));
102
Yunchao He108bcbd2019-02-15 02:20:57 +0000103 // Create the color state descriptor
Austin Eng3ded65e2020-02-28 22:29:15 +0000104 WGPUBlendDescriptor blendDescriptor = {};
Corentin Wallez45b51f52019-10-28 22:15:47 +0000105 blendDescriptor.operation = WGPUBlendOperation_Add;
106 blendDescriptor.srcFactor = WGPUBlendFactor_One;
107 blendDescriptor.dstFactor = WGPUBlendFactor_One;
Austin Eng3ded65e2020-02-28 22:29:15 +0000108 WGPUColorStateDescriptor colorStateDescriptor = {};
Corentin Wallez45b51f52019-10-28 22:15:47 +0000109 colorStateDescriptor.format = WGPUTextureFormat_RGBA8Unorm;
Yunchao He108bcbd2019-02-15 02:20:57 +0000110 colorStateDescriptor.alphaBlend = blendDescriptor;
111 colorStateDescriptor.colorBlend = blendDescriptor;
Corentin Wallez45b51f52019-10-28 22:15:47 +0000112 colorStateDescriptor.writeMask = WGPUColorWriteMask_All;
Austin Eng11982702019-02-14 18:47:07 +0000113
114 // Create the input state
Austin Eng3ded65e2020-02-28 22:29:15 +0000115 WGPUVertexStateDescriptor vertexState = {};
Kai Ninomiyaae1f25f2019-11-07 22:23:29 +0000116 vertexState.indexFormat = WGPUIndexFormat_Uint32;
117 vertexState.vertexBufferCount = 0;
118 vertexState.vertexBuffers = nullptr;
Austin Eng11982702019-02-14 18:47:07 +0000119
Yunchao Hec33a8c12019-04-11 18:46:54 +0000120 // Create the rasterization state
Austin Eng3ded65e2020-02-28 22:29:15 +0000121 WGPURasterizationStateDescriptor rasterizationState = {};
Corentin Wallez45b51f52019-10-28 22:15:47 +0000122 rasterizationState.frontFace = WGPUFrontFace_CCW;
123 rasterizationState.cullMode = WGPUCullMode_None;
Yunchao Hec33a8c12019-04-11 18:46:54 +0000124 rasterizationState.depthBias = 0;
125 rasterizationState.depthBiasSlopeScale = 0.0;
126 rasterizationState.depthBiasClamp = 0.0;
127
Austin Eng11982702019-02-14 18:47:07 +0000128 // Create the depth-stencil state
Austin Eng3ded65e2020-02-28 22:29:15 +0000129 WGPUStencilStateFaceDescriptor stencilFace = {};
Corentin Wallez45b51f52019-10-28 22:15:47 +0000130 stencilFace.compare = WGPUCompareFunction_Always;
131 stencilFace.failOp = WGPUStencilOperation_Keep;
132 stencilFace.depthFailOp = WGPUStencilOperation_Keep;
133 stencilFace.passOp = WGPUStencilOperation_Keep;
Austin Eng11982702019-02-14 18:47:07 +0000134
Austin Eng3ded65e2020-02-28 22:29:15 +0000135 WGPUDepthStencilStateDescriptor depthStencilState = {};
Corentin Wallez45b51f52019-10-28 22:15:47 +0000136 depthStencilState.format = WGPUTextureFormat_Depth24PlusStencil8;
Austin Eng11982702019-02-14 18:47:07 +0000137 depthStencilState.depthWriteEnabled = false;
Corentin Wallez45b51f52019-10-28 22:15:47 +0000138 depthStencilState.depthCompare = WGPUCompareFunction_Always;
Austin Eng11982702019-02-14 18:47:07 +0000139 depthStencilState.stencilBack = stencilFace;
140 depthStencilState.stencilFront = stencilFace;
141 depthStencilState.stencilReadMask = 0xff;
142 depthStencilState.stencilWriteMask = 0xff;
143
144 // Create the pipeline layout
Austin Eng3ded65e2020-02-28 22:29:15 +0000145 WGPUPipelineLayoutDescriptor layoutDescriptor = {};
Jiawei Shao20301662019-02-21 00:45:19 +0000146 layoutDescriptor.bindGroupLayoutCount = 0;
Austin Eng11982702019-02-14 18:47:07 +0000147 layoutDescriptor.bindGroupLayouts = nullptr;
Corentin Wallez45b51f52019-10-28 22:15:47 +0000148 WGPUPipelineLayout layout = wgpuDeviceCreatePipelineLayout(device, &layoutDescriptor);
149 WGPUPipelineLayout apiLayout = api.GetNewPipelineLayout();
Austin Eng11982702019-02-14 18:47:07 +0000150 EXPECT_CALL(api, DeviceCreatePipelineLayout(apiDevice, _)).WillOnce(Return(apiLayout));
151
152 // Create pipeline
Austin Eng3ded65e2020-02-28 22:29:15 +0000153 WGPURenderPipelineDescriptor pipelineDescriptor = {};
Austin Eng11982702019-02-14 18:47:07 +0000154
Corentin Wallezc6c7a422019-09-05 09:35:07 +0000155 pipelineDescriptor.vertexStage.module = vsModule;
156 pipelineDescriptor.vertexStage.entryPoint = "main";
Austin Eng11982702019-02-14 18:47:07 +0000157
Austin Eng3ded65e2020-02-28 22:29:15 +0000158 WGPUProgrammableStageDescriptor fragmentStage = {};
Austin Eng11982702019-02-14 18:47:07 +0000159 fragmentStage.module = vsModule;
160 fragmentStage.entryPoint = "main";
161 pipelineDescriptor.fragmentStage = &fragmentStage;
162
Jiawei Shao20301662019-02-21 00:45:19 +0000163 pipelineDescriptor.colorStateCount = 1;
Corentin Wallezc81a7172019-09-20 23:22:27 +0000164 pipelineDescriptor.colorStates = &colorStateDescriptor;
Austin Eng11982702019-02-14 18:47:07 +0000165
166 pipelineDescriptor.sampleCount = 1;
Corentin Wallezf07e85c2019-07-15 20:47:56 +0000167 pipelineDescriptor.sampleMask = 0xFFFFFFFF;
168 pipelineDescriptor.alphaToCoverageEnabled = false;
Austin Eng11982702019-02-14 18:47:07 +0000169 pipelineDescriptor.layout = layout;
Kai Ninomiyaae1f25f2019-11-07 22:23:29 +0000170 pipelineDescriptor.vertexState = &vertexState;
Corentin Wallez45b51f52019-10-28 22:15:47 +0000171 pipelineDescriptor.primitiveTopology = WGPUPrimitiveTopology_TriangleList;
Yunchao Hec33a8c12019-04-11 18:46:54 +0000172 pipelineDescriptor.rasterizationState = &rasterizationState;
Austin Eng11982702019-02-14 18:47:07 +0000173 pipelineDescriptor.depthStencilState = &depthStencilState;
174
Corentin Wallez45b51f52019-10-28 22:15:47 +0000175 wgpuDeviceCreateRenderPipeline(device, &pipelineDescriptor);
Corentin Wallezcb2c64f2019-04-01 21:04:17 +0000176
Corentin Wallez45b51f52019-10-28 22:15:47 +0000177 WGPURenderPipeline apiDummyPipeline = api.GetNewRenderPipeline();
Austin Eng11982702019-02-14 18:47:07 +0000178 EXPECT_CALL(api,
179 DeviceCreateRenderPipeline(
Corentin Wallez45b51f52019-10-28 22:15:47 +0000180 apiDevice, MatchesLambda([](const WGPURenderPipelineDescriptor* desc) -> bool {
Corentin Wallezc6c7a422019-09-05 09:35:07 +0000181 return desc->vertexStage.entryPoint == std::string("main");
Austin Eng11982702019-02-14 18:47:07 +0000182 })))
Corentin Wallezcb2c64f2019-04-01 21:04:17 +0000183 .WillOnce(Return(apiDummyPipeline));
Austin Eng11982702019-02-14 18:47:07 +0000184
185 FlushClient();
186}
187
188// Test that the wire is able to send objects as value arguments
189TEST_F(WireArgumentTests, ObjectAsValueArgument) {
Corentin Wallez45b51f52019-10-28 22:15:47 +0000190 WGPUCommandEncoder cmdBufEncoder = wgpuDeviceCreateCommandEncoder(device, nullptr);
191 WGPUCommandEncoder apiEncoder = api.GetNewCommandEncoder();
Corentin Wallez4b90c472019-07-10 20:43:13 +0000192 EXPECT_CALL(api, DeviceCreateCommandEncoder(apiDevice, nullptr)).WillOnce(Return(apiEncoder));
Austin Eng11982702019-02-14 18:47:07 +0000193
Austin Eng3ded65e2020-02-28 22:29:15 +0000194 WGPUBufferDescriptor descriptor = {};
Jiawei Shaob2c50232019-02-27 09:21:56 +0000195 descriptor.size = 8;
Corentin Wallez9e9e29f2019-08-27 08:21:39 +0000196 descriptor.usage =
Corentin Wallez45b51f52019-10-28 22:15:47 +0000197 static_cast<WGPUBufferUsage>(WGPUBufferUsage_CopySrc | WGPUBufferUsage_CopyDst);
Austin Eng11982702019-02-14 18:47:07 +0000198
Corentin Wallez45b51f52019-10-28 22:15:47 +0000199 WGPUBuffer buffer = wgpuDeviceCreateBuffer(device, &descriptor);
200 WGPUBuffer apiBuffer = api.GetNewBuffer();
Jiawei Shaob2c50232019-02-27 09:21:56 +0000201 EXPECT_CALL(api, DeviceCreateBuffer(apiDevice, _))
202 .WillOnce(Return(apiBuffer))
203 .RetiresOnSaturation();
Austin Eng11982702019-02-14 18:47:07 +0000204
Corentin Wallez45b51f52019-10-28 22:15:47 +0000205 wgpuCommandEncoderCopyBufferToBuffer(cmdBufEncoder, buffer, 0, buffer, 4, 4);
Jiawei Shaob2c50232019-02-27 09:21:56 +0000206 EXPECT_CALL(api, CommandEncoderCopyBufferToBuffer(apiEncoder, apiBuffer, 0, apiBuffer, 4, 4));
207
Austin Eng11982702019-02-14 18:47:07 +0000208 FlushClient();
209}
210
211// Test that the wire is able to send array of objects
212TEST_F(WireArgumentTests, ObjectsAsPointerArgument) {
Corentin Wallez45b51f52019-10-28 22:15:47 +0000213 WGPUCommandBuffer cmdBufs[2];
214 WGPUCommandBuffer apiCmdBufs[2];
Austin Eng11982702019-02-14 18:47:07 +0000215
216 // Create two command buffers we need to use a GMock sequence otherwise the order of the
Corentin Wallez37b715d2019-02-18 09:42:03 +0000217 // CreateCommandEncoder might be swapped since they are equivalent in term of matchers
Austin Eng11982702019-02-14 18:47:07 +0000218 Sequence s;
219 for (int i = 0; i < 2; ++i) {
Corentin Wallez45b51f52019-10-28 22:15:47 +0000220 WGPUCommandEncoder cmdBufEncoder = wgpuDeviceCreateCommandEncoder(device, nullptr);
221 cmdBufs[i] = wgpuCommandEncoderFinish(cmdBufEncoder, nullptr);
Austin Eng11982702019-02-14 18:47:07 +0000222
Corentin Wallez45b51f52019-10-28 22:15:47 +0000223 WGPUCommandEncoder apiCmdBufEncoder = api.GetNewCommandEncoder();
Corentin Wallez4b90c472019-07-10 20:43:13 +0000224 EXPECT_CALL(api, DeviceCreateCommandEncoder(apiDevice, nullptr))
Austin Eng11982702019-02-14 18:47:07 +0000225 .InSequence(s)
Corentin Wallez37b715d2019-02-18 09:42:03 +0000226 .WillOnce(Return(apiCmdBufEncoder));
Austin Eng11982702019-02-14 18:47:07 +0000227
228 apiCmdBufs[i] = api.GetNewCommandBuffer();
Corentin Wallez4b90c472019-07-10 20:43:13 +0000229 EXPECT_CALL(api, CommandEncoderFinish(apiCmdBufEncoder, nullptr))
Austin Eng11982702019-02-14 18:47:07 +0000230 .WillOnce(Return(apiCmdBufs[i]));
Austin Eng11982702019-02-14 18:47:07 +0000231 }
232
Austin Eng11982702019-02-14 18:47:07 +0000233 // Submit command buffer and check we got a call with both API-side command buffers
Corentin Wallez45b51f52019-10-28 22:15:47 +0000234 wgpuQueueSubmit(queue, 2, cmdBufs);
Austin Eng11982702019-02-14 18:47:07 +0000235
236 EXPECT_CALL(
Corentin Wallez45b51f52019-10-28 22:15:47 +0000237 api, QueueSubmit(apiQueue, 2, MatchesLambda([=](const WGPUCommandBuffer* cmdBufs) -> bool {
Austin Eng11982702019-02-14 18:47:07 +0000238 return cmdBufs[0] == apiCmdBufs[0] && cmdBufs[1] == apiCmdBufs[1];
239 })));
240
Austin Eng11982702019-02-14 18:47:07 +0000241 FlushClient();
242}
243
244// Test that the wire is able to send structures that contain pure values (non-objects)
245TEST_F(WireArgumentTests, StructureOfValuesArgument) {
Austin Eng3ded65e2020-02-28 22:29:15 +0000246 WGPUSamplerDescriptor descriptor = {};
Corentin Wallez45b51f52019-10-28 22:15:47 +0000247 descriptor.magFilter = WGPUFilterMode_Linear;
248 descriptor.minFilter = WGPUFilterMode_Nearest;
249 descriptor.mipmapFilter = WGPUFilterMode_Linear;
250 descriptor.addressModeU = WGPUAddressMode_ClampToEdge;
251 descriptor.addressModeV = WGPUAddressMode_Repeat;
252 descriptor.addressModeW = WGPUAddressMode_MirrorRepeat;
Austin Eng11982702019-02-14 18:47:07 +0000253 descriptor.lodMinClamp = kLodMin;
254 descriptor.lodMaxClamp = kLodMax;
Corentin Wallez45b51f52019-10-28 22:15:47 +0000255 descriptor.compare = WGPUCompareFunction_Never;
Austin Eng11982702019-02-14 18:47:07 +0000256
Corentin Wallez45b51f52019-10-28 22:15:47 +0000257 wgpuDeviceCreateSampler(device, &descriptor);
Corentin Wallezcb2c64f2019-04-01 21:04:17 +0000258
Corentin Wallez45b51f52019-10-28 22:15:47 +0000259 WGPUSampler apiDummySampler = api.GetNewSampler();
Austin Eng11982702019-02-14 18:47:07 +0000260 EXPECT_CALL(api, DeviceCreateSampler(
Corentin Wallez45b51f52019-10-28 22:15:47 +0000261 apiDevice, MatchesLambda([](const WGPUSamplerDescriptor* desc) -> bool {
Austin Eng11982702019-02-14 18:47:07 +0000262 return desc->nextInChain == nullptr &&
Corentin Wallez45b51f52019-10-28 22:15:47 +0000263 desc->magFilter == WGPUFilterMode_Linear &&
264 desc->minFilter == WGPUFilterMode_Nearest &&
265 desc->mipmapFilter == WGPUFilterMode_Linear &&
266 desc->addressModeU == WGPUAddressMode_ClampToEdge &&
267 desc->addressModeV == WGPUAddressMode_Repeat &&
268 desc->addressModeW == WGPUAddressMode_MirrorRepeat &&
269 desc->compare == WGPUCompareFunction_Never &&
Austin Eng11982702019-02-14 18:47:07 +0000270 desc->lodMinClamp == kLodMin && desc->lodMaxClamp == kLodMax;
271 })))
Corentin Wallezcb2c64f2019-04-01 21:04:17 +0000272 .WillOnce(Return(apiDummySampler));
Austin Eng11982702019-02-14 18:47:07 +0000273
274 FlushClient();
275}
276
277// Test that the wire is able to send structures that contain objects
278TEST_F(WireArgumentTests, StructureOfObjectArrayArgument) {
Austin Eng3ded65e2020-02-28 22:29:15 +0000279 WGPUBindGroupLayoutDescriptor bglDescriptor = {};
Corentin Wallez3966eb12020-04-21 07:36:30 +0000280 bglDescriptor.entryCount = 0;
281 bglDescriptor.entries = nullptr;
Austin Eng11982702019-02-14 18:47:07 +0000282
Corentin Wallez45b51f52019-10-28 22:15:47 +0000283 WGPUBindGroupLayout bgl = wgpuDeviceCreateBindGroupLayout(device, &bglDescriptor);
284 WGPUBindGroupLayout apiBgl = api.GetNewBindGroupLayout();
Austin Eng11982702019-02-14 18:47:07 +0000285 EXPECT_CALL(api, DeviceCreateBindGroupLayout(apiDevice, _)).WillOnce(Return(apiBgl));
286
Austin Eng3ded65e2020-02-28 22:29:15 +0000287 WGPUPipelineLayoutDescriptor descriptor = {};
Jiawei Shao20301662019-02-21 00:45:19 +0000288 descriptor.bindGroupLayoutCount = 1;
Austin Eng11982702019-02-14 18:47:07 +0000289 descriptor.bindGroupLayouts = &bgl;
290
Corentin Wallez45b51f52019-10-28 22:15:47 +0000291 wgpuDeviceCreatePipelineLayout(device, &descriptor);
Corentin Wallezcb2c64f2019-04-01 21:04:17 +0000292
Corentin Wallez45b51f52019-10-28 22:15:47 +0000293 WGPUPipelineLayout apiDummyLayout = api.GetNewPipelineLayout();
Austin Eng11982702019-02-14 18:47:07 +0000294 EXPECT_CALL(api, DeviceCreatePipelineLayout(
295 apiDevice,
Corentin Wallez45b51f52019-10-28 22:15:47 +0000296 MatchesLambda([apiBgl](const WGPUPipelineLayoutDescriptor* desc) -> bool {
Austin Eng11982702019-02-14 18:47:07 +0000297 return desc->nextInChain == nullptr &&
Jiawei Shao20301662019-02-21 00:45:19 +0000298 desc->bindGroupLayoutCount == 1 &&
Austin Eng11982702019-02-14 18:47:07 +0000299 desc->bindGroupLayouts[0] == apiBgl;
300 })))
Corentin Wallezcb2c64f2019-04-01 21:04:17 +0000301 .WillOnce(Return(apiDummyLayout));
Austin Eng11982702019-02-14 18:47:07 +0000302
Austin Eng11982702019-02-14 18:47:07 +0000303 FlushClient();
304}
305
306// Test that the wire is able to send structures that contain objects
307TEST_F(WireArgumentTests, StructureOfStructureArrayArgument) {
308 static constexpr int NUM_BINDINGS = 3;
Corentin Wallez3966eb12020-04-21 07:36:30 +0000309 WGPUBindGroupLayoutEntry entries[NUM_BINDINGS]{
Corentin Wallezfc441f92021-01-29 19:08:15 +0000310 {nullptr,
311 0,
Brandon Jones9c52c2992020-12-12 02:09:56 +0000312 WGPUShaderStage_Vertex,
313 WGPUBindingType_Sampler,
314 false,
315 0,
316 WGPUTextureViewDimension_2D,
317 WGPUTextureComponentType_Float,
318 WGPUTextureFormat_RGBA8Unorm,
319 {},
320 {},
321 {},
322 {}},
Corentin Wallezfc441f92021-01-29 19:08:15 +0000323 {nullptr,
324 1,
Brandon Jones9c52c2992020-12-12 02:09:56 +0000325 WGPUShaderStage_Vertex,
326 WGPUBindingType_SampledTexture,
327 false,
328 0,
329 WGPUTextureViewDimension_2D,
330 WGPUTextureComponentType_Float,
331 WGPUTextureFormat_RGBA8Unorm,
332 {},
333 {},
334 {},
335 {}},
Corentin Wallezfc441f92021-01-29 19:08:15 +0000336 {nullptr,
337 2,
Brandon Jones9c52c2992020-12-12 02:09:56 +0000338 static_cast<WGPUShaderStage>(WGPUShaderStage_Vertex | WGPUShaderStage_Fragment),
339 WGPUBindingType_UniformBuffer,
340 false,
341 0,
342 WGPUTextureViewDimension_2D,
343 WGPUTextureComponentType_Float,
344 WGPUTextureFormat_RGBA8Unorm,
345 {},
346 {},
347 {},
348 {}},
Austin Eng11982702019-02-14 18:47:07 +0000349 };
Austin Eng3ded65e2020-02-28 22:29:15 +0000350 WGPUBindGroupLayoutDescriptor bglDescriptor = {};
Corentin Wallez3966eb12020-04-21 07:36:30 +0000351 bglDescriptor.entryCount = NUM_BINDINGS;
352 bglDescriptor.entries = entries;
Austin Eng11982702019-02-14 18:47:07 +0000353
Corentin Wallez45b51f52019-10-28 22:15:47 +0000354 wgpuDeviceCreateBindGroupLayout(device, &bglDescriptor);
355 WGPUBindGroupLayout apiBgl = api.GetNewBindGroupLayout();
Austin Eng11982702019-02-14 18:47:07 +0000356 EXPECT_CALL(
357 api,
358 DeviceCreateBindGroupLayout(
Corentin Wallez3966eb12020-04-21 07:36:30 +0000359 apiDevice, MatchesLambda([entries](const WGPUBindGroupLayoutDescriptor* desc) -> bool {
Austin Eng11982702019-02-14 18:47:07 +0000360 for (int i = 0; i < NUM_BINDINGS; ++i) {
Corentin Wallez3966eb12020-04-21 07:36:30 +0000361 const auto& a = desc->entries[i];
362 const auto& b = entries[i];
Austin Eng11982702019-02-14 18:47:07 +0000363 if (a.binding != b.binding || a.visibility != b.visibility ||
364 a.type != b.type) {
365 return false;
366 }
367 }
Corentin Wallez3966eb12020-04-21 07:36:30 +0000368 return desc->nextInChain == nullptr && desc->entryCount == 3;
Austin Eng11982702019-02-14 18:47:07 +0000369 })))
370 .WillOnce(Return(apiBgl));
371
Austin Eng11982702019-02-14 18:47:07 +0000372 FlushClient();
373}
374
375// Test passing nullptr instead of objects - array of objects version
376TEST_F(WireArgumentTests, DISABLED_NullptrInArray) {
Corentin Wallez45b51f52019-10-28 22:15:47 +0000377 WGPUBindGroupLayout nullBGL = nullptr;
Austin Eng11982702019-02-14 18:47:07 +0000378
Austin Eng3ded65e2020-02-28 22:29:15 +0000379 WGPUPipelineLayoutDescriptor descriptor = {};
Jiawei Shao20301662019-02-21 00:45:19 +0000380 descriptor.bindGroupLayoutCount = 1;
Austin Eng11982702019-02-14 18:47:07 +0000381 descriptor.bindGroupLayouts = &nullBGL;
382
Corentin Wallez45b51f52019-10-28 22:15:47 +0000383 wgpuDeviceCreatePipelineLayout(device, &descriptor);
Austin Eng11982702019-02-14 18:47:07 +0000384 EXPECT_CALL(api,
385 DeviceCreatePipelineLayout(
Corentin Wallez45b51f52019-10-28 22:15:47 +0000386 apiDevice, MatchesLambda([](const WGPUPipelineLayoutDescriptor* desc) -> bool {
Jiawei Shao20301662019-02-21 00:45:19 +0000387 return desc->nextInChain == nullptr && desc->bindGroupLayoutCount == 1 &&
Austin Eng11982702019-02-14 18:47:07 +0000388 desc->bindGroupLayouts[0] == nullptr;
389 })))
390 .WillOnce(Return(nullptr));
391
392 FlushClient();
393}