Add WGPUDawnEncoderInternalUsageDescriptor
This descriptor, when chained on WGPUCommandEncoderDescriptor makes internal usages visible to validation. This CL is to help implement WebGPU Swiftshader support in Chrome. Bug: chromium:1266550 Change-Id: I7253fe45003e9ad5ac4d8ddd2d4782989e9b5c27 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/76440 Reviewed-by: Loko Kung <lokokung@google.com> Reviewed-by: Kai Ninomiya <kainino@chromium.org> Commit-Queue: Austin Eng <enga@chromium.org>
This commit is contained in:
parent
ddca7bc855
commit
aa9475e973
11
dawn.json
11
dawn.json
|
@ -2369,7 +2369,8 @@
|
|||
{"value": 11, "name": "surface descriptor from windows swap chain panel", "tags": ["dawn"]},
|
||||
{"value": 1000, "name": "dawn texture internal usage descriptor", "tags": ["dawn"]},
|
||||
{"value": 1001, "name": "primitive depth clamping state", "tags": ["dawn", "emscripten"]},
|
||||
{"value": 1002, "name": "dawn toggles device descriptor", "tags": ["dawn", "native"]}
|
||||
{"value": 1002, "name": "dawn toggles device descriptor", "tags": ["dawn", "native"]},
|
||||
{"value": 1003, "name": "dawn encoder internal usage descriptor", "tags": ["dawn"]}
|
||||
]
|
||||
},
|
||||
"texture": {
|
||||
|
@ -2733,5 +2734,13 @@
|
|||
"members": [
|
||||
{"name": "internal usage", "type": "texture usage", "default": "none"}
|
||||
]
|
||||
},
|
||||
"dawn encoder internal usage descriptor": {
|
||||
"category": "structure",
|
||||
"chained": "in",
|
||||
"tags": ["dawn"],
|
||||
"members": [
|
||||
{"name": "use internal usages", "type": "bool", "default": "false"}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
# Dawn Internal Usages
|
||||
|
||||
The `dawn-internal-usages` feature allows adding additional usage which affects how a texture is allocated, but does not affect frontend validation.
|
||||
The `dawn-internal-usages` feature allows adding additional usage which affects how a texture is allocated, but does not affect normal frontend validation.
|
||||
|
||||
One use case for this is so that Chromium can use an internal copyTextureToTexture command to implement copies from a WebGPU texture-backed canvas to other Web platform primitives when the swapchain texture was not explicitly created with CopySrc usage in Javascript.
|
||||
Adds `WGPUDawnTextureInternalUsageDescriptor` for specifying additional internal usages to create a texture with.
|
||||
|
||||
Example Usage:
|
||||
```
|
||||
Usage:
|
||||
|
||||
wgpu::DawnTextureInternalUsageDescriptor internalDesc = {};
|
||||
internalDesc.internalUsage = wgpu::TextureUsage::CopySrc;
|
||||
|
||||
|
@ -14,5 +13,26 @@ wgpu::TextureDescriptor desc = {};
|
|||
// set properties of desc.
|
||||
desc.nextInChain = &internalDesc;
|
||||
|
||||
device.createTexture(&desc);
|
||||
device.CreateTexture(&desc);
|
||||
```
|
||||
|
||||
Adds `WGPUDawnEncoderInternalUsageDescriptor` which may be chained on `WGPUCommandEncoderDescriptor`. Setting `WGPUDawnEncoderInternalUsageDescriptor::useInternalUsages` to `true` means that internal resource usages will be visible during validation. ex.) A texture that has `WGPUTextureUsage_CopySrc` in `WGPUDawnEncoderInternalUsageDescriptor::internalUsage`, but not in `WGPUTextureDescriptor::usage` may be used as the source of a copy command.
|
||||
|
||||
|
||||
Example Usage:
|
||||
```
|
||||
wgpu::DawnEncoderInternalUsageDescriptor internalEncoderDesc = { true };
|
||||
wgpu::CommandEncoderDescriptor encoderDesc = {};
|
||||
encoderDesc.nextInChain = &internalEncoderDesc;
|
||||
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder(&encoderDesc);
|
||||
|
||||
// This will be valid
|
||||
wgpu::ImageCopyTexture src = {};
|
||||
src.texture = texture;
|
||||
encoder.CopyTextureToBuffer(&src, ...);
|
||||
```
|
||||
|
||||
One use case for this is so that Chromium can use an internal copyTextureToTexture command to implement copies from a WebGPU texture-backed canvas to other Web platform primitives when the swapchain texture was not explicitly created with CopySrc usage in Javascript.
|
||||
|
||||
Note: copyTextureToTextureInternal will be removed in favor of `WGPUDawnEncoderInternalUsageDescriptor`.
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "common/Math.h"
|
||||
#include "dawn_native/BindGroup.h"
|
||||
#include "dawn_native/Buffer.h"
|
||||
#include "dawn_native/ChainUtils_autogen.h"
|
||||
#include "dawn_native/CommandBuffer.h"
|
||||
#include "dawn_native/CommandBufferStateTracker.h"
|
||||
#include "dawn_native/CommandValidation.h"
|
||||
|
@ -159,7 +160,8 @@ namespace dawn::native {
|
|||
}
|
||||
|
||||
MaybeError ValidateResolveTarget(const DeviceBase* device,
|
||||
const RenderPassColorAttachment& colorAttachment) {
|
||||
const RenderPassColorAttachment& colorAttachment,
|
||||
UsageValidationMode usageValidationMode) {
|
||||
if (colorAttachment.resolveTarget == nullptr) {
|
||||
return {};
|
||||
}
|
||||
|
@ -168,7 +170,7 @@ namespace dawn::native {
|
|||
const TextureViewBase* attachment = colorAttachment.view;
|
||||
DAWN_TRY(device->ValidateObject(colorAttachment.resolveTarget));
|
||||
DAWN_TRY(ValidateCanUseAs(colorAttachment.resolveTarget->GetTexture(),
|
||||
wgpu::TextureUsage::RenderAttachment));
|
||||
wgpu::TextureUsage::RenderAttachment, usageValidationMode));
|
||||
|
||||
DAWN_INVALID_IF(
|
||||
!attachment->GetTexture()->IsMultisampledTexture(),
|
||||
|
@ -216,11 +218,12 @@ namespace dawn::native {
|
|||
const RenderPassColorAttachment& colorAttachment,
|
||||
uint32_t* width,
|
||||
uint32_t* height,
|
||||
uint32_t* sampleCount) {
|
||||
uint32_t* sampleCount,
|
||||
UsageValidationMode usageValidationMode) {
|
||||
TextureViewBase* attachment = colorAttachment.view;
|
||||
DAWN_TRY(device->ValidateObject(attachment));
|
||||
DAWN_TRY(
|
||||
ValidateCanUseAs(attachment->GetTexture(), wgpu::TextureUsage::RenderAttachment));
|
||||
DAWN_TRY(ValidateCanUseAs(attachment->GetTexture(),
|
||||
wgpu::TextureUsage::RenderAttachment, usageValidationMode));
|
||||
|
||||
DAWN_INVALID_IF(!(attachment->GetAspects() & Aspect::Color) ||
|
||||
!attachment->GetFormat().isRenderable,
|
||||
|
@ -241,7 +244,7 @@ namespace dawn::native {
|
|||
|
||||
DAWN_TRY(ValidateOrSetColorAttachmentSampleCount(attachment, sampleCount));
|
||||
|
||||
DAWN_TRY(ValidateResolveTarget(device, colorAttachment));
|
||||
DAWN_TRY(ValidateResolveTarget(device, colorAttachment, usageValidationMode));
|
||||
|
||||
DAWN_TRY(ValidateAttachmentArrayLayersAndLevelCount(attachment));
|
||||
DAWN_TRY(ValidateOrSetAttachmentSize(attachment, width, height));
|
||||
|
@ -254,13 +257,14 @@ namespace dawn::native {
|
|||
const RenderPassDepthStencilAttachment* depthStencilAttachment,
|
||||
uint32_t* width,
|
||||
uint32_t* height,
|
||||
uint32_t* sampleCount) {
|
||||
uint32_t* sampleCount,
|
||||
UsageValidationMode usageValidationMode) {
|
||||
DAWN_ASSERT(depthStencilAttachment != nullptr);
|
||||
|
||||
TextureViewBase* attachment = depthStencilAttachment->view;
|
||||
DAWN_TRY(device->ValidateObject(attachment));
|
||||
DAWN_TRY(
|
||||
ValidateCanUseAs(attachment->GetTexture(), wgpu::TextureUsage::RenderAttachment));
|
||||
DAWN_TRY(ValidateCanUseAs(attachment->GetTexture(),
|
||||
wgpu::TextureUsage::RenderAttachment, usageValidationMode));
|
||||
|
||||
const Format& format = attachment->GetFormat();
|
||||
DAWN_INVALID_IF(
|
||||
|
@ -333,24 +337,25 @@ namespace dawn::native {
|
|||
const RenderPassDescriptor* descriptor,
|
||||
uint32_t* width,
|
||||
uint32_t* height,
|
||||
uint32_t* sampleCount) {
|
||||
uint32_t* sampleCount,
|
||||
UsageValidationMode usageValidationMode) {
|
||||
DAWN_INVALID_IF(
|
||||
descriptor->colorAttachmentCount > kMaxColorAttachments,
|
||||
"Color attachment count (%u) exceeds the maximum number of color attachments (%u).",
|
||||
descriptor->colorAttachmentCount, kMaxColorAttachments);
|
||||
|
||||
for (uint32_t i = 0; i < descriptor->colorAttachmentCount; ++i) {
|
||||
DAWN_TRY_CONTEXT(
|
||||
ValidateRenderPassColorAttachment(device, descriptor->colorAttachments[i],
|
||||
width, height, sampleCount),
|
||||
"validating colorAttachments[%u].", i);
|
||||
DAWN_TRY_CONTEXT(ValidateRenderPassColorAttachment(
|
||||
device, descriptor->colorAttachments[i], width, height,
|
||||
sampleCount, usageValidationMode),
|
||||
"validating colorAttachments[%u].", i);
|
||||
}
|
||||
|
||||
if (descriptor->depthStencilAttachment != nullptr) {
|
||||
DAWN_TRY_CONTEXT(
|
||||
ValidateRenderPassDepthStencilAttachment(
|
||||
device, descriptor->depthStencilAttachment, width, height, sampleCount),
|
||||
"validating depthStencilAttachment.");
|
||||
DAWN_TRY_CONTEXT(ValidateRenderPassDepthStencilAttachment(
|
||||
device, descriptor->depthStencilAttachment, width, height,
|
||||
sampleCount, usageValidationMode),
|
||||
"validating depthStencilAttachment.");
|
||||
}
|
||||
|
||||
if (descriptor->occlusionQuerySet != nullptr) {
|
||||
|
@ -468,9 +473,50 @@ namespace dawn::native {
|
|||
|
||||
} // namespace
|
||||
|
||||
MaybeError ValidateCommandEncoderDescriptor(const DeviceBase* device,
|
||||
const CommandEncoderDescriptor* descriptor) {
|
||||
DAWN_TRY(ValidateSingleSType(descriptor->nextInChain,
|
||||
wgpu::SType::DawnEncoderInternalUsageDescriptor));
|
||||
|
||||
const DawnEncoderInternalUsageDescriptor* internalUsageDesc = nullptr;
|
||||
FindInChain(descriptor->nextInChain, &internalUsageDesc);
|
||||
|
||||
DAWN_INVALID_IF(internalUsageDesc != nullptr &&
|
||||
!device->APIHasFeature(wgpu::FeatureName::DawnInternalUsages),
|
||||
"%s is not available.", wgpu::FeatureName::DawnInternalUsages);
|
||||
return {};
|
||||
}
|
||||
|
||||
// static
|
||||
Ref<CommandEncoder> CommandEncoder::Create(DeviceBase* device,
|
||||
const CommandEncoderDescriptor* descriptor) {
|
||||
return AcquireRef(new CommandEncoder(device, descriptor));
|
||||
}
|
||||
|
||||
// static
|
||||
CommandEncoder* CommandEncoder::MakeError(DeviceBase* device) {
|
||||
return new CommandEncoder(device, ObjectBase::kError);
|
||||
}
|
||||
|
||||
CommandEncoder::CommandEncoder(DeviceBase* device, const CommandEncoderDescriptor* descriptor)
|
||||
: ApiObjectBase(device, descriptor->label), mEncodingContext(device, this) {
|
||||
TrackInDevice();
|
||||
|
||||
const DawnEncoderInternalUsageDescriptor* internalUsageDesc = nullptr;
|
||||
FindInChain(descriptor->nextInChain, &internalUsageDesc);
|
||||
|
||||
if (internalUsageDesc != nullptr && internalUsageDesc->useInternalUsages) {
|
||||
mUsageValidationMode = UsageValidationMode::Internal;
|
||||
} else {
|
||||
mUsageValidationMode = UsageValidationMode::Default;
|
||||
}
|
||||
}
|
||||
|
||||
CommandEncoder::CommandEncoder(DeviceBase* device, ObjectBase::ErrorTag tag)
|
||||
: ApiObjectBase(device, tag),
|
||||
mEncodingContext(device, this),
|
||||
mUsageValidationMode(UsageValidationMode::Default) {
|
||||
mEncodingContext.HandleError(DAWN_FORMAT_VALIDATION_ERROR("%s is invalid.", this));
|
||||
}
|
||||
|
||||
ObjectType CommandEncoder::GetType() const {
|
||||
|
@ -554,7 +600,7 @@ namespace dawn::native {
|
|||
uint32_t sampleCount = 0;
|
||||
|
||||
DAWN_TRY(ValidateRenderPassDescriptor(device, descriptor, &width, &height,
|
||||
&sampleCount));
|
||||
&sampleCount, mUsageValidationMode));
|
||||
|
||||
ASSERT(width > 0 && height > 0 && sampleCount > 0);
|
||||
|
||||
|
@ -703,7 +749,8 @@ namespace dawn::native {
|
|||
|
||||
DAWN_TRY(ValidateImageCopyTexture(GetDevice(), *destination, *copySize));
|
||||
DAWN_TRY_CONTEXT(
|
||||
ValidateCanUseAs(destination->texture, wgpu::TextureUsage::CopyDst),
|
||||
ValidateCanUseAs(destination->texture, wgpu::TextureUsage::CopyDst,
|
||||
mUsageValidationMode),
|
||||
"validating destination %s usage.", destination->texture);
|
||||
DAWN_TRY(ValidateTextureSampleCountInBufferCopyCommands(destination->texture));
|
||||
|
||||
|
@ -757,7 +804,8 @@ namespace dawn::native {
|
|||
[&](CommandAllocator* allocator) -> MaybeError {
|
||||
if (GetDevice()->IsValidationEnabled()) {
|
||||
DAWN_TRY(ValidateImageCopyTexture(GetDevice(), *source, *copySize));
|
||||
DAWN_TRY_CONTEXT(ValidateCanUseAs(source->texture, wgpu::TextureUsage::CopySrc),
|
||||
DAWN_TRY_CONTEXT(ValidateCanUseAs(source->texture, wgpu::TextureUsage::CopySrc,
|
||||
mUsageValidationMode),
|
||||
"validating source %s usage.", source->texture);
|
||||
DAWN_TRY(ValidateTextureSampleCountInBufferCopyCommands(source->texture));
|
||||
DAWN_TRY(ValidateTextureDepthStencilToBufferCopyRestrictions(*source));
|
||||
|
@ -846,14 +894,15 @@ namespace dawn::native {
|
|||
// For internal usages (CopyToCopyInternal) we don't care if the user has added
|
||||
// CopySrc as a usage for this texture, but we will always add it internally.
|
||||
if (Internal) {
|
||||
DAWN_TRY(
|
||||
ValidateInternalCanUseAs(source->texture, wgpu::TextureUsage::CopySrc));
|
||||
DAWN_TRY(ValidateInternalCanUseAs(destination->texture,
|
||||
wgpu::TextureUsage::CopyDst));
|
||||
DAWN_TRY(ValidateCanUseAs(source->texture, wgpu::TextureUsage::CopySrc,
|
||||
UsageValidationMode::Internal));
|
||||
DAWN_TRY(ValidateCanUseAs(destination->texture, wgpu::TextureUsage::CopyDst,
|
||||
UsageValidationMode::Internal));
|
||||
} else {
|
||||
DAWN_TRY(ValidateCanUseAs(source->texture, wgpu::TextureUsage::CopySrc));
|
||||
DAWN_TRY(
|
||||
ValidateCanUseAs(destination->texture, wgpu::TextureUsage::CopyDst));
|
||||
DAWN_TRY(ValidateCanUseAs(source->texture, wgpu::TextureUsage::CopySrc,
|
||||
mUsageValidationMode));
|
||||
DAWN_TRY(ValidateCanUseAs(destination->texture, wgpu::TextureUsage::CopyDst,
|
||||
mUsageValidationMode));
|
||||
}
|
||||
|
||||
mTopLevelTextures.insert(source->texture);
|
||||
|
|
|
@ -26,9 +26,16 @@
|
|||
|
||||
namespace dawn::native {
|
||||
|
||||
enum class UsageValidationMode;
|
||||
|
||||
MaybeError ValidateCommandEncoderDescriptor(const DeviceBase* device,
|
||||
const CommandEncoderDescriptor* descriptor);
|
||||
|
||||
class CommandEncoder final : public ApiObjectBase {
|
||||
public:
|
||||
CommandEncoder(DeviceBase* device, const CommandEncoderDescriptor* descriptor);
|
||||
static Ref<CommandEncoder> Create(DeviceBase* device,
|
||||
const CommandEncoderDescriptor* descriptor);
|
||||
static CommandEncoder* MakeError(DeviceBase* device);
|
||||
|
||||
ObjectType GetType() const override;
|
||||
|
||||
|
@ -80,6 +87,9 @@ namespace dawn::native {
|
|||
CommandBufferBase* APIFinish(const CommandBufferDescriptor* descriptor = nullptr);
|
||||
|
||||
private:
|
||||
CommandEncoder(DeviceBase* device, const CommandEncoderDescriptor* descriptor);
|
||||
CommandEncoder(DeviceBase* device, ObjectBase::ErrorTag tag);
|
||||
|
||||
void DestroyImpl() override;
|
||||
ResultOrError<Ref<CommandBufferBase>> FinishInternal(
|
||||
const CommandBufferDescriptor* descriptor);
|
||||
|
@ -100,6 +110,8 @@ namespace dawn::native {
|
|||
std::set<QuerySetBase*> mUsedQuerySets;
|
||||
|
||||
uint64_t mDebugGroupStackSize = 0;
|
||||
|
||||
UsageValidationMode mUsageValidationMode;
|
||||
};
|
||||
|
||||
} // namespace dawn::native
|
||||
|
|
|
@ -447,19 +447,21 @@ namespace dawn::native {
|
|||
return ValidateTextureToTextureCopyCommonRestrictions(src, dst, copySize);
|
||||
}
|
||||
|
||||
MaybeError ValidateCanUseAs(const TextureBase* texture, wgpu::TextureUsage usage) {
|
||||
MaybeError ValidateCanUseAs(const TextureBase* texture,
|
||||
wgpu::TextureUsage usage,
|
||||
UsageValidationMode mode) {
|
||||
ASSERT(wgpu::HasZeroOrOneBits(usage));
|
||||
DAWN_INVALID_IF(!(texture->GetUsage() & usage), "%s usage (%s) doesn't include %s.",
|
||||
texture, texture->GetUsage(), usage);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
MaybeError ValidateInternalCanUseAs(const TextureBase* texture, wgpu::TextureUsage usage) {
|
||||
ASSERT(wgpu::HasZeroOrOneBits(usage));
|
||||
DAWN_INVALID_IF(!(texture->GetInternalUsage() & usage),
|
||||
"%s internal usage (%s) doesn't include %s.", texture,
|
||||
texture->GetInternalUsage(), usage);
|
||||
switch (mode) {
|
||||
case UsageValidationMode::Default:
|
||||
DAWN_INVALID_IF(!(texture->GetUsage() & usage), "%s usage (%s) doesn't include %s.",
|
||||
texture, texture->GetUsage(), usage);
|
||||
break;
|
||||
case UsageValidationMode::Internal:
|
||||
DAWN_INVALID_IF(!(texture->GetInternalUsage() & usage),
|
||||
"%s internal usage (%s) doesn't include %s.", texture,
|
||||
texture->GetInternalUsage(), usage);
|
||||
break;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
@ -468,7 +470,6 @@ namespace dawn::native {
|
|||
ASSERT(wgpu::HasZeroOrOneBits(usage));
|
||||
DAWN_INVALID_IF(!(buffer->GetUsage() & usage), "%s usage (%s) doesn't include %s.", buffer,
|
||||
buffer->GetUsage(), usage);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
@ -73,10 +73,14 @@ namespace dawn::native {
|
|||
const ImageCopyTexture& dst,
|
||||
const Extent3D& copySize);
|
||||
|
||||
MaybeError ValidateCanUseAs(const TextureBase* texture, wgpu::TextureUsage usage);
|
||||
|
||||
MaybeError ValidateInternalCanUseAs(const TextureBase* texture, wgpu::TextureUsage usage);
|
||||
enum class UsageValidationMode {
|
||||
Default,
|
||||
Internal,
|
||||
};
|
||||
|
||||
MaybeError ValidateCanUseAs(const TextureBase* texture,
|
||||
wgpu::TextureUsage usage,
|
||||
UsageValidationMode mode);
|
||||
MaybeError ValidateCanUseAs(const BufferBase* buffer, wgpu::BufferUsage usage);
|
||||
|
||||
} // namespace dawn::native
|
||||
|
|
|
@ -350,11 +350,15 @@ namespace dawn::native {
|
|||
"not 1.",
|
||||
source->texture->GetSampleCount(), destination->texture->GetSampleCount());
|
||||
|
||||
DAWN_TRY(ValidateCanUseAs(source->texture, wgpu::TextureUsage::CopySrc));
|
||||
DAWN_TRY(ValidateCanUseAs(source->texture, wgpu::TextureUsage::TextureBinding));
|
||||
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));
|
||||
DAWN_TRY(ValidateCanUseAs(destination->texture, wgpu::TextureUsage::RenderAttachment));
|
||||
DAWN_TRY(ValidateCanUseAs(destination->texture, wgpu::TextureUsage::CopyDst,
|
||||
UsageValidationMode::Default));
|
||||
DAWN_TRY(ValidateCanUseAs(destination->texture, wgpu::TextureUsage::RenderAttachment,
|
||||
UsageValidationMode::Default));
|
||||
|
||||
DAWN_TRY(ValidateCopyTextureFormatConversion(source->texture->GetFormat().format,
|
||||
destination->texture->GetFormat().format));
|
||||
|
|
|
@ -953,7 +953,13 @@ namespace dawn::native {
|
|||
if (descriptor == nullptr) {
|
||||
descriptor = &defaultDescriptor;
|
||||
}
|
||||
return new CommandEncoder(this, descriptor);
|
||||
|
||||
Ref<CommandEncoder> result;
|
||||
if (ConsumedError(CreateCommandEncoder(descriptor), &result,
|
||||
"calling %s.CreateCommandEncoder(%s).", this, descriptor)) {
|
||||
return CommandEncoder::MakeError(this);
|
||||
}
|
||||
return result.Detach();
|
||||
}
|
||||
ComputePipelineBase* DeviceBase::APICreateComputePipeline(
|
||||
const ComputePipelineDescriptor* descriptor) {
|
||||
|
@ -1313,6 +1319,15 @@ namespace dawn::native {
|
|||
return AddOrGetCachedComputePipeline(std::move(uninitializedComputePipeline));
|
||||
}
|
||||
|
||||
ResultOrError<Ref<CommandEncoder>> DeviceBase::CreateCommandEncoder(
|
||||
const CommandEncoderDescriptor* descriptor) {
|
||||
DAWN_TRY(ValidateIsAlive());
|
||||
if (IsValidationEnabled()) {
|
||||
DAWN_TRY(ValidateCommandEncoderDescriptor(this, descriptor));
|
||||
}
|
||||
return CommandEncoder::Create(this, descriptor);
|
||||
}
|
||||
|
||||
MaybeError DeviceBase::CreateComputePipelineAsync(
|
||||
const ComputePipelineDescriptor* descriptor,
|
||||
WGPUCreateComputePipelineAsyncCallback callback,
|
||||
|
|
|
@ -198,6 +198,8 @@ namespace dawn::native {
|
|||
const BindGroupLayoutDescriptor* descriptor,
|
||||
bool allowInternalBinding = false);
|
||||
ResultOrError<Ref<BufferBase>> CreateBuffer(const BufferDescriptor* descriptor);
|
||||
ResultOrError<Ref<CommandEncoder>> CreateCommandEncoder(
|
||||
const CommandEncoderDescriptor* descriptor);
|
||||
ResultOrError<Ref<ComputePipelineBase>> CreateComputePipeline(
|
||||
const ComputePipelineDescriptor* descriptor);
|
||||
MaybeError CreateComputePipelineAsync(
|
||||
|
|
|
@ -16,10 +16,11 @@
|
|||
|
||||
#include "utils/WGPUHelpers.h"
|
||||
|
||||
class TextureInternalUsageValidationDisabledTest : public ValidationTest {};
|
||||
class InternalUsageValidationDisabledTest : public ValidationTest {};
|
||||
|
||||
// Test that using the feature is an error if it is not enabled
|
||||
TEST_F(TextureInternalUsageValidationDisabledTest, RequiresFeature) {
|
||||
// Test that using DawnTextureInternalUsageDescriptor is an error if DawnInternalUsages is not
|
||||
// enabled
|
||||
TEST_F(InternalUsageValidationDisabledTest, TextureDescriptorRequiresFeature) {
|
||||
wgpu::TextureDescriptor textureDesc = {};
|
||||
textureDesc.size = {1, 1};
|
||||
textureDesc.usage = wgpu::TextureUsage::CopySrc;
|
||||
|
@ -42,6 +43,26 @@ TEST_F(TextureInternalUsageValidationDisabledTest, RequiresFeature) {
|
|||
ASSERT_DEVICE_ERROR(device.CreateTexture(&textureDesc));
|
||||
}
|
||||
|
||||
// Test that using DawnEncoderInternalUsageDescriptor is an error if DawnInternalUsages is not
|
||||
// enabled
|
||||
TEST_F(InternalUsageValidationDisabledTest, CommandEncoderDescriptorRequiresFeature) {
|
||||
wgpu::CommandEncoderDescriptor encoderDesc = {};
|
||||
|
||||
// Control case: Normal encoder creation works
|
||||
device.CreateCommandEncoder(&encoderDesc);
|
||||
|
||||
wgpu::DawnEncoderInternalUsageDescriptor internalDesc = {};
|
||||
encoderDesc.nextInChain = &internalDesc;
|
||||
|
||||
// Error with chained DawnEncoderInternalUsageDescriptor.
|
||||
ASSERT_DEVICE_ERROR(wgpu::CommandEncoder encoder = device.CreateCommandEncoder(&encoderDesc));
|
||||
|
||||
// Check that the encoder records that it is invalid, and not any other errors.
|
||||
encoder.InjectValidationError("injected error");
|
||||
ASSERT_DEVICE_ERROR(encoder.Finish(),
|
||||
testing::HasSubstr("[Invalid CommandEncoder] is invalid"));
|
||||
}
|
||||
|
||||
class TextureInternalUsageValidationTest : public ValidationTest {
|
||||
WGPUDevice CreateTestDevice() override {
|
||||
wgpu::DeviceDescriptor descriptor;
|
||||
|
@ -117,7 +138,7 @@ TEST_F(TextureInternalUsageValidationTest, UsageValidation) {
|
|||
// Test that internal usage does not add to the validated usage
|
||||
// for command encoding
|
||||
// This test also test the internal copy
|
||||
TEST_F(TextureInternalUsageValidationTest, CommandValidation) {
|
||||
TEST_F(TextureInternalUsageValidationTest, DeprecatedCommandValidation) {
|
||||
wgpu::TextureDescriptor textureDesc = {};
|
||||
textureDesc.size = {1, 1};
|
||||
textureDesc.format = wgpu::TextureFormat::RGBA8Unorm;
|
||||
|
@ -182,3 +203,96 @@ TEST_F(TextureInternalUsageValidationTest, CommandValidation) {
|
|||
encoder.Finish();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TextureInternalUsageValidationTest, CommandValidation) {
|
||||
wgpu::TextureDescriptor textureDesc = {};
|
||||
textureDesc.size = {1, 1};
|
||||
textureDesc.format = wgpu::TextureFormat::RGBA8Unorm;
|
||||
|
||||
textureDesc.usage = wgpu::TextureUsage::CopyDst;
|
||||
wgpu::Texture dst = device.CreateTexture(&textureDesc);
|
||||
|
||||
textureDesc.usage = wgpu::TextureUsage::CopySrc;
|
||||
wgpu::Texture src = device.CreateTexture(&textureDesc);
|
||||
|
||||
textureDesc.usage = wgpu::TextureUsage::None;
|
||||
|
||||
wgpu::DawnTextureInternalUsageDescriptor internalDesc = {};
|
||||
textureDesc.nextInChain = &internalDesc;
|
||||
internalDesc.internalUsage = wgpu::TextureUsage::CopySrc;
|
||||
|
||||
wgpu::Texture srcInternal = device.CreateTexture(&textureDesc);
|
||||
|
||||
// Control: src -> dst
|
||||
{
|
||||
wgpu::ImageCopyTexture srcImageCopyTexture = utils::CreateImageCopyTexture(src, 0, {0, 0});
|
||||
wgpu::ImageCopyTexture dstImageCopyTexture = utils::CreateImageCopyTexture(dst, 0, {0, 0});
|
||||
wgpu::Extent3D extent3D = {1, 1};
|
||||
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
encoder.CopyTextureToTexture(&srcImageCopyTexture, &dstImageCopyTexture, &extent3D);
|
||||
encoder.Finish();
|
||||
}
|
||||
|
||||
// Invalid: src internal -> dst
|
||||
{
|
||||
wgpu::ImageCopyTexture srcImageCopyTexture =
|
||||
utils::CreateImageCopyTexture(srcInternal, 0, {0, 0});
|
||||
wgpu::ImageCopyTexture dstImageCopyTexture = utils::CreateImageCopyTexture(dst, 0, {0, 0});
|
||||
wgpu::Extent3D extent3D = {1, 1};
|
||||
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
encoder.CopyTextureToTexture(&srcImageCopyTexture, &dstImageCopyTexture, &extent3D);
|
||||
ASSERT_DEVICE_ERROR(encoder.Finish());
|
||||
}
|
||||
|
||||
// Invalid: src internal -> dst, with internal descriptor, but useInternalUsages set to false.
|
||||
{
|
||||
wgpu::ImageCopyTexture srcImageCopyTexture =
|
||||
utils::CreateImageCopyTexture(srcInternal, 0, {0, 0});
|
||||
wgpu::ImageCopyTexture dstImageCopyTexture = utils::CreateImageCopyTexture(dst, 0, {0, 0});
|
||||
wgpu::Extent3D extent3D = {1, 1};
|
||||
|
||||
wgpu::CommandEncoderDescriptor encoderDesc = {};
|
||||
wgpu::DawnEncoderInternalUsageDescriptor internalDesc = {};
|
||||
internalDesc.useInternalUsages = false;
|
||||
encoderDesc.nextInChain = &internalDesc;
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder(&encoderDesc);
|
||||
|
||||
encoder.CopyTextureToTexture(&srcImageCopyTexture, &dstImageCopyTexture, &extent3D);
|
||||
ASSERT_DEVICE_ERROR(encoder.Finish());
|
||||
}
|
||||
|
||||
// Control with internal copy: src -> dst
|
||||
{
|
||||
wgpu::ImageCopyTexture srcImageCopyTexture = utils::CreateImageCopyTexture(src, 0, {0, 0});
|
||||
wgpu::ImageCopyTexture dstImageCopyTexture = utils::CreateImageCopyTexture(dst, 0, {0, 0});
|
||||
wgpu::Extent3D extent3D = {1, 1};
|
||||
|
||||
wgpu::CommandEncoderDescriptor encoderDesc = {};
|
||||
wgpu::DawnEncoderInternalUsageDescriptor internalDesc = {};
|
||||
internalDesc.useInternalUsages = true;
|
||||
encoderDesc.nextInChain = &internalDesc;
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder(&encoderDesc);
|
||||
|
||||
encoder.CopyTextureToTexture(&srcImageCopyTexture, &dstImageCopyTexture, &extent3D);
|
||||
encoder.Finish();
|
||||
}
|
||||
|
||||
// Valid with internal copy: src internal -> dst
|
||||
{
|
||||
wgpu::ImageCopyTexture srcImageCopyTexture =
|
||||
utils::CreateImageCopyTexture(srcInternal, 0, {0, 0});
|
||||
wgpu::ImageCopyTexture dstImageCopyTexture = utils::CreateImageCopyTexture(dst, 0, {0, 0});
|
||||
wgpu::Extent3D extent3D = {1, 1};
|
||||
|
||||
wgpu::CommandEncoderDescriptor encoderDesc = {};
|
||||
wgpu::DawnEncoderInternalUsageDescriptor internalDesc = {};
|
||||
internalDesc.useInternalUsages = true;
|
||||
encoderDesc.nextInChain = &internalDesc;
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder(&encoderDesc);
|
||||
|
||||
encoder.CopyTextureToTexture(&srcImageCopyTexture, &dstImageCopyTexture, &extent3D);
|
||||
encoder.Finish();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue