Query if Texture subresource has been initialized

Bug: chromium:1036080
Change-Id: Ieb4c7012ae2d7d7b863c999756930b0ce45c06cb
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/16422
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Natasha Lee <natlee@microsoft.com>
This commit is contained in:
Natasha Lee 2020-03-05 17:07:16 +00:00 committed by Commit Bot service account
parent 56f1678437
commit 1d54767364
3 changed files with 115 additions and 6 deletions

View File

@ -15,6 +15,7 @@
#include "dawn_native/DawnNative.h"
#include "dawn_native/Device.h"
#include "dawn_native/Instance.h"
#include "dawn_native/Texture.h"
#include "dawn_platform/DawnPlatform.h"
// Contains the entry-points into dawn_native
@ -165,6 +166,17 @@ namespace dawn_native {
return deviceBase->GetLazyClearCountForTesting();
}
bool IsTextureSubresourceInitialized(WGPUTexture texture,
uint32_t baseMipLevel,
uint32_t levelCount,
uint32_t baseArrayLayer,
uint32_t layerCount) {
dawn_native::TextureBase* textureBase =
reinterpret_cast<dawn_native::TextureBase*>(texture);
return textureBase->IsSubresourceContentInitialized(baseMipLevel, levelCount,
baseArrayLayer, layerCount);
}
std::vector<const char*> GetProcMapNamesForTestingInternal();
std::vector<const char*> GetProcMapNamesForTesting() {

View File

@ -175,6 +175,13 @@ namespace dawn_native {
// Backdoor to get the number of lazy clears for testing
DAWN_NATIVE_EXPORT size_t GetLazyClearCountForTesting(WGPUDevice device);
// Query if texture has been initialized
DAWN_NATIVE_EXPORT bool IsTextureSubresourceInitialized(WGPUTexture texture,
uint32_t baseMipLevel,
uint32_t levelCount,
uint32_t baseArrayLayer,
uint32_t layerCount);
// Backdoor to get the order of the ProcMap for testing
DAWN_NATIVE_EXPORT std::vector<const char*> GetProcMapNamesForTesting();

View File

@ -31,6 +31,7 @@
class TextureZeroInitTest : public DawnTest {
protected:
void TestSetUp() override {
DAWN_SKIP_TEST_IF(UsesWire());
DawnTest::TestSetUp();
}
wgpu::TextureDescriptor CreateTextureDescriptor(uint32_t mipLevelCount,
@ -123,16 +124,26 @@ TEST_P(TextureZeroInitTest, CopyTextureToBufferSource) {
// Texture's first usage is in EXPECT_PIXEL_RGBA8_EQ's call to CopyTextureToBuffer
RGBA8 filledWithZeros(0, 0, 0, 0);
EXPECT_LAZY_CLEAR(1u, EXPECT_PIXEL_RGBA8_EQ(filledWithZeros, texture, 0, 0));
// Expect texture subresource initialized to be true
EXPECT_EQ(true, dawn_native::IsTextureSubresourceInitialized(texture.Get(), 0, 1, 0, 1));
}
// Test that non-zero mip level clears subresource to Zero after first use
// This goes through the BeginRenderPass's code path
TEST_P(TextureZeroInitTest, RenderingMipMapClearsToZero) {
uint32_t baseMipLevel = 2;
uint32_t levelCount = 4;
uint32_t baseArrayLayer = 0;
uint32_t layerCount = 1;
wgpu::TextureDescriptor descriptor = CreateTextureDescriptor(
4, 1, wgpu::TextureUsage::OutputAttachment | wgpu::TextureUsage::CopySrc, kColorFormat);
levelCount, layerCount, wgpu::TextureUsage::OutputAttachment | wgpu::TextureUsage::CopySrc,
kColorFormat);
wgpu::Texture texture = device.CreateTexture(&descriptor);
wgpu::TextureViewDescriptor viewDescriptor = CreateTextureViewDescriptor(2, 0);
wgpu::TextureViewDescriptor viewDescriptor =
CreateTextureViewDescriptor(baseMipLevel, baseArrayLayer);
wgpu::TextureView view = texture.CreateView(&viewDescriptor);
utils::BasicRenderPass renderPass = utils::BasicRenderPass(kSize, kSize, texture, kColorFormat);
@ -155,17 +166,29 @@ TEST_P(TextureZeroInitTest, RenderingMipMapClearsToZero) {
uint32_t mipSize = kSize >> 2;
std::vector<RGBA8> expected(mipSize * mipSize, {0, 0, 0, 0});
EXPECT_TEXTURE_RGBA8_EQ(expected.data(), renderPass.color, 0, 0, mipSize, mipSize, 2, 0);
EXPECT_TEXTURE_RGBA8_EQ(expected.data(), renderPass.color, 0, 0, mipSize, mipSize, baseMipLevel,
baseArrayLayer);
// Expect texture subresource initialized to be true
EXPECT_EQ(true, dawn_native::IsTextureSubresourceInitialized(
renderPass.color.Get(), baseMipLevel, 1, baseArrayLayer, 1));
}
// Test that non-zero array layers clears subresource to Zero after first use.
// This goes through the BeginRenderPass's code path
TEST_P(TextureZeroInitTest, RenderingArrayLayerClearsToZero) {
uint32_t baseMipLevel = 0;
uint32_t levelCount = 1;
uint32_t baseArrayLayer = 2;
uint32_t layerCount = 4;
wgpu::TextureDescriptor descriptor = CreateTextureDescriptor(
1, 4, wgpu::TextureUsage::OutputAttachment | wgpu::TextureUsage::CopySrc, kColorFormat);
levelCount, layerCount, wgpu::TextureUsage::OutputAttachment | wgpu::TextureUsage::CopySrc,
kColorFormat);
wgpu::Texture texture = device.CreateTexture(&descriptor);
wgpu::TextureViewDescriptor viewDescriptor = CreateTextureViewDescriptor(0, 2);
wgpu::TextureViewDescriptor viewDescriptor =
CreateTextureViewDescriptor(baseMipLevel, baseArrayLayer);
wgpu::TextureView view = texture.CreateView(&viewDescriptor);
utils::BasicRenderPass renderPass = utils::BasicRenderPass(kSize, kSize, texture, kColorFormat);
@ -186,7 +209,12 @@ TEST_P(TextureZeroInitTest, RenderingArrayLayerClearsToZero) {
std::vector<RGBA8> expected(kSize * kSize, {0, 0, 0, 0});
EXPECT_TEXTURE_RGBA8_EQ(expected.data(), renderPass.color, 0, 0, kSize, kSize, 0, 2);
EXPECT_TEXTURE_RGBA8_EQ(expected.data(), renderPass.color, 0, 0, kSize, kSize, baseMipLevel,
baseArrayLayer);
// Expect texture subresource initialized to be true
EXPECT_EQ(true, dawn_native::IsTextureSubresourceInitialized(
renderPass.color.Get(), baseMipLevel, 1, baseArrayLayer, 1));
}
// This tests CopyBufferToTexture fully overwrites copy so lazy init is not needed.
@ -213,6 +241,9 @@ TEST_P(TextureZeroInitTest, CopyBufferToTexture) {
std::vector<RGBA8> expected(kSize * kSize, {100, 100, 100, 100});
EXPECT_TEXTURE_RGBA8_EQ(expected.data(), texture, 0, 0, kSize, kSize, 0, 0);
// Expect texture subresource initialized to be true
EXPECT_EQ(true, dawn_native::IsTextureSubresourceInitialized(texture.Get(), 0, 1, 0, 1));
}
// Test for a copy only to a subset of the subresource, lazy init is necessary to clear the other
@ -243,6 +274,9 @@ TEST_P(TextureZeroInitTest, CopyBufferToTextureHalf) {
EXPECT_TEXTURE_RGBA8_EQ(expected100.data(), texture, 0, 0, kSize / 2, kSize, 0, 0);
// second half should be cleared
EXPECT_TEXTURE_RGBA8_EQ(expectedZeros.data(), texture, kSize / 2, 0, kSize / 2, kSize, 0, 0);
// Expect texture subresource initialized to be true
EXPECT_EQ(true, dawn_native::IsTextureSubresourceInitialized(texture.Get(), 0, 1, 0, 1));
}
// This tests CopyTextureToTexture fully overwrites copy so lazy init is not needed.
@ -275,6 +309,10 @@ TEST_P(TextureZeroInitTest, CopyTextureToTexture) {
EXPECT_TEXTURE_RGBA8_EQ(expected.data(), srcTexture, 0, 0, kSize, kSize, 0, 0);
EXPECT_TEXTURE_RGBA8_EQ(expected.data(), dstTexture, 0, 0, kSize, kSize, 0, 0);
// Expect texture subresource initialized to be true
EXPECT_EQ(true, dawn_native::IsTextureSubresourceInitialized(srcTexture.Get(), 0, 1, 0, 1));
EXPECT_EQ(true, dawn_native::IsTextureSubresourceInitialized(dstTexture.Get(), 0, 1, 0, 1));
}
// This Tests the CopyTextureToTexture's copy only to a subset of the subresource, lazy init is
@ -327,6 +365,10 @@ TEST_P(TextureZeroInitTest, CopyTextureToTextureHalf) {
EXPECT_TEXTURE_RGBA8_EQ(expectedWith100.data(), dstTexture, 0, 0, kSize / 2, kSize, 0, 0);
EXPECT_TEXTURE_RGBA8_EQ(expectedWithZeros.data(), dstTexture, kSize / 2, 0, kSize / 2, kSize, 0,
0);
// Expect texture subresource initialized to be true
EXPECT_EQ(true, dawn_native::IsTextureSubresourceInitialized(srcTexture.Get(), 0, 1, 0, 1));
EXPECT_EQ(true, dawn_native::IsTextureSubresourceInitialized(dstTexture.Get(), 0, 1, 0, 1));
}
// This tests the texture with depth attachment and load op load will init depth stencil texture to
@ -366,6 +408,9 @@ TEST_P(TextureZeroInitTest, RenderingLoadingDepth) {
// Expect the texture to be red because depth test passed.
std::vector<RGBA8> expected(kSize * kSize, {255, 0, 0, 255});
EXPECT_TEXTURE_RGBA8_EQ(expected.data(), srcTexture, 0, 0, kSize, kSize, 0, 0);
// Expect texture subresource initialized to be true
EXPECT_EQ(true, dawn_native::IsTextureSubresourceInitialized(srcTexture.Get(), 0, 1, 0, 1));
}
// This tests the texture with stencil attachment and load op load will init depth stencil texture
@ -405,6 +450,9 @@ TEST_P(TextureZeroInitTest, RenderingLoadingStencil) {
// Expect the texture to be red because stencil test passed.
std::vector<RGBA8> expected(kSize * kSize, {255, 0, 0, 255});
EXPECT_TEXTURE_RGBA8_EQ(expected.data(), srcTexture, 0, 0, kSize, kSize, 0, 0);
// Expect texture subresource initialized to be true
EXPECT_EQ(true, dawn_native::IsTextureSubresourceInitialized(srcTexture.Get(), 0, 1, 0, 1));
}
// This tests the texture with depth stencil attachment and load op load will init depth stencil
@ -441,6 +489,9 @@ TEST_P(TextureZeroInitTest, RenderingLoadingDepthStencil) {
// Expect the texture to be red because both depth and stencil tests passed.
std::vector<RGBA8> expected(kSize * kSize, {255, 0, 0, 255});
EXPECT_TEXTURE_RGBA8_EQ(expected.data(), srcTexture, 0, 0, kSize, kSize, 0, 0);
// Expect texture subresource initialized to be true
EXPECT_EQ(true, dawn_native::IsTextureSubresourceInitialized(srcTexture.Get(), 0, 1, 0, 1));
}
// This tests the color attachments clear to 0s
@ -460,6 +511,10 @@ TEST_P(TextureZeroInitTest, ColorAttachmentsClear) {
std::vector<RGBA8> expected(kSize * kSize, {0, 0, 0, 0});
EXPECT_TEXTURE_RGBA8_EQ(expected.data(), renderPass.color, 0, 0, kSize, kSize, 0, 0);
// Expect texture subresource initialized to be true
EXPECT_EQ(true,
dawn_native::IsTextureSubresourceInitialized(renderPass.color.Get(), 0, 1, 0, 1));
}
// This tests the clearing of sampled textures in render pass
@ -504,6 +559,9 @@ TEST_P(TextureZeroInitTest, RenderPassSampledTextureClear) {
// Expect the rendered texture to be cleared
std::vector<RGBA8> expectedWithZeros(kSize * kSize, {0, 0, 0, 0});
EXPECT_TEXTURE_RGBA8_EQ(expectedWithZeros.data(), renderTexture, 0, 0, kSize, kSize, 0, 0);
// Expect texture subresource initialized to be true
EXPECT_EQ(true, dawn_native::IsTextureSubresourceInitialized(renderTexture.Get(), 0, 1, 0, 1));
}
// This tests the clearing of sampled textures during compute pass
@ -566,6 +624,9 @@ TEST_P(TextureZeroInitTest, ComputePassSampledTextureClear) {
// Expect the buffer to be zeroed out by the compute pass
std::vector<uint32_t> expectedWithZeros(bufferSize, 0);
EXPECT_BUFFER_U32_RANGE_EQ(expectedWithZeros.data(), bufferTex, 0, kFormatBlockByteSize);
// Expect texture subresource initialized to be true
EXPECT_EQ(true, dawn_native::IsTextureSubresourceInitialized(texture.Get(), 0, 1, 0, 1));
}
// This tests that the code path of CopyTextureToBuffer clears correctly for non-renderable textures
@ -592,6 +653,9 @@ TEST_P(TextureZeroInitTest, NonRenderableTextureClear) {
std::vector<uint32_t> expectedWithZeros(bufferSize, 0);
EXPECT_BUFFER_U32_RANGE_EQ(expectedWithZeros.data(), bufferDst, 0, kSize);
// Expect texture subresource initialized to be true
EXPECT_EQ(true, dawn_native::IsTextureSubresourceInitialized(texture.Get(), 0, 1, 0, 1));
}
// This tests that the code path of CopyTextureToBuffer clears correctly for non-renderable textures
@ -619,6 +683,9 @@ TEST_P(TextureZeroInitTest, NonRenderableTextureClearUnalignedSize) {
std::vector<uint32_t> expectedWithZeros(bufferSize, 0);
EXPECT_BUFFER_U32_RANGE_EQ(expectedWithZeros.data(), bufferDst, 0, kUnalignedSize);
// Expect texture subresource initialized to be true
EXPECT_EQ(true, dawn_native::IsTextureSubresourceInitialized(texture.Get(), 0, 1, 0, 1));
}
// This tests that the code path of CopyTextureToBuffer clears correctly for non-renderable textures
@ -649,6 +716,9 @@ TEST_P(TextureZeroInitTest, NonRenderableTextureClearWithMultiArrayLayers) {
std::vector<uint32_t> expectedWithZeros(bufferSize, 0);
EXPECT_BUFFER_U32_RANGE_EQ(expectedWithZeros.data(), bufferDst, 0, 8);
// Expect texture subresource initialized to be true
EXPECT_EQ(true, dawn_native::IsTextureSubresourceInitialized(texture.Get(), 0, 1, 1, 1));
}
// This tests that storeOp clear resets resource state to uninitialized.
@ -712,6 +782,10 @@ TEST_P(TextureZeroInitTest, RenderPassStoreOpClear) {
std::vector<RGBA8> expectedWithZeros(kSize * kSize, {0, 0, 0, 0});
EXPECT_LAZY_CLEAR(1u, EXPECT_TEXTURE_RGBA8_EQ(expectedWithZeros.data(), renderTexture, 0, 0,
kSize, kSize, 0, 0));
// Expect texture subresource initialized to be true
EXPECT_EQ(true, dawn_native::IsTextureSubresourceInitialized(texture.Get(), 0, 1, 0, 1));
EXPECT_EQ(true, dawn_native::IsTextureSubresourceInitialized(renderTexture.Get(), 0, 1, 0, 1));
}
// This tests storeOp Clear on depth and stencil textures.
@ -761,6 +835,11 @@ TEST_P(TextureZeroInitTest, RenderingLoadingDepthStencilStoreOpClear) {
// cleared to 1's by using loadOp clear and set values from descriptor.
std::vector<RGBA8> expectedBlack(kSize * kSize, {0, 0, 0, 0});
EXPECT_TEXTURE_RGBA8_EQ(expectedBlack.data(), srcTexture, 0, 0, kSize, kSize, 0, 0);
// Expect texture subresource initialized to be false since storeop is clear, sets
// subresource as uninitialized
EXPECT_EQ(false, dawn_native::IsTextureSubresourceInitialized(depthStencilTexture.Get(), 0,
1, 0, 1));
}
// Now we put the depth stencil texture back into renderpass, it should be cleared by loadop
@ -781,6 +860,11 @@ TEST_P(TextureZeroInitTest, RenderingLoadingDepthStencilStoreOpClear) {
// loadop load and uninitialized subresource, so we should have a red square
std::vector<RGBA8> expectedRed(kSize * kSize, {255, 0, 0, 255});
EXPECT_TEXTURE_RGBA8_EQ(expectedRed.data(), srcTexture, 0, 0, kSize, kSize, 0, 0);
// Expect texture subresource initialized to be false since storeop is clear, sets
// subresource as uninitialized
EXPECT_EQ(false, dawn_native::IsTextureSubresourceInitialized(depthStencilTexture.Get(), 0,
1, 0, 1));
}
}
@ -860,6 +944,9 @@ TEST_P(TextureZeroInitTest, PreservesInitializedMip) {
std::vector<RGBA8> expectedWithTwos(mipSize * mipSize, {2, 2, 2, 2});
EXPECT_LAZY_CLEAR(0u, EXPECT_TEXTURE_RGBA8_EQ(expectedWithTwos.data(), sampleTexture, 0, 0,
mipSize, mipSize, 1, 0));
// Expect the whole texture to be initialized
EXPECT_EQ(true, dawn_native::IsTextureSubresourceInitialized(sampleTexture.Get(), 0, 2, 0, 1));
}
// Test that if one layer of a texture is initialized and another is uninitialized, lazy clearing
@ -942,6 +1029,9 @@ TEST_P(TextureZeroInitTest, PreservesInitializedArrayLayer) {
std::vector<RGBA8> expectedWithTwos(kSize * kSize, {2, 2, 2, 2});
EXPECT_LAZY_CLEAR(0u, EXPECT_TEXTURE_RGBA8_EQ(expectedWithTwos.data(), sampleTexture, 0, 0,
kSize, kSize, 0, 1));
// Expect the whole texture to be initialized
EXPECT_EQ(true, dawn_native::IsTextureSubresourceInitialized(sampleTexture.Get(), 0, 1, 0, 2));
}
DAWN_INSTANTIATE_TEST(