Implements maxColorAttachmentBytesPerSample
- Adds the limit - Adds relevant format-specific data into format table - Adds deprecation validations regarding the limit - Adds deprecation validation unit tests and helpful utils - Moves deprecated api tests from end2end to unittests, allowing tests to be cross-files for ease after deprecation. - Updates some validation messages to include helpful contexts. Bug: dawn:1522 Change-Id: Ib05f9adb60808ff4d68061d9646e76c729a23643 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/113543 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Austin Eng <enga@chromium.org> Commit-Queue: Loko Kung <lokokung@google.com> Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
parent
28a7827981
commit
e70563ac03
|
@ -1271,6 +1271,7 @@
|
||||||
{"name": "max inter stage shader components", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
{"name": "max inter stage shader components", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||||
{"name": "max inter stage shader variables", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
{"name": "max inter stage shader variables", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||||
{"name": "max color attachments", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
{"name": "max color attachments", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||||
|
{"name": "max color attachment bytes per sample", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||||
{"name": "max compute workgroup storage size", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
{"name": "max compute workgroup storage size", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||||
{"name": "max compute invocations per workgroup", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
{"name": "max compute invocations per workgroup", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||||
{"name": "max compute workgroup size x", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
{"name": "max compute workgroup size x", "type": "uint32_t", "default": "WGPU_LIMIT_U32_UNDEFINED"},
|
||||||
|
|
|
@ -458,6 +458,7 @@ MaybeError ValidateRenderPassDescriptor(DeviceBase* device,
|
||||||
descriptor->colorAttachmentCount, maxColorAttachments);
|
descriptor->colorAttachmentCount, maxColorAttachments);
|
||||||
|
|
||||||
bool isAllColorAttachmentNull = true;
|
bool isAllColorAttachmentNull = true;
|
||||||
|
ColorAttachmentFormats colorAttachmentFormats;
|
||||||
for (uint32_t i = 0; i < descriptor->colorAttachmentCount; ++i) {
|
for (uint32_t i = 0; i < descriptor->colorAttachmentCount; ++i) {
|
||||||
DAWN_TRY_CONTEXT(
|
DAWN_TRY_CONTEXT(
|
||||||
ValidateRenderPassColorAttachment(device, descriptor->colorAttachments[i], width,
|
ValidateRenderPassColorAttachment(device, descriptor->colorAttachments[i], width,
|
||||||
|
@ -465,8 +466,11 @@ MaybeError ValidateRenderPassDescriptor(DeviceBase* device,
|
||||||
"validating colorAttachments[%u].", i);
|
"validating colorAttachments[%u].", i);
|
||||||
if (descriptor->colorAttachments[i].view) {
|
if (descriptor->colorAttachments[i].view) {
|
||||||
isAllColorAttachmentNull = false;
|
isAllColorAttachmentNull = false;
|
||||||
|
colorAttachmentFormats->push_back(&descriptor->colorAttachments[i].view->GetFormat());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
DAWN_TRY_CONTEXT(ValidateColorAttachmentBytesPerSample(device, colorAttachmentFormats),
|
||||||
|
"validating color attachment bytes per sample.");
|
||||||
|
|
||||||
if (descriptor->depthStencilAttachment != nullptr) {
|
if (descriptor->depthStencilAttachment != nullptr) {
|
||||||
DAWN_TRY_CONTEXT(ValidateRenderPassDepthStencilAttachment(
|
DAWN_TRY_CONTEXT(ValidateRenderPassDepthStencilAttachment(
|
||||||
|
@ -854,7 +858,8 @@ Ref<RenderPassEncoder> CommandEncoder::BeginRenderPass(const RenderPassDescripto
|
||||||
|
|
||||||
// If descriptor is invalid, make pass invalid and stop immediately
|
// If descriptor is invalid, make pass invalid and stop immediately
|
||||||
if (device->ConsumedError(ValidateRenderPassDescriptor(device, descriptor, &width, &height,
|
if (device->ConsumedError(ValidateRenderPassDescriptor(device, descriptor, &width, &height,
|
||||||
&sampleCount, mUsageValidationMode))) {
|
&sampleCount, mUsageValidationMode),
|
||||||
|
"validating render pass descriptor.")) {
|
||||||
return RenderPassEncoder::MakeError(device, this, &mEncodingContext);
|
return RenderPassEncoder::MakeError(device, this, &mEncodingContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "dawn/common/BitSetIterator.h"
|
#include "dawn/common/BitSetIterator.h"
|
||||||
|
@ -491,4 +493,34 @@ MaybeError ValidateCanUseAs(const BufferBase* buffer, wgpu::BufferUsage usage) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
std::string TextureFormatsToString(const ColorAttachmentFormats& formats) {
|
||||||
|
std::ostringstream ss;
|
||||||
|
ss << "[ ";
|
||||||
|
for (const Format* format : formats) {
|
||||||
|
ss << absl::StrFormat("%s", format->format) << " ";
|
||||||
|
}
|
||||||
|
ss << "]";
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
MaybeError ValidateColorAttachmentBytesPerSample(DeviceBase* device,
|
||||||
|
const ColorAttachmentFormats& formats) {
|
||||||
|
uint32_t totalByteSize = 0;
|
||||||
|
for (const Format* format : formats) {
|
||||||
|
totalByteSize = Align(totalByteSize, format->renderTargetComponentAlignment);
|
||||||
|
totalByteSize += format->renderTargetPixelByteCost;
|
||||||
|
}
|
||||||
|
uint32_t maxColorAttachmentBytesPerSample =
|
||||||
|
device->GetLimits().v1.maxColorAttachmentBytesPerSample;
|
||||||
|
// TODO(dawn:1522) Promote to DAWN_INVALID_IF after deprecation period.
|
||||||
|
DAWN_DEPRECATED_IF(
|
||||||
|
device, totalByteSize > maxColorAttachmentBytesPerSample,
|
||||||
|
"Total color attachment bytes per sample (%u) exceeds maximum (%u) with formats (%s).",
|
||||||
|
totalByteSize, maxColorAttachmentBytesPerSample, TextureFormatsToString(formats));
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace dawn::native
|
} // namespace dawn::native
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "dawn/common/Constants.h"
|
||||||
|
#include "dawn/common/StackContainer.h"
|
||||||
#include "dawn/native/CommandAllocator.h"
|
#include "dawn/native/CommandAllocator.h"
|
||||||
#include "dawn/native/Error.h"
|
#include "dawn/native/Error.h"
|
||||||
#include "dawn/native/Features.h"
|
#include "dawn/native/Features.h"
|
||||||
|
@ -90,6 +92,10 @@ MaybeError ValidateCanUseAs(const TextureBase* texture,
|
||||||
UsageValidationMode mode);
|
UsageValidationMode mode);
|
||||||
MaybeError ValidateCanUseAs(const BufferBase* buffer, wgpu::BufferUsage usage);
|
MaybeError ValidateCanUseAs(const BufferBase* buffer, wgpu::BufferUsage usage);
|
||||||
|
|
||||||
|
using ColorAttachmentFormats = StackVector<const Format*, kMaxColorAttachments>;
|
||||||
|
MaybeError ValidateColorAttachmentBytesPerSample(DeviceBase* device,
|
||||||
|
const ColorAttachmentFormats& formats);
|
||||||
|
|
||||||
} // namespace dawn::native
|
} // namespace dawn::native
|
||||||
|
|
||||||
#endif // SRC_DAWN_NATIVE_COMMANDVALIDATION_H_
|
#endif // SRC_DAWN_NATIVE_COMMANDVALIDATION_H_
|
||||||
|
|
|
@ -1585,7 +1585,8 @@ ResultOrError<Ref<RenderBundleEncoder>> DeviceBase::CreateRenderBundleEncoder(
|
||||||
const RenderBundleEncoderDescriptor* descriptor) {
|
const RenderBundleEncoderDescriptor* descriptor) {
|
||||||
DAWN_TRY(ValidateIsAlive());
|
DAWN_TRY(ValidateIsAlive());
|
||||||
if (IsValidationEnabled()) {
|
if (IsValidationEnabled()) {
|
||||||
DAWN_TRY(ValidateRenderBundleEncoderDescriptor(this, descriptor));
|
DAWN_TRY_CONTEXT(ValidateRenderBundleEncoderDescriptor(this, descriptor),
|
||||||
|
"validating render bundle encoder descriptor.");
|
||||||
}
|
}
|
||||||
return RenderBundleEncoder::Create(this, descriptor);
|
return RenderBundleEncoder::Create(this, descriptor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,6 +90,14 @@ using ResultOrError = Result<T, ErrorData>;
|
||||||
? MaybeError(DAWN_VALIDATION_ERROR(__VA_ARGS__)) \
|
? MaybeError(DAWN_VALIDATION_ERROR(__VA_ARGS__)) \
|
||||||
: (device->EmitDeprecationWarning(absl::StrFormat(__VA_ARGS__)), MaybeError{})
|
: (device->EmitDeprecationWarning(absl::StrFormat(__VA_ARGS__)), MaybeError{})
|
||||||
|
|
||||||
|
// DAWN_DEPRECATED_IF is used analogous to DAWN_INVALID_IF at deprecation paths.
|
||||||
|
#define DAWN_DEPRECATED_IF(device, EXPR, ...) \
|
||||||
|
if (DAWN_UNLIKELY(EXPR)) { \
|
||||||
|
return DAWN_MAKE_DEPRECATION_ERROR(device, __VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
for (;;) \
|
||||||
|
break
|
||||||
|
|
||||||
// DAWN_DEVICE_LOST_ERROR means that there was a real unrecoverable native device lost error.
|
// DAWN_DEVICE_LOST_ERROR means that there was a real unrecoverable native device lost error.
|
||||||
// We can't even do a graceful shutdown because the Device is gone.
|
// We can't even do a graceful shutdown because the Device is gone.
|
||||||
#define DAWN_DEVICE_LOST_ERROR(MESSAGE) DAWN_MAKE_ERROR(InternalErrorType::DeviceLost, MESSAGE)
|
#define DAWN_DEVICE_LOST_ERROR(MESSAGE) DAWN_MAKE_ERROR(InternalErrorType::DeviceLost, MESSAGE)
|
||||||
|
|
|
@ -160,6 +160,8 @@ FormatTable BuildFormatTable(const DeviceBase* device) {
|
||||||
[&AddFormat](wgpu::TextureFormat format, bool renderable, bool supportsStorageUsage,
|
[&AddFormat](wgpu::TextureFormat format, bool renderable, bool supportsStorageUsage,
|
||||||
bool supportsMultisample, bool supportsResolveTarget, uint32_t byteSize,
|
bool supportsMultisample, bool supportsResolveTarget, uint32_t byteSize,
|
||||||
SampleTypeBit sampleTypes, uint8_t componentCount,
|
SampleTypeBit sampleTypes, uint8_t componentCount,
|
||||||
|
uint8_t renderTargetPixelByteCost = 0,
|
||||||
|
uint8_t renderTargetComponentAlignment = 0,
|
||||||
wgpu::TextureFormat baseFormat = wgpu::TextureFormat::Undefined) {
|
wgpu::TextureFormat baseFormat = wgpu::TextureFormat::Undefined) {
|
||||||
Format internalFormat;
|
Format internalFormat;
|
||||||
internalFormat.format = format;
|
internalFormat.format = format;
|
||||||
|
@ -175,6 +177,13 @@ FormatTable BuildFormatTable(const DeviceBase* device) {
|
||||||
internalFormat.supportsResolveTarget = supportsResolveTarget;
|
internalFormat.supportsResolveTarget = supportsResolveTarget;
|
||||||
internalFormat.aspects = Aspect::Color;
|
internalFormat.aspects = Aspect::Color;
|
||||||
internalFormat.componentCount = componentCount;
|
internalFormat.componentCount = componentCount;
|
||||||
|
if (renderable) {
|
||||||
|
// If the color format is renderable, it must have a pixel byte size and component
|
||||||
|
// alignment specified.
|
||||||
|
ASSERT(renderTargetPixelByteCost != 0 && renderTargetComponentAlignment != 0);
|
||||||
|
internalFormat.renderTargetPixelByteCost = renderTargetPixelByteCost;
|
||||||
|
internalFormat.renderTargetComponentAlignment = renderTargetComponentAlignment;
|
||||||
|
}
|
||||||
|
|
||||||
// Default baseFormat of each color formats should be themselves.
|
// Default baseFormat of each color formats should be themselves.
|
||||||
if (baseFormat == wgpu::TextureFormat::Undefined) {
|
if (baseFormat == wgpu::TextureFormat::Undefined) {
|
||||||
|
@ -333,52 +342,52 @@ FormatTable BuildFormatTable(const DeviceBase* device) {
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
// 1 byte color formats
|
// 1 byte color formats
|
||||||
AddColorFormat(wgpu::TextureFormat::R8Unorm, true, false, true, true, 1, kAnyFloat, 1);
|
AddColorFormat(wgpu::TextureFormat::R8Unorm, true, false, true, true, 1, kAnyFloat, 1, 1, 1);
|
||||||
AddColorFormat(wgpu::TextureFormat::R8Snorm, false, false, false, false, 1, kAnyFloat, 1);
|
AddColorFormat(wgpu::TextureFormat::R8Snorm, false, false, false, false, 1, kAnyFloat, 1);
|
||||||
AddColorFormat(wgpu::TextureFormat::R8Uint, true, false, true, false, 1, SampleTypeBit::Uint, 1);
|
AddColorFormat(wgpu::TextureFormat::R8Uint, true, false, true, false, 1, SampleTypeBit::Uint, 1, 1, 1);
|
||||||
AddColorFormat(wgpu::TextureFormat::R8Sint, true, false, true, false, 1, SampleTypeBit::Sint, 1);
|
AddColorFormat(wgpu::TextureFormat::R8Sint, true, false, true, false, 1, SampleTypeBit::Sint, 1, 1, 1);
|
||||||
|
|
||||||
// 2 bytes color formats
|
// 2 bytes color formats
|
||||||
AddColorFormat(wgpu::TextureFormat::R16Uint, true, false, true, false, 2, SampleTypeBit::Uint, 1);
|
AddColorFormat(wgpu::TextureFormat::R16Uint, true, false, true, false, 2, SampleTypeBit::Uint, 1, 2, 2);
|
||||||
AddColorFormat(wgpu::TextureFormat::R16Sint, true, false, true, false, 2, SampleTypeBit::Sint, 1);
|
AddColorFormat(wgpu::TextureFormat::R16Sint, true, false, true, false, 2, SampleTypeBit::Sint, 1, 2, 2);
|
||||||
AddColorFormat(wgpu::TextureFormat::R16Float, true, false, true, true, 2, kAnyFloat, 1);
|
AddColorFormat(wgpu::TextureFormat::R16Float, true, false, true, true, 2, kAnyFloat, 1, 2, 2);
|
||||||
AddColorFormat(wgpu::TextureFormat::RG8Unorm, true, false, true, true, 2, kAnyFloat, 2);
|
AddColorFormat(wgpu::TextureFormat::RG8Unorm, true, false, true, true, 2, kAnyFloat, 2, 2, 1);
|
||||||
AddColorFormat(wgpu::TextureFormat::RG8Snorm, false, false, false, false, 2, kAnyFloat, 2);
|
AddColorFormat(wgpu::TextureFormat::RG8Snorm, false, false, false, false, 2, kAnyFloat, 2);
|
||||||
AddColorFormat(wgpu::TextureFormat::RG8Uint, true, false, true, false, 2, SampleTypeBit::Uint, 2);
|
AddColorFormat(wgpu::TextureFormat::RG8Uint, true, false, true, false, 2, SampleTypeBit::Uint, 2, 2, 1);
|
||||||
AddColorFormat(wgpu::TextureFormat::RG8Sint, true, false, true, false, 2, SampleTypeBit::Sint, 2);
|
AddColorFormat(wgpu::TextureFormat::RG8Sint, true, false, true, false, 2, SampleTypeBit::Sint, 2, 2, 1);
|
||||||
|
|
||||||
// 4 bytes color formats
|
// 4 bytes color formats
|
||||||
AddColorFormat(wgpu::TextureFormat::R32Uint, true, true, false, false, 4, SampleTypeBit::Uint, 1);
|
AddColorFormat(wgpu::TextureFormat::R32Uint, true, true, false, false, 4, SampleTypeBit::Uint, 1, 4, 4);
|
||||||
AddColorFormat(wgpu::TextureFormat::R32Sint, true, true, false, false, 4, SampleTypeBit::Sint, 1);
|
AddColorFormat(wgpu::TextureFormat::R32Sint, true, true, false, false, 4, SampleTypeBit::Sint, 1, 4, 4);
|
||||||
AddColorFormat(wgpu::TextureFormat::R32Float, true, true, true, false, 4, SampleTypeBit::UnfilterableFloat, 1);
|
AddColorFormat(wgpu::TextureFormat::R32Float, true, true, true, false, 4, SampleTypeBit::UnfilterableFloat, 1, 4, 4);
|
||||||
AddColorFormat(wgpu::TextureFormat::RG16Uint, true, false, true, false, 4, SampleTypeBit::Uint, 2);
|
AddColorFormat(wgpu::TextureFormat::RG16Uint, true, false, true, false, 4, SampleTypeBit::Uint, 2, 4, 2);
|
||||||
AddColorFormat(wgpu::TextureFormat::RG16Sint, true, false, true, false, 4, SampleTypeBit::Sint, 2);
|
AddColorFormat(wgpu::TextureFormat::RG16Sint, true, false, true, false, 4, SampleTypeBit::Sint, 2, 4, 2);
|
||||||
AddColorFormat(wgpu::TextureFormat::RG16Float, true, false, true, true, 4, kAnyFloat, 2);
|
AddColorFormat(wgpu::TextureFormat::RG16Float, true, false, true, true, 4, kAnyFloat, 2, 4, 2);
|
||||||
AddColorFormat(wgpu::TextureFormat::RGBA8Unorm, true, true, true, true, 4, kAnyFloat, 4);
|
AddColorFormat(wgpu::TextureFormat::RGBA8Unorm, true, true, true, true, 4, kAnyFloat, 4, 8, 1);
|
||||||
AddColorFormat(wgpu::TextureFormat::RGBA8UnormSrgb, true, false, true, true, 4, kAnyFloat, 4, wgpu::TextureFormat::RGBA8Unorm);
|
AddColorFormat(wgpu::TextureFormat::RGBA8UnormSrgb, true, false, true, true, 4, kAnyFloat, 4, 8, 1, wgpu::TextureFormat::RGBA8Unorm);
|
||||||
AddColorFormat(wgpu::TextureFormat::RGBA8Snorm, false, true, false, false, 4, kAnyFloat, 4);
|
AddColorFormat(wgpu::TextureFormat::RGBA8Snorm, false, true, false, false, 4, kAnyFloat, 4);
|
||||||
AddColorFormat(wgpu::TextureFormat::RGBA8Uint, true, true, true, false, 4, SampleTypeBit::Uint, 4);
|
AddColorFormat(wgpu::TextureFormat::RGBA8Uint, true, true, true, false, 4, SampleTypeBit::Uint, 4, 4, 1);
|
||||||
AddColorFormat(wgpu::TextureFormat::RGBA8Sint, true, true, true, false, 4, SampleTypeBit::Sint, 4);
|
AddColorFormat(wgpu::TextureFormat::RGBA8Sint, true, true, true, false, 4, SampleTypeBit::Sint, 4, 4, 1);
|
||||||
AddColorFormat(wgpu::TextureFormat::BGRA8Unorm, true, false, true, true, 4, kAnyFloat, 4);
|
AddColorFormat(wgpu::TextureFormat::BGRA8Unorm, true, false, true, true, 4, kAnyFloat, 4, 8, 1);
|
||||||
AddColorFormat(wgpu::TextureFormat::BGRA8UnormSrgb, true, false, true, true, 4, kAnyFloat, 4, wgpu::TextureFormat::BGRA8Unorm);
|
AddColorFormat(wgpu::TextureFormat::BGRA8UnormSrgb, true, false, true, true, 4, kAnyFloat, 4, 8, 1, wgpu::TextureFormat::BGRA8Unorm);
|
||||||
AddColorFormat(wgpu::TextureFormat::RGB10A2Unorm, true, false, true, true, 4, kAnyFloat, 4);
|
AddColorFormat(wgpu::TextureFormat::RGB10A2Unorm, true, false, true, true, 4, kAnyFloat, 4, 8, 4);
|
||||||
|
|
||||||
bool isRG11B10UfloatRenderable = device->HasFeature(Feature::RG11B10UfloatRenderable);
|
bool isRG11B10UfloatRenderable = device->HasFeature(Feature::RG11B10UfloatRenderable);
|
||||||
AddColorFormat(wgpu::TextureFormat::RG11B10Ufloat, isRG11B10UfloatRenderable, false, isRG11B10UfloatRenderable, false, 4, kAnyFloat, 3);
|
AddColorFormat(wgpu::TextureFormat::RG11B10Ufloat, isRG11B10UfloatRenderable, false, isRG11B10UfloatRenderable, false, 4, kAnyFloat, 3, 8, 4);
|
||||||
AddColorFormat(wgpu::TextureFormat::RGB9E5Ufloat, false, false, false, false, 4, kAnyFloat, 3);
|
AddColorFormat(wgpu::TextureFormat::RGB9E5Ufloat, false, false, false, false, 4, kAnyFloat, 3);
|
||||||
|
|
||||||
// 8 bytes color formats
|
// 8 bytes color formats
|
||||||
AddColorFormat(wgpu::TextureFormat::RG32Uint, true, true, false, false, 8, SampleTypeBit::Uint, 2);
|
AddColorFormat(wgpu::TextureFormat::RG32Uint, true, true, false, false, 8, SampleTypeBit::Uint, 2, 8, 4);
|
||||||
AddColorFormat(wgpu::TextureFormat::RG32Sint, true, true, false, false, 8, SampleTypeBit::Sint, 2);
|
AddColorFormat(wgpu::TextureFormat::RG32Sint, true, true, false, false, 8, SampleTypeBit::Sint, 2, 8, 4);
|
||||||
AddColorFormat(wgpu::TextureFormat::RG32Float, true, true, false, false, 8, SampleTypeBit::UnfilterableFloat, 2);
|
AddColorFormat(wgpu::TextureFormat::RG32Float, true, true, false, false, 8, SampleTypeBit::UnfilterableFloat, 2, 8, 4);
|
||||||
AddColorFormat(wgpu::TextureFormat::RGBA16Uint, true, true, true, false, 8, SampleTypeBit::Uint, 4);
|
AddColorFormat(wgpu::TextureFormat::RGBA16Uint, true, true, true, false, 8, SampleTypeBit::Uint, 4, 8, 2);
|
||||||
AddColorFormat(wgpu::TextureFormat::RGBA16Sint, true, true, true, false, 8, SampleTypeBit::Sint, 4);
|
AddColorFormat(wgpu::TextureFormat::RGBA16Sint, true, true, true, false, 8, SampleTypeBit::Sint, 4, 8, 2);
|
||||||
AddColorFormat(wgpu::TextureFormat::RGBA16Float, true, true, true, true, 8, kAnyFloat, 4);
|
AddColorFormat(wgpu::TextureFormat::RGBA16Float, true, true, true, true, 8, kAnyFloat, 4, 8, 2);
|
||||||
|
|
||||||
// 16 bytes color formats
|
// 16 bytes color formats
|
||||||
AddColorFormat(wgpu::TextureFormat::RGBA32Uint, true, true, false, false, 16, SampleTypeBit::Uint, 4);
|
AddColorFormat(wgpu::TextureFormat::RGBA32Uint, true, true, false, false, 16, SampleTypeBit::Uint, 4, 16, 4);
|
||||||
AddColorFormat(wgpu::TextureFormat::RGBA32Sint, true, true, false, false, 16, SampleTypeBit::Sint, 4);
|
AddColorFormat(wgpu::TextureFormat::RGBA32Sint, true, true, false, false, 16, SampleTypeBit::Sint, 4, 16, 4);
|
||||||
AddColorFormat(wgpu::TextureFormat::RGBA32Float, true, true, false, false, 16, SampleTypeBit::UnfilterableFloat, 4);
|
AddColorFormat(wgpu::TextureFormat::RGBA32Float, true, true, false, false, 16, SampleTypeBit::UnfilterableFloat, 4, 16, 4);
|
||||||
|
|
||||||
// Depth-stencil formats
|
// Depth-stencil formats
|
||||||
AddStencilFormat(wgpu::TextureFormat::Stencil8, true);
|
AddStencilFormat(wgpu::TextureFormat::Stencil8, true);
|
||||||
|
|
|
@ -97,8 +97,10 @@ struct Format {
|
||||||
bool supportsMultisample = false;
|
bool supportsMultisample = false;
|
||||||
bool supportsResolveTarget = false;
|
bool supportsResolveTarget = false;
|
||||||
Aspect aspects{};
|
Aspect aspects{};
|
||||||
// Only used for renderable color formats, number of color channels.
|
// Only used for renderable color formats:
|
||||||
uint8_t componentCount = 0;
|
uint8_t componentCount = 0; // number of color channels
|
||||||
|
uint8_t renderTargetPixelByteCost = 0; // byte cost of pixel in render targets
|
||||||
|
uint8_t renderTargetComponentAlignment = 0; // byte alignment for components in render targets
|
||||||
|
|
||||||
bool IsColor() const;
|
bool IsColor() const;
|
||||||
bool HasDepth() const;
|
bool HasDepth() const;
|
||||||
|
|
|
@ -59,6 +59,7 @@
|
||||||
X(Maximum, maxInterStageShaderComponents, 60, 60) \
|
X(Maximum, maxInterStageShaderComponents, 60, 60) \
|
||||||
X(Maximum, maxInterStageShaderVariables, 16, 16) \
|
X(Maximum, maxInterStageShaderVariables, 16, 16) \
|
||||||
X(Maximum, maxColorAttachments, 8, 8) \
|
X(Maximum, maxColorAttachments, 8, 8) \
|
||||||
|
X(Maximum, maxColorAttachmentBytesPerSample, 32, 32) \
|
||||||
X(Maximum, maxComputeInvocationsPerWorkgroup, 256, 256) \
|
X(Maximum, maxComputeInvocationsPerWorkgroup, 256, 256) \
|
||||||
X(Maximum, maxComputeWorkgroupSizeX, 256, 256) \
|
X(Maximum, maxComputeWorkgroupSizeX, 256, 256) \
|
||||||
X(Maximum, maxComputeWorkgroupSizeY, 256, 256) \
|
X(Maximum, maxComputeWorkgroupSizeY, 256, 256) \
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include "dawn/common/StackContainer.h"
|
||||||
#include "dawn/native/CommandValidation.h"
|
#include "dawn/native/CommandValidation.h"
|
||||||
#include "dawn/native/Commands.h"
|
#include "dawn/native/Commands.h"
|
||||||
#include "dawn/native/Device.h"
|
#include "dawn/native/Device.h"
|
||||||
|
@ -57,7 +58,7 @@ MaybeError ValidateDepthStencilAttachmentFormat(const DeviceBase* device,
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
MaybeError ValidateRenderBundleEncoderDescriptor(const DeviceBase* device,
|
MaybeError ValidateRenderBundleEncoderDescriptor(DeviceBase* device,
|
||||||
const RenderBundleEncoderDescriptor* descriptor) {
|
const RenderBundleEncoderDescriptor* descriptor) {
|
||||||
DAWN_INVALID_IF(!IsValidSampleCount(descriptor->sampleCount),
|
DAWN_INVALID_IF(!IsValidSampleCount(descriptor->sampleCount),
|
||||||
"Sample count (%u) is not supported.", descriptor->sampleCount);
|
"Sample count (%u) is not supported.", descriptor->sampleCount);
|
||||||
|
@ -68,14 +69,18 @@ MaybeError ValidateRenderBundleEncoderDescriptor(const DeviceBase* device,
|
||||||
descriptor->colorFormatsCount, maxColorAttachments);
|
descriptor->colorFormatsCount, maxColorAttachments);
|
||||||
|
|
||||||
bool allColorFormatsUndefined = true;
|
bool allColorFormatsUndefined = true;
|
||||||
|
ColorAttachmentFormats colorAttachmentFormats;
|
||||||
for (uint32_t i = 0; i < descriptor->colorFormatsCount; ++i) {
|
for (uint32_t i = 0; i < descriptor->colorFormatsCount; ++i) {
|
||||||
wgpu::TextureFormat format = descriptor->colorFormats[i];
|
wgpu::TextureFormat format = descriptor->colorFormats[i];
|
||||||
if (format != wgpu::TextureFormat::Undefined) {
|
if (format != wgpu::TextureFormat::Undefined) {
|
||||||
DAWN_TRY_CONTEXT(ValidateColorAttachmentFormat(device, format),
|
DAWN_TRY_CONTEXT(ValidateColorAttachmentFormat(device, format),
|
||||||
"validating colorFormats[%u]", i);
|
"validating colorFormats[%u]", i);
|
||||||
|
colorAttachmentFormats->push_back(&device->GetValidInternalFormat(format));
|
||||||
allColorFormatsUndefined = false;
|
allColorFormatsUndefined = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
DAWN_TRY_CONTEXT(ValidateColorAttachmentBytesPerSample(device, colorAttachmentFormats),
|
||||||
|
"validating color attachment bytes per sample.");
|
||||||
|
|
||||||
if (descriptor->depthStencilFormat != wgpu::TextureFormat::Undefined) {
|
if (descriptor->depthStencilFormat != wgpu::TextureFormat::Undefined) {
|
||||||
DAWN_TRY_CONTEXT(ValidateDepthStencilAttachmentFormat(
|
DAWN_TRY_CONTEXT(ValidateDepthStencilAttachmentFormat(
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
namespace dawn::native {
|
namespace dawn::native {
|
||||||
|
|
||||||
MaybeError ValidateRenderBundleEncoderDescriptor(const DeviceBase* device,
|
MaybeError ValidateRenderBundleEncoderDescriptor(DeviceBase* device,
|
||||||
const RenderBundleEncoderDescriptor* descriptor);
|
const RenderBundleEncoderDescriptor* descriptor);
|
||||||
|
|
||||||
class RenderBundleEncoder final : public RenderEncoderBase {
|
class RenderBundleEncoder final : public RenderEncoderBase {
|
||||||
|
|
|
@ -16,10 +16,10 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
#include "dawn/common/BitSetIterator.h"
|
#include "dawn/common/BitSetIterator.h"
|
||||||
#include "dawn/native/ChainUtils_autogen.h"
|
#include "dawn/native/ChainUtils_autogen.h"
|
||||||
|
#include "dawn/native/CommandValidation.h"
|
||||||
#include "dawn/native/Commands.h"
|
#include "dawn/native/Commands.h"
|
||||||
#include "dawn/native/Device.h"
|
#include "dawn/native/Device.h"
|
||||||
#include "dawn/native/InternalPipelineStore.h"
|
#include "dawn/native/InternalPipelineStore.h"
|
||||||
|
@ -351,6 +351,7 @@ MaybeError ValidateFragmentState(DeviceBase* device,
|
||||||
|
|
||||||
const EntryPointMetadata& fragmentMetadata =
|
const EntryPointMetadata& fragmentMetadata =
|
||||||
descriptor->module->GetEntryPoint(descriptor->entryPoint);
|
descriptor->module->GetEntryPoint(descriptor->entryPoint);
|
||||||
|
ColorAttachmentFormats colorAttachmentFormats;
|
||||||
for (ColorAttachmentIndex i(uint8_t(0));
|
for (ColorAttachmentIndex i(uint8_t(0));
|
||||||
i < ColorAttachmentIndex(static_cast<uint8_t>(descriptor->targetCount)); ++i) {
|
i < ColorAttachmentIndex(static_cast<uint8_t>(descriptor->targetCount)); ++i) {
|
||||||
const ColorTargetState* target = &descriptor->targets[static_cast<uint8_t>(i)];
|
const ColorTargetState* target = &descriptor->targets[static_cast<uint8_t>(i)];
|
||||||
|
@ -359,12 +360,14 @@ MaybeError ValidateFragmentState(DeviceBase* device,
|
||||||
ValidateColorTargetState(device, target, fragmentMetadata.fragmentOutputsWritten[i],
|
ValidateColorTargetState(device, target, fragmentMetadata.fragmentOutputsWritten[i],
|
||||||
fragmentMetadata.fragmentOutputVariables[i]),
|
fragmentMetadata.fragmentOutputVariables[i]),
|
||||||
"validating targets[%u].", static_cast<uint8_t>(i));
|
"validating targets[%u].", static_cast<uint8_t>(i));
|
||||||
|
colorAttachmentFormats->push_back(&device->GetValidInternalFormat(target->format));
|
||||||
} else {
|
} else {
|
||||||
DAWN_INVALID_IF(target->blend,
|
DAWN_INVALID_IF(target->blend,
|
||||||
"Color target[%u] blend state is set when the format is undefined.",
|
"Color target[%u] blend state is set when the format is undefined.",
|
||||||
static_cast<uint8_t>(i));
|
static_cast<uint8_t>(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
DAWN_TRY(ValidateColorAttachmentBytesPerSample(device, colorAttachmentFormats));
|
||||||
|
|
||||||
DAWN_INVALID_IF(fragmentMetadata.usesSampleMaskOutput && alphaToCoverageEnabled,
|
DAWN_INVALID_IF(fragmentMetadata.usesSampleMaskOutput && alphaToCoverageEnabled,
|
||||||
"alphaToCoverageEnabled is true when the sample_mask builtin is a "
|
"alphaToCoverageEnabled is true when the sample_mask builtin is a "
|
||||||
|
|
|
@ -317,6 +317,8 @@ dawn_test("dawn_unittests") {
|
||||||
"unittests/validation/CopyCommandsValidationTests.cpp",
|
"unittests/validation/CopyCommandsValidationTests.cpp",
|
||||||
"unittests/validation/CopyTextureForBrowserTests.cpp",
|
"unittests/validation/CopyTextureForBrowserTests.cpp",
|
||||||
"unittests/validation/DebugMarkerValidationTests.cpp",
|
"unittests/validation/DebugMarkerValidationTests.cpp",
|
||||||
|
"unittests/validation/DeprecatedAPITests.cpp",
|
||||||
|
"unittests/validation/DeprecatedAPITests.h",
|
||||||
"unittests/validation/DeviceValidationTests.cpp",
|
"unittests/validation/DeviceValidationTests.cpp",
|
||||||
"unittests/validation/DrawIndirectValidationTests.cpp",
|
"unittests/validation/DrawIndirectValidationTests.cpp",
|
||||||
"unittests/validation/DrawVertexAndIndexBufferOOBValidationTests.cpp",
|
"unittests/validation/DrawVertexAndIndexBufferOOBValidationTests.cpp",
|
||||||
|
@ -486,7 +488,6 @@ source_set("end2end_tests_sources") {
|
||||||
"end2end/CreatePipelineAsyncTests.cpp",
|
"end2end/CreatePipelineAsyncTests.cpp",
|
||||||
"end2end/CullingTests.cpp",
|
"end2end/CullingTests.cpp",
|
||||||
"end2end/DebugMarkerTests.cpp",
|
"end2end/DebugMarkerTests.cpp",
|
||||||
"end2end/DeprecatedAPITests.cpp",
|
|
||||||
"end2end/DepthBiasTests.cpp",
|
"end2end/DepthBiasTests.cpp",
|
||||||
"end2end/DepthStencilCopyTests.cpp",
|
"end2end/DepthStencilCopyTests.cpp",
|
||||||
"end2end/DepthStencilLoadOpTests.cpp",
|
"end2end/DepthStencilLoadOpTests.cpp",
|
||||||
|
|
|
@ -465,6 +465,7 @@ TEST_P(RenderPassLoadOpTests, LoadOpClearNormalizedFormatsOutOfBound) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test clearing multiple color attachments with different big integers can still work correctly.
|
// Test clearing multiple color attachments with different big integers can still work correctly.
|
||||||
|
// TODO(dawn:1522) Refactor and fix this test to avoid deprecation warnings.
|
||||||
TEST_P(RenderPassLoadOpTests, LoadOpClearWithBigInt32ValuesOnMultipleColorAttachments) {
|
TEST_P(RenderPassLoadOpTests, LoadOpClearWithBigInt32ValuesOnMultipleColorAttachments) {
|
||||||
constexpr int32_t kMaxInt32RepresentableInFloat = 1 << std::numeric_limits<float>::digits;
|
constexpr int32_t kMaxInt32RepresentableInFloat = 1 << std::numeric_limits<float>::digits;
|
||||||
constexpr int32_t kMinInt32RepresentableInFloat = -kMaxInt32RepresentableInFloat;
|
constexpr int32_t kMinInt32RepresentableInFloat = -kMaxInt32RepresentableInFloat;
|
||||||
|
@ -523,7 +524,14 @@ TEST_P(RenderPassLoadOpTests, LoadOpClearWithBigInt32ValuesOnMultipleColorAttach
|
||||||
wgpu::RenderPassDescriptor renderPassDescriptor = {};
|
wgpu::RenderPassDescriptor renderPassDescriptor = {};
|
||||||
renderPassDescriptor.colorAttachmentCount = kMaxColorAttachments;
|
renderPassDescriptor.colorAttachmentCount = kMaxColorAttachments;
|
||||||
renderPassDescriptor.colorAttachments = colorAttachmentsInfo.data();
|
renderPassDescriptor.colorAttachments = colorAttachmentsInfo.data();
|
||||||
wgpu::RenderPassEncoder renderPass = encoder.BeginRenderPass(&renderPassDescriptor);
|
wgpu::RenderPassEncoder renderPass;
|
||||||
|
if (HasToggleEnabled("apply_clear_big_integer_color_value_with_draw")) {
|
||||||
|
// When the toggle is enabled, an extra internal pipeline is created which will hit the same
|
||||||
|
// deprecation issue again, hence we need to check for 2 warnings instead of 1.
|
||||||
|
EXPECT_DEPRECATION_WARNINGS(renderPass = encoder.BeginRenderPass(&renderPassDescriptor), 2);
|
||||||
|
} else {
|
||||||
|
EXPECT_DEPRECATION_WARNING(renderPass = encoder.BeginRenderPass(&renderPassDescriptor));
|
||||||
|
}
|
||||||
renderPass.End();
|
renderPass.End();
|
||||||
|
|
||||||
std::array<wgpu::Buffer, kMaxColorAttachments> outputBuffers;
|
std::array<wgpu::Buffer, kMaxColorAttachments> outputBuffers;
|
||||||
|
@ -553,6 +561,7 @@ TEST_P(RenderPassLoadOpTests, LoadOpClearWithBigInt32ValuesOnMultipleColorAttach
|
||||||
|
|
||||||
// Test clearing multiple color attachments with different big unsigned integers can still work
|
// Test clearing multiple color attachments with different big unsigned integers can still work
|
||||||
// correctly.
|
// correctly.
|
||||||
|
// TODO(dawn:1522) Refactor and fix this test to avoid deprecation warnings.
|
||||||
TEST_P(RenderPassLoadOpTests, LoadOpClearWithBigUInt32ValuesOnMultipleColorAttachments) {
|
TEST_P(RenderPassLoadOpTests, LoadOpClearWithBigUInt32ValuesOnMultipleColorAttachments) {
|
||||||
constexpr int32_t kMaxUInt32RepresentableInFloat = 1 << std::numeric_limits<float>::digits;
|
constexpr int32_t kMaxUInt32RepresentableInFloat = 1 << std::numeric_limits<float>::digits;
|
||||||
|
|
||||||
|
@ -628,7 +637,14 @@ TEST_P(RenderPassLoadOpTests, LoadOpClearWithBigUInt32ValuesOnMultipleColorAttac
|
||||||
wgpu::RenderPassDescriptor renderPassDescriptor = {};
|
wgpu::RenderPassDescriptor renderPassDescriptor = {};
|
||||||
renderPassDescriptor.colorAttachmentCount = kMaxColorAttachments;
|
renderPassDescriptor.colorAttachmentCount = kMaxColorAttachments;
|
||||||
renderPassDescriptor.colorAttachments = colorAttachmentsInfo.data();
|
renderPassDescriptor.colorAttachments = colorAttachmentsInfo.data();
|
||||||
wgpu::RenderPassEncoder renderPass = encoder.BeginRenderPass(&renderPassDescriptor);
|
wgpu::RenderPassEncoder renderPass;
|
||||||
|
if (HasToggleEnabled("apply_clear_big_integer_color_value_with_draw")) {
|
||||||
|
// When the toggle is enabled, an extra internal pipeline is created which will hit the same
|
||||||
|
// deprecation issue again, hence we need to check for 2 warnings instead of 1.
|
||||||
|
EXPECT_DEPRECATION_WARNINGS(renderPass = encoder.BeginRenderPass(&renderPassDescriptor), 2);
|
||||||
|
} else {
|
||||||
|
EXPECT_DEPRECATION_WARNING(renderPass = encoder.BeginRenderPass(&renderPassDescriptor));
|
||||||
|
}
|
||||||
renderPass.End();
|
renderPass.End();
|
||||||
|
|
||||||
std::array<wgpu::Buffer, kMaxColorAttachments> outputBuffers;
|
std::array<wgpu::Buffer, kMaxColorAttachments> outputBuffers;
|
||||||
|
|
|
@ -832,7 +832,7 @@ TEST_P(TextureViewRenderingTest, SRGBReinterpretationRenderAttachment) {
|
||||||
wgpu::BindGroup bindGroup = utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
|
wgpu::BindGroup bindGroup = utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
|
||||||
{{0, sampledTexture.CreateView()}});
|
{{0, sampledTexture.CreateView()}});
|
||||||
|
|
||||||
utils::ComboRenderPassDescriptor renderPassInfo{textureView};
|
utils::ComboRenderPassDescriptor renderPassInfo({textureView});
|
||||||
|
|
||||||
wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPassInfo);
|
wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPassInfo);
|
||||||
pass.SetPipeline(pipeline);
|
pass.SetPipeline(pipeline);
|
||||||
|
@ -947,7 +947,7 @@ TEST_P(TextureViewRenderingTest, SRGBReinterpretionResolveAttachment) {
|
||||||
wgpu::BindGroup bindGroup = utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
|
wgpu::BindGroup bindGroup = utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
|
||||||
{{0, sampledTexture.CreateView()}});
|
{{0, sampledTexture.CreateView()}});
|
||||||
|
|
||||||
utils::ComboRenderPassDescriptor renderPassInfo{multisampledTextureView};
|
utils::ComboRenderPassDescriptor renderPassInfo({multisampledTextureView});
|
||||||
renderPassInfo.cColorAttachments[0].resolveTarget = resolveView;
|
renderPassInfo.cColorAttachments[0].resolveTarget = resolveView;
|
||||||
|
|
||||||
wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPassInfo);
|
wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPassInfo);
|
||||||
|
|
|
@ -12,38 +12,27 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
// This file contains test for deprecated parts of Dawn's API while following WebGPU's evolution.
|
|
||||||
// It contains test for the "old" behavior that will be deleted once users are migrated, tests that
|
|
||||||
// a deprecation warning is emitted when the "old" behavior is used, and tests that an error is
|
|
||||||
// emitted when both the old and the new behavior are used (when applicable).
|
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include "dawn/tests/DawnTest.h"
|
#include "dawn/tests/unittests/validation/DeprecatedAPITests.h"
|
||||||
|
|
||||||
#include "dawn/common/Constants.h"
|
#include "dawn/common/Constants.h"
|
||||||
#include "dawn/utils/ComboRenderPipelineDescriptor.h"
|
#include "dawn/utils/ComboRenderPipelineDescriptor.h"
|
||||||
#include "dawn/utils/WGPUHelpers.h"
|
#include "dawn/utils/WGPUHelpers.h"
|
||||||
|
|
||||||
constexpr char kDisallowDeprecatedAPIsToggleName[] = "disallow_deprecated_apis";
|
WGPUDevice DeprecationTests::CreateTestDevice(dawn::native::Adapter dawnAdapter) {
|
||||||
|
wgpu::DeviceDescriptor descriptor = {};
|
||||||
|
|
||||||
#define EXPECT_DEPRECATION_ERROR_OR_WARNING(statement) \
|
wgpu::DawnTogglesDeviceDescriptor togglesDesc = {};
|
||||||
if (HasToggleEnabled(kDisallowDeprecatedAPIsToggleName)) { \
|
const char* forceEnabledToggles[1] = {kDisallowDeprecatedAPIsToggleName};
|
||||||
ASSERT_DEVICE_ERROR(statement); \
|
togglesDesc.forceEnabledToggles = forceEnabledToggles;
|
||||||
} else { \
|
togglesDesc.forceEnabledTogglesCount = 1;
|
||||||
EXPECT_DEPRECATION_WARNING(statement); \
|
|
||||||
} \
|
|
||||||
for (;;) \
|
|
||||||
break
|
|
||||||
|
|
||||||
class DeprecationTests : public DawnTest {
|
if (GetParam()) {
|
||||||
protected:
|
descriptor.nextInChain = &togglesDesc;
|
||||||
void SetUp() override {
|
|
||||||
DawnTest::SetUp();
|
|
||||||
// Skip when validation is off because warnings might be emitted during validation calls
|
|
||||||
DAWN_TEST_UNSUPPORTED_IF(HasToggleEnabled("skip_validation"));
|
|
||||||
}
|
}
|
||||||
};
|
return dawnAdapter.CreateDevice(&descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
// Test that setting attachment rather than view for render pass color and depth/stencil attachments
|
// Test that setting attachment rather than view for render pass color and depth/stencil attachments
|
||||||
// is deprecated.
|
// is deprecated.
|
||||||
|
@ -208,16 +197,9 @@ TEST_P(DeprecationTests, MultisampledTextureSampleType) {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
DAWN_INSTANTIATE_TEST(DeprecationTests,
|
INSTANTIATE_TEST_SUITE_P(DeprecatedAPITest,
|
||||||
D3D12Backend(),
|
DeprecationTests,
|
||||||
MetalBackend(),
|
testing::Values(true, false),
|
||||||
NullBackend(),
|
[](const testing::TestParamInfo<DeprecationTests::ParamType>& info) {
|
||||||
OpenGLBackend(),
|
return info.param ? "Disallowed" : "Allowed";
|
||||||
OpenGLESBackend(),
|
});
|
||||||
VulkanBackend(),
|
|
||||||
D3D12Backend({kDisallowDeprecatedAPIsToggleName}),
|
|
||||||
MetalBackend({kDisallowDeprecatedAPIsToggleName}),
|
|
||||||
NullBackend({kDisallowDeprecatedAPIsToggleName}),
|
|
||||||
OpenGLBackend({kDisallowDeprecatedAPIsToggleName}),
|
|
||||||
OpenGLESBackend({kDisallowDeprecatedAPIsToggleName}),
|
|
||||||
VulkanBackend({kDisallowDeprecatedAPIsToggleName}));
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
// 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_TESTS_UNITTESTS_VALIDATION_DEPRECATEDAPITESTS_H_
|
||||||
|
#define SRC_DAWN_TESTS_UNITTESTS_VALIDATION_DEPRECATEDAPITESTS_H_
|
||||||
|
|
||||||
|
#include "dawn/tests/unittests/validation/ValidationTest.h"
|
||||||
|
|
||||||
|
// This test header should be included when testing for deprecated parts of Dawn's API while
|
||||||
|
// following WebGPU's evolution. Tests in this suite test that a deprecation warning is emitted when
|
||||||
|
// the "old" behavior is used, and tests that an error is emitted when both the old and the new
|
||||||
|
// behavior are used (when applicable). Note that implementations of tests in this suite may be
|
||||||
|
// scattered in other files as well for organizational purposes so that similar tests can live
|
||||||
|
// together.
|
||||||
|
|
||||||
|
static constexpr char kDisallowDeprecatedAPIsToggleName[] = "disallow_deprecated_apis";
|
||||||
|
|
||||||
|
#define EXPECT_DEPRECATION_ERROR_OR_WARNING(statement) \
|
||||||
|
if (HasToggleEnabled(kDisallowDeprecatedAPIsToggleName)) { \
|
||||||
|
ASSERT_DEVICE_ERROR(statement); \
|
||||||
|
} else { \
|
||||||
|
EXPECT_DEPRECATION_WARNING(statement); \
|
||||||
|
} \
|
||||||
|
for (;;) \
|
||||||
|
break
|
||||||
|
|
||||||
|
// Parameter is a single bool. When true, deprecated APIs are strictly disallowed (i.e. generate
|
||||||
|
// errors). Otherwise, deprecated APIs only generate a warning message.
|
||||||
|
class DeprecationTests : public ValidationTest, public testing::WithParamInterface<bool> {
|
||||||
|
protected:
|
||||||
|
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SRC_DAWN_TESTS_UNITTESTS_VALIDATION_DEPRECATEDAPITESTS_H_
|
|
@ -12,6 +12,9 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "dawn/tests/unittests/validation/DeprecatedAPITests.h"
|
||||||
#include "dawn/tests/unittests/validation/ValidationTest.h"
|
#include "dawn/tests/unittests/validation/ValidationTest.h"
|
||||||
|
|
||||||
#include "dawn/common/Constants.h"
|
#include "dawn/common/Constants.h"
|
||||||
|
@ -615,7 +618,7 @@ TEST_F(RenderBundleValidationTest, RequiresAtLeastOneTextureFormat) {
|
||||||
TEST_F(RenderBundleValidationTest, ColorFormatsCountOutOfBounds) {
|
TEST_F(RenderBundleValidationTest, ColorFormatsCountOutOfBounds) {
|
||||||
std::array<wgpu::TextureFormat, kMaxColorAttachments + 1> colorFormats;
|
std::array<wgpu::TextureFormat, kMaxColorAttachments + 1> colorFormats;
|
||||||
for (uint32_t i = 0; i < colorFormats.size(); ++i) {
|
for (uint32_t i = 0; i < colorFormats.size(); ++i) {
|
||||||
colorFormats[i] = wgpu::TextureFormat::RGBA8Unorm;
|
colorFormats[i] = wgpu::TextureFormat::R8Unorm;
|
||||||
}
|
}
|
||||||
|
|
||||||
// colorFormatsCount <= kMaxColorAttachments is valid.
|
// colorFormatsCount <= kMaxColorAttachments is valid.
|
||||||
|
@ -1139,3 +1142,68 @@ TEST_F(RenderBundleValidationTest, TextureFormats) {
|
||||||
|
|
||||||
// Don't test non-renerable depth/stencil formats because we don't have any.
|
// Don't test non-renerable depth/stencil formats because we don't have any.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tests validation for per-pixel accounting for render targets. The tests currently assume that the
|
||||||
|
// default maxColorAttachmentBytesPerSample limit of 32 is used.
|
||||||
|
TEST_P(DeprecationTests, RenderBundleColorFormatsBytesPerSample) {
|
||||||
|
struct TestCase {
|
||||||
|
std::vector<wgpu::TextureFormat> formats;
|
||||||
|
bool success;
|
||||||
|
};
|
||||||
|
static std::vector<TestCase> kTestCases = {
|
||||||
|
// Simple 1 format cases.
|
||||||
|
|
||||||
|
// R8Unorm take 1 byte and are aligned to 1 byte so we can have 8 (max).
|
||||||
|
{{wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::R8Unorm,
|
||||||
|
wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::R8Unorm,
|
||||||
|
wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::R8Unorm},
|
||||||
|
true},
|
||||||
|
// RGBA8Uint takes 4 bytes and are aligned to 1 byte so we can have 8 (max).
|
||||||
|
{{wgpu::TextureFormat::RGBA8Uint, wgpu::TextureFormat::RGBA8Uint,
|
||||||
|
wgpu::TextureFormat::RGBA8Uint, wgpu::TextureFormat::RGBA8Uint,
|
||||||
|
wgpu::TextureFormat::RGBA8Uint, wgpu::TextureFormat::RGBA8Uint,
|
||||||
|
wgpu::TextureFormat::RGBA8Uint, wgpu::TextureFormat::RGBA8Uint},
|
||||||
|
true},
|
||||||
|
// RGBA8Unorm takes 8 bytes (special case) and are aligned to 1 byte so only 4 allowed.
|
||||||
|
{{wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureFormat::RGBA8Unorm,
|
||||||
|
wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureFormat::RGBA8Unorm},
|
||||||
|
true},
|
||||||
|
{{wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureFormat::RGBA8Unorm,
|
||||||
|
wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureFormat::RGBA8Unorm,
|
||||||
|
wgpu::TextureFormat::RGBA8Unorm},
|
||||||
|
false},
|
||||||
|
// RGBA32Float takes 16 bytes and are aligned to 4 bytes so only 2 are allowed.
|
||||||
|
{{wgpu::TextureFormat::RGBA32Float, wgpu::TextureFormat::RGBA32Float}, true},
|
||||||
|
{{wgpu::TextureFormat::RGBA32Float, wgpu::TextureFormat::RGBA32Float,
|
||||||
|
wgpu::TextureFormat::RGBA32Float},
|
||||||
|
false},
|
||||||
|
|
||||||
|
// Different format alignment cases.
|
||||||
|
|
||||||
|
// Alignment causes the first 1 byte R8Unorm to become 4 bytes. So even though 1+4+8+16+1 <
|
||||||
|
// 32, the 4 byte alignment requirement of R32Float makes the first R8Unorm become 4 and
|
||||||
|
// 4+4+8+16+1 > 32. Re-ordering this so the R8Unorm's are at the end, however is allowed:
|
||||||
|
// 4+8+16+1+1 < 32.
|
||||||
|
{{wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::R32Float,
|
||||||
|
wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureFormat::RGBA32Float,
|
||||||
|
wgpu::TextureFormat::R8Unorm},
|
||||||
|
false},
|
||||||
|
{{wgpu::TextureFormat::R32Float, wgpu::TextureFormat::RGBA8Unorm,
|
||||||
|
wgpu::TextureFormat::RGBA32Float, wgpu::TextureFormat::R8Unorm,
|
||||||
|
wgpu::TextureFormat::R8Unorm},
|
||||||
|
true},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const TestCase& testCase : kTestCases) {
|
||||||
|
utils::ComboRenderBundleEncoderDescriptor descriptor;
|
||||||
|
descriptor.colorFormatsCount = testCase.formats.size();
|
||||||
|
for (size_t i = 0; i < testCase.formats.size(); i++) {
|
||||||
|
descriptor.cColorFormats[i] = testCase.formats.at(i);
|
||||||
|
}
|
||||||
|
if (testCase.success) {
|
||||||
|
device.CreateRenderBundleEncoder(&descriptor);
|
||||||
|
} else {
|
||||||
|
EXPECT_DEPRECATION_ERROR_OR_WARNING(device.CreateRenderBundleEncoder(&descriptor));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -13,7 +13,9 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "dawn/tests/unittests/validation/DeprecatedAPITests.h"
|
||||||
#include "dawn/tests/unittests/validation/ValidationTest.h"
|
#include "dawn/tests/unittests/validation/ValidationTest.h"
|
||||||
|
|
||||||
#include "dawn/common/Constants.h"
|
#include "dawn/common/Constants.h"
|
||||||
|
@ -98,8 +100,7 @@ TEST_F(RenderPassDescriptorValidationTest, OneAttachment) {
|
||||||
TEST_F(RenderPassDescriptorValidationTest, ColorAttachmentOutOfBounds) {
|
TEST_F(RenderPassDescriptorValidationTest, ColorAttachmentOutOfBounds) {
|
||||||
std::array<wgpu::RenderPassColorAttachment, kMaxColorAttachments + 1> colorAttachments;
|
std::array<wgpu::RenderPassColorAttachment, kMaxColorAttachments + 1> colorAttachments;
|
||||||
for (uint32_t i = 0; i < colorAttachments.size(); i++) {
|
for (uint32_t i = 0; i < colorAttachments.size(); i++) {
|
||||||
colorAttachments[i].view =
|
colorAttachments[i].view = Create2DAttachment(device, 1, 1, wgpu::TextureFormat::R8Unorm);
|
||||||
Create2DAttachment(device, 1, 1, wgpu::TextureFormat::RGBA8Unorm);
|
|
||||||
colorAttachments[i].resolveTarget = nullptr;
|
colorAttachments[i].resolveTarget = nullptr;
|
||||||
colorAttachments[i].clearValue = {0.0f, 0.0f, 0.0f, 0.0f};
|
colorAttachments[i].clearValue = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||||
colorAttachments[i].loadOp = wgpu::LoadOp::Clear;
|
colorAttachments[i].loadOp = wgpu::LoadOp::Clear;
|
||||||
|
@ -1400,6 +1401,74 @@ TEST_F(RenderPassDescriptorValidationTest, ValidateDepthStencilAllAspects) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tests validation for per-pixel accounting for render targets. The tests currently assume that the
|
||||||
|
// default maxColorAttachmentBytesPerSample limit of 32 is used.
|
||||||
|
TEST_P(DeprecationTests, RenderPassColorAttachmentBytesPerSample) {
|
||||||
|
struct TestCase {
|
||||||
|
std::vector<wgpu::TextureFormat> formats;
|
||||||
|
bool success;
|
||||||
|
};
|
||||||
|
static std::vector<TestCase> kTestCases = {
|
||||||
|
// Simple 1 format cases.
|
||||||
|
|
||||||
|
// R8Unorm take 1 byte and are aligned to 1 byte so we can have 8 (max).
|
||||||
|
{{wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::R8Unorm,
|
||||||
|
wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::R8Unorm,
|
||||||
|
wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::R8Unorm},
|
||||||
|
true},
|
||||||
|
// RGBA8Uint takes 4 bytes and are aligned to 1 byte so we can have 8 (max).
|
||||||
|
{{wgpu::TextureFormat::RGBA8Uint, wgpu::TextureFormat::RGBA8Uint,
|
||||||
|
wgpu::TextureFormat::RGBA8Uint, wgpu::TextureFormat::RGBA8Uint,
|
||||||
|
wgpu::TextureFormat::RGBA8Uint, wgpu::TextureFormat::RGBA8Uint,
|
||||||
|
wgpu::TextureFormat::RGBA8Uint, wgpu::TextureFormat::RGBA8Uint},
|
||||||
|
true},
|
||||||
|
// RGBA8Unorm takes 8 bytes (special case) and are aligned to 1 byte so only 4 allowed.
|
||||||
|
{{wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureFormat::RGBA8Unorm,
|
||||||
|
wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureFormat::RGBA8Unorm},
|
||||||
|
true},
|
||||||
|
{{wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureFormat::RGBA8Unorm,
|
||||||
|
wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureFormat::RGBA8Unorm,
|
||||||
|
wgpu::TextureFormat::RGBA8Unorm},
|
||||||
|
false},
|
||||||
|
// RGBA32Float takes 16 bytes and are aligned to 4 bytes so only 2 are allowed.
|
||||||
|
{{wgpu::TextureFormat::RGBA32Float, wgpu::TextureFormat::RGBA32Float}, true},
|
||||||
|
{{wgpu::TextureFormat::RGBA32Float, wgpu::TextureFormat::RGBA32Float,
|
||||||
|
wgpu::TextureFormat::RGBA32Float},
|
||||||
|
false},
|
||||||
|
|
||||||
|
// Different format alignment cases.
|
||||||
|
|
||||||
|
// Alignment causes the first 1 byte R8Unorm to become 4 bytes. So even though 1+4+8+16+1 <
|
||||||
|
// 32, the 4 byte alignment requirement of R32Float makes the first R8Unorm become 4 and
|
||||||
|
// 4+4+8+16+1 > 32. Re-ordering this so the R8Unorm's are at the end, however is allowed:
|
||||||
|
// 4+8+16+1+1 < 32.
|
||||||
|
{{wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::R32Float,
|
||||||
|
wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureFormat::RGBA32Float,
|
||||||
|
wgpu::TextureFormat::R8Unorm},
|
||||||
|
false},
|
||||||
|
{{wgpu::TextureFormat::R32Float, wgpu::TextureFormat::RGBA8Unorm,
|
||||||
|
wgpu::TextureFormat::RGBA32Float, wgpu::TextureFormat::R8Unorm,
|
||||||
|
wgpu::TextureFormat::R8Unorm},
|
||||||
|
true},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const TestCase& testCase : kTestCases) {
|
||||||
|
std::vector<wgpu::TextureView> colorAttachmentInfo;
|
||||||
|
for (size_t i = 0; i < testCase.formats.size(); i++) {
|
||||||
|
colorAttachmentInfo.push_back(Create2DAttachment(device, 1, 1, testCase.formats.at(i)));
|
||||||
|
}
|
||||||
|
utils::ComboRenderPassDescriptor descriptor(colorAttachmentInfo);
|
||||||
|
wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
|
||||||
|
if (testCase.success) {
|
||||||
|
wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&descriptor);
|
||||||
|
renderPassEncoder.End();
|
||||||
|
commandEncoder.Finish();
|
||||||
|
} else {
|
||||||
|
EXPECT_DEPRECATION_ERROR_OR_WARNING(commandEncoder.BeginRenderPass(&descriptor));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(cwallez@chromium.org): Constraints on attachment aliasing?
|
// TODO(cwallez@chromium.org): Constraints on attachment aliasing?
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "dawn/common/Constants.h"
|
#include "dawn/common/Constants.h"
|
||||||
|
#include "dawn/tests/unittests/validation/DeprecatedAPITests.h"
|
||||||
#include "dawn/tests/unittests/validation/ValidationTest.h"
|
#include "dawn/tests/unittests/validation/ValidationTest.h"
|
||||||
#include "dawn/utils/ComboRenderPipelineDescriptor.h"
|
#include "dawn/utils/ComboRenderPipelineDescriptor.h"
|
||||||
#include "dawn/utils/WGPUHelpers.h"
|
#include "dawn/utils/WGPUHelpers.h"
|
||||||
|
@ -750,7 +751,7 @@ TEST_F(RenderPipelineValidationTest, VertexOnlyPipelineRequireDepthStencilAttach
|
||||||
|
|
||||||
// Vertex-only render pipeline must have a depth stencil attachment
|
// Vertex-only render pipeline must have a depth stencil attachment
|
||||||
{
|
{
|
||||||
utils::ComboRenderPassDescriptor renderPassDescriptor({});
|
utils::ComboRenderPassDescriptor renderPassDescriptor;
|
||||||
|
|
||||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||||
ASSERT_DEVICE_ERROR(encoder.BeginRenderPass(&renderPassDescriptor));
|
ASSERT_DEVICE_ERROR(encoder.BeginRenderPass(&renderPassDescriptor));
|
||||||
|
@ -1380,6 +1381,103 @@ TEST_F(RenderPipelineValidationTest, BindingsFromCorrectEntryPoint) {
|
||||||
ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor));
|
ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tests validation for per-pixel accounting for render targets. The tests currently assume that the
|
||||||
|
// default maxColorAttachmentBytesPerSample limit of 32 is used.
|
||||||
|
TEST_P(DeprecationTests, RenderPipelineColorAttachmentBytesPerSample) {
|
||||||
|
// Creates a fragment shader with maximum number of color attachments to enable testing.
|
||||||
|
auto CreateShader = [&](const std::vector<wgpu::TextureFormat>& formats) -> wgpu::ShaderModule {
|
||||||
|
// Default type to use when formats.size() < kMaxColorAttachments.
|
||||||
|
static constexpr std::string_view kDefaultWgslType = "vec4<f32>";
|
||||||
|
|
||||||
|
std::ostringstream bindings;
|
||||||
|
std::ostringstream outputs;
|
||||||
|
for (size_t i = 0; i < kMaxColorAttachments; i++) {
|
||||||
|
if (i < formats.size()) {
|
||||||
|
std::ostringstream type;
|
||||||
|
type << "vec4<" << utils::GetWGSLColorTextureComponentType(formats.at(i)) << ">";
|
||||||
|
bindings << "@location(" << i << ") o" << i << " : " << type.str() << ", ";
|
||||||
|
outputs << type.str() << "(1), ";
|
||||||
|
} else {
|
||||||
|
bindings << "@location(" << i << ") o" << i << " : " << kDefaultWgslType << ", ";
|
||||||
|
outputs << kDefaultWgslType << "(1), ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostringstream fsShader;
|
||||||
|
fsShader << "struct Outputs { " << bindings.str() << "}\n";
|
||||||
|
fsShader << "@fragment fn main() -> Outputs {\n";
|
||||||
|
fsShader << " return Outputs(" << outputs.str() << ");\n";
|
||||||
|
fsShader << "}";
|
||||||
|
return utils::CreateShaderModule(device, fsShader.str().c_str());
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TestCase {
|
||||||
|
std::vector<wgpu::TextureFormat> formats;
|
||||||
|
bool success;
|
||||||
|
};
|
||||||
|
static std::vector<TestCase> kTestCases = {
|
||||||
|
// Simple 1 format cases.
|
||||||
|
|
||||||
|
// R8Unorm take 1 byte and are aligned to 1 byte so we can have 8 (max).
|
||||||
|
{{wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::R8Unorm,
|
||||||
|
wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::R8Unorm,
|
||||||
|
wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::R8Unorm},
|
||||||
|
true},
|
||||||
|
// RGBA8Uint takes 4 bytes and are aligned to 1 byte so we can have 8 (max).
|
||||||
|
{{wgpu::TextureFormat::RGBA8Uint, wgpu::TextureFormat::RGBA8Uint,
|
||||||
|
wgpu::TextureFormat::RGBA8Uint, wgpu::TextureFormat::RGBA8Uint,
|
||||||
|
wgpu::TextureFormat::RGBA8Uint, wgpu::TextureFormat::RGBA8Uint,
|
||||||
|
wgpu::TextureFormat::RGBA8Uint, wgpu::TextureFormat::RGBA8Uint},
|
||||||
|
true},
|
||||||
|
// RGBA8Unorm takes 8 bytes (special case) and are aligned to 1 byte so only 4 allowed.
|
||||||
|
{{wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureFormat::RGBA8Unorm,
|
||||||
|
wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureFormat::RGBA8Unorm},
|
||||||
|
true},
|
||||||
|
{{wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureFormat::RGBA8Unorm,
|
||||||
|
wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureFormat::RGBA8Unorm,
|
||||||
|
wgpu::TextureFormat::RGBA8Unorm},
|
||||||
|
false},
|
||||||
|
// RGBA32Float takes 16 bytes and are aligned to 4 bytes so only 2 are allowed.
|
||||||
|
{{wgpu::TextureFormat::RGBA32Float, wgpu::TextureFormat::RGBA32Float}, true},
|
||||||
|
{{wgpu::TextureFormat::RGBA32Float, wgpu::TextureFormat::RGBA32Float,
|
||||||
|
wgpu::TextureFormat::RGBA32Float},
|
||||||
|
false},
|
||||||
|
|
||||||
|
// Different format alignment cases.
|
||||||
|
|
||||||
|
// Alignment causes the first 1 byte R8Unorm to become 4 bytes. So even though 1+4+8+16+1 <
|
||||||
|
// 32, the 4 byte alignment requirement of R32Float makes the first R8Unorm become 4 and
|
||||||
|
// 4+4+8+16+1 > 32. Re-ordering this so the R8Unorm's are at the end, however is allowed:
|
||||||
|
// 4+8+16+1+1 < 32.
|
||||||
|
{{wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::R32Float,
|
||||||
|
wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureFormat::RGBA32Float,
|
||||||
|
wgpu::TextureFormat::R8Unorm},
|
||||||
|
false},
|
||||||
|
{{wgpu::TextureFormat::R32Float, wgpu::TextureFormat::RGBA8Unorm,
|
||||||
|
wgpu::TextureFormat::RGBA32Float, wgpu::TextureFormat::R8Unorm,
|
||||||
|
wgpu::TextureFormat::R8Unorm},
|
||||||
|
true},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const TestCase& testCase : kTestCases) {
|
||||||
|
utils::ComboRenderPipelineDescriptor descriptor;
|
||||||
|
descriptor.vertex.module = utils::CreateShaderModule(device, R"(
|
||||||
|
@vertex fn main() -> @builtin(position) vec4<f32> {
|
||||||
|
return vec4<f32>(0.0, 0.0, 0.0, 1.0);
|
||||||
|
})");
|
||||||
|
descriptor.cFragment.module = CreateShader(testCase.formats);
|
||||||
|
descriptor.cFragment.targetCount = testCase.formats.size();
|
||||||
|
for (size_t i = 0; i < testCase.formats.size(); i++) {
|
||||||
|
descriptor.cTargets[i].format = testCase.formats.at(i);
|
||||||
|
}
|
||||||
|
if (testCase.success) {
|
||||||
|
device.CreateRenderPipeline(&descriptor);
|
||||||
|
} else {
|
||||||
|
EXPECT_DEPRECATION_ERROR_OR_WARNING(device.CreateRenderPipeline(&descriptor));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class DepthClipControlValidationTest : public RenderPipelineValidationTest {
|
class DepthClipControlValidationTest : public RenderPipelineValidationTest {
|
||||||
protected:
|
protected:
|
||||||
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
|
WGPUDevice CreateTestDevice(dawn::native::Adapter dawnAdapter) override {
|
||||||
|
|
|
@ -96,7 +96,7 @@ wgpu::Buffer CreateBufferFromData(const wgpu::Device& device,
|
||||||
}
|
}
|
||||||
|
|
||||||
ComboRenderPassDescriptor::ComboRenderPassDescriptor(
|
ComboRenderPassDescriptor::ComboRenderPassDescriptor(
|
||||||
std::initializer_list<wgpu::TextureView> colorAttachmentInfo,
|
const std::vector<wgpu::TextureView>& colorAttachmentInfo,
|
||||||
wgpu::TextureView depthStencil) {
|
wgpu::TextureView depthStencil) {
|
||||||
for (uint32_t i = 0; i < kMaxColorAttachments; ++i) {
|
for (uint32_t i = 0; i < kMaxColorAttachments; ++i) {
|
||||||
cColorAttachments[i].loadOp = wgpu::LoadOp::Clear;
|
cColorAttachments[i].loadOp = wgpu::LoadOp::Clear;
|
||||||
|
@ -174,7 +174,7 @@ BasicRenderPass::BasicRenderPass()
|
||||||
height(0),
|
height(0),
|
||||||
color(nullptr),
|
color(nullptr),
|
||||||
colorFormat(wgpu::TextureFormat::RGBA8Unorm),
|
colorFormat(wgpu::TextureFormat::RGBA8Unorm),
|
||||||
renderPassInfo({}) {}
|
renderPassInfo() {}
|
||||||
|
|
||||||
BasicRenderPass::BasicRenderPass(uint32_t texWidth,
|
BasicRenderPass::BasicRenderPass(uint32_t texWidth,
|
||||||
uint32_t texHeight,
|
uint32_t texHeight,
|
||||||
|
|
|
@ -57,7 +57,7 @@ wgpu::TextureDataLayout CreateTextureDataLayout(uint64_t offset,
|
||||||
|
|
||||||
struct ComboRenderPassDescriptor : public wgpu::RenderPassDescriptor {
|
struct ComboRenderPassDescriptor : public wgpu::RenderPassDescriptor {
|
||||||
public:
|
public:
|
||||||
ComboRenderPassDescriptor(std::initializer_list<wgpu::TextureView> colorAttachmentInfo,
|
ComboRenderPassDescriptor(const std::vector<wgpu::TextureView>& colorAttachmentInfo = {},
|
||||||
wgpu::TextureView depthStencil = wgpu::TextureView());
|
wgpu::TextureView depthStencil = wgpu::TextureView());
|
||||||
~ComboRenderPassDescriptor();
|
~ComboRenderPassDescriptor();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue