Add internal usage for copyTextureForBrowser
Add an internal usage option for copyTextureForBrowserOption allowing internal calls from call to use canvas context texture as source/destination. Bug: chromium:1331139 Change-Id: Ida8421b3962a6434e8ef57c581c7a2e1d607954c Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/94985 Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Shrek Shao <shrekshao@google.com> Reviewed-by: Loko Kung <lokokung@google.com> Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
parent
e629aee91a
commit
c6cbcdb05b
|
@ -922,7 +922,8 @@
|
|||
"length": 9, "optional": true},
|
||||
{"name": "dst transfer function parameters", "type": "float", "annotation": "const*",
|
||||
"length": 7, "optional": true},
|
||||
{"name": "dst alpha mode", "type": "alpha mode", "default": "unpremultiplied"}
|
||||
{"name": "dst alpha mode", "type": "alpha mode", "default": "unpremultiplied"},
|
||||
{"name": "internal usage", "type": "bool", "default": "false"}
|
||||
]
|
||||
},
|
||||
"create compute pipeline async callback": {
|
||||
|
|
|
@ -330,6 +330,7 @@ source_set("sources") {
|
|||
"ToBackend.h",
|
||||
"Toggles.cpp",
|
||||
"Toggles.h",
|
||||
"UsageValidationMode.h",
|
||||
"VertexFormat.cpp",
|
||||
"VertexFormat.h",
|
||||
"dawn_platform.h",
|
||||
|
|
|
@ -20,12 +20,14 @@
|
|||
#include "dawn/native/BindGroupLayout.h"
|
||||
#include "dawn/native/Buffer.h"
|
||||
#include "dawn/native/ChainUtils_autogen.h"
|
||||
#include "dawn/native/CommandValidation.h"
|
||||
#include "dawn/native/Device.h"
|
||||
#include "dawn/native/ExternalTexture.h"
|
||||
#include "dawn/native/ObjectBase.h"
|
||||
#include "dawn/native/ObjectType_autogen.h"
|
||||
#include "dawn/native/Sampler.h"
|
||||
#include "dawn/native/Texture.h"
|
||||
#include "dawn/native/utils/WGPUHelpers.h"
|
||||
|
||||
namespace dawn::native {
|
||||
|
||||
|
@ -114,7 +116,8 @@ MaybeError ValidateBufferBinding(const DeviceBase* device,
|
|||
|
||||
MaybeError ValidateTextureBinding(DeviceBase* device,
|
||||
const BindGroupEntry& entry,
|
||||
const BindingInfo& bindingInfo) {
|
||||
const BindingInfo& bindingInfo,
|
||||
UsageValidationMode mode) {
|
||||
DAWN_INVALID_IF(entry.textureView == nullptr, "Binding entry textureView not set.");
|
||||
|
||||
DAWN_INVALID_IF(entry.sampler != nullptr || entry.buffer != nullptr,
|
||||
|
@ -136,9 +139,7 @@ MaybeError ValidateTextureBinding(DeviceBase* device,
|
|||
texture->GetFormat().GetAspectInfo(aspect).supportedSampleTypes;
|
||||
SampleTypeBit requiredType = SampleTypeToSampleTypeBit(bindingInfo.texture.sampleType);
|
||||
|
||||
DAWN_INVALID_IF(!(texture->GetUsage() & wgpu::TextureUsage::TextureBinding),
|
||||
"Usage (%s) of %s doesn't include TextureUsage::TextureBinding.",
|
||||
texture->GetUsage(), texture);
|
||||
DAWN_TRY(ValidateCanUseAs(texture, wgpu::TextureUsage::TextureBinding, mode));
|
||||
|
||||
DAWN_INVALID_IF(texture->IsMultisampledTexture() != bindingInfo.texture.multisampled,
|
||||
"Sample count (%u) of %s doesn't match expectation (multisampled: %d).",
|
||||
|
@ -157,9 +158,7 @@ MaybeError ValidateTextureBinding(DeviceBase* device,
|
|||
break;
|
||||
}
|
||||
case BindingInfoType::StorageTexture: {
|
||||
DAWN_INVALID_IF(!(texture->GetUsage() & wgpu::TextureUsage::StorageBinding),
|
||||
"Usage (%s) of %s doesn't include TextureUsage::StorageBinding.",
|
||||
texture->GetUsage(), texture);
|
||||
DAWN_TRY(ValidateCanUseAs(texture, wgpu::TextureUsage::StorageBinding, mode));
|
||||
|
||||
ASSERT(!texture->IsMultisampledTexture());
|
||||
|
||||
|
@ -253,7 +252,9 @@ MaybeError ValidateExternalTextureBinding(
|
|||
|
||||
} // anonymous namespace
|
||||
|
||||
MaybeError ValidateBindGroupDescriptor(DeviceBase* device, const BindGroupDescriptor* descriptor) {
|
||||
MaybeError ValidateBindGroupDescriptor(DeviceBase* device,
|
||||
const BindGroupDescriptor* descriptor,
|
||||
UsageValidationMode mode) {
|
||||
DAWN_INVALID_IF(descriptor->nextInChain != nullptr, "nextInChain must be nullptr.");
|
||||
|
||||
DAWN_TRY(device->ValidateObject(descriptor->layout));
|
||||
|
@ -314,6 +315,7 @@ MaybeError ValidateBindGroupDescriptor(DeviceBase* device, const BindGroupDescri
|
|||
// Perform binding-type specific validation.
|
||||
switch (bindingInfo.bindingType) {
|
||||
case BindingInfoType::Buffer:
|
||||
// TODO(dawn:1485): Validate buffer binding with usage validation mode.
|
||||
DAWN_TRY_CONTEXT(ValidateBufferBinding(device, entry, bindingInfo),
|
||||
"validating entries[%u] as a Buffer."
|
||||
"\nExpected entry layout: %s",
|
||||
|
@ -321,7 +323,7 @@ MaybeError ValidateBindGroupDescriptor(DeviceBase* device, const BindGroupDescri
|
|||
break;
|
||||
case BindingInfoType::Texture:
|
||||
case BindingInfoType::StorageTexture:
|
||||
DAWN_TRY_CONTEXT(ValidateTextureBinding(device, entry, bindingInfo),
|
||||
DAWN_TRY_CONTEXT(ValidateTextureBinding(device, entry, bindingInfo, mode),
|
||||
"validating entries[%u] as a Texture."
|
||||
"\nExpected entry layout: %s",
|
||||
i, bindingInfo);
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "dawn/native/Error.h"
|
||||
#include "dawn/native/Forward.h"
|
||||
#include "dawn/native/ObjectBase.h"
|
||||
#include "dawn/native/UsageValidationMode.h"
|
||||
|
||||
#include "dawn/native/dawn_platform.h"
|
||||
|
||||
|
@ -31,7 +32,9 @@ namespace dawn::native {
|
|||
|
||||
class DeviceBase;
|
||||
|
||||
MaybeError ValidateBindGroupDescriptor(DeviceBase* device, const BindGroupDescriptor* descriptor);
|
||||
MaybeError ValidateBindGroupDescriptor(DeviceBase* device,
|
||||
const BindGroupDescriptor* descriptor,
|
||||
UsageValidationMode mode);
|
||||
|
||||
struct BufferBinding {
|
||||
BufferBase* buffer;
|
||||
|
|
|
@ -187,6 +187,7 @@ target_sources(dawn_native PRIVATE
|
|||
"ToBackend.h"
|
||||
"Toggles.cpp"
|
||||
"Toggles.h"
|
||||
"UsageValidationMode.h"
|
||||
"VertexFormat.cpp"
|
||||
"VertexFormat.h"
|
||||
"dawn_platform.h"
|
||||
|
|
|
@ -471,7 +471,6 @@ MaybeError ValidateCanUseAs(const TextureBase* texture,
|
|||
texture->GetInternalUsage(), usage);
|
||||
break;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "dawn/native/CommandAllocator.h"
|
||||
#include "dawn/native/Error.h"
|
||||
#include "dawn/native/Texture.h"
|
||||
#include "dawn/native/UsageValidationMode.h"
|
||||
|
||||
namespace dawn::native {
|
||||
|
||||
|
@ -82,11 +83,6 @@ MaybeError ValidateTextureToTextureCopyRestrictions(const ImageCopyTexture& src,
|
|||
const ImageCopyTexture& dst,
|
||||
const Extent3D& copySize);
|
||||
|
||||
enum class UsageValidationMode {
|
||||
Default,
|
||||
Internal,
|
||||
};
|
||||
|
||||
MaybeError ValidateCanUseAs(const TextureBase* texture,
|
||||
wgpu::TextureUsage usage,
|
||||
UsageValidationMode mode);
|
||||
|
|
|
@ -306,7 +306,8 @@ ComputePassEncoder::TransformIndirectDispatchBuffer(Ref<BufferBase> indirectBuff
|
|||
{1, indirectBuffer, clientIndirectBindingOffset,
|
||||
clientIndirectBindingSize},
|
||||
{2, validatedIndirectBuffer, 0, scratchBufferSize},
|
||||
}));
|
||||
},
|
||||
UsageValidationMode::Internal));
|
||||
|
||||
// Issue commands to validate the indirect buffer.
|
||||
APISetPipeline(validationPipeline.Get());
|
||||
|
|
|
@ -354,15 +354,15 @@ MaybeError ValidateCopyTextureForBrowser(DeviceBase* device,
|
|||
"not 1.",
|
||||
source->texture->GetSampleCount(), destination->texture->GetSampleCount());
|
||||
|
||||
DAWN_TRY(ValidateCanUseAs(source->texture, wgpu::TextureUsage::CopySrc,
|
||||
UsageValidationMode::Default));
|
||||
DAWN_TRY(ValidateCanUseAs(source->texture, wgpu::TextureUsage::TextureBinding,
|
||||
UsageValidationMode::Default));
|
||||
|
||||
DAWN_TRY(ValidateCanUseAs(destination->texture, wgpu::TextureUsage::CopyDst,
|
||||
UsageValidationMode::Default));
|
||||
DAWN_TRY(ValidateCanUseAs(destination->texture, wgpu::TextureUsage::RenderAttachment,
|
||||
UsageValidationMode::Default));
|
||||
DAWN_INVALID_IF(
|
||||
options->internalUsage && !device->IsFeatureEnabled(Feature::DawnInternalUsages),
|
||||
"The internalUsage is true while the dawn-internal-usages feature is not enabled.");
|
||||
UsageValidationMode mode =
|
||||
options->internalUsage ? UsageValidationMode::Internal : UsageValidationMode::Default;
|
||||
DAWN_TRY(ValidateCanUseAs(source->texture, wgpu::TextureUsage::CopySrc, mode));
|
||||
DAWN_TRY(ValidateCanUseAs(source->texture, wgpu::TextureUsage::TextureBinding, mode));
|
||||
DAWN_TRY(ValidateCanUseAs(destination->texture, wgpu::TextureUsage::CopyDst, mode));
|
||||
DAWN_TRY(ValidateCanUseAs(destination->texture, wgpu::TextureUsage::RenderAttachment, mode));
|
||||
|
||||
DAWN_TRY(ValidateCopyTextureFormatConversion(source->texture->GetFormat().format,
|
||||
destination->texture->GetFormat().format));
|
||||
|
@ -546,14 +546,22 @@ MaybeError DoCopyTextureForBrowser(DeviceBase* device,
|
|||
device->CreateTextureView(source->texture, &srcTextureViewDesc));
|
||||
|
||||
// Create bind group after all binding entries are set.
|
||||
UsageValidationMode mode =
|
||||
options->internalUsage ? UsageValidationMode::Internal : UsageValidationMode::Default;
|
||||
Ref<BindGroupBase> bindGroup;
|
||||
DAWN_TRY_ASSIGN(bindGroup,
|
||||
utils::MakeBindGroup(device, layout,
|
||||
{{0, uniformBuffer}, {1, sampler}, {2, srcTextureView}}));
|
||||
DAWN_TRY_ASSIGN(bindGroup, utils::MakeBindGroup(
|
||||
device, layout,
|
||||
{{0, uniformBuffer}, {1, sampler}, {2, srcTextureView}}, mode));
|
||||
|
||||
// Create command encoder.
|
||||
CommandEncoderDescriptor commandEncoderDesc;
|
||||
DawnEncoderInternalUsageDescriptor internalUsageDesc;
|
||||
if (options->internalUsage) {
|
||||
internalUsageDesc.useInternalUsages = true;
|
||||
commandEncoderDesc.nextInChain = &internalUsageDesc;
|
||||
}
|
||||
Ref<CommandEncoder> encoder;
|
||||
DAWN_TRY_ASSIGN(encoder, device->CreateCommandEncoder());
|
||||
DAWN_TRY_ASSIGN(encoder, device->CreateCommandEncoder(&commandEncoderDesc));
|
||||
|
||||
// Prepare dst texture view as color Attachment.
|
||||
TextureViewDescriptor dstTextureViewDesc;
|
||||
|
|
|
@ -1407,12 +1407,12 @@ QueueBase* DeviceBase::GetQueue() const {
|
|||
|
||||
// Implementation details of object creation
|
||||
|
||||
ResultOrError<Ref<BindGroupBase>> DeviceBase::CreateBindGroup(
|
||||
const BindGroupDescriptor* descriptor) {
|
||||
ResultOrError<Ref<BindGroupBase>> DeviceBase::CreateBindGroup(const BindGroupDescriptor* descriptor,
|
||||
UsageValidationMode mode) {
|
||||
DAWN_TRY(ValidateIsAlive());
|
||||
if (IsValidationEnabled()) {
|
||||
DAWN_TRY_CONTEXT(ValidateBindGroupDescriptor(this, descriptor), "validating %s against %s",
|
||||
descriptor, descriptor->layout);
|
||||
DAWN_TRY_CONTEXT(ValidateBindGroupDescriptor(this, descriptor, mode),
|
||||
"validating %s against %s", descriptor, descriptor->layout);
|
||||
}
|
||||
return CreateBindGroupImpl(descriptor);
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "dawn/native/RefCountedWithExternalCount.h"
|
||||
#include "dawn/native/StagingBuffer.h"
|
||||
#include "dawn/native/Toggles.h"
|
||||
#include "dawn/native/UsageValidationMode.h"
|
||||
|
||||
#include "dawn/native/DawnNative.h"
|
||||
#include "dawn/native/dawn_platform.h"
|
||||
|
@ -203,7 +204,9 @@ class DeviceBase : public RefCountedWithExternalCount {
|
|||
Ref<PipelineCacheBase> GetOrCreatePipelineCache(const CacheKey& key);
|
||||
|
||||
// Object creation methods that be used in a reentrant manner.
|
||||
ResultOrError<Ref<BindGroupBase>> CreateBindGroup(const BindGroupDescriptor* descriptor);
|
||||
ResultOrError<Ref<BindGroupBase>> CreateBindGroup(
|
||||
const BindGroupDescriptor* descriptor,
|
||||
UsageValidationMode mode = UsageValidationMode::Default);
|
||||
ResultOrError<Ref<BindGroupLayoutBase>> CreateBindGroupLayout(
|
||||
const BindGroupLayoutDescriptor* descriptor,
|
||||
bool allowInternalBinding = false);
|
||||
|
|
|
@ -199,7 +199,8 @@ MaybeError EncodeConvertTimestampsToNanoseconds(CommandEncoder* encoder,
|
|||
Ref<BindGroupBase> bindGroup;
|
||||
DAWN_TRY_ASSIGN(
|
||||
bindGroup,
|
||||
utils::MakeBindGroup(device, layout, {{0, timestamps}, {1, availability}, {2, params}}));
|
||||
utils::MakeBindGroup(device, layout, {{0, timestamps}, {1, availability}, {2, params}},
|
||||
UsageValidationMode::Internal));
|
||||
|
||||
// Create compute encoder and issue dispatch.
|
||||
Ref<ComputePassEncoder> pass = encoder->BeginComputePass();
|
||||
|
|
|
@ -340,7 +340,7 @@ MaybeError ValidateTextureDescriptor(const DeviceBase* device,
|
|||
|
||||
DAWN_INVALID_IF(
|
||||
internalUsageDesc != nullptr && !device->IsFeatureEnabled(Feature::DawnInternalUsages),
|
||||
"The dawn-internal-usages feature is not enabled");
|
||||
"The internalUsageDesc is not empty while the dawn-internal-usages feature is not enabled");
|
||||
|
||||
const Format* format;
|
||||
DAWN_TRY_ASSIGN(format, device->GetInternalFormat(descriptor->format));
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright 2022 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.
|
||||
|
||||
#ifndef SRC_DAWN_NATIVE_USAGEVALIDATIONMODE_H_
|
||||
#define SRC_DAWN_NATIVE_USAGEVALIDATIONMODE_H_
|
||||
|
||||
namespace dawn::native {
|
||||
|
||||
enum class UsageValidationMode {
|
||||
Default,
|
||||
Internal,
|
||||
};
|
||||
|
||||
} // namespace dawn::native
|
||||
|
||||
#endif // SRC_DAWN_NATIVE_USAGEVALIDATIONMODE_H_
|
|
@ -165,7 +165,8 @@ BindGroupEntry BindingInitializationHelper::GetAsBinding() const {
|
|||
ResultOrError<Ref<BindGroupBase>> MakeBindGroup(
|
||||
DeviceBase* device,
|
||||
const Ref<BindGroupLayoutBase>& layout,
|
||||
std::initializer_list<BindingInitializationHelper> entriesInitializer) {
|
||||
std::initializer_list<BindingInitializationHelper> entriesInitializer,
|
||||
UsageValidationMode mode) {
|
||||
std::vector<BindGroupEntry> entries;
|
||||
for (const BindingInitializationHelper& helper : entriesInitializer) {
|
||||
entries.push_back(helper.GetAsBinding());
|
||||
|
@ -176,7 +177,7 @@ ResultOrError<Ref<BindGroupBase>> MakeBindGroup(
|
|||
descriptor.entryCount = entries.size();
|
||||
descriptor.entries = entries.data();
|
||||
|
||||
return device->CreateBindGroup(&descriptor);
|
||||
return device->CreateBindGroup(&descriptor, mode);
|
||||
}
|
||||
|
||||
const char* GetLabelForTrace(const char* label) {
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "dawn/common/RefCounted.h"
|
||||
#include "dawn/native/Error.h"
|
||||
#include "dawn/native/UsageValidationMode.h"
|
||||
#include "dawn/native/dawn_platform.h"
|
||||
|
||||
namespace dawn::native::utils {
|
||||
|
@ -110,10 +111,12 @@ struct BindingInitializationHelper {
|
|||
uint64_t size = 0;
|
||||
};
|
||||
|
||||
// This helper is only used inside dawn native.
|
||||
ResultOrError<Ref<BindGroupBase>> MakeBindGroup(
|
||||
DeviceBase* device,
|
||||
const Ref<BindGroupLayoutBase>& layout,
|
||||
std::initializer_list<BindingInitializationHelper> entriesInitializer);
|
||||
std::initializer_list<BindingInitializationHelper> entriesInitializer,
|
||||
UsageValidationMode mode);
|
||||
|
||||
const char* GetLabelForTrace(const char* label);
|
||||
|
||||
|
|
|
@ -22,14 +22,17 @@
|
|||
|
||||
class CopyTextureForBrowserTest : public ValidationTest {
|
||||
protected:
|
||||
wgpu::Texture Create2DTexture(uint32_t width,
|
||||
wgpu::Texture Create2DTexture(
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
uint32_t mipLevelCount,
|
||||
uint32_t arrayLayerCount,
|
||||
wgpu::TextureFormat format,
|
||||
wgpu::TextureUsage usage,
|
||||
uint32_t sampleCount = 1) {
|
||||
uint32_t sampleCount = 1,
|
||||
const wgpu::DawnTextureInternalUsageDescriptor* internalDesc = nullptr) {
|
||||
wgpu::TextureDescriptor descriptor;
|
||||
descriptor.nextInChain = internalDesc;
|
||||
descriptor.dimension = wgpu::TextureDimension::e2D;
|
||||
descriptor.size.width = width;
|
||||
descriptor.size.height = height;
|
||||
|
@ -67,6 +70,17 @@ class CopyTextureForBrowserTest : public ValidationTest {
|
|||
}
|
||||
};
|
||||
|
||||
class CopyTextureForBrowserInternalUsageTest : public CopyTextureForBrowserTest {
|
||||
protected:
|
||||
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
|
||||
wgpu::DeviceDescriptor descriptor;
|
||||
wgpu::FeatureName feature = wgpu::FeatureName::DawnInternalUsages;
|
||||
descriptor.requiredFeatures = &feature;
|
||||
descriptor.requiredFeaturesCount = 1;
|
||||
return dawnAdapter.CreateDevice(&descriptor);
|
||||
}
|
||||
};
|
||||
|
||||
// Tests should be Success
|
||||
TEST_F(CopyTextureForBrowserTest, Success) {
|
||||
wgpu::Texture source =
|
||||
|
@ -434,3 +448,54 @@ TEST_F(CopyTextureForBrowserTest, ColorSpaceConversion_TextureAlphaState) {
|
|||
{0, 0, 0}, {4, 4, 1}, wgpu::TextureAspect::All, options);
|
||||
}
|
||||
}
|
||||
|
||||
// Test that the internal usage can only be set to true when the device internal usage feature is
|
||||
// enabled
|
||||
TEST_F(CopyTextureForBrowserTest, InternalUsage) {
|
||||
wgpu::DawnTextureInternalUsageDescriptor internalDesc = {};
|
||||
internalDesc.internalUsage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::TextureBinding;
|
||||
|
||||
// Validation should fail because internal descriptor is not empty.
|
||||
ASSERT_DEVICE_ERROR(Create2DTexture(16, 16, 5, 4, wgpu::TextureFormat::RGBA8Unorm,
|
||||
wgpu::TextureUsage::CopySrc, 1, &internalDesc));
|
||||
|
||||
wgpu::Texture source =
|
||||
Create2DTexture(16, 16, 5, 4, wgpu::TextureFormat::RGBA8Unorm,
|
||||
wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::TextureBinding);
|
||||
|
||||
wgpu::Texture destination =
|
||||
Create2DTexture(16, 16, 5, 4, wgpu::TextureFormat::RGBA8Unorm,
|
||||
wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment);
|
||||
|
||||
// Validation should fail because of device internal usage feature is missing when internal
|
||||
// usage option is on
|
||||
wgpu::CopyTextureForBrowserOptions options = {};
|
||||
options.internalUsage = true;
|
||||
TestCopyTextureForBrowser(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0,
|
||||
{0, 0, 0}, {16, 16, 1}, wgpu::TextureAspect::All, options);
|
||||
}
|
||||
|
||||
// Test that the internal usages are taken into account when interalUsage = true
|
||||
TEST_F(CopyTextureForBrowserInternalUsageTest, InternalUsage) {
|
||||
wgpu::DawnTextureInternalUsageDescriptor internalDesc1 = {};
|
||||
internalDesc1.internalUsage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::TextureBinding;
|
||||
|
||||
wgpu::Texture source = Create2DTexture(16, 16, 5, 4, wgpu::TextureFormat::RGBA8Unorm,
|
||||
wgpu::TextureUsage::CopySrc, 1, &internalDesc1);
|
||||
|
||||
wgpu::DawnTextureInternalUsageDescriptor internalDesc2 = {};
|
||||
internalDesc2.internalUsage =
|
||||
wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment;
|
||||
wgpu::Texture destination = Create2DTexture(16, 16, 5, 4, wgpu::TextureFormat::RGBA8Unorm,
|
||||
wgpu::TextureUsage::CopyDst, 1, &internalDesc2);
|
||||
|
||||
// Without internal usage option should fail usage validation
|
||||
TestCopyTextureForBrowser(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0,
|
||||
{0, 0, 0}, {16, 16, 1});
|
||||
|
||||
// With internal usage option should pass usage validation
|
||||
wgpu::CopyTextureForBrowserOptions options = {};
|
||||
options.internalUsage = true;
|
||||
TestCopyTextureForBrowser(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0,
|
||||
{0, 0, 0}, {16, 16, 1}, wgpu::TextureAspect::All, options);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue