• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 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 using namespace testing;
18 using namespace dawn_wire;
19 
20 class WireExtensionTests : public WireTest {
21   public:
WireExtensionTests()22     WireExtensionTests() {
23     }
24     ~WireExtensionTests() override = default;
25 };
26 
27 // Serialize/Deserializes a chained struct correctly.
TEST_F(WireExtensionTests,ChainedStruct)28 TEST_F(WireExtensionTests, ChainedStruct) {
29     WGPUShaderModuleDescriptor shaderModuleDesc = {};
30     WGPUShaderModule apiShaderModule = api.GetNewShaderModule();
31     WGPUShaderModule shaderModule = wgpuDeviceCreateShaderModule(device, &shaderModuleDesc);
32     EXPECT_CALL(api, DeviceCreateShaderModule(apiDevice, _)).WillOnce(Return(apiShaderModule));
33     FlushClient();
34 
35     WGPUPrimitiveDepthClampingState clientExt = {};
36     clientExt.chain.sType = WGPUSType_PrimitiveDepthClampingState;
37     clientExt.chain.next = nullptr;
38     clientExt.clampDepth = true;
39 
40     WGPURenderPipelineDescriptor renderPipelineDesc = {};
41     renderPipelineDesc.vertex.module = shaderModule;
42     renderPipelineDesc.vertex.entryPoint = "main";
43     renderPipelineDesc.primitive.nextInChain = &clientExt.chain;
44 
45     wgpuDeviceCreateRenderPipeline(device, &renderPipelineDesc);
46     EXPECT_CALL(api, DeviceCreateRenderPipeline(apiDevice, NotNull()))
47         .WillOnce(Invoke([&](Unused,
48                              const WGPURenderPipelineDescriptor* serverDesc) -> WGPURenderPipeline {
49             const auto* ext = reinterpret_cast<const WGPUPrimitiveDepthClampingState*>(
50                 serverDesc->primitive.nextInChain);
51             EXPECT_EQ(ext->chain.sType, clientExt.chain.sType);
52             EXPECT_EQ(ext->clampDepth, true);
53             EXPECT_EQ(ext->chain.next, nullptr);
54 
55             return api.GetNewRenderPipeline();
56         }));
57     FlushClient();
58 }
59 
60 // Serialize/Deserializes multiple chained structs correctly.
TEST_F(WireExtensionTests,MutlipleChainedStructs)61 TEST_F(WireExtensionTests, MutlipleChainedStructs) {
62     WGPUShaderModuleDescriptor shaderModuleDesc = {};
63     WGPUShaderModule apiShaderModule = api.GetNewShaderModule();
64     WGPUShaderModule shaderModule = wgpuDeviceCreateShaderModule(device, &shaderModuleDesc);
65     EXPECT_CALL(api, DeviceCreateShaderModule(apiDevice, _)).WillOnce(Return(apiShaderModule));
66     FlushClient();
67 
68     WGPUPrimitiveDepthClampingState clientExt2 = {};
69     clientExt2.chain.sType = WGPUSType_PrimitiveDepthClampingState;
70     clientExt2.chain.next = nullptr;
71     clientExt2.clampDepth = false;
72 
73     WGPUPrimitiveDepthClampingState clientExt1 = {};
74     clientExt1.chain.sType = WGPUSType_PrimitiveDepthClampingState;
75     clientExt1.chain.next = &clientExt2.chain;
76     clientExt1.clampDepth = true;
77 
78     WGPURenderPipelineDescriptor renderPipelineDesc = {};
79     renderPipelineDesc.vertex.module = shaderModule;
80     renderPipelineDesc.vertex.entryPoint = "main";
81     renderPipelineDesc.primitive.nextInChain = &clientExt1.chain;
82 
83     wgpuDeviceCreateRenderPipeline(device, &renderPipelineDesc);
84     EXPECT_CALL(api, DeviceCreateRenderPipeline(apiDevice, NotNull()))
85         .WillOnce(Invoke([&](Unused,
86                              const WGPURenderPipelineDescriptor* serverDesc) -> WGPURenderPipeline {
87             const auto* ext1 = reinterpret_cast<const WGPUPrimitiveDepthClampingState*>(
88                 serverDesc->primitive.nextInChain);
89             EXPECT_EQ(ext1->chain.sType, clientExt1.chain.sType);
90             EXPECT_EQ(ext1->clampDepth, true);
91 
92             const auto* ext2 = reinterpret_cast<const WGPUPrimitiveDepthClampingState*>(
93                 ext1->chain.next);
94             EXPECT_EQ(ext2->chain.sType, clientExt2.chain.sType);
95             EXPECT_EQ(ext2->clampDepth, false);
96             EXPECT_EQ(ext2->chain.next, nullptr);
97 
98             return api.GetNewRenderPipeline();
99         }));
100     FlushClient();
101 
102     // Swap the order of the chained structs.
103     renderPipelineDesc.primitive.nextInChain = &clientExt2.chain;
104     clientExt2.chain.next = &clientExt1.chain;
105     clientExt1.chain.next = nullptr;
106 
107     wgpuDeviceCreateRenderPipeline(device, &renderPipelineDesc);
108     EXPECT_CALL(api, DeviceCreateRenderPipeline(apiDevice, NotNull()))
109         .WillOnce(Invoke([&](Unused,
110                              const WGPURenderPipelineDescriptor* serverDesc) -> WGPURenderPipeline {
111             const auto* ext2 = reinterpret_cast<const WGPUPrimitiveDepthClampingState*>(
112                 serverDesc->primitive.nextInChain);
113             EXPECT_EQ(ext2->chain.sType, clientExt2.chain.sType);
114             EXPECT_EQ(ext2->clampDepth, false);
115 
116             const auto* ext1 = reinterpret_cast<const WGPUPrimitiveDepthClampingState*>(
117                 ext2->chain.next);
118             EXPECT_EQ(ext1->chain.sType, clientExt1.chain.sType);
119             EXPECT_EQ(ext1->clampDepth, true);
120             EXPECT_EQ(ext1->chain.next, nullptr);
121 
122             return api.GetNewRenderPipeline();
123         }));
124     FlushClient();
125 }
126 
127 // Test that a chained struct with Invalid sType passes through as Invalid.
TEST_F(WireExtensionTests,InvalidSType)128 TEST_F(WireExtensionTests, InvalidSType) {
129     WGPUShaderModuleDescriptor shaderModuleDesc = {};
130     WGPUShaderModule apiShaderModule = api.GetNewShaderModule();
131     WGPUShaderModule shaderModule = wgpuDeviceCreateShaderModule(device, &shaderModuleDesc);
132     EXPECT_CALL(api, DeviceCreateShaderModule(apiDevice, _)).WillOnce(Return(apiShaderModule));
133     FlushClient();
134 
135     WGPUPrimitiveDepthClampingState clientExt = {};
136     clientExt.chain.sType = WGPUSType_Invalid;
137     clientExt.chain.next = nullptr;
138 
139     WGPURenderPipelineDescriptor renderPipelineDesc = {};
140     renderPipelineDesc.vertex.module = shaderModule;
141     renderPipelineDesc.vertex.entryPoint = "main";
142     renderPipelineDesc.primitive.nextInChain = &clientExt.chain;
143 
144     wgpuDeviceCreateRenderPipeline(device, &renderPipelineDesc);
145     EXPECT_CALL(api, DeviceCreateRenderPipeline(apiDevice, NotNull()))
146         .WillOnce(Invoke(
147             [&](Unused, const WGPURenderPipelineDescriptor* serverDesc) -> WGPURenderPipeline {
148                 EXPECT_EQ(serverDesc->primitive.nextInChain->sType, WGPUSType_Invalid);
149                 EXPECT_EQ(serverDesc->primitive.nextInChain->next, nullptr);
150                 return api.GetNewRenderPipeline();
151             }));
152     FlushClient();
153 }
154 
155 // Test that a chained struct with unknown sType passes through as Invalid.
TEST_F(WireExtensionTests,UnknownSType)156 TEST_F(WireExtensionTests, UnknownSType) {
157     WGPUShaderModuleDescriptor shaderModuleDesc = {};
158     WGPUShaderModule apiShaderModule = api.GetNewShaderModule();
159     WGPUShaderModule shaderModule = wgpuDeviceCreateShaderModule(device, &shaderModuleDesc);
160     EXPECT_CALL(api, DeviceCreateShaderModule(apiDevice, _)).WillOnce(Return(apiShaderModule));
161     FlushClient();
162 
163     WGPUPrimitiveDepthClampingState clientExt = {};
164     clientExt.chain.sType = static_cast<WGPUSType>(-1);
165     clientExt.chain.next = nullptr;
166 
167     WGPURenderPipelineDescriptor renderPipelineDesc = {};
168     renderPipelineDesc.vertex.module = shaderModule;
169     renderPipelineDesc.vertex.entryPoint = "main";
170     renderPipelineDesc.primitive.nextInChain = &clientExt.chain;
171 
172     wgpuDeviceCreateRenderPipeline(device, &renderPipelineDesc);
173     EXPECT_CALL(api, DeviceCreateRenderPipeline(apiDevice, NotNull()))
174         .WillOnce(Invoke(
175             [&](Unused, const WGPURenderPipelineDescriptor* serverDesc) -> WGPURenderPipeline {
176                 EXPECT_EQ(serverDesc->primitive.nextInChain->sType, WGPUSType_Invalid);
177                 EXPECT_EQ(serverDesc->primitive.nextInChain->next, nullptr);
178                 return api.GetNewRenderPipeline();
179             }));
180     FlushClient();
181 }
182 
183 // Test that if both an invalid and valid stype are passed on the chain, only the invalid
184 // sType passes through as Invalid.
TEST_F(WireExtensionTests,ValidAndInvalidSTypeInChain)185 TEST_F(WireExtensionTests, ValidAndInvalidSTypeInChain) {
186     WGPUShaderModuleDescriptor shaderModuleDesc = {};
187     WGPUShaderModule apiShaderModule = api.GetNewShaderModule();
188     WGPUShaderModule shaderModule = wgpuDeviceCreateShaderModule(device, &shaderModuleDesc);
189     EXPECT_CALL(api, DeviceCreateShaderModule(apiDevice, _)).WillOnce(Return(apiShaderModule));
190     FlushClient();
191 
192     WGPUPrimitiveDepthClampingState clientExt2 = {};
193     clientExt2.chain.sType = WGPUSType_Invalid;
194     clientExt2.chain.next = nullptr;
195 
196     WGPUPrimitiveDepthClampingState clientExt1 = {};
197     clientExt1.chain.sType = WGPUSType_PrimitiveDepthClampingState;
198     clientExt1.chain.next = &clientExt2.chain;
199     clientExt1.clampDepth = true;
200 
201     WGPURenderPipelineDescriptor renderPipelineDesc = {};
202     renderPipelineDesc.vertex.module = shaderModule;
203     renderPipelineDesc.vertex.entryPoint = "main";
204     renderPipelineDesc.primitive.nextInChain = &clientExt1.chain;
205 
206     wgpuDeviceCreateRenderPipeline(device, &renderPipelineDesc);
207     EXPECT_CALL(api, DeviceCreateRenderPipeline(apiDevice, NotNull()))
208         .WillOnce(Invoke([&](Unused,
209                              const WGPURenderPipelineDescriptor* serverDesc) -> WGPURenderPipeline {
210             const auto* ext = reinterpret_cast<const WGPUPrimitiveDepthClampingState*>(
211                 serverDesc->primitive.nextInChain);
212             EXPECT_EQ(ext->chain.sType, clientExt1.chain.sType);
213             EXPECT_EQ(ext->clampDepth, true);
214 
215             EXPECT_EQ(ext->chain.next->sType, WGPUSType_Invalid);
216             EXPECT_EQ(ext->chain.next->next, nullptr);
217             return api.GetNewRenderPipeline();
218         }));
219     FlushClient();
220 
221     // Swap the order of the chained structs.
222     renderPipelineDesc.primitive.nextInChain = &clientExt2.chain;
223     clientExt2.chain.next = &clientExt1.chain;
224     clientExt1.chain.next = nullptr;
225 
226     wgpuDeviceCreateRenderPipeline(device, &renderPipelineDesc);
227     EXPECT_CALL(api, DeviceCreateRenderPipeline(apiDevice, NotNull()))
228         .WillOnce(Invoke([&](Unused,
229                              const WGPURenderPipelineDescriptor* serverDesc) -> WGPURenderPipeline {
230             EXPECT_EQ(serverDesc->primitive.nextInChain->sType, WGPUSType_Invalid);
231 
232             const auto* ext = reinterpret_cast<const WGPUPrimitiveDepthClampingState*>(
233                 serverDesc->primitive.nextInChain->next);
234             EXPECT_EQ(ext->chain.sType, clientExt1.chain.sType);
235             EXPECT_EQ(ext->clampDepth, true);
236             EXPECT_EQ(ext->chain.next, nullptr);
237 
238             return api.GetNewRenderPipeline();
239         }));
240     FlushClient();
241 }
242