Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 1 | // Copyright 2020 The Dawn Authors |
| 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
| 14 | |
| 15 | #include "tests/DawnTest.h" |
| 16 | |
| 17 | #include <array> |
| 18 | #include "common/Constants.h" |
| 19 | #include "common/Math.h" |
| 20 | #include "utils/ComboRenderPipelineDescriptor.h" |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 21 | #include "utils/TestUtils.h" |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 22 | #include "utils/TextureFormatUtils.h" |
| 23 | #include "utils/WGPUHelpers.h" |
| 24 | |
| 25 | class DepthStencilCopyTests : public DawnTest { |
| 26 | protected: |
| 27 | void SetUp() override { |
| 28 | DawnTest::SetUp(); |
| 29 | |
| 30 | // Draw a square in the bottom left quarter of the screen. |
Corentin Wallez | 7aec4ae | 2021-03-24 15:55:32 +0000 | [diff] [blame] | 31 | mVertexModule = utils::CreateShaderModule(device, R"( |
Brandon Jones | e87ea2b | 2021-04-14 17:05:07 +0000 | [diff] [blame] | 32 | [[stage(vertex)]] |
| 33 | fn main([[builtin(vertex_index)]] VertexIndex : u32) -> [[builtin(position)]] vec4<f32> { |
| 34 | let pos : array<vec2<f32>, 6> = array<vec2<f32>, 6>( |
Austin Eng | 84e1dca | 2020-11-30 20:33:50 +0000 | [diff] [blame] | 35 | vec2<f32>(-1.0, -1.0), |
| 36 | vec2<f32>( 0.0, -1.0), |
| 37 | vec2<f32>(-1.0, 0.0), |
| 38 | vec2<f32>(-1.0, 0.0), |
| 39 | vec2<f32>( 0.0, -1.0), |
| 40 | vec2<f32>( 0.0, 0.0)); |
Brandon Jones | e87ea2b | 2021-04-14 17:05:07 +0000 | [diff] [blame] | 41 | return vec4<f32>(pos[VertexIndex], 0.0, 1.0); |
Austin Eng | 84e1dca | 2020-11-30 20:33:50 +0000 | [diff] [blame] | 42 | })"); |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 43 | } |
| 44 | |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 45 | wgpu::Texture CreateDepthStencilTexture(uint32_t width, |
| 46 | uint32_t height, |
| 47 | wgpu::TextureUsage usage, |
| 48 | uint32_t mipLevelCount = 1) { |
| 49 | wgpu::TextureDescriptor texDescriptor = {}; |
| 50 | texDescriptor.size = {width, height, 1}; |
| 51 | texDescriptor.format = wgpu::TextureFormat::Depth24PlusStencil8; |
| 52 | texDescriptor.usage = usage; |
| 53 | texDescriptor.mipLevelCount = mipLevelCount; |
| 54 | return device.CreateTexture(&texDescriptor); |
| 55 | } |
| 56 | |
| 57 | wgpu::Texture CreateDepthTexture(uint32_t width, |
| 58 | uint32_t height, |
| 59 | wgpu::TextureUsage usage, |
| 60 | uint32_t mipLevelCount = 1) { |
| 61 | wgpu::TextureDescriptor texDescriptor = {}; |
| 62 | texDescriptor.size = {width, height, 1}; |
| 63 | texDescriptor.format = wgpu::TextureFormat::Depth32Float; |
| 64 | texDescriptor.usage = usage; |
| 65 | texDescriptor.mipLevelCount = mipLevelCount; |
| 66 | return device.CreateTexture(&texDescriptor); |
| 67 | } |
| 68 | |
Brandon Jones | bff9d3a | 2021-03-18 02:54:27 +0000 | [diff] [blame] | 69 | void PopulatePipelineDescriptorWriteDepth(utils::ComboRenderPipelineDescriptor2* desc, |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 70 | wgpu::TextureFormat format, |
| 71 | float regionDepth) { |
Brandon Jones | bff9d3a | 2021-03-18 02:54:27 +0000 | [diff] [blame] | 72 | desc->vertex.module = mVertexModule; |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 73 | |
| 74 | std::string fsSource = R"( |
Brandon Jones | e87ea2b | 2021-04-14 17:05:07 +0000 | [diff] [blame] | 75 | [[stage(fragment)]] fn main() -> [[builtin(frag_depth)]] f32 { |
| 76 | return )" + std::to_string(regionDepth) + |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 77 | ";\n}"; |
| 78 | |
Corentin Wallez | 7aec4ae | 2021-03-24 15:55:32 +0000 | [diff] [blame] | 79 | desc->cFragment.module = utils::CreateShaderModule(device, fsSource.c_str()); |
Brandon Jones | bff9d3a | 2021-03-18 02:54:27 +0000 | [diff] [blame] | 80 | wgpu::DepthStencilState* depthStencil = desc->EnableDepthStencil(format); |
| 81 | depthStencil->depthWriteEnabled = true; |
| 82 | desc->cFragment.targetCount = 0; |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 83 | } |
| 84 | |
| 85 | // Initialize the depth/stencil values for the texture using a render pass. |
| 86 | // The texture will be cleared to the "clear" value, and then bottom left corner will |
| 87 | // be written with the "region" value. |
| 88 | void InitializeDepthTextureRegion(wgpu::Texture texture, |
| 89 | float clearDepth, |
| 90 | float regionDepth, |
| 91 | uint32_t mipLevel = 0) { |
| 92 | wgpu::TextureViewDescriptor viewDesc = {}; |
| 93 | viewDesc.baseMipLevel = mipLevel; |
| 94 | viewDesc.mipLevelCount = 1; |
| 95 | |
| 96 | utils::ComboRenderPassDescriptor renderPassDesc({}, texture.CreateView(&viewDesc)); |
| 97 | renderPassDesc.cDepthStencilAttachmentInfo.clearDepth = clearDepth; |
| 98 | |
Brandon Jones | bff9d3a | 2021-03-18 02:54:27 +0000 | [diff] [blame] | 99 | utils::ComboRenderPipelineDescriptor2 renderPipelineDesc; |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 100 | PopulatePipelineDescriptorWriteDepth(&renderPipelineDesc, wgpu::TextureFormat::Depth32Float, |
| 101 | regionDepth); |
| 102 | |
Brandon Jones | bff9d3a | 2021-03-18 02:54:27 +0000 | [diff] [blame] | 103 | wgpu::RenderPipeline pipeline = device.CreateRenderPipeline2(&renderPipelineDesc); |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 104 | wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder(); |
| 105 | wgpu::RenderPassEncoder pass = commandEncoder.BeginRenderPass(&renderPassDesc); |
| 106 | pass.SetPipeline(pipeline); |
| 107 | pass.Draw(6); |
| 108 | pass.EndPass(); |
| 109 | |
| 110 | wgpu::CommandBuffer commands = commandEncoder.Finish(); |
| 111 | queue.Submit(1, &commands); |
| 112 | } |
| 113 | |
| 114 | // Initialize the depth/stencil values for the texture using a render pass. |
| 115 | // The texture will be cleared to the "clear" values, and then bottom left corner will |
| 116 | // be written with the "region" values. |
| 117 | void InitializeDepthStencilTextureRegion(wgpu::Texture texture, |
| 118 | float clearDepth, |
| 119 | float regionDepth, |
| 120 | uint8_t clearStencil, |
| 121 | uint8_t regionStencil, |
| 122 | uint32_t mipLevel = 0) { |
| 123 | wgpu::TextureViewDescriptor viewDesc = {}; |
| 124 | viewDesc.baseMipLevel = mipLevel; |
| 125 | viewDesc.mipLevelCount = 1; |
| 126 | |
| 127 | utils::ComboRenderPassDescriptor renderPassDesc({}, texture.CreateView(&viewDesc)); |
| 128 | renderPassDesc.cDepthStencilAttachmentInfo.clearDepth = clearDepth; |
| 129 | renderPassDesc.cDepthStencilAttachmentInfo.clearStencil = clearStencil; |
| 130 | |
Brandon Jones | bff9d3a | 2021-03-18 02:54:27 +0000 | [diff] [blame] | 131 | utils::ComboRenderPipelineDescriptor2 renderPipelineDesc; |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 132 | PopulatePipelineDescriptorWriteDepth(&renderPipelineDesc, |
| 133 | wgpu::TextureFormat::Depth24PlusStencil8, regionDepth); |
Brandon Jones | bff9d3a | 2021-03-18 02:54:27 +0000 | [diff] [blame] | 134 | renderPipelineDesc.cDepthStencil.stencilFront.passOp = wgpu::StencilOperation::Replace; |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 135 | |
Brandon Jones | bff9d3a | 2021-03-18 02:54:27 +0000 | [diff] [blame] | 136 | wgpu::RenderPipeline pipeline = device.CreateRenderPipeline2(&renderPipelineDesc); |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 137 | |
| 138 | // Draw the quad (two triangles) |
| 139 | wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder(); |
| 140 | wgpu::RenderPassEncoder pass = commandEncoder.BeginRenderPass(&renderPassDesc); |
| 141 | pass.SetPipeline(pipeline); |
| 142 | pass.SetStencilReference(regionStencil); |
| 143 | pass.Draw(6); |
| 144 | pass.EndPass(); |
| 145 | |
| 146 | wgpu::CommandBuffer commands = commandEncoder.Finish(); |
| 147 | queue.Submit(1, &commands); |
| 148 | } |
| 149 | |
| 150 | wgpu::Texture CreateInitializeDepthStencilTextureAndCopyT2T(float clearDepth, |
| 151 | float regionDepth, |
| 152 | uint8_t clearStencil, |
| 153 | uint8_t regionStencil, |
| 154 | uint32_t width, |
| 155 | uint32_t height, |
| 156 | wgpu::TextureUsage usage, |
| 157 | uint32_t mipLevel = 0) { |
| 158 | wgpu::Texture src = CreateDepthStencilTexture( |
Corentin Wallez | 6b08781 | 2020-10-27 15:35:56 +0000 | [diff] [blame] | 159 | width, height, wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc, |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 160 | mipLevel + 1); |
| 161 | |
| 162 | wgpu::Texture dst = CreateDepthStencilTexture( |
| 163 | width, height, usage | wgpu::TextureUsage::CopyDst, mipLevel + 1); |
| 164 | |
| 165 | InitializeDepthStencilTextureRegion(src, clearDepth, regionDepth, clearStencil, |
| 166 | regionStencil, mipLevel); |
| 167 | |
| 168 | // Perform a T2T copy of all aspects |
| 169 | { |
| 170 | wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder(); |
Corentin Wallez | 8091584 | 2021-03-04 18:13:45 +0000 | [diff] [blame] | 171 | wgpu::ImageCopyTexture srcView = |
| 172 | utils::CreateImageCopyTexture(src, mipLevel, {0, 0, 0}); |
| 173 | wgpu::ImageCopyTexture dstView = |
| 174 | utils::CreateImageCopyTexture(dst, mipLevel, {0, 0, 0}); |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 175 | wgpu::Extent3D copySize = {width >> mipLevel, height >> mipLevel, 1}; |
| 176 | commandEncoder.CopyTextureToTexture(&srcView, &dstView, ©Size); |
| 177 | |
| 178 | wgpu::CommandBuffer commands = commandEncoder.Finish(); |
| 179 | queue.Submit(1, &commands); |
| 180 | } |
| 181 | |
| 182 | return dst; |
| 183 | } |
| 184 | |
| 185 | // Check depth by uploading expected data to a sampled texture, writing it out as a depth |
| 186 | // attachment, and then using the "equals" depth test to check the contents are the same. |
| 187 | void ExpectDepthData(wgpu::Texture depthTexture, |
| 188 | wgpu::TextureFormat depthFormat, |
| 189 | uint32_t width, |
| 190 | uint32_t height, |
| 191 | uint32_t mipLevel, |
| 192 | std::vector<float> expected) { |
| 193 | wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder(); |
| 194 | |
| 195 | // Make the color attachment that we'll use to read back. |
| 196 | wgpu::TextureDescriptor colorTexDesc = {}; |
| 197 | colorTexDesc.size = {width, height, 1}; |
| 198 | colorTexDesc.format = wgpu::TextureFormat::R32Uint; |
Corentin Wallez | 6b08781 | 2020-10-27 15:35:56 +0000 | [diff] [blame] | 199 | colorTexDesc.usage = wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc; |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 200 | wgpu::Texture colorTexture = device.CreateTexture(&colorTexDesc); |
| 201 | |
| 202 | // Make a sampleable texture to store the depth data. We'll sample this in the |
| 203 | // shader to output depth. |
| 204 | wgpu::TextureDescriptor depthDataDesc = {}; |
| 205 | depthDataDesc.size = {width, height, 1}; |
| 206 | depthDataDesc.format = wgpu::TextureFormat::R32Float; |
| 207 | depthDataDesc.usage = wgpu::TextureUsage::Sampled | wgpu::TextureUsage::CopyDst; |
| 208 | wgpu::Texture depthDataTexture = device.CreateTexture(&depthDataDesc); |
| 209 | |
| 210 | // Upload the depth data. |
| 211 | uint32_t bytesPerRow = utils::GetMinimumBytesPerRow(wgpu::TextureFormat::R32Float, width); |
| 212 | wgpu::BufferDescriptor uploadBufferDesc = {}; |
| 213 | uploadBufferDesc.size = utils::RequiredBytesInCopy(bytesPerRow, height, depthDataDesc.size, |
| 214 | wgpu::TextureFormat::R32Float); |
| 215 | uploadBufferDesc.usage = wgpu::BufferUsage::CopySrc; |
| 216 | uploadBufferDesc.mappedAtCreation = true; |
| 217 | |
| 218 | // TODO(enga): Use WriteTexture when implemented on OpenGL. |
| 219 | wgpu::Buffer uploadBuffer = device.CreateBuffer(&uploadBufferDesc); |
| 220 | uint8_t* dst = static_cast<uint8_t*>(uploadBuffer.GetMappedRange()); |
| 221 | float* src = expected.data(); |
| 222 | for (uint32_t y = 0; y < height; ++y) { |
| 223 | memcpy(dst, src, width * sizeof(float)); |
| 224 | dst += bytesPerRow; |
| 225 | src += width; |
| 226 | } |
| 227 | uploadBuffer.Unmap(); |
| 228 | |
Corentin Wallez | 8091584 | 2021-03-04 18:13:45 +0000 | [diff] [blame] | 229 | wgpu::ImageCopyBuffer bufferCopy = |
| 230 | utils::CreateImageCopyBuffer(uploadBuffer, 0, bytesPerRow, height); |
| 231 | wgpu::ImageCopyTexture textureCopy = |
| 232 | utils::CreateImageCopyTexture(depthDataTexture, 0, {0, 0, 0}, wgpu::TextureAspect::All); |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 233 | commandEncoder.CopyBufferToTexture(&bufferCopy, &textureCopy, &depthDataDesc.size); |
| 234 | |
| 235 | // Pipeline for a full screen quad. |
Brandon Jones | bff9d3a | 2021-03-18 02:54:27 +0000 | [diff] [blame] | 236 | utils::ComboRenderPipelineDescriptor2 pipelineDescriptor; |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 237 | |
Corentin Wallez | 7aec4ae | 2021-03-24 15:55:32 +0000 | [diff] [blame] | 238 | pipelineDescriptor.vertex.module = utils::CreateShaderModule(device, R"( |
Brandon Jones | e87ea2b | 2021-04-14 17:05:07 +0000 | [diff] [blame] | 239 | [[stage(vertex)]] |
| 240 | fn main([[builtin(vertex_index)]] VertexIndex : u32) -> [[builtin(position)]] vec4<f32> { |
| 241 | let pos : array<vec2<f32>, 3> = array<vec2<f32>, 3>( |
Austin Eng | 84e1dca | 2020-11-30 20:33:50 +0000 | [diff] [blame] | 242 | vec2<f32>(-1.0, -1.0), |
| 243 | vec2<f32>( 3.0, -1.0), |
| 244 | vec2<f32>(-1.0, 3.0)); |
Brandon Jones | e87ea2b | 2021-04-14 17:05:07 +0000 | [diff] [blame] | 245 | return vec4<f32>(pos[VertexIndex], 0.0, 1.0); |
Austin Eng | 84e1dca | 2020-11-30 20:33:50 +0000 | [diff] [blame] | 246 | })"); |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 247 | |
| 248 | // Sample the input texture and write out depth. |result| will only be set to 1 if we |
| 249 | // pass the depth test. |
Corentin Wallez | 7aec4ae | 2021-03-24 15:55:32 +0000 | [diff] [blame] | 250 | pipelineDescriptor.cFragment.module = utils::CreateShaderModule(device, R"( |
James Price | 7e80cce | 2021-02-10 20:17:14 +0000 | [diff] [blame] | 251 | [[group(0), binding(0)]] var texture0 : texture_2d<f32>; |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 252 | |
Brandon Jones | e87ea2b | 2021-04-14 17:05:07 +0000 | [diff] [blame] | 253 | struct FragmentOut { |
| 254 | [[location(0)]] result : u32; |
| 255 | [[builtin(frag_depth)]] fragDepth : f32; |
| 256 | }; |
Austin Eng | 0243602 | 2020-12-17 19:20:27 +0000 | [diff] [blame] | 257 | |
Brandon Jones | e87ea2b | 2021-04-14 17:05:07 +0000 | [diff] [blame] | 258 | [[stage(fragment)]] |
James Price | eae70b7 | 2021-04-19 15:29:49 +0000 | [diff] [blame] | 259 | fn main([[builtin(position)]] FragCoord : vec4<f32>) -> FragmentOut { |
Brandon Jones | e87ea2b | 2021-04-14 17:05:07 +0000 | [diff] [blame] | 260 | var output : FragmentOut; |
| 261 | output.result = 1u; |
| 262 | output.fragDepth = textureLoad(texture0, vec2<i32>(FragCoord.xy), 0)[0]; |
| 263 | return output; |
Austin Eng | 0243602 | 2020-12-17 19:20:27 +0000 | [diff] [blame] | 264 | })"); |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 265 | |
| 266 | // Pass the depth test only if the depth is equal. |
Brandon Jones | bff9d3a | 2021-03-18 02:54:27 +0000 | [diff] [blame] | 267 | pipelineDescriptor.primitive.topology = wgpu::PrimitiveTopology::TriangleList; |
| 268 | wgpu::DepthStencilState* depthStencil = pipelineDescriptor.EnableDepthStencil(depthFormat); |
| 269 | depthStencil->depthCompare = wgpu::CompareFunction::Equal; |
| 270 | pipelineDescriptor.cTargets[0].format = colorTexDesc.format; |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 271 | |
| 272 | // TODO(jiawei.shao@intel.com): The Intel Mesa Vulkan driver can't set gl_FragDepth unless |
| 273 | // depthWriteEnabled == true. This either needs to be fixed in the driver or restricted by |
| 274 | // the WebGPU API. |
Brandon Jones | bff9d3a | 2021-03-18 02:54:27 +0000 | [diff] [blame] | 275 | depthStencil->depthWriteEnabled = true; |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 276 | |
| 277 | wgpu::TextureViewDescriptor viewDesc = {}; |
| 278 | viewDesc.baseMipLevel = mipLevel; |
| 279 | viewDesc.mipLevelCount = 1; |
| 280 | |
| 281 | utils::ComboRenderPassDescriptor passDescriptor({colorTexture.CreateView()}, |
| 282 | depthTexture.CreateView(&viewDesc)); |
| 283 | passDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Load; |
| 284 | passDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Load; |
| 285 | |
Brandon Jones | bff9d3a | 2021-03-18 02:54:27 +0000 | [diff] [blame] | 286 | wgpu::RenderPipeline pipeline = device.CreateRenderPipeline2(&pipelineDescriptor); |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 287 | |
Austin Eng | 0243602 | 2020-12-17 19:20:27 +0000 | [diff] [blame] | 288 | // Bind the depth data texture. |
| 289 | wgpu::BindGroup bindGroup = utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0), |
| 290 | {{0, depthDataTexture.CreateView()}}); |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 291 | |
| 292 | wgpu::RenderPassEncoder pass = commandEncoder.BeginRenderPass(&passDescriptor); |
| 293 | pass.SetPipeline(pipeline); |
| 294 | pass.SetBindGroup(0, bindGroup); |
| 295 | pass.Draw(3); |
| 296 | pass.EndPass(); |
| 297 | |
| 298 | wgpu::CommandBuffer commands = commandEncoder.Finish(); |
| 299 | queue.Submit(1, &commands); |
| 300 | |
| 301 | std::vector<uint32_t> colorData(width * height, 1u); |
Yunchao He | ff55b2f | 2021-04-07 16:57:11 +0000 | [diff] [blame] | 302 | EXPECT_TEXTURE_EQ(colorData.data(), colorTexture, {0, 0}, {width, height}); |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 303 | } |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 304 | |
| 305 | wgpu::ShaderModule mVertexModule; |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 306 | }; |
| 307 | |
| 308 | // Test copying the depth-only aspect into a buffer. |
| 309 | TEST_P(DepthStencilCopyTests, FromDepthAspect) { |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 310 | constexpr uint32_t kWidth = 4; |
| 311 | constexpr uint32_t kHeight = 4; |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 312 | |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 313 | wgpu::Texture depthTexture = CreateDepthTexture( |
Corentin Wallez | 6b08781 | 2020-10-27 15:35:56 +0000 | [diff] [blame] | 314 | kWidth, kHeight, wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc); |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 315 | |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 316 | InitializeDepthTextureRegion(depthTexture, 0.f, 0.3f); |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 317 | |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 318 | // This expectation is the test as it performs the CopyTextureToBuffer. |
| 319 | std::vector<float> expectedData = { |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 320 | 0.0, 0.0, 0.0, 0.0, // |
| 321 | 0.0, 0.0, 0.0, 0.0, // |
| 322 | 0.3, 0.3, 0.0, 0.0, // |
| 323 | 0.3, 0.3, 0.0, 0.0, // |
| 324 | }; |
Yunchao He | ff55b2f | 2021-04-07 16:57:11 +0000 | [diff] [blame] | 325 | EXPECT_TEXTURE_EQ(expectedData.data(), depthTexture, {0, 0}, {kWidth, kHeight}, 0, |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 326 | wgpu::TextureAspect::DepthOnly); |
| 327 | } |
| 328 | |
| 329 | // Test copying the stencil-only aspect into a buffer. |
| 330 | TEST_P(DepthStencilCopyTests, FromStencilAspect) { |
Stephen White | 39b478d | 2021-02-10 02:10:08 +0000 | [diff] [blame] | 331 | // TODO(crbug.com/dawn/667): Work around the fact that some platforms are unable to read |
| 332 | // stencil. |
| 333 | DAWN_SKIP_TEST_IF(HasToggleEnabled("disable_depth_stencil_read")); |
Stephen White | f09a670 | 2021-01-18 17:47:07 +0000 | [diff] [blame] | 334 | |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 335 | constexpr uint32_t kWidth = 4; |
| 336 | constexpr uint32_t kHeight = 4; |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 337 | |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 338 | wgpu::Texture depthStencilTexture = CreateDepthStencilTexture( |
Corentin Wallez | 6b08781 | 2020-10-27 15:35:56 +0000 | [diff] [blame] | 339 | kWidth, kHeight, wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc); |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 340 | |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 341 | InitializeDepthStencilTextureRegion(depthStencilTexture, 0.f, 0.3f, 0u, 1u); |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 342 | |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 343 | // This expectation is the test as it performs the CopyTextureToBuffer. |
| 344 | std::vector<uint8_t> expectedData = { |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 345 | 0u, 0u, 0u, 0u, // |
| 346 | 0u, 0u, 0u, 0u, // |
| 347 | 1u, 1u, 0u, 0u, // |
| 348 | 1u, 1u, 0u, 0u, // |
| 349 | }; |
Yunchao He | ff55b2f | 2021-04-07 16:57:11 +0000 | [diff] [blame] | 350 | EXPECT_TEXTURE_EQ(expectedData.data(), depthStencilTexture, {0, 0}, {kWidth, kHeight}, 0, |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 351 | wgpu::TextureAspect::StencilOnly); |
| 352 | } |
| 353 | |
| 354 | // Test copying the non-zero mip, stencil-only aspect into a buffer. |
| 355 | TEST_P(DepthStencilCopyTests, FromNonZeroMipStencilAspect) { |
| 356 | // TODO(enga): Figure out why this fails on MacOS Intel Iris. |
| 357 | // It passes on AMD Radeon Pro and Intel HD Graphics 630. |
| 358 | DAWN_SKIP_TEST_IF(IsMetal() && IsIntel()); |
| 359 | |
Stephen White | 39b478d | 2021-02-10 02:10:08 +0000 | [diff] [blame] | 360 | // TODO(crbug.com/dawn/667): Work around some platforms' inability to read back stencil. |
| 361 | DAWN_SKIP_TEST_IF(HasToggleEnabled("disable_depth_stencil_read")); |
Stephen White | f09a670 | 2021-01-18 17:47:07 +0000 | [diff] [blame] | 362 | |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 363 | wgpu::Texture depthStencilTexture = CreateDepthStencilTexture( |
Corentin Wallez | 6b08781 | 2020-10-27 15:35:56 +0000 | [diff] [blame] | 364 | 9, 9, wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc, 2); |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 365 | |
| 366 | InitializeDepthStencilTextureRegion(depthStencilTexture, 0.f, 0.3f, 0u, 1u, 1u); |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 367 | |
| 368 | // This expectation is the test as it performs the CopyTextureToBuffer. |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 369 | std::vector<uint8_t> expectedData = { |
| 370 | 0u, 0u, 0u, 0u, // |
| 371 | 0u, 0u, 0u, 0u, // |
| 372 | 1u, 1u, 0u, 0u, // |
| 373 | 1u, 1u, 0u, 0u, // |
| 374 | }; |
Yunchao He | ff55b2f | 2021-04-07 16:57:11 +0000 | [diff] [blame] | 375 | EXPECT_TEXTURE_EQ(expectedData.data(), depthStencilTexture, {0, 0}, {4, 4}, 1, |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 376 | wgpu::TextureAspect::StencilOnly); |
| 377 | } |
| 378 | |
| 379 | // Test copying the non-zero mip, depth-only aspect into a buffer. |
| 380 | TEST_P(DepthStencilCopyTests, FromNonZeroMipDepthAspect) { |
| 381 | wgpu::Texture depthTexture = CreateDepthTexture( |
Corentin Wallez | 6b08781 | 2020-10-27 15:35:56 +0000 | [diff] [blame] | 382 | 9, 9, wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc, 2); |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 383 | |
| 384 | InitializeDepthTextureRegion(depthTexture, 0.f, 0.4f, 1); |
| 385 | |
| 386 | // This expectation is the test as it performs the CopyTextureToBuffer. |
| 387 | std::vector<float> expectedData = { |
| 388 | 0.0, 0.0, 0.0, 0.0, // |
| 389 | 0.0, 0.0, 0.0, 0.0, // |
| 390 | 0.4, 0.4, 0.0, 0.0, // |
| 391 | 0.4, 0.4, 0.0, 0.0, // |
| 392 | }; |
Yunchao He | ff55b2f | 2021-04-07 16:57:11 +0000 | [diff] [blame] | 393 | EXPECT_TEXTURE_EQ(expectedData.data(), depthTexture, {0, 0}, {4, 4}, 1, |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 394 | wgpu::TextureAspect::DepthOnly); |
| 395 | } |
| 396 | |
| 397 | // Test copying both aspects in a T2T copy, then copying only stencil. |
| 398 | TEST_P(DepthStencilCopyTests, T2TBothAspectsThenCopyStencil) { |
| 399 | // TODO(enga): Figure out why this fails on MacOS Intel Iris. |
| 400 | // It passes on AMD Radeon Pro and Intel HD Graphics 630. |
Corentin Wallez | 6b08781 | 2020-10-27 15:35:56 +0000 | [diff] [blame] | 401 | // Maybe has to do with the RenderAttachment usage. Notably, a later test |
| 402 | // T2TBothAspectsThenCopyNonRenderableStencil does not use RenderAttachment and works correctly. |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 403 | DAWN_SKIP_TEST_IF(IsMetal() && IsIntel()); |
| 404 | |
Stephen White | 39b478d | 2021-02-10 02:10:08 +0000 | [diff] [blame] | 405 | // TODO(crbug.com/dawn/667): Work around some platforms' inability to read back stencil. |
| 406 | DAWN_SKIP_TEST_IF(HasToggleEnabled("disable_depth_stencil_read")); |
Stephen White | f09a670 | 2021-01-18 17:47:07 +0000 | [diff] [blame] | 407 | |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 408 | constexpr uint32_t kWidth = 4; |
| 409 | constexpr uint32_t kHeight = 4; |
| 410 | |
| 411 | wgpu::Texture texture = CreateInitializeDepthStencilTextureAndCopyT2T( |
| 412 | 0.1f, 0.3f, 1u, 3u, kWidth, kHeight, |
Corentin Wallez | 6b08781 | 2020-10-27 15:35:56 +0000 | [diff] [blame] | 413 | wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::RenderAttachment); |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 414 | |
| 415 | // Check the stencil |
| 416 | std::vector<uint8_t> expectedData = { |
| 417 | 1u, 1u, 1u, 1u, // |
| 418 | 1u, 1u, 1u, 1u, // |
| 419 | 3u, 3u, 1u, 1u, // |
| 420 | 3u, 3u, 1u, 1u, // |
| 421 | }; |
Yunchao He | ff55b2f | 2021-04-07 16:57:11 +0000 | [diff] [blame] | 422 | EXPECT_TEXTURE_EQ(expectedData.data(), texture, {0, 0}, {kWidth, kHeight}, 0, |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 423 | wgpu::TextureAspect::StencilOnly); |
| 424 | } |
| 425 | |
| 426 | // Test that part of a non-renderable stencil aspect can be copied. Notably, |
| 427 | // this test has different behavior on some platforms than T2TBothAspectsThenCopyStencil. |
| 428 | TEST_P(DepthStencilCopyTests, T2TBothAspectsThenCopyNonRenderableStencil) { |
Stephen White | 39b478d | 2021-02-10 02:10:08 +0000 | [diff] [blame] | 429 | // TODO(crbug.com/dawn/667): Work around some platforms' inability to read back stencil. |
| 430 | DAWN_SKIP_TEST_IF(HasToggleEnabled("disable_depth_stencil_read")); |
Stephen White | f09a670 | 2021-01-18 17:47:07 +0000 | [diff] [blame] | 431 | |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 432 | constexpr uint32_t kWidth = 4; |
| 433 | constexpr uint32_t kHeight = 4; |
| 434 | |
| 435 | wgpu::Texture texture = CreateInitializeDepthStencilTextureAndCopyT2T( |
| 436 | 0.1f, 0.3f, 1u, 3u, kWidth, kHeight, wgpu::TextureUsage::CopySrc); |
| 437 | |
| 438 | // Check the stencil |
| 439 | std::vector<uint8_t> expectedData = { |
| 440 | 1u, 1u, 1u, 1u, // |
| 441 | 1u, 1u, 1u, 1u, // |
| 442 | 3u, 3u, 1u, 1u, // |
| 443 | 3u, 3u, 1u, 1u, // |
| 444 | }; |
Yunchao He | ff55b2f | 2021-04-07 16:57:11 +0000 | [diff] [blame] | 445 | EXPECT_TEXTURE_EQ(expectedData.data(), texture, {0, 0}, {kWidth, kHeight}, 0, |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 446 | wgpu::TextureAspect::StencilOnly); |
| 447 | } |
| 448 | |
| 449 | // Test that part of a non-renderable, non-zero mip stencil aspect can be copied. Notably, |
| 450 | // this test has different behavior on some platforms than T2TBothAspectsThenCopyStencil. |
| 451 | TEST_P(DepthStencilCopyTests, T2TBothAspectsThenCopyNonRenderableNonZeroMipStencil) { |
| 452 | // TODO(enga): Figure out why this fails on MacOS Intel Iris. |
| 453 | // It passes on AMD Radeon Pro and Intel HD Graphics 630. |
| 454 | // Maybe has to do with the non-zero mip. Notably, a previous test |
| 455 | // T2TBothAspectsThenCopyNonRenderableStencil works correctly. |
| 456 | DAWN_SKIP_TEST_IF(IsMetal() && IsIntel()); |
| 457 | |
Stephen White | 39b478d | 2021-02-10 02:10:08 +0000 | [diff] [blame] | 458 | // TODO(crbug.com/dawn/667): Work around some platforms' inability to read back stencil. |
| 459 | DAWN_SKIP_TEST_IF(HasToggleEnabled("disable_depth_stencil_read")); |
Stephen White | f09a670 | 2021-01-18 17:47:07 +0000 | [diff] [blame] | 460 | |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 461 | wgpu::Texture texture = CreateInitializeDepthStencilTextureAndCopyT2T( |
| 462 | 0.1f, 0.3f, 1u, 3u, 9, 9, wgpu::TextureUsage::CopySrc, 1); |
| 463 | |
| 464 | // Check the stencil |
| 465 | std::vector<uint8_t> expectedData = { |
| 466 | 1u, 1u, 1u, 1u, // |
| 467 | 1u, 1u, 1u, 1u, // |
| 468 | 3u, 3u, 1u, 1u, // |
| 469 | 3u, 3u, 1u, 1u, // |
| 470 | }; |
Yunchao He | ff55b2f | 2021-04-07 16:57:11 +0000 | [diff] [blame] | 471 | EXPECT_TEXTURE_EQ(expectedData.data(), texture, {0, 0}, {4, 4}, 1, |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 472 | wgpu::TextureAspect::StencilOnly); |
| 473 | } |
| 474 | |
| 475 | // Test copying both aspects in a T2T copy, then copying only depth. |
| 476 | TEST_P(DepthStencilCopyTests, T2TBothAspectsThenCopyDepth) { |
| 477 | constexpr uint32_t kWidth = 4; |
| 478 | constexpr uint32_t kHeight = 4; |
| 479 | |
| 480 | wgpu::Texture texture = CreateInitializeDepthStencilTextureAndCopyT2T( |
Corentin Wallez | 6b08781 | 2020-10-27 15:35:56 +0000 | [diff] [blame] | 481 | 0.1f, 0.3f, 1u, 3u, kWidth, kHeight, wgpu::TextureUsage::RenderAttachment); |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 482 | |
| 483 | // Check the depth |
| 484 | ExpectDepthData(texture, wgpu::TextureFormat::Depth24PlusStencil8, kWidth, kHeight, 0, |
| 485 | { |
| 486 | 0.1, 0.1, 0.1, 0.1, // |
| 487 | 0.1, 0.1, 0.1, 0.1, // |
| 488 | 0.3, 0.3, 0.1, 0.1, // |
| 489 | 0.3, 0.3, 0.1, 0.1, // |
| 490 | }); |
| 491 | } |
| 492 | |
| 493 | // Test copying both aspects in a T2T copy, then copying only depth at a nonzero mip. |
| 494 | TEST_P(DepthStencilCopyTests, T2TBothAspectsThenCopyNonZeroMipDepth) { |
| 495 | wgpu::Texture texture = CreateInitializeDepthStencilTextureAndCopyT2T( |
Corentin Wallez | 6b08781 | 2020-10-27 15:35:56 +0000 | [diff] [blame] | 496 | 0.1f, 0.3f, 1u, 3u, 8, 8, wgpu::TextureUsage::RenderAttachment, 1); |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 497 | |
| 498 | // Check the depth |
| 499 | ExpectDepthData(texture, wgpu::TextureFormat::Depth24PlusStencil8, 4, 4, 1, |
| 500 | { |
| 501 | 0.1, 0.1, 0.1, 0.1, // |
| 502 | 0.1, 0.1, 0.1, 0.1, // |
| 503 | 0.3, 0.3, 0.1, 0.1, // |
| 504 | 0.3, 0.3, 0.1, 0.1, // |
| 505 | }); |
| 506 | } |
| 507 | |
| 508 | // Test copying both aspects in a T2T copy, then copying stencil, then copying depth |
| 509 | TEST_P(DepthStencilCopyTests, T2TBothAspectsThenCopyStencilThenDepth) { |
Stephen White | 39b478d | 2021-02-10 02:10:08 +0000 | [diff] [blame] | 510 | // TODO(crbug.com/dawn/667): Work around some platforms' inability to read back stencil. |
| 511 | DAWN_SKIP_TEST_IF(HasToggleEnabled("disable_depth_stencil_read")); |
Stephen White | f09a670 | 2021-01-18 17:47:07 +0000 | [diff] [blame] | 512 | |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 513 | constexpr uint32_t kWidth = 4; |
| 514 | constexpr uint32_t kHeight = 4; |
| 515 | |
| 516 | wgpu::Texture texture = CreateInitializeDepthStencilTextureAndCopyT2T( |
| 517 | 0.1f, 0.3f, 1u, 3u, kWidth, kHeight, |
Corentin Wallez | 6b08781 | 2020-10-27 15:35:56 +0000 | [diff] [blame] | 518 | wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::RenderAttachment); |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 519 | |
| 520 | // Check the stencil |
| 521 | std::vector<uint8_t> expectedData = { |
| 522 | 1u, 1u, 1u, 1u, // |
| 523 | 1u, 1u, 1u, 1u, // |
| 524 | 3u, 3u, 1u, 1u, // |
| 525 | 3u, 3u, 1u, 1u, // |
| 526 | }; |
Yunchao He | ff55b2f | 2021-04-07 16:57:11 +0000 | [diff] [blame] | 527 | EXPECT_TEXTURE_EQ(expectedData.data(), texture, {0, 0}, {kWidth, kHeight}, 0, |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 528 | wgpu::TextureAspect::StencilOnly); |
| 529 | |
| 530 | // Check the depth |
| 531 | ExpectDepthData(texture, wgpu::TextureFormat::Depth24PlusStencil8, kWidth, kHeight, 0, |
| 532 | { |
| 533 | 0.1, 0.1, 0.1, 0.1, // |
| 534 | 0.1, 0.1, 0.1, 0.1, // |
| 535 | 0.3, 0.3, 0.1, 0.1, // |
| 536 | 0.3, 0.3, 0.1, 0.1, // |
| 537 | }); |
| 538 | } |
| 539 | |
| 540 | // Test copying both aspects in a T2T copy, then copying depth, then copying stencil |
| 541 | TEST_P(DepthStencilCopyTests, T2TBothAspectsThenCopyDepthThenStencil) { |
| 542 | // TODO(enga): Figure out why this fails on MacOS Intel Iris. |
| 543 | // It passes on AMD Radeon Pro and Intel HD Graphics 630. |
| 544 | // It seems like the depth readback copy mutates the stencil because the previous |
| 545 | // test T2TBothAspectsThenCopyStencil passes. |
| 546 | // T2TBothAspectsThenCopyStencilThenDepth which checks stencil first also passes. |
| 547 | DAWN_SKIP_TEST_IF(IsMetal() && IsIntel()); |
| 548 | |
Stephen White | 39b478d | 2021-02-10 02:10:08 +0000 | [diff] [blame] | 549 | // TODO(crbug.com/dawn/667): Work around the fact that some platforms are unable to read |
| 550 | // stencil. |
| 551 | DAWN_SKIP_TEST_IF(HasToggleEnabled("disable_depth_stencil_read")); |
Stephen White | f09a670 | 2021-01-18 17:47:07 +0000 | [diff] [blame] | 552 | |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 553 | constexpr uint32_t kWidth = 4; |
| 554 | constexpr uint32_t kHeight = 4; |
| 555 | |
| 556 | wgpu::Texture texture = CreateInitializeDepthStencilTextureAndCopyT2T( |
| 557 | 0.1f, 0.3f, 1u, 3u, kWidth, kHeight, |
Corentin Wallez | 6b08781 | 2020-10-27 15:35:56 +0000 | [diff] [blame] | 558 | wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::RenderAttachment); |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 559 | |
| 560 | // Check the depth |
| 561 | ExpectDepthData(texture, wgpu::TextureFormat::Depth24PlusStencil8, kWidth, kHeight, 0, |
| 562 | { |
| 563 | 0.1, 0.1, 0.1, 0.1, // |
| 564 | 0.1, 0.1, 0.1, 0.1, // |
| 565 | 0.3, 0.3, 0.1, 0.1, // |
| 566 | 0.3, 0.3, 0.1, 0.1, // |
| 567 | }); |
| 568 | |
| 569 | // Check the stencil |
| 570 | std::vector<uint8_t> expectedData = { |
| 571 | 1u, 1u, 1u, 1u, // |
| 572 | 1u, 1u, 1u, 1u, // |
| 573 | 3u, 3u, 1u, 1u, // |
| 574 | 3u, 3u, 1u, 1u, // |
| 575 | }; |
Yunchao He | ff55b2f | 2021-04-07 16:57:11 +0000 | [diff] [blame] | 576 | EXPECT_TEXTURE_EQ(expectedData.data(), texture, {0, 0}, {kWidth, kHeight}, 0, |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 577 | wgpu::TextureAspect::StencilOnly); |
| 578 | } |
| 579 | |
| 580 | // Test copying to the stencil-aspect of a buffer |
| 581 | TEST_P(DepthStencilCopyTests, ToStencilAspect) { |
Austin Eng | b54c82e | 2020-08-18 18:53:26 +0000 | [diff] [blame] | 582 | // Copies to a single aspect are unsupported on OpenGL. |
| 583 | DAWN_SKIP_TEST_IF(IsOpenGL()); |
Stephen White | 6f5151f | 2020-12-01 21:52:37 +0000 | [diff] [blame] | 584 | DAWN_SKIP_TEST_IF(IsOpenGLES()); |
Austin Eng | b54c82e | 2020-08-18 18:53:26 +0000 | [diff] [blame] | 585 | |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 586 | // TODO(enga): Figure out why this fails on MacOS Intel Iris. |
| 587 | // It passes on AMD Radeon Pro and Intel HD Graphics 630. |
| 588 | DAWN_SKIP_TEST_IF(IsMetal() && IsIntel()); |
| 589 | |
| 590 | // Create a stencil texture |
| 591 | constexpr uint32_t kWidth = 4; |
| 592 | constexpr uint32_t kHeight = 4; |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 593 | |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 594 | wgpu::Texture depthStencilTexture = |
| 595 | CreateDepthStencilTexture(kWidth, kHeight, |
Corentin Wallez | 6b08781 | 2020-10-27 15:35:56 +0000 | [diff] [blame] | 596 | wgpu::TextureUsage::RenderAttachment | |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 597 | wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst); |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 598 | |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 599 | { |
| 600 | wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder(); |
| 601 | |
| 602 | // Clear depth to 0.7, so we can check that the stencil copy doesn't mutate the depth. |
| 603 | utils::ComboRenderPassDescriptor passDescriptor({}, depthStencilTexture.CreateView()); |
| 604 | passDescriptor.cDepthStencilAttachmentInfo.clearDepth = 0.7; |
| 605 | |
| 606 | wgpu::RenderPassEncoder pass = commandEncoder.BeginRenderPass(&passDescriptor); |
| 607 | pass.EndPass(); |
| 608 | |
| 609 | wgpu::CommandBuffer commands = commandEncoder.Finish(); |
| 610 | queue.Submit(1, &commands); |
| 611 | } |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 612 | |
| 613 | std::vector<uint8_t> stencilData = { |
| 614 | 1u, 2u, 3u, 4u, // |
| 615 | 5u, 6u, 7u, 8u, // |
| 616 | 9u, 10u, 11u, 12u, // |
| 617 | 13u, 14u, 15u, 16u, // |
| 618 | }; |
| 619 | |
| 620 | // After copying stencil data in, we will decrement stencil values in the bottom left |
| 621 | // of the screen. This is the expected result. |
| 622 | std::vector<uint8_t> expectedStencilData = { |
| 623 | 1u, 2u, 3u, 4u, // |
| 624 | 5u, 6u, 7u, 8u, // |
| 625 | 8u, 9u, 11u, 12u, // |
| 626 | 12u, 13u, 15u, 16u, // |
| 627 | }; |
| 628 | |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 629 | // Upload the stencil data. |
| 630 | wgpu::TextureDataLayout stencilDataLayout = {}; |
| 631 | stencilDataLayout.bytesPerRow = kWidth * sizeof(uint8_t); |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 632 | |
Corentin Wallez | 8091584 | 2021-03-04 18:13:45 +0000 | [diff] [blame] | 633 | wgpu::ImageCopyTexture stencilDataCopyTexture = utils::CreateImageCopyTexture( |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 634 | depthStencilTexture, 0, {0, 0, 0}, wgpu::TextureAspect::StencilOnly); |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 635 | |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 636 | wgpu::Extent3D writeSize = {kWidth, kHeight, 1}; |
Corentin Wallez | 8091584 | 2021-03-04 18:13:45 +0000 | [diff] [blame] | 637 | queue.WriteTexture(&stencilDataCopyTexture, stencilData.data(), |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 638 | stencilData.size() * sizeof(uint8_t), &stencilDataLayout, &writeSize); |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 639 | |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 640 | // Decrement the stencil value in a render pass to ensure the data is visible to the pipeline. |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 641 | { |
| 642 | wgpu::CommandEncoder commandEncoder = device.CreateCommandEncoder(); |
| 643 | // Create a render pipline which decrements the stencil value for passing fragments. |
| 644 | // A quad is drawn in the bottom left. |
Brandon Jones | bff9d3a | 2021-03-18 02:54:27 +0000 | [diff] [blame] | 645 | utils::ComboRenderPipelineDescriptor2 renderPipelineDesc; |
| 646 | renderPipelineDesc.vertex.module = mVertexModule; |
Corentin Wallez | 7aec4ae | 2021-03-24 15:55:32 +0000 | [diff] [blame] | 647 | renderPipelineDesc.cFragment.module = utils::CreateShaderModule(device, R"( |
Corentin Wallez | 21bd02b | 2021-04-13 09:48:24 +0000 | [diff] [blame] | 648 | [[stage(fragment)]] fn main() { |
Austin Eng | 84e1dca | 2020-11-30 20:33:50 +0000 | [diff] [blame] | 649 | })"); |
Brandon Jones | bff9d3a | 2021-03-18 02:54:27 +0000 | [diff] [blame] | 650 | wgpu::DepthStencilState* depthStencil = |
| 651 | renderPipelineDesc.EnableDepthStencil(wgpu::TextureFormat::Depth24PlusStencil8); |
| 652 | depthStencil->stencilFront.passOp = wgpu::StencilOperation::DecrementClamp; |
| 653 | renderPipelineDesc.cFragment.targetCount = 0; |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 654 | |
Brandon Jones | bff9d3a | 2021-03-18 02:54:27 +0000 | [diff] [blame] | 655 | wgpu::RenderPipeline pipeline = device.CreateRenderPipeline2(&renderPipelineDesc); |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 656 | |
| 657 | // Create a render pass which loads the stencil. We want to load the values we |
| 658 | // copied in. Also load the canary depth values so they're not lost. |
| 659 | utils::ComboRenderPassDescriptor passDescriptor({}, depthStencilTexture.CreateView()); |
| 660 | passDescriptor.cDepthStencilAttachmentInfo.stencilLoadOp = wgpu::LoadOp::Load; |
| 661 | passDescriptor.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Load; |
| 662 | |
| 663 | // Draw the quad in the bottom left (two triangles). |
| 664 | wgpu::RenderPassEncoder pass = commandEncoder.BeginRenderPass(&passDescriptor); |
| 665 | pass.SetPipeline(pipeline); |
| 666 | pass.Draw(6); |
| 667 | pass.EndPass(); |
| 668 | |
| 669 | wgpu::CommandBuffer commands = commandEncoder.Finish(); |
| 670 | queue.Submit(1, &commands); |
| 671 | } |
| 672 | |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 673 | // Copy back the stencil data and check it is correct. |
Yunchao He | 4eb40c1 | 2021-03-31 22:15:53 +0000 | [diff] [blame] | 674 | EXPECT_TEXTURE_EQ(expectedStencilData.data(), depthStencilTexture, {0, 0}, {kWidth, kHeight}, 0, |
Yunchao He | ff55b2f | 2021-04-07 16:57:11 +0000 | [diff] [blame] | 675 | wgpu::TextureAspect::StencilOnly); |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 676 | |
Austin Eng | f114a68 | 2020-09-01 18:40:18 +0000 | [diff] [blame] | 677 | ExpectDepthData(depthStencilTexture, wgpu::TextureFormat::Depth24PlusStencil8, kWidth, kHeight, |
| 678 | 0, |
| 679 | { |
| 680 | 0.7, 0.7, 0.7, 0.7, // |
| 681 | 0.7, 0.7, 0.7, 0.7, // |
| 682 | 0.7, 0.7, 0.7, 0.7, // |
| 683 | 0.7, 0.7, 0.7, 0.7, // |
| 684 | }); |
Austin Eng | 0a43427 | 2020-08-04 19:46:37 +0000 | [diff] [blame] | 685 | } |
| 686 | |
Austin Eng | b54c82e | 2020-08-18 18:53:26 +0000 | [diff] [blame] | 687 | DAWN_INSTANTIATE_TEST(DepthStencilCopyTests, |
| 688 | D3D12Backend(), |
| 689 | MetalBackend(), |
| 690 | OpenGLBackend(), |
Stephen White | 6f5151f | 2020-12-01 21:52:37 +0000 | [diff] [blame] | 691 | OpenGLESBackend(), |
Austin Eng | b54c82e | 2020-08-18 18:53:26 +0000 | [diff] [blame] | 692 | VulkanBackend()); |