Disallow creating multisampled textures without RenderAttachment usage
Bug: dawn:1450 Test: dawn_unittests Change-Id: I9b8d3ce0cdfc557bd1ac0be8f0ab0f1acac88718 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/92700 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Austin Eng <enga@chromium.org> Commit-Queue: Jiawei Shao <jiawei.shao@intel.com> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
662095decd
commit
d527ffa3c0
2
DEPS
2
DEPS
|
@ -155,7 +155,7 @@ deps = {
|
||||||
|
|
||||||
# WebGPU CTS - not used directly by Dawn, only transitively by Chromium.
|
# WebGPU CTS - not used directly by Dawn, only transitively by Chromium.
|
||||||
'third_party/webgpu-cts': {
|
'third_party/webgpu-cts': {
|
||||||
'url': '{chromium_git}/external/github.com/gpuweb/cts@fee6d96eb34b10e232bceb1e1fb7b13c28912ee1',
|
'url': '{chromium_git}/external/github.com/gpuweb/cts@f19f0c38c943499913a9ab59b0fe0c26168a2368',
|
||||||
'condition': 'build_with_chromium',
|
'condition': 'build_with_chromium',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -169,6 +169,10 @@ MaybeError ValidateSampleCount(const TextureDescriptor* descriptor,
|
||||||
DAWN_INVALID_IF(usage & wgpu::TextureUsage::StorageBinding,
|
DAWN_INVALID_IF(usage & wgpu::TextureUsage::StorageBinding,
|
||||||
"The sample count (%u) of a storage textures is not 1.",
|
"The sample count (%u) of a storage textures is not 1.",
|
||||||
descriptor->sampleCount);
|
descriptor->sampleCount);
|
||||||
|
|
||||||
|
DAWN_INVALID_IF((usage & wgpu::TextureUsage::RenderAttachment) == 0,
|
||||||
|
"The usage (%s) of a multisampled texture doesn't include (%s).",
|
||||||
|
descriptor->usage, wgpu::TextureUsage::RenderAttachment);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -77,19 +77,14 @@ D3D12_RESOURCE_STATES D3D12TextureUsage(wgpu::TextureUsage usage, const Format&
|
||||||
return resourceState;
|
return resourceState;
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D12_RESOURCE_FLAGS D3D12ResourceFlags(wgpu::TextureUsage usage,
|
D3D12_RESOURCE_FLAGS D3D12ResourceFlags(wgpu::TextureUsage usage, const Format& format) {
|
||||||
const Format& format,
|
|
||||||
bool isMultisampledTexture) {
|
|
||||||
D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE;
|
D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE;
|
||||||
|
|
||||||
if (usage & wgpu::TextureUsage::StorageBinding) {
|
if (usage & wgpu::TextureUsage::StorageBinding) {
|
||||||
flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
|
flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// A multisampled resource must have either D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET or
|
if (usage & wgpu::TextureUsage::RenderAttachment) {
|
||||||
// D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL set in D3D12_RESOURCE_DESC::Flags.
|
|
||||||
// https://docs.microsoft.com/en-us/windows/desktop/api/d3d12/ns-d3d12-d3d12_resource_desc
|
|
||||||
if ((usage & wgpu::TextureUsage::RenderAttachment) != 0 || isMultisampledTexture) {
|
|
||||||
if (format.HasDepthOrStencil()) {
|
if (format.HasDepthOrStencil()) {
|
||||||
flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
|
flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
|
||||||
} else {
|
} else {
|
||||||
|
@ -591,8 +586,7 @@ MaybeError Texture::InitializeAsInternalTexture() {
|
||||||
resourceDescriptor.SampleDesc.Count = GetSampleCount();
|
resourceDescriptor.SampleDesc.Count = GetSampleCount();
|
||||||
resourceDescriptor.SampleDesc.Quality = 0;
|
resourceDescriptor.SampleDesc.Quality = 0;
|
||||||
resourceDescriptor.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
|
resourceDescriptor.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
|
||||||
resourceDescriptor.Flags =
|
resourceDescriptor.Flags = D3D12ResourceFlags(GetInternalUsage(), GetFormat());
|
||||||
D3D12ResourceFlags(GetInternalUsage(), GetFormat(), IsMultisampledTexture());
|
|
||||||
mD3D12ResourceFlags = resourceDescriptor.Flags;
|
mD3D12ResourceFlags = resourceDescriptor.Flags;
|
||||||
|
|
||||||
DAWN_TRY_ASSIGN(mResourceAllocation,
|
DAWN_TRY_ASSIGN(mResourceAllocation,
|
||||||
|
@ -1080,6 +1074,8 @@ MaybeError Texture::ClearTexture(CommandRecordingContext* commandContext,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
ASSERT(!IsMultisampledTexture());
|
||||||
|
|
||||||
// create temp buffer with clear color to copy to the texture image
|
// create temp buffer with clear color to copy to the texture image
|
||||||
TrackUsageAndTransitionNow(commandContext, D3D12_RESOURCE_STATE_COPY_DEST, range);
|
TrackUsageAndTransitionNow(commandContext, D3D12_RESOURCE_STATE_COPY_DEST, range);
|
||||||
|
|
||||||
|
|
|
@ -29,9 +29,7 @@ namespace dawn::native::metal {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
MTLTextureUsage MetalTextureUsage(const Format& format,
|
MTLTextureUsage MetalTextureUsage(const Format& format, wgpu::TextureUsage usage) {
|
||||||
wgpu::TextureUsage usage,
|
|
||||||
uint32_t sampleCount) {
|
|
||||||
MTLTextureUsage result = MTLTextureUsageUnknown; // This is 0
|
MTLTextureUsage result = MTLTextureUsageUnknown; // This is 0
|
||||||
|
|
||||||
if (usage & (wgpu::TextureUsage::StorageBinding)) {
|
if (usage & (wgpu::TextureUsage::StorageBinding)) {
|
||||||
|
@ -52,8 +50,7 @@ MTLTextureUsage MetalTextureUsage(const Format& format,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MTLTextureUsageRenderTarget is needed to clear multisample textures.
|
if (usage & wgpu::TextureUsage::RenderAttachment) {
|
||||||
if (usage & (wgpu::TextureUsage::RenderAttachment) || sampleCount > 1) {
|
|
||||||
result |= MTLTextureUsageRenderTarget;
|
result |= MTLTextureUsageRenderTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,8 +117,7 @@ bool RequiresCreatingNewTextureView(const TextureBase* texture,
|
||||||
|
|
||||||
// If the texture is created with MTLTextureUsagePixelFormatView, we need
|
// If the texture is created with MTLTextureUsagePixelFormatView, we need
|
||||||
// a new view to perform format reinterpretation.
|
// a new view to perform format reinterpretation.
|
||||||
if ((MetalTextureUsage(texture->GetFormat(), texture->GetInternalUsage(),
|
if ((MetalTextureUsage(texture->GetFormat(), texture->GetInternalUsage()) &
|
||||||
texture->GetSampleCount()) &
|
|
||||||
MTLTextureUsagePixelFormatView) != 0) {
|
MTLTextureUsagePixelFormatView) != 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -652,7 +648,7 @@ NSRef<MTLTextureDescriptor> Texture::CreateMetalTextureDescriptor() const {
|
||||||
// Metal only allows format reinterpretation to happen on swizzle pattern or conversion
|
// Metal only allows format reinterpretation to happen on swizzle pattern or conversion
|
||||||
// between linear space and sRGB. For example, creating bgra8Unorm texture view on
|
// between linear space and sRGB. For example, creating bgra8Unorm texture view on
|
||||||
// rgba8Unorm texture or creating rgba8Unorm_srgb texture view on rgab8Unorm texture.
|
// rgba8Unorm texture or creating rgba8Unorm_srgb texture view on rgab8Unorm texture.
|
||||||
mtlDesc.usage = MetalTextureUsage(GetFormat(), GetInternalUsage(), GetSampleCount());
|
mtlDesc.usage = MetalTextureUsage(GetFormat(), GetInternalUsage());
|
||||||
mtlDesc.pixelFormat = MetalPixelFormat(GetFormat().format);
|
mtlDesc.pixelFormat = MetalPixelFormat(GetFormat().format);
|
||||||
mtlDesc.mipmapLevelCount = GetNumMipLevels();
|
mtlDesc.mipmapLevelCount = GetNumMipLevels();
|
||||||
mtlDesc.storageMode = MTLStorageModePrivate;
|
mtlDesc.storageMode = MTLStorageModePrivate;
|
||||||
|
@ -932,6 +928,8 @@ MaybeError Texture::ClearTexture(CommandRecordingContext* commandContext,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
ASSERT(!IsMultisampledTexture());
|
||||||
|
|
||||||
// Encode a buffer to texture copy to clear each subresource.
|
// Encode a buffer to texture copy to clear each subresource.
|
||||||
for (Aspect aspect : IterateEnumMask(range.aspects)) {
|
for (Aspect aspect : IterateEnumMask(range.aspects)) {
|
||||||
// Compute the buffer size big enough to fill the largest mip.
|
// Compute the buffer size big enough to fill the largest mip.
|
||||||
|
@ -1035,8 +1033,7 @@ MaybeError TextureView::Initialize(const TextureViewDescriptor* descriptor) {
|
||||||
MTLTextureDescriptor* mtlDesc = mtlDescRef.Get();
|
MTLTextureDescriptor* mtlDesc = mtlDescRef.Get();
|
||||||
|
|
||||||
mtlDesc.sampleCount = texture->GetSampleCount();
|
mtlDesc.sampleCount = texture->GetSampleCount();
|
||||||
mtlDesc.usage = MetalTextureUsage(texture->GetFormat(), texture->GetInternalUsage(),
|
mtlDesc.usage = MetalTextureUsage(texture->GetFormat(), texture->GetInternalUsage());
|
||||||
texture->GetSampleCount());
|
|
||||||
mtlDesc.pixelFormat = MetalPixelFormat(descriptor->format);
|
mtlDesc.pixelFormat = MetalPixelFormat(descriptor->format);
|
||||||
mtlDesc.mipmapLevelCount = texture->GetNumMipLevels();
|
mtlDesc.mipmapLevelCount = texture->GetNumMipLevels();
|
||||||
mtlDesc.storageMode = kIOSurfaceStorageMode;
|
mtlDesc.storageMode = kIOSurfaceStorageMode;
|
||||||
|
|
|
@ -414,8 +414,7 @@ DAWN_INSTANTIATE_TEST_P(
|
||||||
{"lazy_clear_resource_on_first_use"})},
|
{"lazy_clear_resource_on_first_use"})},
|
||||||
{wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::RG8Unorm, wgpu::TextureFormat::RGBA8Unorm},
|
{wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::RG8Unorm, wgpu::TextureFormat::RGBA8Unorm},
|
||||||
{wgpu::TextureAspect::All},
|
{wgpu::TextureAspect::All},
|
||||||
{wgpu::TextureUsage(wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::TextureBinding),
|
{wgpu::TextureUsage(wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::TextureBinding)},
|
||||||
wgpu::TextureUsage::TextureBinding},
|
|
||||||
{wgpu::TextureDimension::e2D},
|
{wgpu::TextureDimension::e2D},
|
||||||
{1u}, // depth or array layers
|
{1u}, // depth or array layers
|
||||||
{1u}, // mip count
|
{1u}, // mip count
|
||||||
|
|
|
@ -447,6 +447,7 @@ TEST_F(BindGroupValidationTest, StorageTextureUsage) {
|
||||||
// Multisampled texture is invalid with storage buffer binding
|
// Multisampled texture is invalid with storage buffer binding
|
||||||
// Regression case for crbug.com/dawn/614 where this hit an ASSERT.
|
// Regression case for crbug.com/dawn/614 where this hit an ASSERT.
|
||||||
descriptor.sampleCount = 4;
|
descriptor.sampleCount = 4;
|
||||||
|
descriptor.usage |= wgpu::TextureUsage::RenderAttachment;
|
||||||
view = device.CreateTexture(&descriptor).CreateView();
|
view = device.CreateTexture(&descriptor).CreateView();
|
||||||
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, view}}));
|
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, view}}));
|
||||||
}
|
}
|
||||||
|
@ -727,7 +728,7 @@ TEST_F(BindGroupValidationTest, MultisampledTexture) {
|
||||||
// Control case: setting a multisampled 2D texture works
|
// Control case: setting a multisampled 2D texture works
|
||||||
wgpu::TextureDescriptor textureDesc;
|
wgpu::TextureDescriptor textureDesc;
|
||||||
textureDesc.sampleCount = 4;
|
textureDesc.sampleCount = 4;
|
||||||
textureDesc.usage = wgpu::TextureUsage::TextureBinding;
|
textureDesc.usage = wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::RenderAttachment;
|
||||||
textureDesc.dimension = wgpu::TextureDimension::e2D;
|
textureDesc.dimension = wgpu::TextureDimension::e2D;
|
||||||
textureDesc.format = wgpu::TextureFormat::RGBA8Unorm;
|
textureDesc.format = wgpu::TextureFormat::RGBA8Unorm;
|
||||||
textureDesc.size = {1, 1, 1};
|
textureDesc.size = {1, 1, 1};
|
||||||
|
|
|
@ -751,8 +751,9 @@ TEST_F(CopyCommandTest_B2T, IncorrectBufferOffsetForDepthStencilTexture) {
|
||||||
TEST_F(CopyCommandTest_B2T, CopyToMultisampledTexture) {
|
TEST_F(CopyCommandTest_B2T, CopyToMultisampledTexture) {
|
||||||
uint64_t bufferSize = BufferSizeForTextureCopy(16, 16, 1);
|
uint64_t bufferSize = BufferSizeForTextureCopy(16, 16, 1);
|
||||||
wgpu::Buffer source = CreateBuffer(bufferSize, wgpu::BufferUsage::CopySrc);
|
wgpu::Buffer source = CreateBuffer(bufferSize, wgpu::BufferUsage::CopySrc);
|
||||||
wgpu::Texture destination = Create2DTexture(2, 2, 1, 1, wgpu::TextureFormat::RGBA8Unorm,
|
wgpu::Texture destination =
|
||||||
wgpu::TextureUsage::CopyDst, 4);
|
Create2DTexture(2, 2, 1, 1, wgpu::TextureFormat::RGBA8Unorm,
|
||||||
|
wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment, 4);
|
||||||
|
|
||||||
TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 2, destination, 0, {0, 0, 0},
|
TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 2, destination, 0, {0, 0, 0},
|
||||||
{2, 2, 1});
|
{2, 2, 1});
|
||||||
|
@ -1387,8 +1388,9 @@ TEST_F(CopyCommandTest_T2B, IncorrectBufferOffsetForDepthStencilTexture) {
|
||||||
|
|
||||||
// Test multisampled textures cannot be used in T2B copies.
|
// Test multisampled textures cannot be used in T2B copies.
|
||||||
TEST_F(CopyCommandTest_T2B, CopyFromMultisampledTexture) {
|
TEST_F(CopyCommandTest_T2B, CopyFromMultisampledTexture) {
|
||||||
wgpu::Texture source = Create2DTexture(2, 2, 1, 1, wgpu::TextureFormat::RGBA8Unorm,
|
wgpu::Texture source =
|
||||||
wgpu::TextureUsage::CopySrc, 4);
|
Create2DTexture(2, 2, 1, 1, wgpu::TextureFormat::RGBA8Unorm,
|
||||||
|
wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::RenderAttachment, 4);
|
||||||
uint64_t bufferSize = BufferSizeForTextureCopy(16, 16, 1);
|
uint64_t bufferSize = BufferSizeForTextureCopy(16, 16, 1);
|
||||||
wgpu::Buffer destination = CreateBuffer(bufferSize, wgpu::BufferUsage::CopyDst);
|
wgpu::Buffer destination = CreateBuffer(bufferSize, wgpu::BufferUsage::CopyDst);
|
||||||
|
|
||||||
|
@ -1956,10 +1958,12 @@ TEST_F(CopyCommandTest_T2T, SrgbFormatsCompatibility) {
|
||||||
TEST_F(CopyCommandTest_T2T, MultisampledCopies) {
|
TEST_F(CopyCommandTest_T2T, MultisampledCopies) {
|
||||||
wgpu::Texture sourceMultiSampled1x = Create2DTexture(
|
wgpu::Texture sourceMultiSampled1x = Create2DTexture(
|
||||||
16, 16, 1, 1, wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureUsage::CopySrc, 1);
|
16, 16, 1, 1, wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureUsage::CopySrc, 1);
|
||||||
wgpu::Texture sourceMultiSampled4x = Create2DTexture(
|
wgpu::Texture sourceMultiSampled4x =
|
||||||
16, 16, 1, 1, wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureUsage::CopySrc, 4);
|
Create2DTexture(16, 16, 1, 1, wgpu::TextureFormat::RGBA8Unorm,
|
||||||
wgpu::Texture destinationMultiSampled4x = Create2DTexture(
|
wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::RenderAttachment, 4);
|
||||||
16, 16, 1, 1, wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureUsage::CopyDst, 4);
|
wgpu::Texture destinationMultiSampled4x =
|
||||||
|
Create2DTexture(16, 16, 1, 1, wgpu::TextureFormat::RGBA8Unorm,
|
||||||
|
wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment, 4);
|
||||||
|
|
||||||
// Success when entire multisampled subresource is copied
|
// Success when entire multisampled subresource is copied
|
||||||
{
|
{
|
||||||
|
|
|
@ -297,7 +297,9 @@ TEST_F(CopyTextureForBrowserTest, InvalidSampleCount) {
|
||||||
wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment, 1);
|
wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment, 1);
|
||||||
wgpu::Texture sourceMultiSampled4x =
|
wgpu::Texture sourceMultiSampled4x =
|
||||||
Create2DTexture(16, 16, 1, 1, wgpu::TextureFormat::RGBA8Unorm,
|
Create2DTexture(16, 16, 1, 1, wgpu::TextureFormat::RGBA8Unorm,
|
||||||
wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::TextureBinding, 4);
|
wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::TextureBinding |
|
||||||
|
wgpu::TextureUsage::RenderAttachment,
|
||||||
|
4);
|
||||||
wgpu::Texture destinationMultiSampled4x =
|
wgpu::Texture destinationMultiSampled4x =
|
||||||
Create2DTexture(16, 16, 1, 1, wgpu::TextureFormat::RGBA8Unorm,
|
Create2DTexture(16, 16, 1, 1, wgpu::TextureFormat::RGBA8Unorm,
|
||||||
wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment, 4);
|
wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment, 4);
|
||||||
|
|
|
@ -115,7 +115,7 @@ TEST_F(TextureInternalUsageValidationTest, UsageValidation) {
|
||||||
{
|
{
|
||||||
wgpu::TextureDescriptor textureDesc = {};
|
wgpu::TextureDescriptor textureDesc = {};
|
||||||
textureDesc.size = {1, 1};
|
textureDesc.size = {1, 1};
|
||||||
textureDesc.usage = wgpu::TextureUsage::CopySrc;
|
textureDesc.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::RenderAttachment;
|
||||||
textureDesc.format = wgpu::TextureFormat::RGBA8Unorm;
|
textureDesc.format = wgpu::TextureFormat::RGBA8Unorm;
|
||||||
textureDesc.sampleCount = 4;
|
textureDesc.sampleCount = 4;
|
||||||
|
|
||||||
|
|
|
@ -322,8 +322,9 @@ TEST_F(QueueWriteTextureValidationTest, DataOffset) {
|
||||||
TEST_F(QueueWriteTextureValidationTest, WriteToMultisampledTexture) {
|
TEST_F(QueueWriteTextureValidationTest, WriteToMultisampledTexture) {
|
||||||
uint64_t dataSize =
|
uint64_t dataSize =
|
||||||
utils::RequiredBytesInCopy(256, 0, {2, 2, 1}, wgpu::TextureFormat::RGBA8Unorm);
|
utils::RequiredBytesInCopy(256, 0, {2, 2, 1}, wgpu::TextureFormat::RGBA8Unorm);
|
||||||
wgpu::Texture destination = Create2DTexture({2, 2, 1}, 1, wgpu::TextureFormat::RGBA8Unorm,
|
wgpu::Texture destination =
|
||||||
wgpu::TextureUsage::CopyDst, 4);
|
Create2DTexture({2, 2, 1}, 1, wgpu::TextureFormat::RGBA8Unorm,
|
||||||
|
wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment, 4);
|
||||||
|
|
||||||
ASSERT_DEVICE_ERROR(
|
ASSERT_DEVICE_ERROR(
|
||||||
TestWriteTexture(dataSize, 0, 256, 2, destination, 0, {0, 0, 0}, {2, 2, 1}));
|
TestWriteTexture(dataSize, 0, 256, 2, destination, 0, {0, 0, 0}, {2, 2, 1}));
|
||||||
|
|
|
@ -143,9 +143,12 @@ TEST_F(TextureValidationTest, SampleCount) {
|
||||||
{
|
{
|
||||||
wgpu::TextureDescriptor descriptor = defaultDescriptor;
|
wgpu::TextureDescriptor descriptor = defaultDescriptor;
|
||||||
descriptor.sampleCount = 4;
|
descriptor.sampleCount = 4;
|
||||||
descriptor.usage = wgpu::TextureUsage::TextureBinding;
|
|
||||||
|
|
||||||
for (wgpu::TextureFormat format : utils::kFormatsInCoreSpec) {
|
for (wgpu::TextureFormat format : utils::kFormatsInCoreSpec) {
|
||||||
|
if (!utils::TextureFormatSupportsRendering(format)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
descriptor.format = format;
|
descriptor.format = format;
|
||||||
if (utils::TextureFormatSupportsMultisampling(format)) {
|
if (utils::TextureFormatSupportsMultisampling(format)) {
|
||||||
device.CreateTexture(&descriptor);
|
device.CreateTexture(&descriptor);
|
||||||
|
@ -172,6 +175,16 @@ TEST_F(TextureValidationTest, SampleCount) {
|
||||||
|
|
||||||
ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
|
ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// It is an error to create a texture without TextureUsage::RenderAttachment usage when
|
||||||
|
// sampleCount > 1.
|
||||||
|
{
|
||||||
|
wgpu::TextureDescriptor descriptor = defaultDescriptor;
|
||||||
|
descriptor.sampleCount = 4;
|
||||||
|
descriptor.usage = wgpu::TextureUsage::TextureBinding;
|
||||||
|
|
||||||
|
ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test the validation of the mip level count
|
// Test the validation of the mip level count
|
||||||
|
|
|
@ -41,7 +41,7 @@ wgpu::Texture Create2DArrayTexture(wgpu::Device& device,
|
||||||
descriptor.sampleCount = sampleCount;
|
descriptor.sampleCount = sampleCount;
|
||||||
descriptor.format = kDefaultTextureFormat;
|
descriptor.format = kDefaultTextureFormat;
|
||||||
descriptor.mipLevelCount = mipLevelCount;
|
descriptor.mipLevelCount = mipLevelCount;
|
||||||
descriptor.usage = wgpu::TextureUsage::TextureBinding;
|
descriptor.usage = wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::RenderAttachment;
|
||||||
return device.CreateTexture(&descriptor);
|
return device.CreateTexture(&descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue