• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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/DawnTest.h"
16 
17 #include "utils/ComboRenderPipelineDescriptor.h"
18 #include "utils/DawnHelpers.h"
19 
20 class ObjectCachingTest : public DawnTest {};
21 
22 // Test that BindGroupLayouts are correctly deduplicated.
TEST_P(ObjectCachingTest,BindGroupLayoutDeduplication)23 TEST_P(ObjectCachingTest, BindGroupLayoutDeduplication) {
24     dawn::BindGroupLayout bgl = utils::MakeBindGroupLayout(
25         device, {{1, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}});
26     dawn::BindGroupLayout sameBgl = utils::MakeBindGroupLayout(
27         device, {{1, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}});
28     dawn::BindGroupLayout otherBgl = utils::MakeBindGroupLayout(
29         device, {{1, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}});
30 
31     EXPECT_NE(bgl.Get(), otherBgl.Get());
32     EXPECT_EQ(bgl.Get() == sameBgl.Get(), !UsesWire());
33 }
34 
35 // Test that two similar bind group layouts won't refer to the same one.
TEST_P(ObjectCachingTest,BindGroupLayoutDynamic)36 TEST_P(ObjectCachingTest, BindGroupLayoutDynamic) {
37     dawn::BindGroupLayout bgl = utils::MakeBindGroupLayout(
38         device, {{1, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer, true}});
39     dawn::BindGroupLayout sameBgl = utils::MakeBindGroupLayout(
40         device, {{1, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer, true}});
41     dawn::BindGroupLayout otherBgl = utils::MakeBindGroupLayout(
42         device, {{1, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer, false}});
43 
44     EXPECT_NE(bgl.Get(), otherBgl.Get());
45     EXPECT_EQ(bgl.Get() == sameBgl.Get(), !UsesWire());
46 }
47 
48 // Test that an error object doesn't try to uncache itself
TEST_P(ObjectCachingTest,ErrorObjectDoesntUncache)49 TEST_P(ObjectCachingTest, ErrorObjectDoesntUncache) {
50     ASSERT_DEVICE_ERROR(
51         dawn::BindGroupLayout bgl = utils::MakeBindGroupLayout(
52             device, {{0, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer},
53                      {0, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}}));
54 }
55 
56 // Test that PipelineLayouts are correctly deduplicated.
TEST_P(ObjectCachingTest,PipelineLayoutDeduplication)57 TEST_P(ObjectCachingTest, PipelineLayoutDeduplication) {
58     dawn::BindGroupLayout bgl = utils::MakeBindGroupLayout(
59         device, {{1, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}});
60     dawn::BindGroupLayout otherBgl = utils::MakeBindGroupLayout(
61         device, {{1, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}});
62 
63     dawn::PipelineLayout pl = utils::MakeBasicPipelineLayout(device, &bgl);
64     dawn::PipelineLayout samePl = utils::MakeBasicPipelineLayout(device, &bgl);
65     dawn::PipelineLayout otherPl1 = utils::MakeBasicPipelineLayout(device, nullptr);
66     dawn::PipelineLayout otherPl2 = utils::MakeBasicPipelineLayout(device, &otherBgl);
67 
68     EXPECT_NE(pl.Get(), otherPl1.Get());
69     EXPECT_NE(pl.Get(), otherPl2.Get());
70     EXPECT_EQ(pl.Get() == samePl.Get(), !UsesWire());
71 }
72 
73 // Test that ShaderModules are correctly deduplicated.
TEST_P(ObjectCachingTest,ShaderModuleDeduplication)74 TEST_P(ObjectCachingTest, ShaderModuleDeduplication) {
75     dawn::ShaderModule module = utils::CreateShaderModule(device, utils::ShaderStage::Fragment, R"(
76             #version 450
77             layout(location = 0) out vec4 fragColor;
78             void main() {
79                 fragColor = vec4(0.0, 1.0, 0.0, 1.0);
80             })");
81     dawn::ShaderModule sameModule =
82         utils::CreateShaderModule(device, utils::ShaderStage::Fragment, R"(
83             #version 450
84             layout(location = 0) out vec4 fragColor;
85             void main() {
86                 fragColor = vec4(0.0, 1.0, 0.0, 1.0);
87             })");
88     dawn::ShaderModule otherModule =
89         utils::CreateShaderModule(device, utils::ShaderStage::Fragment, R"(
90             #version 450
91             layout(location = 0) out vec4 fragColor;
92             void main() {
93                 fragColor = vec4(0.0);
94             })");
95 
96     EXPECT_NE(module.Get(), otherModule.Get());
97     EXPECT_EQ(module.Get() == sameModule.Get(), !UsesWire());
98 }
99 
100 // Test that ComputePipeline are correctly deduplicated wrt. their ShaderModule
TEST_P(ObjectCachingTest,ComputePipelineDeduplicationOnShaderModule)101 TEST_P(ObjectCachingTest, ComputePipelineDeduplicationOnShaderModule) {
102     dawn::ShaderModule module = utils::CreateShaderModule(device, utils::ShaderStage::Compute, R"(
103             #version 450
104             void main() {
105                 int i = 0;
106             })");
107     dawn::ShaderModule sameModule =
108         utils::CreateShaderModule(device, utils::ShaderStage::Compute, R"(
109             #version 450
110             void main() {
111                 int i = 0;
112             })");
113     dawn::ShaderModule otherModule =
114         utils::CreateShaderModule(device, utils::ShaderStage::Compute, R"(
115             #version 450
116             void main() {
117             })");
118 
119     EXPECT_NE(module.Get(), otherModule.Get());
120     EXPECT_EQ(module.Get() == sameModule.Get(), !UsesWire());
121 
122     dawn::PipelineLayout layout = utils::MakeBasicPipelineLayout(device, nullptr);
123 
124     dawn::PipelineStageDescriptor stageDesc;
125     stageDesc.entryPoint = "main";
126     stageDesc.module = module;
127 
128     dawn::ComputePipelineDescriptor desc;
129     desc.computeStage = &stageDesc;
130     desc.layout = layout;
131 
132     dawn::ComputePipeline pipeline = device.CreateComputePipeline(&desc);
133 
134     stageDesc.module = sameModule;
135     dawn::ComputePipeline samePipeline = device.CreateComputePipeline(&desc);
136 
137     stageDesc.module = otherModule;
138     dawn::ComputePipeline otherPipeline = device.CreateComputePipeline(&desc);
139 
140     EXPECT_NE(pipeline.Get(), otherPipeline.Get());
141     EXPECT_EQ(pipeline.Get() == samePipeline.Get(), !UsesWire());
142 }
143 
144 // Test that ComputePipeline are correctly deduplicated wrt. their layout
TEST_P(ObjectCachingTest,ComputePipelineDeduplicationOnLayout)145 TEST_P(ObjectCachingTest, ComputePipelineDeduplicationOnLayout) {
146     dawn::BindGroupLayout bgl = utils::MakeBindGroupLayout(
147         device, {{1, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}});
148     dawn::BindGroupLayout otherBgl = utils::MakeBindGroupLayout(
149         device, {{1, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}});
150 
151     dawn::PipelineLayout pl = utils::MakeBasicPipelineLayout(device, &bgl);
152     dawn::PipelineLayout samePl = utils::MakeBasicPipelineLayout(device, &bgl);
153     dawn::PipelineLayout otherPl = utils::MakeBasicPipelineLayout(device, nullptr);
154 
155     EXPECT_NE(pl.Get(), otherPl.Get());
156     EXPECT_EQ(pl.Get() == samePl.Get(), !UsesWire());
157 
158     dawn::PipelineStageDescriptor stageDesc;
159     stageDesc.entryPoint = "main";
160     stageDesc.module = utils::CreateShaderModule(device, utils::ShaderStage::Compute, R"(
161             #version 450
162             void main() {
163                 int i = 0;
164             })");
165 
166     dawn::ComputePipelineDescriptor desc;
167     desc.computeStage = &stageDesc;
168 
169     desc.layout = pl;
170     dawn::ComputePipeline pipeline = device.CreateComputePipeline(&desc);
171 
172     desc.layout = samePl;
173     dawn::ComputePipeline samePipeline = device.CreateComputePipeline(&desc);
174 
175     desc.layout = otherPl;
176     dawn::ComputePipeline otherPipeline = device.CreateComputePipeline(&desc);
177 
178     EXPECT_NE(pipeline.Get(), otherPipeline.Get());
179     EXPECT_EQ(pipeline.Get() == samePipeline.Get(), !UsesWire());
180 }
181 
182 // Test that RenderPipelines are correctly deduplicated wrt. their layout
TEST_P(ObjectCachingTest,RenderPipelineDeduplicationOnLayout)183 TEST_P(ObjectCachingTest, RenderPipelineDeduplicationOnLayout) {
184     dawn::BindGroupLayout bgl = utils::MakeBindGroupLayout(
185         device, {{1, dawn::ShaderStageBit::Fragment, dawn::BindingType::UniformBuffer}});
186     dawn::BindGroupLayout otherBgl = utils::MakeBindGroupLayout(
187         device, {{1, dawn::ShaderStageBit::Vertex, dawn::BindingType::UniformBuffer}});
188 
189     dawn::PipelineLayout pl = utils::MakeBasicPipelineLayout(device, &bgl);
190     dawn::PipelineLayout samePl = utils::MakeBasicPipelineLayout(device, &bgl);
191     dawn::PipelineLayout otherPl = utils::MakeBasicPipelineLayout(device, nullptr);
192 
193     EXPECT_NE(pl.Get(), otherPl.Get());
194     EXPECT_EQ(pl.Get() == samePl.Get(), !UsesWire());
195 
196     utils::ComboRenderPipelineDescriptor desc(device);
197     desc.cVertexStage.module = utils::CreateShaderModule(device, utils::ShaderStage::Vertex, R"(
198             #version 450
199             void main() {
200                 gl_Position = vec4(0.0);
201             })");
202     desc.cFragmentStage.module = utils::CreateShaderModule(device, utils::ShaderStage::Fragment, R"(
203             #version 450
204             void main() {
205             })");
206 
207     desc.layout = pl;
208     dawn::RenderPipeline pipeline = device.CreateRenderPipeline(&desc);
209 
210     desc.layout = samePl;
211     dawn::RenderPipeline samePipeline = device.CreateRenderPipeline(&desc);
212 
213     desc.layout = otherPl;
214     dawn::RenderPipeline otherPipeline = device.CreateRenderPipeline(&desc);
215 
216     EXPECT_NE(pipeline.Get(), otherPipeline.Get());
217     EXPECT_EQ(pipeline.Get() == samePipeline.Get(), !UsesWire());
218 }
219 
220 // Test that RenderPipelines are correctly deduplicated wrt. their vertex module
TEST_P(ObjectCachingTest,RenderPipelineDeduplicationOnVertexModule)221 TEST_P(ObjectCachingTest, RenderPipelineDeduplicationOnVertexModule) {
222     dawn::ShaderModule module = utils::CreateShaderModule(device, utils::ShaderStage::Vertex, R"(
223             #version 450
224             void main() {
225                 gl_Position = vec4(0.0);
226             })");
227     dawn::ShaderModule sameModule =
228         utils::CreateShaderModule(device, utils::ShaderStage::Vertex, R"(
229             #version 450
230             void main() {
231                 gl_Position = vec4(0.0);
232             })");
233     dawn::ShaderModule otherModule =
234         utils::CreateShaderModule(device, utils::ShaderStage::Vertex, R"(
235             #version 450
236             void main() {
237                 gl_Position = vec4(1.0);
238             })");
239 
240     EXPECT_NE(module.Get(), otherModule.Get());
241     EXPECT_EQ(module.Get() == sameModule.Get(), !UsesWire());
242 
243     utils::ComboRenderPipelineDescriptor desc(device);
244     desc.cFragmentStage.module = utils::CreateShaderModule(device, utils::ShaderStage::Fragment, R"(
245             #version 450
246             void main() {
247             })");
248 
249     desc.cVertexStage.module = module;
250     dawn::RenderPipeline pipeline = device.CreateRenderPipeline(&desc);
251 
252     desc.cVertexStage.module = sameModule;
253     dawn::RenderPipeline samePipeline = device.CreateRenderPipeline(&desc);
254 
255     desc.cVertexStage.module = otherModule;
256     dawn::RenderPipeline otherPipeline = device.CreateRenderPipeline(&desc);
257 
258     EXPECT_NE(pipeline.Get(), otherPipeline.Get());
259     EXPECT_EQ(pipeline.Get() == samePipeline.Get(), !UsesWire());
260 }
261 
262 // Test that RenderPipelines are correctly deduplicated wrt. their fragment module
TEST_P(ObjectCachingTest,RenderPipelineDeduplicationOnFragmentModule)263 TEST_P(ObjectCachingTest, RenderPipelineDeduplicationOnFragmentModule) {
264     dawn::ShaderModule module = utils::CreateShaderModule(device, utils::ShaderStage::Fragment, R"(
265             #version 450
266             void main() {
267             })");
268     dawn::ShaderModule sameModule =
269         utils::CreateShaderModule(device, utils::ShaderStage::Fragment, R"(
270             #version 450
271             void main() {
272             })");
273     dawn::ShaderModule otherModule =
274         utils::CreateShaderModule(device, utils::ShaderStage::Fragment, R"(
275             #version 450
276             void main() {
277                 int i = 0;
278             })");
279 
280     EXPECT_NE(module.Get(), otherModule.Get());
281     EXPECT_EQ(module.Get() == sameModule.Get(), !UsesWire());
282 
283     utils::ComboRenderPipelineDescriptor desc(device);
284     desc.cVertexStage.module = utils::CreateShaderModule(device, utils::ShaderStage::Vertex, R"(
285             #version 450
286             void main() {
287                 gl_Position = vec4(0.0);
288             })");
289 
290     desc.cFragmentStage.module = module;
291     dawn::RenderPipeline pipeline = device.CreateRenderPipeline(&desc);
292 
293     desc.cFragmentStage.module = sameModule;
294     dawn::RenderPipeline samePipeline = device.CreateRenderPipeline(&desc);
295 
296     desc.cFragmentStage.module = otherModule;
297     dawn::RenderPipeline otherPipeline = device.CreateRenderPipeline(&desc);
298 
299     EXPECT_NE(pipeline.Get(), otherPipeline.Get());
300     EXPECT_EQ(pipeline.Get() == samePipeline.Get(), !UsesWire());
301 }
302 
303 // Test that Samplers are correctly deduplicated.
TEST_P(ObjectCachingTest,SamplerDeduplication)304 TEST_P(ObjectCachingTest, SamplerDeduplication) {
305     dawn::SamplerDescriptor samplerDesc = utils::GetDefaultSamplerDescriptor();
306     dawn::Sampler sampler = device.CreateSampler(&samplerDesc);
307 
308     dawn::SamplerDescriptor sameSamplerDesc = utils::GetDefaultSamplerDescriptor();
309     dawn::Sampler sameSampler = device.CreateSampler(&sameSamplerDesc);
310 
311     dawn::SamplerDescriptor otherSamplerDescAddressModeU = utils::GetDefaultSamplerDescriptor();
312     otherSamplerDescAddressModeU.addressModeU = dawn::AddressMode::ClampToEdge;
313     dawn::Sampler otherSamplerAddressModeU = device.CreateSampler(&otherSamplerDescAddressModeU);
314 
315     dawn::SamplerDescriptor otherSamplerDescAddressModeV = utils::GetDefaultSamplerDescriptor();
316     otherSamplerDescAddressModeV.addressModeV = dawn::AddressMode::ClampToEdge;
317     dawn::Sampler otherSamplerAddressModeV = device.CreateSampler(&otherSamplerDescAddressModeV);
318 
319     dawn::SamplerDescriptor otherSamplerDescAddressModeW = utils::GetDefaultSamplerDescriptor();
320     otherSamplerDescAddressModeW.addressModeW = dawn::AddressMode::ClampToEdge;
321     dawn::Sampler otherSamplerAddressModeW = device.CreateSampler(&otherSamplerDescAddressModeW);
322 
323     dawn::SamplerDescriptor otherSamplerDescMagFilter = utils::GetDefaultSamplerDescriptor();
324     otherSamplerDescMagFilter.magFilter = dawn::FilterMode::Nearest;
325     dawn::Sampler otherSamplerMagFilter = device.CreateSampler(&otherSamplerDescMagFilter);
326 
327     dawn::SamplerDescriptor otherSamplerDescMinFilter = utils::GetDefaultSamplerDescriptor();
328     otherSamplerDescMinFilter.minFilter = dawn::FilterMode::Nearest;
329     dawn::Sampler otherSamplerMinFilter = device.CreateSampler(&otherSamplerDescMinFilter);
330 
331     dawn::SamplerDescriptor otherSamplerDescMipmapFilter = utils::GetDefaultSamplerDescriptor();
332     otherSamplerDescMipmapFilter.mipmapFilter = dawn::FilterMode::Nearest;
333     dawn::Sampler otherSamplerMipmapFilter = device.CreateSampler(&otherSamplerDescMipmapFilter);
334 
335     dawn::SamplerDescriptor otherSamplerDescLodMinClamp = utils::GetDefaultSamplerDescriptor();
336     otherSamplerDescLodMinClamp.lodMinClamp += 1;
337     dawn::Sampler otherSamplerLodMinClamp = device.CreateSampler(&otherSamplerDescLodMinClamp);
338 
339     dawn::SamplerDescriptor otherSamplerDescLodMaxClamp = utils::GetDefaultSamplerDescriptor();
340     otherSamplerDescLodMaxClamp.lodMaxClamp += 1;
341     dawn::Sampler otherSamplerLodMaxClamp = device.CreateSampler(&otherSamplerDescLodMaxClamp);
342 
343     dawn::SamplerDescriptor otherSamplerDescCompareFunction = utils::GetDefaultSamplerDescriptor();
344     otherSamplerDescCompareFunction.compare = dawn::CompareFunction::Always;
345     dawn::Sampler otherSamplerCompareFunction =
346         device.CreateSampler(&otherSamplerDescCompareFunction);
347 
348     EXPECT_NE(sampler.Get(), otherSamplerAddressModeU.Get());
349     EXPECT_NE(sampler.Get(), otherSamplerAddressModeV.Get());
350     EXPECT_NE(sampler.Get(), otherSamplerAddressModeW.Get());
351     EXPECT_NE(sampler.Get(), otherSamplerMagFilter.Get());
352     EXPECT_NE(sampler.Get(), otherSamplerMinFilter.Get());
353     EXPECT_NE(sampler.Get(), otherSamplerMipmapFilter.Get());
354     EXPECT_NE(sampler.Get(), otherSamplerLodMinClamp.Get());
355     EXPECT_NE(sampler.Get(), otherSamplerLodMaxClamp.Get());
356     EXPECT_NE(sampler.Get(), otherSamplerCompareFunction.Get());
357     EXPECT_EQ(sampler.Get() == sameSampler.Get(), !UsesWire());
358 }
359 
360 DAWN_INSTANTIATE_TEST(ObjectCachingTest, D3D12Backend, MetalBackend, OpenGLBackend, VulkanBackend);
361