Metal/GL: Make new texture view for non-2D view of single-layer texture

Fixed: dawn:1309
Change-Id: Ide68f6498fc5fe9dd9e06c6c5caf7d3fff74e526
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/83060
Reviewed-by: Jiawei Shao <jiawei.shao@intel.com>
Commit-Queue: Austin Eng <enga@chromium.org>
This commit is contained in:
Austin Eng 2022-03-09 01:07:20 +00:00 committed by Dawn LUCI CQ
parent 5073fb5685
commit 154bcbbf4d
3 changed files with 51 additions and 9 deletions

View File

@ -90,7 +90,13 @@ namespace dawn::native::metal {
return true; return true;
} }
if (texture->GetArrayLayers() != textureViewDescriptor->arrayLayerCount) { if (texture->GetArrayLayers() != textureViewDescriptor->arrayLayerCount ||
(texture->GetArrayLayers() == 1 &&
texture->GetDimension() == wgpu::TextureDimension::e2D &&
textureViewDescriptor->dimension == wgpu::TextureViewDimension::e2DArray)) {
// If the view has a different number of array layers, we need a new view.
// And, if the original texture is a 2D texture with one array layer, we need a new
// view to view it as a 2D array texture.
return true; return true;
} }

View File

@ -56,8 +56,9 @@ namespace dawn::native::opengl {
case wgpu::TextureViewDimension::e2D: case wgpu::TextureViewDimension::e2D:
return (sampleCount > 1) ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D; return (sampleCount > 1) ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D;
case wgpu::TextureViewDimension::e2DArray: case wgpu::TextureViewDimension::e2DArray:
if (arrayLayerCount == 1) { if (sampleCount > 1) {
return (sampleCount > 1) ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D; ASSERT(arrayLayerCount == 1);
return GL_TEXTURE_2D_MULTISAMPLE;
} }
ASSERT(sampleCount == 1); ASSERT(sampleCount == 1);
return GL_TEXTURE_2D_ARRAY; return GL_TEXTURE_2D_ARRAY;
@ -93,7 +94,13 @@ namespace dawn::native::opengl {
return true; return true;
} }
if (texture->GetArrayLayers() != textureViewDescriptor->arrayLayerCount) { if (texture->GetArrayLayers() != textureViewDescriptor->arrayLayerCount ||
(texture->GetArrayLayers() == 1 &&
texture->GetDimension() == wgpu::TextureDimension::e2D &&
textureViewDescriptor->dimension == wgpu::TextureViewDimension::e2DArray)) {
// If the view has a different number of array layers, we need a new view.
// And, if the original texture is a 2D texture with one array layer, we need a new
// view to view it as a 2D array texture.
return true; return true;
} }

View File

@ -119,7 +119,7 @@ class TextureViewSamplingTest : public DawnTest {
mVSModule = CreateDefaultVertexShaderModule(device); mVSModule = CreateDefaultVertexShaderModule(device);
} }
void initTexture(uint32_t arrayLayerCount, uint32_t mipLevelCount) { void InitTexture(uint32_t arrayLayerCount, uint32_t mipLevelCount) {
ASSERT(arrayLayerCount > 0 && mipLevelCount > 0); ASSERT(arrayLayerCount > 0 && mipLevelCount > 0);
const uint32_t textureWidthLevel0 = 1 << mipLevelCount; const uint32_t textureWidthLevel0 = 1 << mipLevelCount;
@ -208,7 +208,7 @@ class TextureViewSamplingTest : public DawnTest {
ASSERT(textureViewBaseLayer < textureArrayLayers); ASSERT(textureViewBaseLayer < textureArrayLayers);
ASSERT(textureViewBaseMipLevel < textureMipLevels); ASSERT(textureViewBaseMipLevel < textureMipLevels);
initTexture(textureArrayLayers, textureMipLevels); InitTexture(textureArrayLayers, textureMipLevels);
wgpu::TextureViewDescriptor descriptor = mDefaultTextureViewDescriptor; wgpu::TextureViewDescriptor descriptor = mDefaultTextureViewDescriptor;
descriptor.dimension = wgpu::TextureViewDimension::e2D; descriptor.dimension = wgpu::TextureViewDimension::e2D;
@ -246,7 +246,7 @@ class TextureViewSamplingTest : public DawnTest {
constexpr uint32_t kTextureViewLayerCount = 3; constexpr uint32_t kTextureViewLayerCount = 3;
ASSERT(textureArrayLayers >= textureViewBaseLayer + kTextureViewLayerCount); ASSERT(textureArrayLayers >= textureViewBaseLayer + kTextureViewLayerCount);
initTexture(textureArrayLayers, textureMipLevels); InitTexture(textureArrayLayers, textureMipLevels);
wgpu::TextureViewDescriptor descriptor = mDefaultTextureViewDescriptor; wgpu::TextureViewDescriptor descriptor = mDefaultTextureViewDescriptor;
descriptor.dimension = wgpu::TextureViewDimension::e2DArray; descriptor.dimension = wgpu::TextureViewDimension::e2DArray;
@ -320,7 +320,7 @@ class TextureViewSamplingTest : public DawnTest {
// of 2D textures. Find a workaround. // of 2D textures. Find a workaround.
DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES()); DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
constexpr uint32_t kMipLevels = 1u; constexpr uint32_t kMipLevels = 1u;
initTexture(textureArrayLayers, kMipLevels); InitTexture(textureArrayLayers, kMipLevels);
ASSERT_TRUE((textureViewLayerCount == 6) || ASSERT_TRUE((textureViewLayerCount == 6) ||
(isCubeMapArray && textureViewLayerCount % 6 == 0)); (isCubeMapArray && textureViewLayerCount % 6 == 0));
@ -359,7 +359,7 @@ TEST_P(TextureViewSamplingTest, Default2DArrayTexture) {
constexpr uint32_t kLayers = 3; constexpr uint32_t kLayers = 3;
constexpr uint32_t kMipLevels = 1; constexpr uint32_t kMipLevels = 1;
initTexture(kLayers, kMipLevels); InitTexture(kLayers, kMipLevels);
wgpu::TextureViewDescriptor descriptor; wgpu::TextureViewDescriptor descriptor;
descriptor.dimension = wgpu::TextureViewDimension::e2DArray; descriptor.dimension = wgpu::TextureViewDimension::e2DArray;
@ -393,6 +393,35 @@ TEST_P(TextureViewSamplingTest, Texture2DArrayViewOn2DArrayTexture) {
Texture2DArrayViewTest(6, 1, 2, 0); Texture2DArrayViewTest(6, 1, 2, 0);
} }
// Test sampling from a 2D array texture view created on a 2D texture with one layer.
// Regression test for crbug.com/dawn/1309.
TEST_P(TextureViewSamplingTest, Texture2DArrayViewOnSingleLayer2DTexture) {
// TODO(crbug.com/dawn/593): This test requires glTextureView, which is unsupported on GLES.
DAWN_TEST_UNSUPPORTED_IF(IsOpenGLES());
InitTexture(1 /* array layer count */, 1 /* mip level count */);
wgpu::TextureViewDescriptor descriptor = mDefaultTextureViewDescriptor;
descriptor.dimension = wgpu::TextureViewDimension::e2DArray;
descriptor.baseArrayLayer = 0;
descriptor.arrayLayerCount = 1;
descriptor.baseMipLevel = 0;
descriptor.mipLevelCount = 1;
wgpu::TextureView textureView = mTexture.CreateView(&descriptor);
const char* fragmentShader = R"(
@group(0) @binding(0) var sampler0 : sampler;
@group(0) @binding(1) var texture0 : texture_2d_array<f32>;
@stage(fragment)
fn main(@location(0) texCoord : vec2<f32>) -> @location(0) vec4<f32> {
return textureSample(texture0, sampler0, texCoord, 0);
}
)";
int expected = GenerateTestPixelValue(0, 0);
Verify(textureView, fragmentShader, expected);
}
// Test sampling from a 2D texture view created on a mipmap level of a 2D texture. // Test sampling from a 2D texture view created on a mipmap level of a 2D texture.
TEST_P(TextureViewSamplingTest, Texture2DViewOnOneLevelOf2DTexture) { TEST_P(TextureViewSamplingTest, Texture2DViewOnOneLevelOf2DTexture) {
Texture2DViewTest(1, 6, 0, 4); Texture2DViewTest(1, 6, 0, 4);