Make loapOp/storeOp undefined valid

It is valid for depth/stencil attachment if the attachments are
readonly. It is not valid for color attachments. Make the enum valid,
and update validation.

Caught in CTS roll
https://chromium-review.googlesource.com/c/chromium/src/+/3499286

Bug: dawn:1269
Change-Id: Ib849ed757ccca145f85cadea6f92a1f2a5082d49
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/82540
Reviewed-by: Loko Kung <lokokung@google.com>
Reviewed-by: Brandon Jones <bajones@chromium.org>
Commit-Queue: Austin Eng <enga@chromium.org>
This commit is contained in:
Austin Eng 2022-03-09 18:43:51 +00:00 committed by Dawn LUCI CQ
parent a297e072d3
commit 74d4e53fc6
17 changed files with 155 additions and 27 deletions

View File

@ -1456,7 +1456,7 @@
"category": "enum", "category": "enum",
"emscripten_no_enum_table": true, "emscripten_no_enum_table": true,
"values": [ "values": [
{"value": 0, "name": "undefined", "valid": false, "jsrepr": "undefined"}, {"value": 0, "name": "undefined", "jsrepr": "undefined"},
{"value": 1, "name": "clear"}, {"value": 1, "name": "clear"},
{"value": 2, "name": "load"} {"value": 2, "name": "load"}
] ]
@ -1472,7 +1472,7 @@
"store op": { "store op": {
"category": "enum", "category": "enum",
"values": [ "values": [
{"value": 0, "name": "undefined", "valid": false, "jsrepr": "undefined"}, {"value": 0, "name": "undefined", "jsrepr": "undefined"},
{"value": 1, "name": "store"}, {"value": 1, "name": "store"},
{"value": 2, "name": "discard"} {"value": 2, "name": "discard"}
] ]

View File

@ -241,6 +241,10 @@ namespace dawn::native {
DAWN_TRY(ValidateLoadOp(colorAttachment.loadOp)); DAWN_TRY(ValidateLoadOp(colorAttachment.loadOp));
DAWN_TRY(ValidateStoreOp(colorAttachment.storeOp)); DAWN_TRY(ValidateStoreOp(colorAttachment.storeOp));
DAWN_INVALID_IF(colorAttachment.loadOp == wgpu::LoadOp::Undefined,
"loadOp must be set.");
DAWN_INVALID_IF(colorAttachment.storeOp == wgpu::StoreOp::Undefined,
"storeOp must be set.");
// TODO(dawn:1269): Remove after the deprecation period. // TODO(dawn:1269): Remove after the deprecation period.
bool useClearColor = HasDeprecatedColor(colorAttachment); bool useClearColor = HasDeprecatedColor(colorAttachment);
@ -303,47 +307,77 @@ namespace dawn::native {
"is 'all'.", "is 'all'.",
depthStencilAttachment->depthReadOnly, depthStencilAttachment->stencilReadOnly); depthStencilAttachment->depthReadOnly, depthStencilAttachment->stencilReadOnly);
if (depthStencilAttachment->depthReadOnly) { // Read only, or depth doesn't exist.
if (depthStencilAttachment->depthReadOnly ||
!IsSubset(Aspect::Depth, attachment->GetAspects())) {
if (depthStencilAttachment->depthLoadOp == wgpu::LoadOp::Load && if (depthStencilAttachment->depthLoadOp == wgpu::LoadOp::Load &&
depthStencilAttachment->depthStoreOp == wgpu::StoreOp::Store) { depthStencilAttachment->depthStoreOp == wgpu::StoreOp::Store) {
// TODO(dawn:1269): Remove this branch after the deprecation period. // TODO(dawn:1269): Remove this branch after the deprecation period.
device->EmitDeprecationWarning( device->EmitDeprecationWarning(
"Setting depthLoadOp and depthStore when " "Setting depthLoadOp and depthStoreOp when "
"depthReadOnly is true is deprecated."); "the attachment has no depth aspect or depthReadOnly is true is "
"deprecated.");
} else { } else {
DAWN_INVALID_IF(depthStencilAttachment->depthLoadOp != wgpu::LoadOp::Undefined, DAWN_INVALID_IF(depthStencilAttachment->depthLoadOp != wgpu::LoadOp::Undefined,
"depthLoadOp (%s) must not be set when depthReadOnly is true.", "depthLoadOp (%s) must not be set if the attachment (%s) has "
depthStencilAttachment->depthLoadOp); "no depth aspect or depthReadOnly (%u) is true.",
depthStencilAttachment->depthLoadOp, attachment,
depthStencilAttachment->depthReadOnly);
DAWN_INVALID_IF( DAWN_INVALID_IF(
depthStencilAttachment->depthStoreOp != wgpu::StoreOp::Undefined, depthStencilAttachment->depthStoreOp != wgpu::StoreOp::Undefined,
"depthStoreOp (%s) must not be set when depthReadOnly is true.", "depthStoreOp (%s) must not be set if the attachment (%s) has no depth "
depthStencilAttachment->depthStoreOp); "aspect or depthReadOnly (%u) is true.",
depthStencilAttachment->depthStoreOp, attachment,
depthStencilAttachment->depthReadOnly);
} }
} else { } else {
DAWN_TRY(ValidateLoadOp(depthStencilAttachment->depthLoadOp)); DAWN_TRY(ValidateLoadOp(depthStencilAttachment->depthLoadOp));
DAWN_INVALID_IF(depthStencilAttachment->depthLoadOp == wgpu::LoadOp::Undefined,
"depthLoadOp must be set if the attachment (%s) has a depth aspect "
"and depthReadOnly (%u) is false.",
attachment, depthStencilAttachment->depthReadOnly);
DAWN_TRY(ValidateStoreOp(depthStencilAttachment->depthStoreOp)); DAWN_TRY(ValidateStoreOp(depthStencilAttachment->depthStoreOp));
DAWN_INVALID_IF(depthStencilAttachment->depthStoreOp == wgpu::StoreOp::Undefined,
"depthStoreOp must be set if the attachment (%s) has a depth "
"aspect and depthReadOnly (%u) is false.",
attachment, depthStencilAttachment->depthReadOnly);
} }
if (depthStencilAttachment->stencilReadOnly) { // Read only, or stencil doesn't exist.
if (depthStencilAttachment->stencilReadOnly ||
!IsSubset(Aspect::Stencil, attachment->GetAspects())) {
if (depthStencilAttachment->stencilLoadOp == wgpu::LoadOp::Load && if (depthStencilAttachment->stencilLoadOp == wgpu::LoadOp::Load &&
depthStencilAttachment->stencilStoreOp == wgpu::StoreOp::Store) { depthStencilAttachment->stencilStoreOp == wgpu::StoreOp::Store) {
// TODO(dawn:1269): Remove this branch after the deprecation period. // TODO(dawn:1269): Remove this branch after the deprecation period.
device->EmitDeprecationWarning( device->EmitDeprecationWarning(
"Setting stencilLoadOp and stencilStoreOp when " "Setting stencilLoadOp and stencilStoreOp when "
"stencilReadOnly is true is deprecated."); "the attachment has no stencil aspect or stencilReadOnly is true is "
"deprecated.");
} else { } else {
DAWN_INVALID_IF( DAWN_INVALID_IF(
depthStencilAttachment->stencilLoadOp != wgpu::LoadOp::Undefined, depthStencilAttachment->stencilLoadOp != wgpu::LoadOp::Undefined,
"stencilLoadOp (%s) must not be set when stencilReadOnly is true.", "stencilLoadOp (%s) must not be set if the attachment (%s) has no stencil "
depthStencilAttachment->stencilLoadOp); "aspect or stencilReadOnly (%u) is true.",
depthStencilAttachment->stencilLoadOp, attachment,
depthStencilAttachment->stencilReadOnly);
DAWN_INVALID_IF( DAWN_INVALID_IF(
depthStencilAttachment->stencilStoreOp != wgpu::StoreOp::Undefined, depthStencilAttachment->stencilStoreOp != wgpu::StoreOp::Undefined,
"stencilStoreOp (%s) must not be set when stencilReadOnly is true.", "stencilStoreOp (%s) must not be set if the attachment (%s) has no stencil "
depthStencilAttachment->stencilStoreOp); "aspect or stencilReadOnly (%u) is true.",
depthStencilAttachment->stencilStoreOp, attachment,
depthStencilAttachment->stencilReadOnly);
} }
} else { } else {
DAWN_TRY(ValidateLoadOp(depthStencilAttachment->stencilLoadOp)); DAWN_TRY(ValidateLoadOp(depthStencilAttachment->stencilLoadOp));
DAWN_INVALID_IF(depthStencilAttachment->stencilLoadOp == wgpu::LoadOp::Undefined,
"stencilLoadOp must be set if the attachment (%s) has a stencil "
"aspect and stencilReadOnly (%u) is false.",
attachment, depthStencilAttachment->stencilReadOnly);
DAWN_TRY(ValidateStoreOp(depthStencilAttachment->stencilStoreOp)); DAWN_TRY(ValidateStoreOp(depthStencilAttachment->stencilStoreOp));
DAWN_INVALID_IF(depthStencilAttachment->depthStoreOp == wgpu::StoreOp::Undefined,
"stencilStoreOp must be set if the attachment (%s) has a stencil "
"aspect and stencilReadOnly (%u) is false.",
attachment, depthStencilAttachment->stencilReadOnly);
} }
if (!std::isnan(depthStencilAttachment->clearDepth)) { if (!std::isnan(depthStencilAttachment->clearDepth)) {
@ -823,7 +857,9 @@ namespace dawn::native {
cmd->depthStencilAttachment.stencilReadOnly = cmd->depthStencilAttachment.stencilReadOnly =
descriptor->depthStencilAttachment->stencilReadOnly; descriptor->depthStencilAttachment->stencilReadOnly;
if (descriptor->depthStencilAttachment->depthReadOnly) { if (descriptor->depthStencilAttachment->depthReadOnly ||
!IsSubset(Aspect::Depth,
descriptor->depthStencilAttachment->view->GetAspects())) {
cmd->depthStencilAttachment.depthLoadOp = wgpu::LoadOp::Load; cmd->depthStencilAttachment.depthLoadOp = wgpu::LoadOp::Load;
cmd->depthStencilAttachment.depthStoreOp = wgpu::StoreOp::Store; cmd->depthStencilAttachment.depthStoreOp = wgpu::StoreOp::Store;
} else { } else {
@ -833,7 +869,9 @@ namespace dawn::native {
descriptor->depthStencilAttachment->depthStoreOp; descriptor->depthStencilAttachment->depthStoreOp;
} }
if (descriptor->depthStencilAttachment->stencilReadOnly) { if (descriptor->depthStencilAttachment->stencilReadOnly ||
!IsSubset(Aspect::Stencil,
descriptor->depthStencilAttachment->view->GetAspects())) {
cmd->depthStencilAttachment.stencilLoadOp = wgpu::LoadOp::Load; cmd->depthStencilAttachment.stencilLoadOp = wgpu::LoadOp::Load;
cmd->depthStencilAttachment.stencilStoreOp = wgpu::StoreOp::Store; cmd->depthStencilAttachment.stencilStoreOp = wgpu::StoreOp::Store;
} else { } else {

View File

@ -1399,6 +1399,20 @@ std::ostringstream& DawnTestBase::ExpectAttachmentDepthStencilTestData(
texture.CreateView(&viewDesc)); texture.CreateView(&viewDesc));
passDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Load; passDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Load;
passDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Load; passDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Load;
switch (format) {
case wgpu::TextureFormat::Depth24Plus:
case wgpu::TextureFormat::Depth32Float:
case wgpu::TextureFormat::Depth16Unorm:
passDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Undefined;
passDescriptor.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Undefined;
break;
case wgpu::TextureFormat::Stencil8:
passDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Undefined;
passDescriptor.cDepthStencilAttachmentInfo.depthStoreOp = wgpu::StoreOp::Undefined;
break;
default:
break;
}
wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&pipelineDescriptor); wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&pipelineDescriptor);

View File

@ -1039,6 +1039,7 @@ TEST_P(CopyTests_T2B, CopyOneRowWithDepth32Float) {
// Initialize the depth texture with 0.5f. // Initialize the depth texture with 0.5f.
constexpr float kClearDepthValue = 0.5f; constexpr float kClearDepthValue = 0.5f;
utils::ComboRenderPassDescriptor renderPass({}, texture.CreateView()); utils::ComboRenderPassDescriptor renderPass({}, texture.CreateView());
renderPass.UnsetDepthStencilLoadStoreOpsForFormat(kFormat);
renderPass.cDepthStencilAttachmentInfo.depthClearValue = kClearDepthValue; renderPass.cDepthStencilAttachmentInfo.depthClearValue = kClearDepthValue;
renderPass.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Clear; renderPass.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Clear;
renderPass.cDepthStencilAttachmentInfo.depthStoreOp = wgpu::StoreOp::Store; renderPass.cDepthStencilAttachmentInfo.depthStoreOp = wgpu::StoreOp::Store;

View File

@ -92,6 +92,7 @@ class DepthBiasTests : public DawnTest {
// Create a render pass which clears depth to depthClear // Create a render pass which clears depth to depthClear
utils::ComboRenderPassDescriptor renderPassDesc({mRenderTarget.CreateView()}, utils::ComboRenderPassDescriptor renderPassDesc({mRenderTarget.CreateView()},
mDepthTexture.CreateView()); mDepthTexture.CreateView());
renderPassDesc.UnsetDepthStencilLoadStoreOpsForFormat(depthFormat);
renderPassDesc.cDepthStencilAttachmentInfo.depthClearValue = depthClear; renderPassDesc.cDepthStencilAttachmentInfo.depthClearValue = depthClear;
// Create a render pipeline to render the quad // Create a render pipeline to render the quad

View File

@ -142,6 +142,7 @@ class DepthStencilCopyTests : public DawnTestWithParams<DepthStencilCopyTestPara
// The texture will be cleared to the "clear" value, and then bottom left corner will // The texture will be cleared to the "clear" value, and then bottom left corner will
// be written with the "region" value. // be written with the "region" value.
void InitializeDepthTextureRegion(wgpu::Texture texture, void InitializeDepthTextureRegion(wgpu::Texture texture,
wgpu::TextureFormat depthFormat,
float clearDepth, float clearDepth,
float regionDepth, float regionDepth,
uint32_t mipLevel = 0) { uint32_t mipLevel = 0) {
@ -150,6 +151,7 @@ class DepthStencilCopyTests : public DawnTestWithParams<DepthStencilCopyTestPara
viewDesc.mipLevelCount = 1; viewDesc.mipLevelCount = 1;
utils::ComboRenderPassDescriptor renderPassDesc({}, texture.CreateView(&viewDesc)); utils::ComboRenderPassDescriptor renderPassDesc({}, texture.CreateView(&viewDesc));
renderPassDesc.UnsetDepthStencilLoadStoreOpsForFormat(depthFormat);
renderPassDesc.cDepthStencilAttachmentInfo.depthClearValue = clearDepth; renderPassDesc.cDepthStencilAttachmentInfo.depthClearValue = clearDepth;
utils::ComboRenderPipelineDescriptor renderPipelineDesc; utils::ComboRenderPipelineDescriptor renderPipelineDesc;
@ -455,7 +457,7 @@ TEST_P(DepthCopyTests, FromDepthAspect) {
kWidth, kHeight, wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc); kWidth, kHeight, wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc);
constexpr float kInitDepth = 0.2f; constexpr float kInitDepth = 0.2f;
InitializeDepthTextureRegion(texture, 0.f, kInitDepth); InitializeDepthTextureRegion(texture, GetParam().mTextureFormat, 0.f, kInitDepth);
// This expectation is the test as it performs the CopyTextureToBuffer. // This expectation is the test as it performs the CopyTextureToBuffer.
if (GetParam().mTextureFormat == wgpu::TextureFormat::Depth16Unorm) { if (GetParam().mTextureFormat == wgpu::TextureFormat::Depth16Unorm) {
@ -495,7 +497,7 @@ TEST_P(DepthCopyTests, FromNonZeroMipDepthAspect) {
9, 9, wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc, 2); 9, 9, wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc, 2);
constexpr float kInitDepth = 0.4f; constexpr float kInitDepth = 0.4f;
InitializeDepthTextureRegion(depthTexture, 0.f, kInitDepth, 1); InitializeDepthTextureRegion(depthTexture, GetParam().mTextureFormat, 0.f, kInitDepth, 1);
// This expectation is the test as it performs the CopyTextureToBuffer. // This expectation is the test as it performs the CopyTextureToBuffer.
if (GetParam().mTextureFormat == wgpu::TextureFormat::Depth16Unorm) { if (GetParam().mTextureFormat == wgpu::TextureFormat::Depth16Unorm) {

View File

@ -85,6 +85,7 @@ namespace {
textureViews[mipLevel] = texture.CreateView(&textureViewDesc); textureViews[mipLevel] = texture.CreateView(&textureViewDesc);
utils::ComboRenderPassDescriptor renderPassDescriptor({}, textureViews[mipLevel]); utils::ComboRenderPassDescriptor renderPassDescriptor({}, textureViews[mipLevel]);
renderPassDescriptor.UnsetDepthStencilLoadStoreOpsForFormat(GetParam().mFormat);
renderPassDescriptor.cDepthStencilAttachmentInfo.depthClearValue = renderPassDescriptor.cDepthStencilAttachmentInfo.depthClearValue =
kDepthValues[mipLevel]; kDepthValues[mipLevel];
renderPassDescriptor.cDepthStencilAttachmentInfo.stencilClearValue = renderPassDescriptor.cDepthStencilAttachmentInfo.stencilClearValue =

View File

@ -264,8 +264,10 @@ class DepthStencilSamplingTest : public DawnTestWithParams<DepthStencilSamplingT
void UpdateInputDepth(wgpu::CommandEncoder commandEncoder, void UpdateInputDepth(wgpu::CommandEncoder commandEncoder,
wgpu::Texture texture, wgpu::Texture texture,
wgpu::TextureFormat format,
float depthValue) { float depthValue) {
utils::ComboRenderPassDescriptor passDescriptor({}, texture.CreateView()); utils::ComboRenderPassDescriptor passDescriptor({}, texture.CreateView());
passDescriptor.UnsetDepthStencilLoadStoreOpsForFormat(format);
passDescriptor.cDepthStencilAttachmentInfo.depthClearValue = depthValue; passDescriptor.cDepthStencilAttachmentInfo.depthClearValue = depthValue;
wgpu::RenderPassEncoder pass = commandEncoder.BeginRenderPass(&passDescriptor); wgpu::RenderPassEncoder pass = commandEncoder.BeginRenderPass(&passDescriptor);
@ -274,8 +276,10 @@ class DepthStencilSamplingTest : public DawnTestWithParams<DepthStencilSamplingT
void UpdateInputStencil(wgpu::CommandEncoder commandEncoder, void UpdateInputStencil(wgpu::CommandEncoder commandEncoder,
wgpu::Texture texture, wgpu::Texture texture,
wgpu::TextureFormat format,
uint8_t stencilValue) { uint8_t stencilValue) {
utils::ComboRenderPassDescriptor passDescriptor({}, texture.CreateView()); utils::ComboRenderPassDescriptor passDescriptor({}, texture.CreateView());
passDescriptor.UnsetDepthStencilLoadStoreOpsForFormat(format);
passDescriptor.cDepthStencilAttachmentInfo.stencilClearValue = stencilValue; passDescriptor.cDepthStencilAttachmentInfo.stencilClearValue = stencilValue;
wgpu::RenderPassEncoder pass = commandEncoder.BeginRenderPass(&passDescriptor); wgpu::RenderPassEncoder pass = commandEncoder.BeginRenderPass(&passDescriptor);
@ -311,10 +315,10 @@ class DepthStencilSamplingTest : public DawnTestWithParams<DepthStencilSamplingT
wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder(); wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
switch (aspect) { switch (aspect) {
case TestAspect::Depth: case TestAspect::Depth:
UpdateInputDepth(commandEncoder, inputTexture, textureValues[i]); UpdateInputDepth(commandEncoder, inputTexture, format, textureValues[i]);
break; break;
case TestAspect::Stencil: case TestAspect::Stencil:
UpdateInputStencil(commandEncoder, inputTexture, textureValues[i]); UpdateInputStencil(commandEncoder, inputTexture, format, textureValues[i]);
break; break;
} }
@ -366,10 +370,10 @@ class DepthStencilSamplingTest : public DawnTestWithParams<DepthStencilSamplingT
wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder(); wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
switch (aspect) { switch (aspect) {
case TestAspect::Depth: case TestAspect::Depth:
UpdateInputDepth(commandEncoder, inputTexture, textureValues[i]); UpdateInputDepth(commandEncoder, inputTexture, format, textureValues[i]);
break; break;
case TestAspect::Stencil: case TestAspect::Stencil:
UpdateInputStencil(commandEncoder, inputTexture, textureValues[i]); UpdateInputStencil(commandEncoder, inputTexture, format, textureValues[i]);
break; break;
} }
@ -522,7 +526,7 @@ class DepthStencilSamplingTest : public DawnTestWithParams<DepthStencilSamplingT
for (float textureValue : textureValues) { for (float textureValue : textureValues) {
// Set the input depth texture to the provided texture value // Set the input depth texture to the provided texture value
wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder(); wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
UpdateInputDepth(commandEncoder, inputTexture, textureValue); UpdateInputDepth(commandEncoder, inputTexture, format, textureValue);
// Render into the output texture // Render into the output texture
{ {
@ -569,7 +573,7 @@ class DepthStencilSamplingTest : public DawnTestWithParams<DepthStencilSamplingT
for (float textureValue : textureValues) { for (float textureValue : textureValues) {
// Set the input depth texture to the provided texture value // Set the input depth texture to the provided texture value
wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder(); wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
UpdateInputDepth(commandEncoder, inputTexture, textureValue); UpdateInputDepth(commandEncoder, inputTexture, format, textureValue);
// Sample into the output buffer // Sample into the output buffer
{ {

View File

@ -199,6 +199,8 @@ TEST_P(MultisampledSamplingTest, SamplePositions) {
utils::ComboRenderPassDescriptor renderPass({colorView}, depthView); utils::ComboRenderPassDescriptor renderPass({colorView}, depthView);
renderPass.cDepthStencilAttachmentInfo.depthClearValue = 0.f; renderPass.cDepthStencilAttachmentInfo.depthClearValue = 0.f;
renderPass.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Undefined;
renderPass.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Undefined;
wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&renderPass); wgpu::RenderPassEncoder renderPassEncoder = commandEncoder.BeginRenderPass(&renderPass);
renderPassEncoder.SetPipeline(drawPipeline); renderPassEncoder.SetPipeline(drawPipeline);

View File

@ -149,6 +149,7 @@ class ReadOnlyDepthStencilAttachmentTests
// Note that we must encompass all aspects for texture view used in attachment. // Note that we must encompass all aspects for texture view used in attachment.
wgpu::TextureView depthStencilViewInAttachment = depthStencilTexture.CreateView(); wgpu::TextureView depthStencilViewInAttachment = depthStencilTexture.CreateView();
utils::ComboRenderPassDescriptor passDescriptorInit({}, depthStencilViewInAttachment); utils::ComboRenderPassDescriptor passDescriptorInit({}, depthStencilViewInAttachment);
passDescriptorInit.UnsetDepthStencilLoadStoreOpsForFormat(format);
if (aspect == wgpu::TextureAspect::DepthOnly) { if (aspect == wgpu::TextureAspect::DepthOnly) {
passDescriptorInit.cDepthStencilAttachmentInfo.depthClearValue = values->depthInitValue; passDescriptorInit.cDepthStencilAttachmentInfo.depthClearValue = values->depthInitValue;
} else { } else {

View File

@ -56,11 +56,13 @@ class SubresourceRenderAttachmentTest : public DawnTest {
} }
case Type::Depth: { case Type::Depth: {
utils::ComboRenderPassDescriptor renderPass({}, renderTargetView); utils::ComboRenderPassDescriptor renderPass({}, renderTargetView);
renderPass.UnsetDepthStencilLoadStoreOpsForFormat(format);
renderPass.cDepthStencilAttachmentInfo.depthClearValue = expectedDepth; renderPass.cDepthStencilAttachmentInfo.depthClearValue = expectedDepth;
return renderPass; return renderPass;
} }
case Type::Stencil: { case Type::Stencil: {
utils::ComboRenderPassDescriptor renderPass({}, renderTargetView); utils::ComboRenderPassDescriptor renderPass({}, renderTargetView);
renderPass.UnsetDepthStencilLoadStoreOpsForFormat(format);
renderPass.cDepthStencilAttachmentInfo.stencilClearValue = expectedStencil; renderPass.cDepthStencilAttachmentInfo.stencilClearValue = expectedStencil;
return renderPass; return renderPass;
} }

View File

@ -119,6 +119,8 @@ class ViewportTest : public DawnTest {
utils::ComboRenderPassDescriptor rpDesc({}, depthTexture.CreateView()); utils::ComboRenderPassDescriptor rpDesc({}, depthTexture.CreateView());
rpDesc.cDepthStencilAttachmentInfo.depthClearValue = 0.0f; rpDesc.cDepthStencilAttachmentInfo.depthClearValue = 0.0f;
rpDesc.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Clear; rpDesc.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Clear;
rpDesc.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Undefined;
rpDesc.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Undefined;
wgpu::CommandEncoder encoder = device.CreateCommandEncoder(); wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&rpDesc); wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&rpDesc);
pass.SetPipeline(pipeline); pass.SetPipeline(pipeline);

View File

@ -1033,6 +1033,8 @@ TEST_F(RenderBundleValidationTest, RenderPassDepthStencilFormatMismatch) {
// Test the success case // Test the success case
{ {
utils::ComboRenderPassDescriptor renderPass({tex0.CreateView()}, tex1.CreateView()); utils::ComboRenderPassDescriptor renderPass({tex0.CreateView()}, tex1.CreateView());
renderPass.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Undefined;
renderPass.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Undefined;
wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder(); wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
wgpu::RenderPassEncoder pass = commandEncoder.BeginRenderPass(&renderPass); wgpu::RenderPassEncoder pass = commandEncoder.BeginRenderPass(&renderPass);
@ -1044,6 +1046,8 @@ TEST_F(RenderBundleValidationTest, RenderPassDepthStencilFormatMismatch) {
// Test the failure case for mismatched format // Test the failure case for mismatched format
{ {
utils::ComboRenderPassDescriptor renderPass({tex0.CreateView()}, tex2.CreateView()); utils::ComboRenderPassDescriptor renderPass({tex0.CreateView()}, tex2.CreateView());
renderPass.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Undefined;
renderPass.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Undefined;
wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder(); wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder();
wgpu::RenderPassEncoder pass = commandEncoder.BeginRenderPass(&renderPass); wgpu::RenderPassEncoder pass = commandEncoder.BeginRenderPass(&renderPass);

View File

@ -414,6 +414,9 @@ namespace {
wgpu::TextureView renderView = wgpu::TextureView renderView =
Create2DAttachment(device, 1, 1, wgpu::TextureFormat::Depth32Float); Create2DAttachment(device, 1, 1, wgpu::TextureFormat::Depth32Float);
utils::ComboRenderPassDescriptor renderPass({}, renderView); utils::ComboRenderPassDescriptor renderPass({}, renderView);
renderPass.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Undefined;
renderPass.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Undefined;
AssertBeginRenderPassSuccess(&renderPass); AssertBeginRenderPassSuccess(&renderPass);
} }
@ -427,6 +430,9 @@ namespace {
wgpu::TextureView sampledView = sampledTex.CreateView(); wgpu::TextureView sampledView = sampledTex.CreateView();
utils::ComboRenderPassDescriptor renderPass({}, sampledView); utils::ComboRenderPassDescriptor renderPass({}, sampledView);
renderPass.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Undefined;
renderPass.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Undefined;
AssertBeginRenderPassError(&renderPass); AssertBeginRenderPassError(&renderPass);
} }
} }
@ -861,6 +867,8 @@ namespace {
wgpu::TextureView depth = wgpu::TextureView depth =
Create2DAttachment(device, 1, 1, wgpu::TextureFormat::Depth24Plus); Create2DAttachment(device, 1, 1, wgpu::TextureFormat::Depth24Plus);
utils::ComboRenderPassDescriptor renderPass({color}, depth); utils::ComboRenderPassDescriptor renderPass({color}, depth);
renderPass.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Undefined;
renderPass.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Undefined;
renderPass.cDepthStencilAttachmentInfo.depthClearValue = NAN; renderPass.cDepthStencilAttachmentInfo.depthClearValue = NAN;
AssertBeginRenderPassError(&renderPass); AssertBeginRenderPassError(&renderPass);
} }
@ -870,6 +878,8 @@ namespace {
wgpu::TextureView depth = wgpu::TextureView depth =
Create2DAttachment(device, 1, 1, wgpu::TextureFormat::Depth24Plus); Create2DAttachment(device, 1, 1, wgpu::TextureFormat::Depth24Plus);
utils::ComboRenderPassDescriptor renderPass({color}, depth); utils::ComboRenderPassDescriptor renderPass({color}, depth);
renderPass.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Undefined;
renderPass.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Undefined;
renderPass.cDepthStencilAttachmentInfo.depthClearValue = INFINITY; renderPass.cDepthStencilAttachmentInfo.depthClearValue = INFINITY;
AssertBeginRenderPassSuccess(&renderPass); AssertBeginRenderPassSuccess(&renderPass);
} }
@ -899,7 +909,7 @@ namespace {
} }
// Tests that a pass with mismatched depthReadOnly and stencilReadOnly values passes when // Tests that a pass with mismatched depthReadOnly and stencilReadOnly values passes when
// there is no stencil component in the format. // there is no stencil component in the format (deprecated).
{ {
utils::ComboRenderPassDescriptor renderPass({colorView}, depthStencilViewNoStencil); utils::ComboRenderPassDescriptor renderPass({colorView}, depthStencilViewNoStencil);
renderPass.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Undefined; renderPass.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Undefined;
@ -908,7 +918,29 @@ namespace {
renderPass.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Load; renderPass.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Load;
renderPass.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Store; renderPass.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Store;
renderPass.cDepthStencilAttachmentInfo.stencilReadOnly = false; renderPass.cDepthStencilAttachmentInfo.stencilReadOnly = false;
AssertBeginRenderPassSuccess(&renderPass); EXPECT_DEPRECATION_WARNING(AssertBeginRenderPassSuccess(&renderPass));
}
// Tests that a pass with mismatched depthReadOnly and stencilReadOnly values fails when
// there there is no stencil component in the format and stencil loadOp/storeOp are passed.
{
utils::ComboRenderPassDescriptor renderPass({colorView}, depthStencilViewNoStencil);
renderPass.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Undefined;
renderPass.cDepthStencilAttachmentInfo.depthStoreOp = wgpu::StoreOp::Undefined;
renderPass.cDepthStencilAttachmentInfo.depthReadOnly = true;
renderPass.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Clear;
renderPass.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Store;
renderPass.cDepthStencilAttachmentInfo.stencilReadOnly = false;
AssertBeginRenderPassError(&renderPass);
renderPass.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Undefined;
renderPass.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Store;
AssertBeginRenderPassError(&renderPass);
renderPass.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Clear;
renderPass.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Undefined;
renderPass.cDepthStencilAttachmentInfo.stencilReadOnly = false;
AssertBeginRenderPassError(&renderPass);
} }
// Tests that a pass with depthReadOnly=true and stencilReadOnly=true can pass // Tests that a pass with depthReadOnly=true and stencilReadOnly=true can pass
@ -1077,6 +1109,9 @@ namespace {
wgpu::TextureView view = device.CreateTexture(&texDesc).CreateView(&viewDesc); wgpu::TextureView view = device.CreateTexture(&texDesc).CreateView(&viewDesc);
utils::ComboRenderPassDescriptor renderPass({}, view); utils::ComboRenderPassDescriptor renderPass({}, view);
renderPass.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Undefined;
renderPass.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Undefined;
AssertBeginRenderPassSuccess(&renderPass); AssertBeginRenderPassSuccess(&renderPass);
} }

View File

@ -902,6 +902,8 @@ namespace {
utils::ComboRenderPassDescriptor passDescriptor({}, view); utils::ComboRenderPassDescriptor passDescriptor({}, view);
passDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Load; passDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Load;
passDescriptor.cDepthStencilAttachmentInfo.depthStoreOp = wgpu::StoreOp::Store; passDescriptor.cDepthStencilAttachmentInfo.depthStoreOp = wgpu::StoreOp::Store;
passDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Undefined;
passDescriptor.cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Undefined;
// It is invalid to use the texture as both sampled and writeable depth/stencil attachment // It is invalid to use the texture as both sampled and writeable depth/stencil attachment
// in the same pass // in the same pass

View File

@ -138,6 +138,23 @@ namespace utils {
return *this; return *this;
} }
void ComboRenderPassDescriptor::UnsetDepthStencilLoadStoreOpsForFormat(
wgpu::TextureFormat format) {
switch (format) {
case wgpu::TextureFormat::Depth24Plus:
case wgpu::TextureFormat::Depth32Float:
case wgpu::TextureFormat::Depth16Unorm:
cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Undefined;
cDepthStencilAttachmentInfo.stencilStoreOp = wgpu::StoreOp::Undefined;
break;
case wgpu::TextureFormat::Stencil8:
cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Undefined;
cDepthStencilAttachmentInfo.depthStoreOp = wgpu::StoreOp::Undefined;
break;
default:
break;
}
}
BasicRenderPass::BasicRenderPass() BasicRenderPass::BasicRenderPass()
: width(0), : width(0),

View File

@ -66,6 +66,8 @@ namespace utils {
const ComboRenderPassDescriptor& operator=( const ComboRenderPassDescriptor& operator=(
const ComboRenderPassDescriptor& otherRenderPass); const ComboRenderPassDescriptor& otherRenderPass);
void UnsetDepthStencilLoadStoreOpsForFormat(wgpu::TextureFormat format);
std::array<wgpu::RenderPassColorAttachment, kMaxColorAttachments> cColorAttachments; std::array<wgpu::RenderPassColorAttachment, kMaxColorAttachments> cColorAttachments;
wgpu::RenderPassDepthStencilAttachment cDepthStencilAttachmentInfo = {}; wgpu::RenderPassDepthStencilAttachment cDepthStencilAttachmentInfo = {};
}; };