Revert "CopyTextureForBrowser: Support color format conversion"
This reverts commit f84daa070f
.
Reason for revert: Adds static initializers.
Original change's description:
> CopyTextureForBrowser: Support color format conversion
>
> This CL enables blit from RGBA8Unorm soruce texture to dst texture that
> |CopyImageBitmapToTexture| supported dst format.
>
> BUG=dawn:465
>
> Change-Id: I99846cf8dc37bc89e0c168a3d86193bb3a0c0ebb
> Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/44020
> Commit-Queue: Shaobo Yan <shaobo.yan@intel.com>
> Reviewed-by: Corentin Wallez <cwallez@chromium.org>
> Reviewed-by: Austin Eng <enga@chromium.org>
TBR=cwallez@chromium.org,jiawei.shao@intel.com,shaobo.yan@intel.com,enga@chromium.org
Change-Id: I29a4faf38332995db6bded9f5aead9af28dadfd3
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: dawn:465
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/45420
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
parent
5709060143
commit
682f32af32
|
@ -392,9 +392,9 @@ namespace dawn_native {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
MaybeError ValidateTextureToTextureCopyCommonRestrictions(const ImageCopyTexture& src,
|
MaybeError ValidateTextureToTextureCopyRestrictions(const ImageCopyTexture& src,
|
||||||
const ImageCopyTexture& dst,
|
const ImageCopyTexture& dst,
|
||||||
const Extent3D& copySize) {
|
const Extent3D& copySize) {
|
||||||
const uint32_t srcSamples = src.texture->GetSampleCount();
|
const uint32_t srcSamples = src.texture->GetSampleCount();
|
||||||
const uint32_t dstSamples = dst.texture->GetSampleCount();
|
const uint32_t dstSamples = dst.texture->GetSampleCount();
|
||||||
|
|
||||||
|
@ -403,6 +403,11 @@ namespace dawn_native {
|
||||||
"Source and destination textures must have matching sample counts.");
|
"Source and destination textures must have matching sample counts.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (src.texture->GetFormat().format != dst.texture->GetFormat().format) {
|
||||||
|
// Metal requires texture-to-texture copies be the same format
|
||||||
|
return DAWN_VALIDATION_ERROR("Source and destination texture formats must match.");
|
||||||
|
}
|
||||||
|
|
||||||
// Metal cannot select a single aspect for texture-to-texture copies.
|
// Metal cannot select a single aspect for texture-to-texture copies.
|
||||||
const Format& format = src.texture->GetFormat();
|
const Format& format = src.texture->GetFormat();
|
||||||
if (SelectFormatAspects(format, src.aspect) != format.aspects) {
|
if (SelectFormatAspects(format, src.aspect) != format.aspects) {
|
||||||
|
@ -427,34 +432,6 @@ namespace dawn_native {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
MaybeError ValidateTextureToTextureCopyRestrictions(const ImageCopyTexture& src,
|
|
||||||
const ImageCopyTexture& dst,
|
|
||||||
const Extent3D& copySize) {
|
|
||||||
if (src.texture->GetFormat().format != dst.texture->GetFormat().format) {
|
|
||||||
// Metal requires texture-to-texture copies be the same format
|
|
||||||
return DAWN_VALIDATION_ERROR("Source and destination texture formats must match.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return ValidateTextureToTextureCopyCommonRestrictions(src, dst, copySize);
|
|
||||||
}
|
|
||||||
|
|
||||||
// CopyTextureForBrowser could handle color conversion during the copy and it
|
|
||||||
// requires the source must be sampleable and the destination must be writable
|
|
||||||
// using a render pass
|
|
||||||
MaybeError ValidateCopyTextureForBrowserRestrictions(const ImageCopyTexture& src,
|
|
||||||
const ImageCopyTexture& dst,
|
|
||||||
const Extent3D& copySize) {
|
|
||||||
if (!(src.texture->GetUsage() & wgpu::TextureUsage::Sampled)) {
|
|
||||||
return DAWN_VALIDATION_ERROR("Source texture must have sampled usage");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(dst.texture->GetUsage() & wgpu::TextureUsage::OutputAttachment)) {
|
|
||||||
return DAWN_VALIDATION_ERROR("Dest texture must have outputAttachment usage");
|
|
||||||
}
|
|
||||||
|
|
||||||
return ValidateTextureToTextureCopyCommonRestrictions(src, dst, copySize);
|
|
||||||
}
|
|
||||||
|
|
||||||
MaybeError ValidateCanUseAs(const TextureBase* texture, wgpu::TextureUsage usage) {
|
MaybeError ValidateCanUseAs(const TextureBase* texture, wgpu::TextureUsage usage) {
|
||||||
ASSERT(wgpu::HasZeroOrOneBits(usage));
|
ASSERT(wgpu::HasZeroOrOneBits(usage));
|
||||||
if (!(texture->GetUsage() & usage)) {
|
if (!(texture->GetUsage() & usage)) {
|
||||||
|
|
|
@ -75,10 +75,6 @@ namespace dawn_native {
|
||||||
const ImageCopyTexture& dst,
|
const ImageCopyTexture& dst,
|
||||||
const Extent3D& copySize);
|
const Extent3D& copySize);
|
||||||
|
|
||||||
MaybeError ValidateCopyTextureForBrowserRestrictions(const ImageCopyTexture& src,
|
|
||||||
const ImageCopyTexture& dst,
|
|
||||||
const Extent3D& copySize);
|
|
||||||
|
|
||||||
MaybeError ValidateCanUseAs(const TextureBase* texture, wgpu::TextureUsage usage);
|
MaybeError ValidateCanUseAs(const TextureBase* texture, wgpu::TextureUsage usage);
|
||||||
|
|
||||||
MaybeError ValidateCanUseAs(const BufferBase* buffer, wgpu::BufferUsage usage);
|
MaybeError ValidateCanUseAs(const BufferBase* buffer, wgpu::BufferUsage usage);
|
||||||
|
|
|
@ -32,8 +32,8 @@
|
||||||
|
|
||||||
namespace dawn_native {
|
namespace dawn_native {
|
||||||
namespace {
|
namespace {
|
||||||
// TODO(shaobo.yan@intel.com) : Support premultiplay-alpha
|
// TODO(shaobo.yan@intel.com) : Support premultiplay-alpha, flipY.
|
||||||
static const std::string sCopyTextureForBrowserVertex = R"(
|
static const char sCopyTextureForBrowserVertex[] = R"(
|
||||||
[[block]] struct Uniforms {
|
[[block]] struct Uniforms {
|
||||||
u_scale : vec2<f32>;
|
u_scale : vec2<f32>;
|
||||||
u_offset : vec2<f32>;
|
u_offset : vec2<f32>;
|
||||||
|
@ -56,31 +56,25 @@ namespace dawn_native {
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
static const std::string sCopyTextureForBrowserFragment = R"(
|
static const char sPassthrough2D4ChannelFrag[] = R"(
|
||||||
[[binding(1), group(0)]] var mySampler: sampler;
|
[[binding(1), group(0)]] var mySampler: sampler;
|
||||||
[[binding(2), group(0)]] var myTexture: texture_2d<f32>;
|
[[binding(2), group(0)]] var myTexture: texture_2d<f32>;
|
||||||
[[location(0)]] var<in> v_texcoord : vec2<f32>;
|
[[location(0)]] var<in> v_texcoord : vec2<f32>;
|
||||||
[[location(0)]] var<out> outputColor : vec4<f32>;
|
[[location(0)]] var<out> rgbaColor : vec4<f32>;
|
||||||
[[stage(fragment)]] fn main() -> void {
|
[[stage(fragment)]] fn main() -> void {
|
||||||
// Clamp the texcoord and discard the out-of-bound pixels.
|
// Clamp the texcoord and discard the out-of-bound pixels.
|
||||||
var clampedTexcoord : vec2<f32> =
|
var clampedTexcoord : vec2<f32> =
|
||||||
clamp(v_texcoord, vec2<f32>(0.0, 0.0), vec2<f32>(1.0, 1.0));
|
clamp(v_texcoord, vec2<f32>(0.0, 0.0), vec2<f32>(1.0, 1.0));
|
||||||
if (all(clampedTexcoord == v_texcoord)) {
|
if (all(clampedTexcoord == v_texcoord)) {
|
||||||
var srcColor : vec4<f32> = textureSample(myTexture, mySampler, v_texcoord);
|
rgbaColor = textureSample(myTexture, mySampler, v_texcoord);
|
||||||
// Swizzling of texture formats when sampling / rendering is handled by the
|
|
||||||
// hardware so we don't need special logic in this shader. This is covered by tests.
|
|
||||||
outputColor = srcColor;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
// TODO(shaobo.yan@intel.com): Expand copyTextureForBrowser to support any
|
// TODO(shaobo.yan@intel.com): Expand supported texture formats
|
||||||
// non-depth, non-stencil, non-compressed texture format pair copy. Now this API
|
|
||||||
// supports CopyImageBitmapToTexture normal format pairs.
|
|
||||||
MaybeError ValidateCopyTextureFormatConversion(const wgpu::TextureFormat srcFormat,
|
MaybeError ValidateCopyTextureFormatConversion(const wgpu::TextureFormat srcFormat,
|
||||||
const wgpu::TextureFormat dstFormat) {
|
const wgpu::TextureFormat dstFormat) {
|
||||||
switch (srcFormat) {
|
switch (srcFormat) {
|
||||||
case wgpu::TextureFormat::BGRA8Unorm:
|
|
||||||
case wgpu::TextureFormat::RGBA8Unorm:
|
case wgpu::TextureFormat::RGBA8Unorm:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -90,12 +84,6 @@ namespace dawn_native {
|
||||||
|
|
||||||
switch (dstFormat) {
|
switch (dstFormat) {
|
||||||
case wgpu::TextureFormat::RGBA8Unorm:
|
case wgpu::TextureFormat::RGBA8Unorm:
|
||||||
case wgpu::TextureFormat::BGRA8Unorm:
|
|
||||||
case wgpu::TextureFormat::RGBA32Float:
|
|
||||||
case wgpu::TextureFormat::RG8Unorm:
|
|
||||||
case wgpu::TextureFormat::RGBA16Float:
|
|
||||||
case wgpu::TextureFormat::RG16Float:
|
|
||||||
case wgpu::TextureFormat::RGB10A2Unorm:
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return DAWN_VALIDATION_ERROR(
|
return DAWN_VALIDATION_ERROR(
|
||||||
|
@ -115,26 +103,15 @@ namespace dawn_native {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderPipelineBase* GetCachedPipeline(InternalPipelineStore* store,
|
RenderPipelineBase* GetOrCreateCopyTextureForBrowserPipeline(DeviceBase* device) {
|
||||||
wgpu::TextureFormat dstFormat) {
|
|
||||||
auto pipeline = store->copyTextureForBrowserPipelines.find(dstFormat);
|
|
||||||
if (pipeline != store->copyTextureForBrowserPipelines.end()) {
|
|
||||||
return pipeline->second.Get();
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderPipelineBase* GetOrCreateCopyTextureForBrowserPipeline(
|
|
||||||
DeviceBase* device,
|
|
||||||
wgpu::TextureFormat dstFormat) {
|
|
||||||
InternalPipelineStore* store = device->GetInternalPipelineStore();
|
InternalPipelineStore* store = device->GetInternalPipelineStore();
|
||||||
|
|
||||||
if (GetCachedPipeline(store, dstFormat) == nullptr) {
|
if (store->copyTextureForBrowserPipeline == nullptr) {
|
||||||
// Create vertex shader module if not cached before.
|
// Create vertex shader module if not cached before.
|
||||||
if (store->copyTextureForBrowserVS == nullptr) {
|
if (store->copyTextureForBrowserVS == nullptr) {
|
||||||
ShaderModuleDescriptor descriptor;
|
ShaderModuleDescriptor descriptor;
|
||||||
ShaderModuleWGSLDescriptor wgslDesc;
|
ShaderModuleWGSLDescriptor wgslDesc;
|
||||||
wgslDesc.source = sCopyTextureForBrowserVertex.c_str();
|
wgslDesc.source = sCopyTextureForBrowserVertex;
|
||||||
descriptor.nextInChain = reinterpret_cast<ChainedStruct*>(&wgslDesc);
|
descriptor.nextInChain = reinterpret_cast<ChainedStruct*>(&wgslDesc);
|
||||||
|
|
||||||
store->copyTextureForBrowserVS =
|
store->copyTextureForBrowserVS =
|
||||||
|
@ -147,7 +124,7 @@ namespace dawn_native {
|
||||||
if (store->copyTextureForBrowserFS == nullptr) {
|
if (store->copyTextureForBrowserFS == nullptr) {
|
||||||
ShaderModuleDescriptor descriptor;
|
ShaderModuleDescriptor descriptor;
|
||||||
ShaderModuleWGSLDescriptor wgslDesc;
|
ShaderModuleWGSLDescriptor wgslDesc;
|
||||||
wgslDesc.source = sCopyTextureForBrowserFragment.c_str();
|
wgslDesc.source = sPassthrough2D4ChannelFrag;
|
||||||
descriptor.nextInChain = reinterpret_cast<ChainedStruct*>(&wgslDesc);
|
descriptor.nextInChain = reinterpret_cast<ChainedStruct*>(&wgslDesc);
|
||||||
store->copyTextureForBrowserFS =
|
store->copyTextureForBrowserFS =
|
||||||
AcquireRef(device->CreateShaderModule(&descriptor));
|
AcquireRef(device->CreateShaderModule(&descriptor));
|
||||||
|
@ -167,7 +144,7 @@ namespace dawn_native {
|
||||||
|
|
||||||
// Prepare color state.
|
// Prepare color state.
|
||||||
ColorTargetState target = {};
|
ColorTargetState target = {};
|
||||||
target.format = dstFormat;
|
target.format = wgpu::TextureFormat::RGBA8Unorm;
|
||||||
|
|
||||||
// Create RenderPipeline.
|
// Create RenderPipeline.
|
||||||
RenderPipelineDescriptor2 renderPipelineDesc = {};
|
RenderPipelineDescriptor2 renderPipelineDesc = {};
|
||||||
|
@ -183,11 +160,11 @@ namespace dawn_native {
|
||||||
fragment.targetCount = 1;
|
fragment.targetCount = 1;
|
||||||
fragment.targets = ⌖
|
fragment.targets = ⌖
|
||||||
|
|
||||||
store->copyTextureForBrowserPipelines.insert(
|
store->copyTextureForBrowserPipeline =
|
||||||
{dstFormat, AcquireRef(device->CreateRenderPipeline2(&renderPipelineDesc))});
|
AcquireRef(device->CreateRenderPipeline2(&renderPipelineDesc));
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetCachedPipeline(store, dstFormat);
|
return store->copyTextureForBrowserPipeline.Get();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
@ -203,7 +180,7 @@ namespace dawn_native {
|
||||||
DAWN_TRY(ValidateImageCopyTexture(device, *source, *copySize));
|
DAWN_TRY(ValidateImageCopyTexture(device, *source, *copySize));
|
||||||
DAWN_TRY(ValidateImageCopyTexture(device, *destination, *copySize));
|
DAWN_TRY(ValidateImageCopyTexture(device, *destination, *copySize));
|
||||||
|
|
||||||
DAWN_TRY(ValidateCopyTextureForBrowserRestrictions(*source, *destination, *copySize));
|
DAWN_TRY(ValidateTextureToTextureCopyRestrictions(*source, *destination, *copySize));
|
||||||
|
|
||||||
DAWN_TRY(ValidateTextureCopyRange(*source, *copySize));
|
DAWN_TRY(ValidateTextureCopyRange(*source, *copySize));
|
||||||
DAWN_TRY(ValidateTextureCopyRange(*destination, *copySize));
|
DAWN_TRY(ValidateTextureCopyRange(*destination, *copySize));
|
||||||
|
@ -237,9 +214,7 @@ namespace dawn_native {
|
||||||
const CopyTextureForBrowserOptions* options) {
|
const CopyTextureForBrowserOptions* options) {
|
||||||
// TODO(shaobo.yan@intel.com): In D3D12 and Vulkan, compatible texture format can directly
|
// TODO(shaobo.yan@intel.com): In D3D12 and Vulkan, compatible texture format can directly
|
||||||
// copy to each other. This can be a potential fast path.
|
// copy to each other. This can be a potential fast path.
|
||||||
|
RenderPipelineBase* pipeline = GetOrCreateCopyTextureForBrowserPipeline(device);
|
||||||
RenderPipelineBase* pipeline = GetOrCreateCopyTextureForBrowserPipeline(
|
|
||||||
device, destination->texture->GetFormat().format);
|
|
||||||
|
|
||||||
// Prepare bind group layout.
|
// Prepare bind group layout.
|
||||||
Ref<BindGroupLayoutBase> layout = AcquireRef(pipeline->GetBindGroupLayout(0));
|
Ref<BindGroupLayoutBase> layout = AcquireRef(pipeline->GetBindGroupLayout(0));
|
||||||
|
@ -257,7 +232,7 @@ namespace dawn_native {
|
||||||
0.0, 0.0 // offset
|
0.0, 0.0 // offset
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle flipY
|
// Handle flipY.
|
||||||
if (options && options->flipY) {
|
if (options && options->flipY) {
|
||||||
uniformData[1] *= -1.0;
|
uniformData[1] *= -1.0;
|
||||||
uniformData[3] += 1.0;
|
uniformData[3] += 1.0;
|
||||||
|
@ -307,7 +282,6 @@ namespace dawn_native {
|
||||||
|
|
||||||
// Prepare render pass color attachment descriptor.
|
// Prepare render pass color attachment descriptor.
|
||||||
RenderPassColorAttachmentDescriptor colorAttachmentDesc;
|
RenderPassColorAttachmentDescriptor colorAttachmentDesc;
|
||||||
|
|
||||||
colorAttachmentDesc.attachment = dstView.Get();
|
colorAttachmentDesc.attachment = dstView.Get();
|
||||||
colorAttachmentDesc.loadOp = wgpu::LoadOp::Load;
|
colorAttachmentDesc.loadOp = wgpu::LoadOp::Load;
|
||||||
colorAttachmentDesc.storeOp = wgpu::StoreOp::Store;
|
colorAttachmentDesc.storeOp = wgpu::StoreOp::Store;
|
||||||
|
|
|
@ -25,9 +25,7 @@ namespace dawn_native {
|
||||||
class ShaderModuleBase;
|
class ShaderModuleBase;
|
||||||
|
|
||||||
struct InternalPipelineStore {
|
struct InternalPipelineStore {
|
||||||
std::unordered_map<wgpu::TextureFormat, Ref<RenderPipelineBase>>
|
Ref<RenderPipelineBase> copyTextureForBrowserPipeline;
|
||||||
copyTextureForBrowserPipelines;
|
|
||||||
|
|
||||||
Ref<ShaderModuleBase> copyTextureForBrowserVS;
|
Ref<ShaderModuleBase> copyTextureForBrowserVS;
|
||||||
Ref<ShaderModuleBase> copyTextureForBrowserFS;
|
Ref<ShaderModuleBase> copyTextureForBrowserFS;
|
||||||
|
|
||||||
|
|
|
@ -21,23 +21,12 @@
|
||||||
#include "utils/TextureFormatUtils.h"
|
#include "utils/TextureFormatUtils.h"
|
||||||
#include "utils/WGPUHelpers.h"
|
#include "utils/WGPUHelpers.h"
|
||||||
|
|
||||||
namespace {
|
|
||||||
static constexpr wgpu::TextureFormat kTextureFormat = wgpu::TextureFormat::RGBA8Unorm;
|
|
||||||
|
|
||||||
// Set default texture size to single line texture for color conversion tests.
|
|
||||||
static constexpr uint64_t kDefaultTextureWidth = 10;
|
|
||||||
static constexpr uint64_t kDefaultTextureHeight = 1;
|
|
||||||
|
|
||||||
// Dst texture format copyTextureForBrowser accept
|
|
||||||
static constexpr wgpu::TextureFormat kDstTextureFormat[] = {
|
|
||||||
wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureFormat::BGRA8Unorm,
|
|
||||||
wgpu::TextureFormat::RGBA32Float, wgpu::TextureFormat::RG8Unorm,
|
|
||||||
wgpu::TextureFormat::RGBA16Float, wgpu::TextureFormat::RG16Float,
|
|
||||||
wgpu::TextureFormat::RGB10A2Unorm};
|
|
||||||
} // anonymous namespace
|
|
||||||
|
|
||||||
class CopyTextureForBrowserTests : public DawnTest {
|
class CopyTextureForBrowserTests : public DawnTest {
|
||||||
protected:
|
protected:
|
||||||
|
static constexpr wgpu::TextureFormat kTextureFormat = wgpu::TextureFormat::RGBA8Unorm;
|
||||||
|
static constexpr uint64_t kDefaultTextureWidth = 4;
|
||||||
|
static constexpr uint64_t kDefaultTextureHeight = 4;
|
||||||
|
|
||||||
struct TextureSpec {
|
struct TextureSpec {
|
||||||
wgpu::Origin3D copyOrigin = {};
|
wgpu::Origin3D copyOrigin = {};
|
||||||
wgpu::Extent3D textureSize = {kDefaultTextureWidth, kDefaultTextureHeight};
|
wgpu::Extent3D textureSize = {kDefaultTextureWidth, kDefaultTextureHeight};
|
||||||
|
@ -45,33 +34,6 @@ class CopyTextureForBrowserTests : public DawnTest {
|
||||||
wgpu::TextureFormat format = kTextureFormat;
|
wgpu::TextureFormat format = kTextureFormat;
|
||||||
};
|
};
|
||||||
|
|
||||||
// This fixed source texture data is for color conversion tests.
|
|
||||||
// The source data can fill a texture in default width and height.
|
|
||||||
static std::vector<RGBA8> GetFixedSourceTextureData() {
|
|
||||||
std::vector<RGBA8> sourceTextureData{
|
|
||||||
// Take RGBA8Unorm as example:
|
|
||||||
// R channel has different values
|
|
||||||
RGBA8(0, 255, 255, 255), // r = 0.0
|
|
||||||
RGBA8(102, 255, 255, 255), // r = 0.4
|
|
||||||
RGBA8(153, 255, 255, 255), // r = 0.6
|
|
||||||
|
|
||||||
// G channel has different values
|
|
||||||
RGBA8(255, 0, 255, 255), // g = 0.0
|
|
||||||
RGBA8(255, 102, 255, 255), // g = 0.4
|
|
||||||
RGBA8(255, 153, 255, 255), // g = 0.6
|
|
||||||
|
|
||||||
// B channel has different values
|
|
||||||
RGBA8(255, 255, 0, 255), // b = 0.0
|
|
||||||
RGBA8(255, 255, 102, 255), // b = 0.4
|
|
||||||
RGBA8(255, 255, 153, 255), // b = 0.6
|
|
||||||
|
|
||||||
// A channel set to 0
|
|
||||||
RGBA8(255, 255, 255, 0) // a = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
return sourceTextureData;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::vector<RGBA8> GetSourceTextureData(const utils::TextureDataCopyLayout& layout) {
|
static std::vector<RGBA8> GetSourceTextureData(const utils::TextureDataCopyLayout& layout) {
|
||||||
std::vector<RGBA8> textureData(layout.texelBlockCount);
|
std::vector<RGBA8> textureData(layout.texelBlockCount);
|
||||||
for (uint32_t layer = 0; layer < layout.mipSize.depth; ++layer) {
|
for (uint32_t layer = 0; layer < layout.mipSize.depth; ++layer) {
|
||||||
|
@ -82,7 +44,7 @@ class CopyTextureForBrowserTests : public DawnTest {
|
||||||
textureData[sliceOffset + rowOffset + x] =
|
textureData[sliceOffset + rowOffset + x] =
|
||||||
RGBA8(static_cast<uint8_t>((x + layer * x) % 256),
|
RGBA8(static_cast<uint8_t>((x + layer * x) % 256),
|
||||||
static_cast<uint8_t>((y + layer * y) % 256),
|
static_cast<uint8_t>((y + layer * y) % 256),
|
||||||
static_cast<uint8_t>(x % 256), static_cast<uint8_t>(x % 256));
|
static_cast<uint8_t>(x / 256), static_cast<uint8_t>(y / 256));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,7 +59,6 @@ class CopyTextureForBrowserTests : public DawnTest {
|
||||||
|
|
||||||
uint32_t uniformBufferData[] = {
|
uint32_t uniformBufferData[] = {
|
||||||
0, // copy have flipY option
|
0, // copy have flipY option
|
||||||
4, // channelCount
|
|
||||||
};
|
};
|
||||||
|
|
||||||
wgpu::BufferDescriptor uniformBufferDesc = {};
|
wgpu::BufferDescriptor uniformBufferDesc = {};
|
||||||
|
@ -113,7 +74,6 @@ class CopyTextureForBrowserTests : public DawnTest {
|
||||||
wgpu::ShaderModule csModule = utils::CreateShaderModuleFromWGSL(device, R"(
|
wgpu::ShaderModule csModule = utils::CreateShaderModuleFromWGSL(device, R"(
|
||||||
[[block]] struct Uniforms {
|
[[block]] struct Uniforms {
|
||||||
dstTextureFlipY : u32;
|
dstTextureFlipY : u32;
|
||||||
channelCount : u32;
|
|
||||||
};
|
};
|
||||||
[[block]] struct OutputBuf {
|
[[block]] struct OutputBuf {
|
||||||
result : array<u32>;
|
result : array<u32>;
|
||||||
|
@ -123,13 +83,10 @@ class CopyTextureForBrowserTests : public DawnTest {
|
||||||
[[group(0), binding(2)]] var<storage> output : [[access(read_write)]] OutputBuf;
|
[[group(0), binding(2)]] var<storage> output : [[access(read_write)]] OutputBuf;
|
||||||
[[group(0), binding(3)]] var<uniform> uniforms : Uniforms;
|
[[group(0), binding(3)]] var<uniform> uniforms : Uniforms;
|
||||||
[[builtin(global_invocation_id)]] var<in> GlobalInvocationID : vec3<u32>;
|
[[builtin(global_invocation_id)]] var<in> GlobalInvocationID : vec3<u32>;
|
||||||
fn aboutEqual(value : f32, expect : f32) -> bool {
|
[[stage(compute), workgroup_size(1, 1, 1)]]
|
||||||
// The value diff should be smaller than the hard coded tolerance.
|
fn main() -> void {
|
||||||
return abs(value - expect) < 0.001;
|
|
||||||
}
|
|
||||||
[[stage(compute), workgroup_size(1, 1, 1)]] fn main() -> void {
|
|
||||||
// Current CopyTextureForBrowser only support full copy now.
|
// Current CopyTextureForBrowser only support full copy now.
|
||||||
// TODO(crbug.com/dawn/465): Refactor this after CopyTextureForBrowser
|
// TODO(dawn:465): Refactor this after CopyTextureForBrowser
|
||||||
// support sub-rect copy.
|
// support sub-rect copy.
|
||||||
var size : vec2<i32> = textureDimensions(src);
|
var size : vec2<i32> = textureDimensions(src);
|
||||||
var dstTexCoord : vec2<i32> = vec2<i32>(GlobalInvocationID.xy);
|
var dstTexCoord : vec2<i32> = vec2<i32>(GlobalInvocationID.xy);
|
||||||
|
@ -140,21 +97,7 @@ class CopyTextureForBrowserTests : public DawnTest {
|
||||||
|
|
||||||
var srcColor : vec4<f32> = textureLoad(src, srcTexCoord, 0);
|
var srcColor : vec4<f32> = textureLoad(src, srcTexCoord, 0);
|
||||||
var dstColor : vec4<f32> = textureLoad(dst, dstTexCoord, 0);
|
var dstColor : vec4<f32> = textureLoad(dst, dstTexCoord, 0);
|
||||||
var success : bool = true;
|
var success : bool = all(srcColor == dstColor);
|
||||||
|
|
||||||
// Not use loop and variable index format to workaround
|
|
||||||
// crbug.com/tint/638.
|
|
||||||
if (uniforms.channelCount == 2u) { // All have rg components.
|
|
||||||
success = success &&
|
|
||||||
aboutEqual(dstColor.r, srcColor.r) &&
|
|
||||||
aboutEqual(dstColor.g, srcColor.g);
|
|
||||||
} else {
|
|
||||||
success = success &&
|
|
||||||
aboutEqual(dstColor.r, srcColor.r) &&
|
|
||||||
aboutEqual(dstColor.g, srcColor.g) &&
|
|
||||||
aboutEqual(dstColor.b, srcColor.b) &&
|
|
||||||
aboutEqual(dstColor.a, srcColor.a);
|
|
||||||
}
|
|
||||||
|
|
||||||
var outputIndex : u32 = GlobalInvocationID.y * u32(size.x) + GlobalInvocationID.x;
|
var outputIndex : u32 = GlobalInvocationID.y * u32(size.x) + GlobalInvocationID.x;
|
||||||
if (success) {
|
if (success) {
|
||||||
|
@ -171,31 +114,11 @@ class CopyTextureForBrowserTests : public DawnTest {
|
||||||
|
|
||||||
return device.CreateComputePipeline(&csDesc);
|
return device.CreateComputePipeline(&csDesc);
|
||||||
}
|
}
|
||||||
static uint32_t GetTextureFormatComponentCount(wgpu::TextureFormat format) {
|
|
||||||
switch (format) {
|
|
||||||
case wgpu::TextureFormat::RGBA8Unorm:
|
|
||||||
case wgpu::TextureFormat::BGRA8Unorm:
|
|
||||||
case wgpu::TextureFormat::RGB10A2Unorm:
|
|
||||||
case wgpu::TextureFormat::RGBA16Float:
|
|
||||||
case wgpu::TextureFormat::RGBA32Float:
|
|
||||||
return 4;
|
|
||||||
case wgpu::TextureFormat::RG8Unorm:
|
|
||||||
case wgpu::TextureFormat::RG16Float:
|
|
||||||
return 2;
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DoColorConversionTest(const TextureSpec& srcSpec, const TextureSpec& dstSpec) {
|
|
||||||
DoTest(srcSpec, dstSpec, {kDefaultTextureWidth, kDefaultTextureHeight}, {}, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DoTest(const TextureSpec& srcSpec,
|
void DoTest(const TextureSpec& srcSpec,
|
||||||
const TextureSpec& dstSpec,
|
const TextureSpec& dstSpec,
|
||||||
const wgpu::Extent3D& copySize = {kDefaultTextureWidth, kDefaultTextureHeight},
|
const wgpu::Extent3D& copySize = {kDefaultTextureWidth, kDefaultTextureHeight},
|
||||||
const wgpu::CopyTextureForBrowserOptions options = {},
|
const wgpu::CopyTextureForBrowserOptions options = {}) {
|
||||||
bool useFixedTestValue = false) {
|
|
||||||
wgpu::TextureDescriptor srcDescriptor;
|
wgpu::TextureDescriptor srcDescriptor;
|
||||||
srcDescriptor.size = srcSpec.textureSize;
|
srcDescriptor.size = srcSpec.textureSize;
|
||||||
srcDescriptor.format = srcSpec.format;
|
srcDescriptor.format = srcSpec.format;
|
||||||
|
@ -210,7 +133,7 @@ class CopyTextureForBrowserTests : public DawnTest {
|
||||||
dstDescriptor.format = dstSpec.format;
|
dstDescriptor.format = dstSpec.format;
|
||||||
dstDescriptor.mipLevelCount = dstSpec.level + 1;
|
dstDescriptor.mipLevelCount = dstSpec.level + 1;
|
||||||
dstDescriptor.usage = wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::Sampled |
|
dstDescriptor.usage = wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::Sampled |
|
||||||
wgpu::TextureUsage::OutputAttachment | wgpu::TextureUsage::CopySrc;
|
wgpu::TextureUsage::OutputAttachment;
|
||||||
dstTexture = device.CreateTexture(&dstDescriptor);
|
dstTexture = device.CreateTexture(&dstDescriptor);
|
||||||
|
|
||||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||||
|
@ -221,8 +144,7 @@ class CopyTextureForBrowserTests : public DawnTest {
|
||||||
{srcSpec.textureSize.width, srcSpec.textureSize.height, copySize.depth},
|
{srcSpec.textureSize.width, srcSpec.textureSize.height, copySize.depth},
|
||||||
srcSpec.level);
|
srcSpec.level);
|
||||||
|
|
||||||
const std::vector<RGBA8> textureArrayCopyData =
|
const std::vector<RGBA8> textureArrayCopyData = GetSourceTextureData(copyLayout);
|
||||||
useFixedTestValue ? GetFixedSourceTextureData() : GetSourceTextureData(copyLayout);
|
|
||||||
wgpu::ImageCopyTexture imageCopyTexture =
|
wgpu::ImageCopyTexture imageCopyTexture =
|
||||||
utils::CreateImageCopyTexture(srcTexture, srcSpec.level, {0, 0, srcSpec.copyOrigin.z});
|
utils::CreateImageCopyTexture(srcTexture, srcSpec.level, {0, 0, srcSpec.copyOrigin.z});
|
||||||
|
|
||||||
|
@ -249,8 +171,8 @@ class CopyTextureForBrowserTests : public DawnTest {
|
||||||
|
|
||||||
// Update uniform buffer based on test config
|
// Update uniform buffer based on test config
|
||||||
uint32_t uniformBufferData[] = {
|
uint32_t uniformBufferData[] = {
|
||||||
options.flipY, // copy have flipY option
|
options.flipY, // copy have flipY option
|
||||||
GetTextureFormatComponentCount(dstSpec.format)}; // channelCount
|
};
|
||||||
|
|
||||||
device.GetQueue().WriteBuffer(uniformBuffer, 0, uniformBufferData,
|
device.GetQueue().WriteBuffer(uniformBuffer, 0, uniformBufferData,
|
||||||
sizeof(uniformBufferData));
|
sizeof(uniformBufferData));
|
||||||
|
@ -388,45 +310,6 @@ TEST_P(CopyTextureForBrowserTests, VerifyFlipYInSlimTexture) {
|
||||||
DoTest(textureSpec, textureSpec, {kWidth, kHeight}, options);
|
DoTest(textureSpec, textureSpec, {kWidth, kHeight}, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify |CopyTextureForBrowser| doing color conversion correctly when
|
|
||||||
// the source texture is RGBA8Unorm format.
|
|
||||||
TEST_P(CopyTextureForBrowserTests, FromRGBA8UnormCopy) {
|
|
||||||
// Tests skip due to crbug.com/dawn/592.
|
|
||||||
DAWN_SKIP_TEST_IF(IsD3D12() && IsBackendValidationEnabled());
|
|
||||||
// Skip OpenGLES backend because it fails on using RGBA8Unorm as
|
|
||||||
// source texture format.
|
|
||||||
DAWN_SKIP_TEST_IF(IsOpenGLES());
|
|
||||||
|
|
||||||
for (wgpu::TextureFormat dstFormat : kDstTextureFormat) {
|
|
||||||
TextureSpec srcTextureSpec = {}; // default format is RGBA8Unorm
|
|
||||||
|
|
||||||
TextureSpec dstTextureSpec;
|
|
||||||
dstTextureSpec.format = dstFormat;
|
|
||||||
|
|
||||||
DoColorConversionTest(srcTextureSpec, dstTextureSpec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify |CopyTextureForBrowser| doing color conversion correctly when
|
|
||||||
// the source texture is BGRAUnorm format.
|
|
||||||
TEST_P(CopyTextureForBrowserTests, FromBGRA8UnormCopy) {
|
|
||||||
// Tests skip due to crbug.com/dawn/592.
|
|
||||||
DAWN_SKIP_TEST_IF(IsD3D12() && IsBackendValidationEnabled());
|
|
||||||
// Skip OpenGLES backend because it fails on using BGRA8Unorm as
|
|
||||||
// source texture format.
|
|
||||||
DAWN_SKIP_TEST_IF(IsOpenGLES());
|
|
||||||
|
|
||||||
for (wgpu::TextureFormat dstFormat : kDstTextureFormat) {
|
|
||||||
TextureSpec srcTextureSpec;
|
|
||||||
srcTextureSpec.format = wgpu::TextureFormat::BGRA8Unorm;
|
|
||||||
|
|
||||||
TextureSpec dstTextureSpec;
|
|
||||||
dstTextureSpec.format = dstFormat;
|
|
||||||
|
|
||||||
DoColorConversionTest(srcTextureSpec, dstTextureSpec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DAWN_INSTANTIATE_TEST(CopyTextureForBrowserTests,
|
DAWN_INSTANTIATE_TEST(CopyTextureForBrowserTests,
|
||||||
D3D12Backend(),
|
D3D12Backend(),
|
||||||
MetalBackend(),
|
MetalBackend(),
|
||||||
|
|
Loading…
Reference in New Issue