• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 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/validation/ValidationTest.h"
16 
17 namespace {
18 
19     class TextureViewValidationTest : public ValidationTest {};
20 
21     constexpr uint32_t kWidth = 32u;
22     constexpr uint32_t kHeight = 32u;
23     constexpr uint32_t kDepth = 6u;
24     constexpr uint32_t kDefaultMipLevels = 6u;
25 
26     constexpr wgpu::TextureFormat kDefaultTextureFormat = wgpu::TextureFormat::RGBA8Unorm;
27 
Create2DArrayTexture(wgpu::Device & device,uint32_t arrayLayerCount,uint32_t width=kWidth,uint32_t height=kHeight,uint32_t mipLevelCount=kDefaultMipLevels,uint32_t sampleCount=1)28     wgpu::Texture Create2DArrayTexture(wgpu::Device& device,
29                                        uint32_t arrayLayerCount,
30                                        uint32_t width = kWidth,
31                                        uint32_t height = kHeight,
32                                        uint32_t mipLevelCount = kDefaultMipLevels,
33                                        uint32_t sampleCount = 1) {
34         wgpu::TextureDescriptor descriptor;
35         descriptor.dimension = wgpu::TextureDimension::e2D;
36         descriptor.size.width = width;
37         descriptor.size.height = height;
38         descriptor.size.depthOrArrayLayers = arrayLayerCount;
39         descriptor.sampleCount = sampleCount;
40         descriptor.format = kDefaultTextureFormat;
41         descriptor.mipLevelCount = mipLevelCount;
42         descriptor.usage = wgpu::TextureUsage::TextureBinding;
43         return device.CreateTexture(&descriptor);
44     }
45 
Create3DTexture(wgpu::Device & device)46     wgpu::Texture Create3DTexture(wgpu::Device& device) {
47         wgpu::TextureDescriptor descriptor;
48         descriptor.dimension = wgpu::TextureDimension::e3D;
49         descriptor.size = {kWidth, kHeight, kDepth};
50         descriptor.sampleCount = 1;
51         descriptor.format = kDefaultTextureFormat;
52         descriptor.mipLevelCount = kDefaultMipLevels;
53         descriptor.usage = wgpu::TextureUsage::TextureBinding;
54         return device.CreateTexture(&descriptor);
55     }
56 
CreateDepthStencilTexture(wgpu::Device & device,wgpu::TextureFormat format)57     wgpu::Texture CreateDepthStencilTexture(wgpu::Device& device, wgpu::TextureFormat format) {
58         wgpu::TextureDescriptor descriptor = {};
59         descriptor.size = {kWidth, kHeight, kDepth};
60         descriptor.usage =
61             wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::RenderAttachment;
62         descriptor.mipLevelCount = kDefaultMipLevels;
63         descriptor.format = format;
64         return device.CreateTexture(&descriptor);
65     }
66 
CreateDefaultViewDescriptor(wgpu::TextureViewDimension dimension)67     wgpu::TextureViewDescriptor CreateDefaultViewDescriptor(wgpu::TextureViewDimension dimension) {
68         wgpu::TextureViewDescriptor descriptor;
69         descriptor.format = kDefaultTextureFormat;
70         descriptor.dimension = dimension;
71         descriptor.baseMipLevel = 0;
72         descriptor.mipLevelCount = kDefaultMipLevels;
73         descriptor.baseArrayLayer = 0;
74         descriptor.arrayLayerCount = 1;
75         return descriptor;
76     }
77 
78     // Test creating texture view on a 2D non-array texture
TEST_F(TextureViewValidationTest,CreateTextureViewOnTexture2D)79     TEST_F(TextureViewValidationTest, CreateTextureViewOnTexture2D) {
80         wgpu::Texture texture = Create2DArrayTexture(device, 1);
81 
82         wgpu::TextureViewDescriptor base2DTextureViewDescriptor =
83             CreateDefaultViewDescriptor(wgpu::TextureViewDimension::e2D);
84 
85         // It is an error to create a view with zero 'arrayLayerCount'.
86         {
87             wgpu::TextureViewDescriptor descriptor = base2DTextureViewDescriptor;
88             descriptor.arrayLayerCount = 0;
89             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
90         }
91 
92         // It is an error to create a view with zero 'mipLevelCount'.
93         {
94             wgpu::TextureViewDescriptor descriptor = base2DTextureViewDescriptor;
95             descriptor.mipLevelCount = 0;
96             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
97         }
98 
99         // It is OK to create a 2D texture view on a 2D texture.
100         {
101             wgpu::TextureViewDescriptor descriptor = base2DTextureViewDescriptor;
102             descriptor.arrayLayerCount = 1;
103             texture.CreateView(&descriptor);
104         }
105 
106         // It is an error to view a layer past the end of the texture.
107         {
108             wgpu::TextureViewDescriptor descriptor = base2DTextureViewDescriptor;
109             descriptor.arrayLayerCount = 2;
110             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
111         }
112 
113         // It is OK to create a 1-layer 2D array texture view on a 2D texture.
114         {
115             wgpu::TextureViewDescriptor descriptor = base2DTextureViewDescriptor;
116             descriptor.dimension = wgpu::TextureViewDimension::e2DArray;
117             descriptor.arrayLayerCount = 1;
118             texture.CreateView(&descriptor);
119         }
120 
121         // It is an error to create a 3D texture view on a 2D texture.
122         {
123             wgpu::TextureViewDescriptor descriptor = base2DTextureViewDescriptor;
124             descriptor.dimension = wgpu::TextureViewDimension::e3D;
125             descriptor.arrayLayerCount = 1;
126             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
127         }
128 
129         // baseMipLevel == k && mipLevelCount == WGPU_MIP_LEVEL_COUNT_UNDEFINED means to use levels
130         // k..end.
131         {
132             wgpu::TextureViewDescriptor descriptor = base2DTextureViewDescriptor;
133             descriptor.mipLevelCount = WGPU_MIP_LEVEL_COUNT_UNDEFINED;
134 
135             descriptor.baseMipLevel = 0;
136             texture.CreateView(&descriptor);
137             descriptor.baseMipLevel = 1;
138             texture.CreateView(&descriptor);
139             descriptor.baseMipLevel = kDefaultMipLevels - 1;
140             texture.CreateView(&descriptor);
141             descriptor.baseMipLevel = kDefaultMipLevels;
142             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
143         }
144 
145         // It is an error to make the mip level out of range.
146         {
147             wgpu::TextureViewDescriptor descriptor = base2DTextureViewDescriptor;
148             descriptor.baseMipLevel = 0;
149             descriptor.mipLevelCount = kDefaultMipLevels + 1;
150             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
151             descriptor.baseMipLevel = 1;
152             descriptor.mipLevelCount = kDefaultMipLevels;
153             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
154             descriptor.baseMipLevel = kDefaultMipLevels - 1;
155             descriptor.mipLevelCount = 2;
156             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
157             descriptor.baseMipLevel = kDefaultMipLevels;
158             descriptor.mipLevelCount = 1;
159             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
160         }
161     }
162 
163     // Test creating texture view on a 2D array texture
TEST_F(TextureViewValidationTest,CreateTextureViewOnTexture2DArray)164     TEST_F(TextureViewValidationTest, CreateTextureViewOnTexture2DArray) {
165         constexpr uint32_t kDefaultArrayLayers = 6;
166 
167         wgpu::Texture texture = Create2DArrayTexture(device, kDefaultArrayLayers);
168 
169         wgpu::TextureViewDescriptor base2DArrayTextureViewDescriptor =
170             CreateDefaultViewDescriptor(wgpu::TextureViewDimension::e2DArray);
171 
172         // It is an error to create a view with zero 'arrayLayerCount'.
173         {
174             wgpu::TextureViewDescriptor descriptor = base2DArrayTextureViewDescriptor;
175             descriptor.dimension = wgpu::TextureViewDimension::e2D;
176             descriptor.arrayLayerCount = 0;
177             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
178         }
179 
180         // It is an error to create a view with zero 'mipLevelCount'.
181         {
182             wgpu::TextureViewDescriptor descriptor = base2DArrayTextureViewDescriptor;
183             descriptor.dimension = wgpu::TextureViewDimension::e2D;
184             descriptor.mipLevelCount = 0;
185             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
186         }
187 
188         // It is OK to create a 2D texture view on a 2D array texture.
189         {
190             wgpu::TextureViewDescriptor descriptor = base2DArrayTextureViewDescriptor;
191             descriptor.dimension = wgpu::TextureViewDimension::e2D;
192             descriptor.arrayLayerCount = 1;
193             texture.CreateView(&descriptor);
194         }
195 
196         // It is OK to create a 2D array texture view on a 2D array texture.
197         {
198             wgpu::TextureViewDescriptor descriptor = base2DArrayTextureViewDescriptor;
199             descriptor.arrayLayerCount = kDefaultArrayLayers;
200             texture.CreateView(&descriptor);
201         }
202 
203         // It is an error to create a 3D texture view on a 2D array texture.
204         {
205             wgpu::TextureViewDescriptor descriptor = base2DArrayTextureViewDescriptor;
206             descriptor.dimension = wgpu::TextureViewDimension::e3D;
207             descriptor.arrayLayerCount = 1;
208             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
209         }
210 
211         // baseArrayLayer == k && arrayLayerCount == wgpu::kArrayLayerCountUndefined means to use
212         // layers k..end.
213         {
214             wgpu::TextureViewDescriptor descriptor = base2DArrayTextureViewDescriptor;
215             descriptor.arrayLayerCount = wgpu::kArrayLayerCountUndefined;
216 
217             descriptor.baseArrayLayer = 0;
218             texture.CreateView(&descriptor);
219             descriptor.baseArrayLayer = 1;
220             texture.CreateView(&descriptor);
221             descriptor.baseArrayLayer = kDefaultArrayLayers - 1;
222             texture.CreateView(&descriptor);
223             descriptor.baseArrayLayer = kDefaultArrayLayers;
224             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
225         }
226 
227         // It is an error for the array layer range of the view to exceed that of the texture.
228         {
229             wgpu::TextureViewDescriptor descriptor = base2DArrayTextureViewDescriptor;
230             descriptor.baseArrayLayer = 0;
231             descriptor.arrayLayerCount = kDefaultArrayLayers + 1;
232             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
233             descriptor.baseArrayLayer = 1;
234             descriptor.arrayLayerCount = kDefaultArrayLayers;
235             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
236             descriptor.baseArrayLayer = kDefaultArrayLayers - 1;
237             descriptor.arrayLayerCount = 2;
238             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
239             descriptor.baseArrayLayer = kDefaultArrayLayers;
240             descriptor.arrayLayerCount = 1;
241             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
242         }
243     }
244 
245     // Test creating texture view on a 3D texture
TEST_F(TextureViewValidationTest,CreateTextureViewOnTexture3D)246     TEST_F(TextureViewValidationTest, CreateTextureViewOnTexture3D) {
247         wgpu::Texture texture = Create3DTexture(device);
248 
249         wgpu::TextureViewDescriptor base3DTextureViewDescriptor =
250             CreateDefaultViewDescriptor(wgpu::TextureViewDimension::e3D);
251 
252         // It is an error to create a view with zero 'arrayLayerCount'.
253         {
254             wgpu::TextureViewDescriptor descriptor = base3DTextureViewDescriptor;
255             descriptor.arrayLayerCount = 0;
256             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
257         }
258 
259         // It is an error to create a view with zero 'mipLevelCount'.
260         {
261             wgpu::TextureViewDescriptor descriptor = base3DTextureViewDescriptor;
262             descriptor.mipLevelCount = 0;
263             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
264         }
265 
266         // It is OK to create a 3D texture view on a 3D texture.
267         {
268             wgpu::TextureViewDescriptor descriptor = base3DTextureViewDescriptor;
269             texture.CreateView(&descriptor);
270         }
271 
272         // It is an error to create a 2D/2DArray/Cube/CubeArray texture view on a 3D texture.
273         {
274             wgpu::TextureViewDimension invalidDimensions[] = {
275                 wgpu::TextureViewDimension::e2D,
276                 wgpu::TextureViewDimension::e2DArray,
277                 wgpu::TextureViewDimension::Cube,
278                 wgpu::TextureViewDimension::CubeArray,
279             };
280             for (wgpu::TextureViewDimension dimension : invalidDimensions) {
281                 wgpu::TextureViewDescriptor descriptor = base3DTextureViewDescriptor;
282                 descriptor.dimension = dimension;
283                 if (dimension == wgpu::TextureViewDimension::Cube ||
284                     dimension == wgpu::TextureViewDimension::CubeArray) {
285                     descriptor.arrayLayerCount = 6;
286                 }
287                 ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
288             }
289         }
290 
291         // baseMipLevel == k && mipLevelCount == WGPU_MIP_LEVEL_COUNT_UNDEFINED means to use levels
292         // k..end.
293         {
294             wgpu::TextureViewDescriptor descriptor = base3DTextureViewDescriptor;
295             descriptor.mipLevelCount = WGPU_MIP_LEVEL_COUNT_UNDEFINED;
296 
297             descriptor.baseMipLevel = 0;
298             texture.CreateView(&descriptor);
299             descriptor.baseMipLevel = 1;
300             texture.CreateView(&descriptor);
301             descriptor.baseMipLevel = kDefaultMipLevels - 1;
302             texture.CreateView(&descriptor);
303             descriptor.baseMipLevel = kDefaultMipLevels;
304             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
305         }
306 
307         // It is an error to make the mip level out of range.
308         {
309             wgpu::TextureViewDescriptor descriptor = base3DTextureViewDescriptor;
310             descriptor.baseMipLevel = 0;
311             descriptor.mipLevelCount = kDefaultMipLevels + 1;
312             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
313             descriptor.baseMipLevel = 1;
314             descriptor.mipLevelCount = kDefaultMipLevels;
315             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
316             descriptor.baseMipLevel = kDefaultMipLevels - 1;
317             descriptor.mipLevelCount = 2;
318             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
319             descriptor.baseMipLevel = kDefaultMipLevels;
320             descriptor.mipLevelCount = 1;
321             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
322         }
323 
324         // baseArrayLayer == k && arrayLayerCount == wgpu::kArrayLayerCountUndefined means to use
325         // layers k..end. But baseArrayLayer must be 0, and arrayLayerCount must be 1 at most for 3D
326         // texture view.
327         {
328             wgpu::TextureViewDescriptor descriptor = base3DTextureViewDescriptor;
329             descriptor.arrayLayerCount = wgpu::kArrayLayerCountUndefined;
330             descriptor.baseArrayLayer = 0;
331             texture.CreateView(&descriptor);
332             descriptor.baseArrayLayer = 1;
333             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
334 
335             descriptor.baseArrayLayer = 0;
336             descriptor.arrayLayerCount = 1;
337             texture.CreateView(&descriptor);
338             descriptor.arrayLayerCount = 2;
339             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
340             descriptor.arrayLayerCount = kDepth;
341             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
342         }
343     }
344 
345     // Using the "none" ("default") values validates the same as explicitly
346     // specifying the values they're supposed to default to.
347     // Variant for a 2D texture with more than 1 array layer.
TEST_F(TextureViewValidationTest,TextureViewDescriptorDefaults2DArray)348     TEST_F(TextureViewValidationTest, TextureViewDescriptorDefaults2DArray) {
349         constexpr uint32_t kDefaultArrayLayers = 8;
350         wgpu::Texture texture = Create2DArrayTexture(device, kDefaultArrayLayers);
351 
352         { texture.CreateView(); }
353         {
354             wgpu::TextureViewDescriptor descriptor;
355             descriptor.format = wgpu::TextureFormat::Undefined;
356             texture.CreateView(&descriptor);
357             descriptor.format = wgpu::TextureFormat::RGBA8Unorm;
358             texture.CreateView(&descriptor);
359             descriptor.format = wgpu::TextureFormat::R8Unorm;
360             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
361         }
362         {
363             wgpu::TextureViewDescriptor descriptor;
364             descriptor.dimension = wgpu::TextureViewDimension::Undefined;
365             texture.CreateView(&descriptor);
366             descriptor.dimension = wgpu::TextureViewDimension::e2DArray;
367             texture.CreateView(&descriptor);
368             // Setting view dimension to 2D, its arrayLayer will default to 1. And view creation
369             // will success.
370             descriptor.dimension = wgpu::TextureViewDimension::e2D;
371             texture.CreateView(&descriptor);
372             // Setting view dimension to Cube, its arrayLayer will default to 6.
373             descriptor.dimension = wgpu::TextureViewDimension::Cube;
374             texture.CreateView(&descriptor);
375             descriptor.baseArrayLayer = 2;
376             texture.CreateView(&descriptor);
377             descriptor.baseArrayLayer = 3;
378             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
379             // Setting view dimension to CubeArray, its arrayLayer will default to
380             // size.depthOrArrayLayers (kDefaultArrayLayers) - baseArrayLayer.
381             descriptor.dimension = wgpu::TextureViewDimension::CubeArray;
382             descriptor.baseArrayLayer = 0;
383             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
384             descriptor.baseArrayLayer = 2;
385             texture.CreateView(&descriptor);
386             descriptor.baseArrayLayer = 3;
387             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
388         }
389         {
390             wgpu::TextureViewDescriptor descriptor;
391 
392             // Setting array layers to non-0 means the dimensionality will
393             // default to 2D so by itself it causes an error.
394             descriptor.arrayLayerCount = kDefaultArrayLayers;
395             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
396             descriptor.dimension = wgpu::TextureViewDimension::e2DArray;
397             texture.CreateView(&descriptor);
398 
399             descriptor.mipLevelCount = kDefaultMipLevels;
400             texture.CreateView(&descriptor);
401         }
402     }
403 
404     // Using the "none" ("default") values validates the same as explicitly
405     // specifying the values they're supposed to default to.
406     // Variant for a 2D texture with only 1 array layer.
TEST_F(TextureViewValidationTest,TextureViewDescriptorDefaults2DNonArray)407     TEST_F(TextureViewValidationTest, TextureViewDescriptorDefaults2DNonArray) {
408         constexpr uint32_t kDefaultArrayLayers = 1;
409         wgpu::Texture texture = Create2DArrayTexture(device, kDefaultArrayLayers);
410 
411         { texture.CreateView(); }
412         {
413             wgpu::TextureViewDescriptor descriptor;
414             descriptor.format = wgpu::TextureFormat::Undefined;
415             texture.CreateView(&descriptor);
416             descriptor.format = wgpu::TextureFormat::RGBA8Unorm;
417             texture.CreateView(&descriptor);
418             descriptor.format = wgpu::TextureFormat::R8Unorm;
419             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
420         }
421         {
422             wgpu::TextureViewDescriptor descriptor;
423             descriptor.dimension = wgpu::TextureViewDimension::Undefined;
424             texture.CreateView(&descriptor);
425             descriptor.dimension = wgpu::TextureViewDimension::e2D;
426             texture.CreateView(&descriptor);
427             descriptor.dimension = wgpu::TextureViewDimension::e2DArray;
428             texture.CreateView(&descriptor);
429         }
430         {
431             wgpu::TextureViewDescriptor descriptor;
432             descriptor.arrayLayerCount = wgpu::kArrayLayerCountUndefined;
433             texture.CreateView(&descriptor);
434             descriptor.arrayLayerCount = 1;
435             texture.CreateView(&descriptor);
436             descriptor.arrayLayerCount = 2;
437             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
438         }
439         {
440             wgpu::TextureViewDescriptor descriptor;
441             descriptor.mipLevelCount = kDefaultMipLevels;
442             texture.CreateView(&descriptor);
443             descriptor.arrayLayerCount = kDefaultArrayLayers;
444             texture.CreateView(&descriptor);
445         }
446     }
447 
448     // Using the "none" ("default") values validates the same as explicitly
449     // specifying the values they're supposed to default to.
450     // Variant for a 3D texture.
TEST_F(TextureViewValidationTest,TextureViewDescriptorDefaults3D)451     TEST_F(TextureViewValidationTest, TextureViewDescriptorDefaults3D) {
452         wgpu::Texture texture = Create3DTexture(device);
453 
454         { texture.CreateView(); }
455         {
456             wgpu::TextureViewDescriptor descriptor;
457             descriptor.format = wgpu::TextureFormat::Undefined;
458             texture.CreateView(&descriptor);
459             descriptor.format = wgpu::TextureFormat::RGBA8Unorm;
460             texture.CreateView(&descriptor);
461             descriptor.format = wgpu::TextureFormat::R8Unorm;
462             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
463         }
464         {
465             wgpu::TextureViewDescriptor descriptor;
466             descriptor.dimension = wgpu::TextureViewDimension::Undefined;
467             texture.CreateView(&descriptor);
468             descriptor.dimension = wgpu::TextureViewDimension::e3D;
469             texture.CreateView(&descriptor);
470             descriptor.dimension = wgpu::TextureViewDimension::e2DArray;
471             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
472             descriptor.dimension = wgpu::TextureViewDimension::e2D;
473             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
474         }
475         {
476             wgpu::TextureViewDescriptor descriptor;
477             descriptor.arrayLayerCount = wgpu::kArrayLayerCountUndefined;
478             texture.CreateView(&descriptor);
479             descriptor.arrayLayerCount = 1;
480             texture.CreateView(&descriptor);
481             descriptor.arrayLayerCount = 2;
482             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
483         }
484         {
485             wgpu::TextureViewDescriptor descriptor;
486             descriptor.mipLevelCount = kDefaultMipLevels;
487             texture.CreateView(&descriptor);
488             descriptor.arrayLayerCount = kDepth;
489             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
490         }
491     }
492 
493     // Test creating cube map texture view
TEST_F(TextureViewValidationTest,CreateCubeMapTextureView)494     TEST_F(TextureViewValidationTest, CreateCubeMapTextureView) {
495         constexpr uint32_t kDefaultArrayLayers = 16;
496 
497         wgpu::Texture texture = Create2DArrayTexture(device, kDefaultArrayLayers);
498 
499         wgpu::TextureViewDescriptor base2DArrayTextureViewDescriptor =
500             CreateDefaultViewDescriptor(wgpu::TextureViewDimension::e2DArray);
501 
502         // It is an error to create a view with zero 'arrayLayerCount'.
503         {
504             wgpu::TextureViewDescriptor descriptor = base2DArrayTextureViewDescriptor;
505             descriptor.dimension = wgpu::TextureViewDimension::Cube;
506             descriptor.arrayLayerCount = 0;
507             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
508         }
509 
510         // It is an error to create a view with zero 'mipLevelCount'.
511         {
512             wgpu::TextureViewDescriptor descriptor = base2DArrayTextureViewDescriptor;
513             descriptor.dimension = wgpu::TextureViewDimension::Cube;
514             descriptor.mipLevelCount = 0;
515             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
516         }
517 
518         // It is OK to create a cube map texture view with arrayLayerCount == 6.
519         {
520             wgpu::TextureViewDescriptor descriptor = base2DArrayTextureViewDescriptor;
521             descriptor.dimension = wgpu::TextureViewDimension::Cube;
522             descriptor.arrayLayerCount = 6;
523             texture.CreateView(&descriptor);
524         }
525 
526         // It is an error to create a cube map texture view with arrayLayerCount != 6.
527         {
528             wgpu::TextureViewDescriptor descriptor = base2DArrayTextureViewDescriptor;
529             descriptor.dimension = wgpu::TextureViewDimension::Cube;
530             descriptor.arrayLayerCount = 3;
531             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
532         }
533 
534         // It is OK to create a cube map array texture view with arrayLayerCount % 6 == 0.
535         {
536             wgpu::TextureViewDescriptor descriptor = base2DArrayTextureViewDescriptor;
537             descriptor.dimension = wgpu::TextureViewDimension::CubeArray;
538             descriptor.arrayLayerCount = 12;
539             texture.CreateView(&descriptor);
540         }
541 
542         // It is an error to create a cube map array texture view with arrayLayerCount % 6 != 0.
543         {
544             wgpu::TextureViewDescriptor descriptor = base2DArrayTextureViewDescriptor;
545             descriptor.dimension = wgpu::TextureViewDimension::CubeArray;
546             descriptor.arrayLayerCount = 11;
547             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
548         }
549 
550         // It is an error to create a cube map texture view with width != height.
551         {
552             wgpu::Texture nonSquareTexture = Create2DArrayTexture(device, 18, 32, 16, 5);
553 
554             wgpu::TextureViewDescriptor descriptor = base2DArrayTextureViewDescriptor;
555             descriptor.dimension = wgpu::TextureViewDimension::Cube;
556             descriptor.arrayLayerCount = 6;
557             ASSERT_DEVICE_ERROR(nonSquareTexture.CreateView(&descriptor));
558         }
559 
560         // It is an error to create a cube map array texture view with width != height.
561         {
562             wgpu::Texture nonSquareTexture = Create2DArrayTexture(device, 18, 32, 16, 5);
563 
564             wgpu::TextureViewDescriptor descriptor = base2DArrayTextureViewDescriptor;
565             descriptor.dimension = wgpu::TextureViewDimension::CubeArray;
566             descriptor.arrayLayerCount = 12;
567             ASSERT_DEVICE_ERROR(nonSquareTexture.CreateView(&descriptor));
568         }
569     }
570 
571     // Test the format compatibility rules when creating a texture view.
572     // TODO(jiawei.shao@intel.com): add more tests when the rules are fully implemented.
TEST_F(TextureViewValidationTest,TextureViewFormatCompatibility)573     TEST_F(TextureViewValidationTest, TextureViewFormatCompatibility) {
574         wgpu::Texture texture = Create2DArrayTexture(device, 1);
575 
576         wgpu::TextureViewDescriptor base2DTextureViewDescriptor =
577             CreateDefaultViewDescriptor(wgpu::TextureViewDimension::e2D);
578 
579         // It is an error to create a texture view in depth-stencil format on a RGBA texture.
580         {
581             wgpu::TextureViewDescriptor descriptor = base2DTextureViewDescriptor;
582             descriptor.format = wgpu::TextureFormat::Depth24PlusStencil8;
583             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
584         }
585     }
586 
587     // Test that it's valid to create a texture view from a destroyed texture
TEST_F(TextureViewValidationTest,DestroyCreateTextureView)588     TEST_F(TextureViewValidationTest, DestroyCreateTextureView) {
589         wgpu::Texture texture = Create2DArrayTexture(device, 1);
590         wgpu::TextureViewDescriptor descriptor =
591             CreateDefaultViewDescriptor(wgpu::TextureViewDimension::e2D);
592         texture.Destroy();
593         texture.CreateView(&descriptor);
594     }
595 
596     // Test that the selected TextureAspects must exist in the texture format
TEST_F(TextureViewValidationTest,AspectMustExist)597     TEST_F(TextureViewValidationTest, AspectMustExist) {
598         wgpu::TextureDescriptor descriptor = {};
599         descriptor.size = {1, 1, 1};
600         descriptor.usage =
601             wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::RenderAttachment;
602 
603         // Can select: All and DepthOnly from Depth32Float, but not StencilOnly
604         {
605             descriptor.format = wgpu::TextureFormat::Depth32Float;
606             wgpu::Texture texture = device.CreateTexture(&descriptor);
607 
608             wgpu::TextureViewDescriptor viewDescriptor = {};
609             viewDescriptor.aspect = wgpu::TextureAspect::All;
610             texture.CreateView(&viewDescriptor);
611 
612             viewDescriptor.aspect = wgpu::TextureAspect::DepthOnly;
613             texture.CreateView(&viewDescriptor);
614 
615             viewDescriptor.aspect = wgpu::TextureAspect::StencilOnly;
616             ASSERT_DEVICE_ERROR(texture.CreateView(&viewDescriptor));
617         }
618 
619         // Can select: All, DepthOnly, and StencilOnly from Depth24PlusStencil8
620         {
621             descriptor.format = wgpu::TextureFormat::Depth24PlusStencil8;
622             wgpu::Texture texture = device.CreateTexture(&descriptor);
623 
624             wgpu::TextureViewDescriptor viewDescriptor = {};
625             viewDescriptor.aspect = wgpu::TextureAspect::All;
626             texture.CreateView(&viewDescriptor);
627 
628             viewDescriptor.aspect = wgpu::TextureAspect::DepthOnly;
629             texture.CreateView(&viewDescriptor);
630 
631             viewDescriptor.aspect = wgpu::TextureAspect::StencilOnly;
632             texture.CreateView(&viewDescriptor);
633         }
634 
635         // Can select: All from RGBA8Unorm
636         {
637             descriptor.format = wgpu::TextureFormat::RGBA8Unorm;
638             wgpu::Texture texture = device.CreateTexture(&descriptor);
639 
640             wgpu::TextureViewDescriptor viewDescriptor = {};
641             viewDescriptor.aspect = wgpu::TextureAspect::All;
642             texture.CreateView(&viewDescriptor);
643 
644             viewDescriptor.aspect = wgpu::TextureAspect::DepthOnly;
645             ASSERT_DEVICE_ERROR(texture.CreateView(&viewDescriptor));
646 
647             viewDescriptor.aspect = wgpu::TextureAspect::StencilOnly;
648             ASSERT_DEVICE_ERROR(texture.CreateView(&viewDescriptor));
649         }
650     }
651 
652     class D24S8TextureViewValidationTests : public ValidationTest {
653       protected:
CreateTestDevice()654         WGPUDevice CreateTestDevice() override {
655             dawn_native::DeviceDescriptor descriptor;
656             descriptor.requiredFeatures = {"depth24unorm-stencil8"};
657             return adapter.CreateDevice(&descriptor);
658         }
659     };
660 
661     // Test that the selected TextureAspects must exist in the Depth24UnormStencil8 texture format
TEST_F(D24S8TextureViewValidationTests,AspectMustExist)662     TEST_F(D24S8TextureViewValidationTests, AspectMustExist) {
663         wgpu::Texture texture =
664             CreateDepthStencilTexture(device, wgpu::TextureFormat::Depth24UnormStencil8);
665 
666         // Can select: All, DepthOnly, and StencilOnly from Depth24UnormStencil8
667         {
668             wgpu::TextureViewDescriptor viewDescriptor = {};
669             viewDescriptor.aspect = wgpu::TextureAspect::All;
670             texture.CreateView(&viewDescriptor);
671 
672             viewDescriptor.aspect = wgpu::TextureAspect::DepthOnly;
673             texture.CreateView(&viewDescriptor);
674 
675             viewDescriptor.aspect = wgpu::TextureAspect::StencilOnly;
676             texture.CreateView(&viewDescriptor);
677         }
678     }
679 
680     // Test the format compatibility rules when creating a texture view.
TEST_F(D24S8TextureViewValidationTests,TextureViewFormatCompatibility)681     TEST_F(D24S8TextureViewValidationTests, TextureViewFormatCompatibility) {
682         wgpu::Texture texture =
683             CreateDepthStencilTexture(device, wgpu::TextureFormat::Depth24UnormStencil8);
684 
685         wgpu::TextureViewDescriptor base2DTextureViewDescriptor =
686             CreateDefaultViewDescriptor(wgpu::TextureViewDimension::e2D);
687 
688         // It is an error to create a texture view in color format on a depth-stencil texture.
689         {
690             wgpu::TextureViewDescriptor descriptor = base2DTextureViewDescriptor;
691             descriptor.format = wgpu::TextureFormat::RGBA8Unorm;
692             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
693         }
694     }
695 
696     class D32S8TextureViewValidationTests : public ValidationTest {
697       protected:
CreateTestDevice()698         WGPUDevice CreateTestDevice() override {
699             dawn_native::DeviceDescriptor descriptor;
700             descriptor.requiredFeatures = {"depth32float-stencil8"};
701             return adapter.CreateDevice(&descriptor);
702         }
703     };
704 
705     // Test that the selected TextureAspects must exist in the Depth32FloatStencil8 texture format
TEST_F(D32S8TextureViewValidationTests,AspectMustExist)706     TEST_F(D32S8TextureViewValidationTests, AspectMustExist) {
707         wgpu::Texture texture =
708             CreateDepthStencilTexture(device, wgpu::TextureFormat::Depth32FloatStencil8);
709 
710         // Can select: All, DepthOnly, and StencilOnly from Depth32FloatStencil8
711         {
712             wgpu::TextureViewDescriptor viewDescriptor = {};
713             viewDescriptor.aspect = wgpu::TextureAspect::All;
714             texture.CreateView(&viewDescriptor);
715 
716             viewDescriptor.aspect = wgpu::TextureAspect::DepthOnly;
717             texture.CreateView(&viewDescriptor);
718 
719             viewDescriptor.aspect = wgpu::TextureAspect::StencilOnly;
720             texture.CreateView(&viewDescriptor);
721         }
722     }
723 
724     // Test the format compatibility rules when creating a texture view.
TEST_F(D32S8TextureViewValidationTests,TextureViewFormatCompatibility)725     TEST_F(D32S8TextureViewValidationTests, TextureViewFormatCompatibility) {
726         wgpu::Texture texture =
727             CreateDepthStencilTexture(device, wgpu::TextureFormat::Depth32FloatStencil8);
728 
729         wgpu::TextureViewDescriptor base2DTextureViewDescriptor =
730             CreateDefaultViewDescriptor(wgpu::TextureViewDimension::e2D);
731 
732         // It is an error to create a texture view in color format on a depth-stencil texture.
733         {
734             wgpu::TextureViewDescriptor descriptor = base2DTextureViewDescriptor;
735             descriptor.format = wgpu::TextureFormat::RGBA8Unorm;
736             ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
737         }
738     }
739 
740 }  // anonymous namespace
741