1 // Copyright 2021 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 #include "utils/WGPUHelpers.h"
18
19 class TextureInternalUsageValidationDisabledTest : public ValidationTest {};
20
21 // Test that using the feature is an error if it is not enabled
TEST_F(TextureInternalUsageValidationDisabledTest,RequiresFeature)22 TEST_F(TextureInternalUsageValidationDisabledTest, RequiresFeature) {
23 wgpu::TextureDescriptor textureDesc = {};
24 textureDesc.size = {1, 1};
25 textureDesc.usage = wgpu::TextureUsage::CopySrc;
26 textureDesc.format = wgpu::TextureFormat::RGBA8Unorm;
27
28 // Control case: Normal texture creation works
29 device.CreateTexture(&textureDesc);
30
31 wgpu::DawnTextureInternalUsageDescriptor internalDesc = {};
32 textureDesc.nextInChain = &internalDesc;
33
34 // Error with chained feature struct.
35 ASSERT_DEVICE_ERROR(device.CreateTexture(&textureDesc));
36
37 // Also does not work with various internal usages.
38 internalDesc.internalUsage = wgpu::TextureUsage::CopySrc;
39 ASSERT_DEVICE_ERROR(device.CreateTexture(&textureDesc));
40
41 internalDesc.internalUsage = wgpu::TextureUsage::CopyDst;
42 ASSERT_DEVICE_ERROR(device.CreateTexture(&textureDesc));
43 }
44
45 class TextureInternalUsageValidationTest : public ValidationTest {
CreateTestDevice()46 WGPUDevice CreateTestDevice() override {
47 dawn_native::DawnDeviceDescriptor descriptor;
48 descriptor.requiredFeatures.push_back("dawn-internal-usages");
49
50 return adapter.CreateDevice(&descriptor);
51 }
52 };
53
54 // Test that internal usages can be passed in a chained descriptor.
TEST_F(TextureInternalUsageValidationTest,Basic)55 TEST_F(TextureInternalUsageValidationTest, Basic) {
56 wgpu::TextureDescriptor textureDesc = {};
57 textureDesc.size = {1, 1};
58 textureDesc.usage = wgpu::TextureUsage::CopySrc;
59 textureDesc.format = wgpu::TextureFormat::RGBA8Unorm;
60
61 wgpu::DawnTextureInternalUsageDescriptor internalDesc = {};
62 textureDesc.nextInChain = &internalDesc;
63
64 // Internal usage: none
65 device.CreateTexture(&textureDesc);
66
67 // Internal usage is the same as the base usage.
68 internalDesc.internalUsage = wgpu::TextureUsage::CopySrc;
69 device.CreateTexture(&textureDesc);
70
71 // Internal usage adds to the base usage.
72 internalDesc.internalUsage = wgpu::TextureUsage::CopyDst;
73 device.CreateTexture(&textureDesc);
74 }
75
76 // Test that internal usages takes part in other validation that
77 // depends on the usage.
TEST_F(TextureInternalUsageValidationTest,UsageValidation)78 TEST_F(TextureInternalUsageValidationTest, UsageValidation) {
79 {
80 wgpu::TextureDescriptor textureDesc = {};
81 textureDesc.size = {1, 1};
82 textureDesc.usage = wgpu::TextureUsage::CopySrc;
83 textureDesc.format = wgpu::TextureFormat::RGBA8Unorm;
84
85 wgpu::DawnTextureInternalUsageDescriptor internalDesc = {};
86 textureDesc.nextInChain = &internalDesc;
87
88 // Internal usage adds an invalid usage.
89 internalDesc.internalUsage = static_cast<wgpu::TextureUsage>(-1);
90 ASSERT_DEVICE_ERROR(device.CreateTexture(&textureDesc));
91 }
92
93 {
94 wgpu::TextureDescriptor textureDesc = {};
95 textureDesc.size = {1, 1};
96 textureDesc.usage = wgpu::TextureUsage::CopySrc;
97 textureDesc.format = wgpu::TextureFormat::RGBA8Unorm;
98 textureDesc.sampleCount = 4;
99
100 // Control case: multisampled texture
101 device.CreateTexture(&textureDesc);
102
103 wgpu::DawnTextureInternalUsageDescriptor internalDesc = {};
104 textureDesc.nextInChain = &internalDesc;
105
106 // OK: internal usage adds nothing.
107 device.CreateTexture(&textureDesc);
108
109 // Internal usage adds storage usage which is invalid
110 // with multisampling.
111 internalDesc.internalUsage = wgpu::TextureUsage::StorageBinding;
112 ASSERT_DEVICE_ERROR(device.CreateTexture(&textureDesc));
113 }
114 }
115
116 // Test that internal usage does not add to the validated usage
117 // for command encoding
118 // This test also test the internal copy
TEST_F(TextureInternalUsageValidationTest,CommandValidation)119 TEST_F(TextureInternalUsageValidationTest, CommandValidation) {
120 wgpu::TextureDescriptor textureDesc = {};
121 textureDesc.size = {1, 1};
122 textureDesc.format = wgpu::TextureFormat::RGBA8Unorm;
123
124 textureDesc.usage = wgpu::TextureUsage::CopyDst;
125 wgpu::Texture dst = device.CreateTexture(&textureDesc);
126
127 textureDesc.usage = wgpu::TextureUsage::CopySrc;
128 wgpu::Texture src = device.CreateTexture(&textureDesc);
129
130 textureDesc.usage = wgpu::TextureUsage::None;
131
132 wgpu::DawnTextureInternalUsageDescriptor internalDesc = {};
133 textureDesc.nextInChain = &internalDesc;
134 internalDesc.internalUsage = wgpu::TextureUsage::CopySrc;
135
136 wgpu::Texture srcInternal = device.CreateTexture(&textureDesc);
137
138 // Control: src -> dst
139 {
140 wgpu::ImageCopyTexture srcImageCopyTexture = utils::CreateImageCopyTexture(src, 0, {0, 0});
141 wgpu::ImageCopyTexture dstImageCopyTexture = utils::CreateImageCopyTexture(dst, 0, {0, 0});
142 wgpu::Extent3D extent3D = {1, 1};
143
144 wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
145 encoder.CopyTextureToTexture(&srcImageCopyTexture, &dstImageCopyTexture, &extent3D);
146 encoder.Finish();
147 }
148
149 // Invalid: src internal -> dst
150 {
151 wgpu::ImageCopyTexture srcImageCopyTexture =
152 utils::CreateImageCopyTexture(srcInternal, 0, {0, 0});
153 wgpu::ImageCopyTexture dstImageCopyTexture = utils::CreateImageCopyTexture(dst, 0, {0, 0});
154 wgpu::Extent3D extent3D = {1, 1};
155
156 wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
157 encoder.CopyTextureToTexture(&srcImageCopyTexture, &dstImageCopyTexture, &extent3D);
158 ASSERT_DEVICE_ERROR(encoder.Finish());
159 }
160
161 // Control with internal copy: src -> dst
162 {
163 wgpu::ImageCopyTexture srcImageCopyTexture = utils::CreateImageCopyTexture(src, 0, {0, 0});
164 wgpu::ImageCopyTexture dstImageCopyTexture = utils::CreateImageCopyTexture(dst, 0, {0, 0});
165 wgpu::Extent3D extent3D = {1, 1};
166
167 wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
168 encoder.CopyTextureToTextureInternal(&srcImageCopyTexture, &dstImageCopyTexture, &extent3D);
169 encoder.Finish();
170 }
171
172 // Valid with internal copy: src internal -> dst
173 {
174 wgpu::ImageCopyTexture srcImageCopyTexture =
175 utils::CreateImageCopyTexture(srcInternal, 0, {0, 0});
176 wgpu::ImageCopyTexture dstImageCopyTexture = utils::CreateImageCopyTexture(dst, 0, {0, 0});
177 wgpu::Extent3D extent3D = {1, 1};
178
179 wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
180 encoder.CopyTextureToTextureInternal(&srcImageCopyTexture, &dstImageCopyTexture, &extent3D);
181 encoder.Finish();
182 }
183 }
184