diff --git a/src/dawn_native/RenderBundleEncoder.cpp b/src/dawn_native/RenderBundleEncoder.cpp index b4febefdbd..03bf7cc82b 100644 --- a/src/dawn_native/RenderBundleEncoder.cpp +++ b/src/dawn_native/RenderBundleEncoder.cpp @@ -17,11 +17,37 @@ #include "dawn_native/CommandValidation.h" #include "dawn_native/Commands.h" #include "dawn_native/Device.h" +#include "dawn_native/Format.h" #include "dawn_native/RenderPipeline.h" #include "dawn_native/ValidationUtils_autogen.h" namespace dawn_native { + MaybeError ValidateColorAttachmentFormat(const DeviceBase* device, + dawn::TextureFormat textureFormat) { + DAWN_TRY(ValidateTextureFormat(textureFormat)); + const Format* format = nullptr; + DAWN_TRY_ASSIGN(format, device->GetInternalFormat(textureFormat)); + if (!format->IsColor() || !format->isRenderable) { + return DAWN_VALIDATION_ERROR( + "The color attachment texture format is not color renderable"); + } + return {}; + } + + MaybeError ValidateDepthStencilAttachmentFormat(const DeviceBase* device, + dawn::TextureFormat textureFormat) { + DAWN_TRY(ValidateTextureFormat(textureFormat)); + const Format* format = nullptr; + DAWN_TRY_ASSIGN(format, device->GetInternalFormat(textureFormat)); + if (!format->HasDepthOrStencil() || !format->isRenderable) { + return DAWN_VALIDATION_ERROR( + "The depth stencil attachment texture format is not a renderable depth/stencil " + "format"); + } + return {}; + } + MaybeError ValidateRenderBundleEncoderDescriptor( const DeviceBase* device, const RenderBundleEncoderDescriptor* descriptor) { @@ -38,11 +64,11 @@ namespace dawn_native { } for (uint32_t i = 0; i < descriptor->colorFormatsCount; ++i) { - DAWN_TRY(ValidateTextureFormat(descriptor->colorFormats[i])); + DAWN_TRY(ValidateColorAttachmentFormat(device, descriptor->colorFormats[i])); } if (descriptor->depthStencilFormat != nullptr) { - DAWN_TRY(ValidateTextureFormat(*descriptor->depthStencilFormat)); + DAWN_TRY(ValidateDepthStencilAttachmentFormat(device, *descriptor->depthStencilFormat)); } return {}; diff --git a/src/tests/unittests/validation/RenderBundleValidationTests.cpp b/src/tests/unittests/validation/RenderBundleValidationTests.cpp index 6c38506691..416405fb0f 100644 --- a/src/tests/unittests/validation/RenderBundleValidationTests.cpp +++ b/src/tests/unittests/validation/RenderBundleValidationTests.cpp @@ -988,3 +988,33 @@ TEST_F(RenderBundleValidationTest, RenderPassSampleCountMismatch) { ASSERT_DEVICE_ERROR(commandEncoder.Finish()); } } + +// Test that color attachment texture formats must be color renderable and +// depth stencil texture formats must be depth/stencil. +TEST_F(RenderBundleValidationTest, TextureFormats) { + // Test that color formats are validated as color. + { + utils::ComboRenderBundleEncoderDescriptor desc = {}; + desc.colorFormatsCount = 1; + desc.cColorFormats[0] = dawn::TextureFormat::Depth24PlusStencil8; + ASSERT_DEVICE_ERROR(device.CreateRenderBundleEncoder(&desc)); + } + + // Test that color formats are validated as renderable. + { + utils::ComboRenderBundleEncoderDescriptor desc = {}; + desc.colorFormatsCount = 1; + desc.cColorFormats[0] = dawn::TextureFormat::RGBA8Snorm; + ASSERT_DEVICE_ERROR(device.CreateRenderBundleEncoder(&desc)); + } + + // Test that depth/stencil formats are validated as depth/stencil. + { + utils::ComboRenderBundleEncoderDescriptor desc = {}; + desc.cDepthStencilFormat = dawn::TextureFormat::RGBA8Unorm; + desc.depthStencilFormat = &desc.cDepthStencilFormat; + ASSERT_DEVICE_ERROR(device.CreateRenderBundleEncoder(&desc)); + } + + // Don't test non-renerable depth/stencil formats because we don't have any. +}