Support internal pipelines for Dawn

Like copyTextureCHROMIUM in Chromium, CopyImageBitmapToTexture can use
internal pipeline to do the GPU uploading. But Dawn doesn't support
internal pipeline now.

This patch adds the first internal pipeline for Dawn and add the API
CopyTextureForBrowser to use internal pipeline to do gpu uploading.

The patch integrates very simple wgsl vertex/fragment shaders to do
simple direct blit to verify the whole system works.

BUG=dawn:465

Change-Id: I8b566af38a10eea00f7426c39e752958ef057abd
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/30960
Commit-Queue: Shaobo Yan <shaobo.yan@intel.com>
Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
Yan, Shaobo
2020-11-04 02:30:16 +00:00
committed by Commit Bot service account
parent 131e619fe4
commit db8766bb23
18 changed files with 683 additions and 60 deletions

View File

@@ -275,6 +275,7 @@ source_set("dawn_end2end_tests_sources") {
"end2end/ComputeSharedMemoryTests.cpp",
"end2end/ComputeStorageBufferBarrierTests.cpp",
"end2end/CopyTests.cpp",
"end2end/CopyTextureForBrowserTests.cpp",
"end2end/CreateReadyPipelineTests.cpp",
"end2end/CullingTests.cpp",
"end2end/DebugMarkerTests.cpp",

View File

@@ -0,0 +1,183 @@
// Copyright 2020 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "tests/DawnTest.h"
#include "common/Constants.h"
#include "common/Math.h"
#include "utils/TestUtils.h"
#include "utils/TextureFormatUtils.h"
#include "utils/WGPUHelpers.h"
class CopyTextureForBrowserTests : public DawnTest {
protected:
static constexpr wgpu::TextureFormat kTextureFormat = wgpu::TextureFormat::RGBA8Unorm;
struct TextureSpec {
wgpu::Origin3D copyOrigin;
wgpu::Extent3D textureSize;
uint32_t level;
};
static std::vector<RGBA8> GetExpectedTextureData(const utils::TextureDataCopyLayout& layout) {
std::vector<RGBA8> textureData(layout.texelBlockCount);
for (uint32_t layer = 0; layer < layout.mipSize.depth; ++layer) {
const uint32_t sliceOffset = layout.texelBlocksPerImage * layer;
for (uint32_t y = 0; y < layout.mipSize.height; ++y) {
const uint32_t rowOffset = layout.texelBlocksPerRow * y;
for (uint32_t x = 0; x < layout.mipSize.width; ++x) {
textureData[sliceOffset + rowOffset + x] =
RGBA8(static_cast<uint8_t>((x + layer * x) % 256),
static_cast<uint8_t>((y + layer * y) % 256),
static_cast<uint8_t>(x / 256), static_cast<uint8_t>(y / 256));
}
}
}
return textureData;
}
static void PackTextureData(const RGBA8* srcData,
uint32_t width,
uint32_t height,
uint32_t srcTexelsPerRow,
RGBA8* dstData,
uint32_t dstTexelsPerRow) {
for (unsigned int y = 0; y < height; ++y) {
for (unsigned int x = 0; x < width; ++x) {
unsigned int src = x + y * srcTexelsPerRow;
unsigned int dst = x + y * dstTexelsPerRow;
dstData[dst] = srcData[src];
}
}
}
void DoTest(const TextureSpec& srcSpec,
const TextureSpec& dstSpec,
const wgpu::Extent3D& copySize) {
wgpu::TextureDescriptor srcDescriptor;
srcDescriptor.size = srcSpec.textureSize;
srcDescriptor.format = kTextureFormat;
srcDescriptor.mipLevelCount = srcSpec.level + 1;
srcDescriptor.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst |
wgpu::TextureUsage::Sampled | wgpu::TextureUsage::OutputAttachment;
wgpu::Texture srcTexture = device.CreateTexture(&srcDescriptor);
wgpu::Texture dstTexture;
wgpu::TextureDescriptor dstDescriptor;
dstDescriptor.size = dstSpec.textureSize;
dstDescriptor.format = kTextureFormat;
dstDescriptor.mipLevelCount = dstSpec.level + 1;
dstDescriptor.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst |
wgpu::TextureUsage::OutputAttachment;
dstTexture = device.CreateTexture(&dstDescriptor);
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
// Use writeTexture to populate the current slice of the texture in
// `level` mip level for all platforms except OpenGL.
// TODO(shaobo.yan@intel.com): OpenGL doesn't have 'WriteTexture' implementation.
const utils::TextureDataCopyLayout copyLayout =
utils::GetTextureDataCopyLayoutForTexture2DAtLevel(
kTextureFormat,
{srcSpec.textureSize.width, srcSpec.textureSize.height, copySize.depth},
srcSpec.level, 0);
const std::vector<RGBA8> textureArrayCopyData = GetExpectedTextureData(copyLayout);
wgpu::TextureCopyView textureCopyView =
utils::CreateTextureCopyView(srcTexture, srcSpec.level, {0, 0, srcSpec.copyOrigin.z});
wgpu::TextureDataLayout textureDataLayout;
textureDataLayout.offset = 0;
textureDataLayout.bytesPerRow = copyLayout.bytesPerRow;
textureDataLayout.rowsPerImage = copyLayout.bytesPerImage / copyLayout.bytesPerRow;
device.GetDefaultQueue().WriteTexture(&textureCopyView, textureArrayCopyData.data(),
textureArrayCopyData.size() * sizeof(RGBA8),
&textureDataLayout, &copyLayout.mipSize);
const wgpu::Extent3D copySizePerSlice = {copySize.width, copySize.height, 1};
// Perform the texture to texture copy
wgpu::TextureCopyView srcTextureCopyView =
utils::CreateTextureCopyView(srcTexture, srcSpec.level, srcSpec.copyOrigin);
wgpu::TextureCopyView dstTextureCopyView =
utils::CreateTextureCopyView(dstTexture, dstSpec.level, dstSpec.copyOrigin);
wgpu::CommandBuffer commands = encoder.Finish();
queue.Submit(1, &commands);
// Perform a copy here for testing.
device.GetDefaultQueue().CopyTextureForBrowser(&srcTextureCopyView, &dstTextureCopyView,
&copySize);
// Texels in single slice.
const uint32_t texelCountInCopyRegion = utils::GetTexelCountInCopyRegion(
copyLayout.bytesPerRow, copyLayout.bytesPerImage / copyLayout.bytesPerRow,
copySizePerSlice, kTextureFormat);
std::vector<RGBA8> expected(texelCountInCopyRegion);
for (uint32_t slice = 0; slice < copySize.depth; ++slice) {
std::fill(expected.begin(), expected.end(), RGBA8());
const uint32_t texelIndexOffset = copyLayout.texelBlocksPerImage * slice;
const uint32_t expectedTexelArrayDataStartIndex =
texelIndexOffset +
(srcSpec.copyOrigin.x + srcSpec.copyOrigin.y * copyLayout.texelBlocksPerRow);
PackTextureData(&textureArrayCopyData[expectedTexelArrayDataStartIndex], copySize.width,
copySize.height, copyLayout.texelBlocksPerRow, expected.data(),
copySize.width);
EXPECT_TEXTURE_RGBA8_EQ(expected.data(), dstTexture, dstSpec.copyOrigin.x,
dstSpec.copyOrigin.y, copySize.width, copySize.height,
dstSpec.level, dstSpec.copyOrigin.z + slice)
<< "Texture to Texture copy failed copying region [(" << srcSpec.copyOrigin.x
<< ", " << srcSpec.copyOrigin.y << "), (" << srcSpec.copyOrigin.x + copySize.width
<< ", " << srcSpec.copyOrigin.y + copySize.height << ")) from "
<< srcSpec.textureSize.width << " x " << srcSpec.textureSize.height
<< " texture at mip level " << srcSpec.level << " layer "
<< srcSpec.copyOrigin.z + slice << " to [(" << dstSpec.copyOrigin.x << ", "
<< dstSpec.copyOrigin.y << "), (" << dstSpec.copyOrigin.x + copySize.width << ", "
<< dstSpec.copyOrigin.y + copySize.height << ")) region of "
<< dstSpec.textureSize.width << " x " << dstSpec.textureSize.height
<< " texture at mip level " << dstSpec.level << " layer "
<< dstSpec.copyOrigin.z + slice << std::endl;
}
}
};
// Verify CopyTextureForBrowserTests works with internal pipeline.
// The case do copy without any transform.
TEST_P(CopyTextureForBrowserTests, PassthroughCopy) {
// These tests fails due to crbug.com/tint/63.
DAWN_SKIP_TEST_IF(IsSwiftshader());
DAWN_SKIP_TEST_IF(IsVulkan());
DAWN_SKIP_TEST_IF(IsD3D12() && IsBackendValidationEnabled());
// OpenGL tests fails due to 'WriteTexture' unimplemented.
// Related bug : crbug.com/dawn/483
DAWN_SKIP_TEST_IF(IsOpenGL());
constexpr uint32_t kWidth = 10;
constexpr uint32_t kHeight = 1;
TextureSpec textureSpec;
textureSpec.copyOrigin = {0, 0, 0};
textureSpec.level = 0;
textureSpec.textureSize = {kWidth, kHeight, 1};
DoTest(textureSpec, textureSpec, {kWidth, kHeight, 1});
}
DAWN_INSTANTIATE_TEST(CopyTextureForBrowserTests,
D3D12Backend(),
MetalBackend(),
OpenGLBackend(),
VulkanBackend());