diff --git a/src/dawn_native/Texture.cpp b/src/dawn_native/Texture.cpp index 53e8d10f44..0baedf2377 100644 --- a/src/dawn_native/Texture.cpp +++ b/src/dawn_native/Texture.cpp @@ -66,19 +66,43 @@ namespace dawn_native { } } + bool IsTextureSizeValidForTextureViewDimension( + dawn::TextureViewDimension textureViewDimension, + const Extent3D& textureSize) { + switch (textureViewDimension) { + case dawn::TextureViewDimension::Cube: + case dawn::TextureViewDimension::CubeArray: + return textureSize.width == textureSize.height; + case dawn::TextureViewDimension::e2D: + case dawn::TextureViewDimension::e2DArray: + return true; + default: + UNREACHABLE(); + return false; + } + } + MaybeError ValidateTextureViewDimensionCompatibility( const TextureBase* texture, const TextureViewDescriptor* descriptor) { if (!IsArrayLayerValidForTextureViewDimension(descriptor->dimension, descriptor->layerCount)) { return DAWN_VALIDATION_ERROR( - "The dimension of the texture view is not compatible to the layer count"); + "The dimension of the texture view is not compatible with the layer count"); } if (!IsTextureViewDimensionCompatibleWithTextureDimension(descriptor->dimension, texture->GetDimension())) { return DAWN_VALIDATION_ERROR( - "The dimension of texture view is not compatible to the original texture"); + "The dimension of the texture view is not compatible with the dimension of the" + "original texture"); + } + + if (!IsTextureSizeValidForTextureViewDimension(descriptor->dimension, + texture->GetSize())) { + return DAWN_VALIDATION_ERROR( + "The dimension of the texture view is not compatible with the size of the" + "original texture"); } return {}; diff --git a/src/dawn_native/vulkan/DeviceVk.cpp b/src/dawn_native/vulkan/DeviceVk.cpp index 5998674225..5b3b976fa4 100644 --- a/src/dawn_native/vulkan/DeviceVk.cpp +++ b/src/dawn_native/vulkan/DeviceVk.cpp @@ -497,8 +497,10 @@ namespace dawn_native { namespace vulkan { usedKnobs->swapchain = true; } - // Always require independentBlend because it is a core Dawn feature, + // Always require independentBlend because it is a core Dawn feature usedKnobs->features.independentBlend = VK_TRUE; + // Always require imageCubeArray because it is a core Dawn feature + usedKnobs->features.imageCubeArray = VK_TRUE; // Find a universal queue family { diff --git a/src/dawn_native/vulkan/TextureVk.cpp b/src/dawn_native/vulkan/TextureVk.cpp index 6cba63cf3d..b120f64f12 100644 --- a/src/dawn_native/vulkan/TextureVk.cpp +++ b/src/dawn_native/vulkan/TextureVk.cpp @@ -267,6 +267,10 @@ namespace dawn_native { namespace vulkan { createInfo.pQueueFamilyIndices = nullptr; createInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + if (GetArrayLayers() >= 6 && GetSize().width == GetSize().height) { + createInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; + } + if (device->fn.CreateImage(device->GetVkDevice(), &createInfo, nullptr, &mHandle) != VK_SUCCESS) { ASSERT(false); diff --git a/src/tests/unittests/validation/TextureViewValidationTests.cpp b/src/tests/unittests/validation/TextureViewValidationTests.cpp index a81ae3e9f0..0d4ec769e2 100644 --- a/src/tests/unittests/validation/TextureViewValidationTests.cpp +++ b/src/tests/unittests/validation/TextureViewValidationTests.cpp @@ -27,14 +27,15 @@ constexpr dawn::TextureFormat kDefaultTextureFormat = dawn::TextureFormat::R8G8B dawn::Texture Create2DArrayTexture(dawn::Device& device, uint32_t arrayLayers, - dawn::TextureFormat format = kDefaultTextureFormat) { + uint32_t width = kWidth, + uint32_t height = kHeight) { dawn::TextureDescriptor descriptor; descriptor.dimension = dawn::TextureDimension::e2D; - descriptor.size.width = kWidth; - descriptor.size.height = kHeight; + descriptor.size.width = width; + descriptor.size.height = height; descriptor.size.depth = 1; descriptor.arrayLayer = arrayLayers; - descriptor.format = format; + descriptor.format = kDefaultTextureFormat; descriptor.levelCount = kDefaultMipLevels; descriptor.usage = dawn::TextureUsageBit::Sampled; return device.CreateTexture(&descriptor); @@ -169,13 +170,33 @@ TEST_F(TextureViewValidationTest, CreateCubeMapTextureView) { texture.CreateTextureView(&descriptor); } - // It is an error create a cube map array texture view with layerCount % 6 != 0. + // It is an error to create a cube map array texture view with layerCount % 6 != 0. { dawn::TextureViewDescriptor descriptor = base2DArrayTextureViewDescriptor; descriptor.dimension = dawn::TextureViewDimension::CubeArray; descriptor.layerCount = 11; ASSERT_DEVICE_ERROR(texture.CreateTextureView(&descriptor)); } + + // It is an error to create a cube map texture view with width != height. + { + dawn::Texture nonSquareTexture = Create2DArrayTexture(device, 18, 32, 16); + + dawn::TextureViewDescriptor descriptor = base2DArrayTextureViewDescriptor; + descriptor.dimension = dawn::TextureViewDimension::Cube; + descriptor.layerCount = 6; + ASSERT_DEVICE_ERROR(nonSquareTexture.CreateTextureView(&descriptor)); + } + + // It is an error to create a cube map array texture view with width != height. + { + dawn::Texture nonSquareTexture = Create2DArrayTexture(device, 18, 32, 16); + + dawn::TextureViewDescriptor descriptor = base2DArrayTextureViewDescriptor; + descriptor.dimension = dawn::TextureViewDimension::CubeArray; + descriptor.layerCount = 12; + ASSERT_DEVICE_ERROR(nonSquareTexture.CreateTextureView(&descriptor)); + } } // Test the format compatibility rules when creating a texture view.