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