Test that sampled textures in compute and render pass get lazy cleared

Bug: dawn:145
Change-Id: I719faf0a07a2011be0cdee3a7bead2437f524ba7
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/8660
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Natasha Lee <natlee@microsoft.com>
This commit is contained in:
Natasha Lee 2019-07-23 20:30:24 +00:00 committed by Commit Bot service account
parent 68d97adf88
commit 8944f0205b
1 changed files with 140 additions and 4 deletions

View File

@ -412,10 +412,9 @@ TEST_P(TextureZeroInitTest, ColorAttachmentsClear) {
renderPass.renderPassInfo.cColorAttachmentsInfoPtr[0]->loadOp = dawn::LoadOp::Load; renderPass.renderPassInfo.cColorAttachmentsInfoPtr[0]->loadOp = dawn::LoadOp::Load;
dawn::CommandEncoder encoder = device.CreateCommandEncoder(); dawn::CommandEncoder encoder = device.CreateCommandEncoder();
{ dawn::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
dawn::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo); pass.EndPass();
pass.EndPass();
}
dawn::CommandBuffer commands = encoder.Finish(); dawn::CommandBuffer commands = encoder.Finish();
queue.Submit(1, &commands); queue.Submit(1, &commands);
@ -423,6 +422,143 @@ TEST_P(TextureZeroInitTest, ColorAttachmentsClear) {
EXPECT_TEXTURE_RGBA8_EQ(expected.data(), renderPass.color, 0, 0, kSize, kSize, 0, 0); EXPECT_TEXTURE_RGBA8_EQ(expected.data(), renderPass.color, 0, 0, kSize, kSize, 0, 0);
} }
// This tests the clearing of sampled textures in render pass
TEST_P(TextureZeroInitTest, RenderPassSampledTextureClear) {
// Create needed resources
dawn::TextureDescriptor descriptor =
CreateTextureDescriptor(1, 1, dawn::TextureUsageBit::Sampled, kColorFormat);
dawn::Texture texture = device.CreateTexture(&descriptor);
dawn::TextureDescriptor renderTextureDescriptor = CreateTextureDescriptor(
1, 1, dawn::TextureUsageBit::CopySrc | dawn::TextureUsageBit::OutputAttachment,
kColorFormat);
dawn::Texture renderTexture = device.CreateTexture(&renderTextureDescriptor);
dawn::SamplerDescriptor samplerDesc = utils::GetDefaultSamplerDescriptor();
dawn::Sampler sampler = device.CreateSampler(&samplerDesc);
dawn::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
device, {{0, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler},
{1, dawn::ShaderStageBit::Fragment, dawn::BindingType::SampledTexture}});
// Create render pipeline
utils::ComboRenderPipelineDescriptor renderPipelineDescriptor(device);
renderPipelineDescriptor.layout = utils::MakeBasicPipelineLayout(device, &bindGroupLayout);
renderPipelineDescriptor.cVertexStage.module =
utils::CreateShaderModule(device, utils::ShaderStage::Vertex, R"(#version 450
const vec2 pos[6] = vec2[6](vec2(-1.0f, -1.0f),
vec2(-1.0f, 1.0f),
vec2( 1.0f, -1.0f),
vec2( 1.0f, 1.0f),
vec2(-1.0f, 1.0f),
vec2( 1.0f, -1.0f)
);
void main() {
gl_Position = vec4(pos[gl_VertexIndex], 0.0, 1.0);
})");
renderPipelineDescriptor.cFragmentStage.module =
utils::CreateShaderModule(device, utils::ShaderStage::Fragment,
R"(#version 450
layout(set = 0, binding = 0) uniform sampler sampler0;
layout(set = 0, binding = 1) uniform texture2D texture0;
layout(location = 0) out vec4 fragColor;
void main() {
fragColor = texelFetch(sampler2D(texture0, sampler0), ivec2(gl_FragCoord), 0);
})");
renderPipelineDescriptor.cColorStates[0]->format = kColorFormat;
dawn::RenderPipeline renderPipeline = device.CreateRenderPipeline(&renderPipelineDescriptor);
// Create bindgroup
dawn::BindGroup bindGroup = utils::MakeBindGroup(
device, bindGroupLayout, {{0, sampler}, {1, texture.CreateDefaultView()}});
// Encode pass and submit
dawn::CommandEncoder encoder = device.CreateCommandEncoder();
utils::ComboRenderPassDescriptor renderPassDesc({renderTexture.CreateDefaultView()});
renderPassDesc.cColorAttachmentsInfoPtr[0]->clearColor = {1.0, 1.0, 1.0, 1.0};
renderPassDesc.cColorAttachmentsInfoPtr[0]->loadOp = dawn::LoadOp::Clear;
dawn::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPassDesc);
pass.SetPipeline(renderPipeline);
pass.SetBindGroup(0, bindGroup, 0, nullptr);
pass.Draw(6, 1, 0, 0);
pass.EndPass();
dawn::CommandBuffer commands = encoder.Finish();
queue.Submit(1, &commands);
// Expect the rendered texture to be cleared
std::vector<RGBA8> expectedWithZeros(kSize * kSize, {0, 0, 0, 0});
EXPECT_TEXTURE_RGBA8_EQ(expectedWithZeros.data(), renderTexture, 0, 0, kSize, kSize, 0, 0);
}
// This tests the clearing of sampled textures during compute pass
TEST_P(TextureZeroInitTest, ComputePassSampledTextureClear) {
// Create needed resources
dawn::TextureDescriptor descriptor =
CreateTextureDescriptor(1, 1, dawn::TextureUsageBit::Sampled, kColorFormat);
descriptor.size.width = 1;
descriptor.size.height = 1;
dawn::Texture texture = device.CreateTexture(&descriptor);
uint32_t bufferSize = 4 * sizeof(uint32_t);
dawn::BufferDescriptor bufferDescriptor;
bufferDescriptor.size = bufferSize;
bufferDescriptor.usage = dawn::BufferUsageBit::CopySrc | dawn::BufferUsageBit::Storage |
dawn::BufferUsageBit::CopyDst;
dawn::Buffer bufferTex = device.CreateBuffer(&bufferDescriptor);
// Add data to buffer to ensure it is initialized
uint32_t data = 100;
bufferTex.SetSubData(0, sizeof(data), &data);
dawn::SamplerDescriptor samplerDesc = utils::GetDefaultSamplerDescriptor();
dawn::Sampler sampler = device.CreateSampler(&samplerDesc);
dawn::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
device, {{0, dawn::ShaderStageBit::Compute, dawn::BindingType::SampledTexture},
{1, dawn::ShaderStageBit::Compute, dawn::BindingType::StorageBuffer},
{2, dawn::ShaderStageBit::Compute, dawn::BindingType::Sampler}});
// Create compute pipeline
dawn::ComputePipelineDescriptor computePipelineDescriptor;
computePipelineDescriptor.layout = utils::MakeBasicPipelineLayout(device, &bindGroupLayout);
dawn::PipelineStageDescriptor computeStage;
const char* cs =
R"(#version 450
layout(binding = 0) uniform texture2D sampleTex;
layout(std430, binding = 1) buffer BufferTex {
vec4 result;
} bufferTex;
layout(binding = 2) uniform sampler sampler0;
void main() {
bufferTex.result =
texelFetch(sampler2D(sampleTex, sampler0), ivec2(0,0), 0);
})";
computeStage.module = utils::CreateShaderModule(device, utils::ShaderStage::Compute, cs);
computeStage.entryPoint = "main";
computePipelineDescriptor.computeStage = &computeStage;
dawn::ComputePipeline computePipeline =
device.CreateComputePipeline(&computePipelineDescriptor);
// Create bindgroup
dawn::BindGroup bindGroup = utils::MakeBindGroup(
device, bindGroupLayout,
{{0, texture.CreateDefaultView()}, {1, bufferTex, 0, bufferSize}, {2, sampler}});
// Encode the pass and submit
dawn::CommandEncoder encoder = device.CreateCommandEncoder();
dawn::ComputePassEncoder pass = encoder.BeginComputePass();
pass.SetPipeline(computePipeline);
pass.SetBindGroup(0, bindGroup, 0, nullptr);
pass.Dispatch(1, 1, 1);
pass.EndPass();
dawn::CommandBuffer commands = encoder.Finish();
queue.Submit(1, &commands);
// Expect the buffer to be zeroed out by the compute pass
std::vector<uint32_t> expectedWithZeros(bufferSize, 0);
EXPECT_BUFFER_U32_RANGE_EQ(expectedWithZeros.data(), bufferTex, 0, 4);
}
DAWN_INSTANTIATE_TEST( DAWN_INSTANTIATE_TEST(
TextureZeroInitTest, TextureZeroInitTest,
ForceWorkarounds(D3D12Backend, {"nonzero_clear_resources_on_creation_for_testing"}), ForceWorkarounds(D3D12Backend, {"nonzero_clear_resources_on_creation_for_testing"}),