• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 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/perf_tests/DawnPerfTest.h"
16 
17 #include "utils/ComboRenderPipelineDescriptor.h"
18 #include "utils/WGPUHelpers.h"
19 
20 struct SubresourceTrackingParams : AdapterTestParam {
SubresourceTrackingParamsSubresourceTrackingParams21     SubresourceTrackingParams(const AdapterTestParam& param,
22                               uint32_t arrayLayerCountIn,
23                               uint32_t mipLevelCountIn)
24         : AdapterTestParam(param),
25           arrayLayerCount(arrayLayerCountIn),
26           mipLevelCount(mipLevelCountIn) {
27     }
28     uint32_t arrayLayerCount;
29     uint32_t mipLevelCount;
30 };
31 
operator <<(std::ostream & ostream,const SubresourceTrackingParams & param)32 std::ostream& operator<<(std::ostream& ostream, const SubresourceTrackingParams& param) {
33     ostream << static_cast<const AdapterTestParam&>(param);
34     ostream << "_arrayLayer_" << param.arrayLayerCount;
35     ostream << "_mipLevel_" << param.mipLevelCount;
36     return ostream;
37 }
38 
39 // Test the performance of Subresource usage and barrier tracking on a case that would generally be
40 // difficult. It uses a 2D array texture with mipmaps and updates one of the layers with data from
41 // another texture, then generates mipmaps for that layer. It is difficult because it requires
42 // tracking the state of individual subresources in the middle of the subresources of that texture.
43 class SubresourceTrackingPerf : public DawnPerfTestWithParams<SubresourceTrackingParams> {
44   public:
45     static constexpr unsigned int kNumIterations = 50;
46 
SubresourceTrackingPerf()47     SubresourceTrackingPerf() : DawnPerfTestWithParams(kNumIterations, 1) {
48     }
49     ~SubresourceTrackingPerf() override = default;
50 
SetUp()51     void SetUp() override {
52         DawnPerfTestWithParams<SubresourceTrackingParams>::SetUp();
53         const SubresourceTrackingParams& params = GetParam();
54 
55         wgpu::TextureDescriptor materialDesc;
56         materialDesc.dimension = wgpu::TextureDimension::e2D;
57         materialDesc.size = {1u << (params.mipLevelCount - 1), 1u << (params.mipLevelCount - 1),
58                              params.arrayLayerCount};
59         materialDesc.mipLevelCount = params.mipLevelCount;
60         materialDesc.usage = wgpu::TextureUsage::TextureBinding |
61                              wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopyDst;
62         materialDesc.format = wgpu::TextureFormat::RGBA8Unorm;
63         mMaterials = device.CreateTexture(&materialDesc);
64 
65         wgpu::TextureDescriptor uploadTexDesc = materialDesc;
66         uploadTexDesc.size.depthOrArrayLayers = 1;
67         uploadTexDesc.mipLevelCount = 1;
68         uploadTexDesc.usage = wgpu::TextureUsage::CopySrc;
69         mUploadTexture = device.CreateTexture(&uploadTexDesc);
70 
71         utils::ComboRenderPipelineDescriptor pipelineDesc;
72         pipelineDesc.vertex.module = utils::CreateShaderModule(device, R"(
73             [[stage(vertex)]] fn main() -> [[builtin(position)]] vec4<f32> {
74                 return vec4<f32>(1.0, 0.0, 0.0, 1.0);
75             }
76         )");
77         pipelineDesc.cFragment.module = utils::CreateShaderModule(device, R"(
78             [[group(0), binding(0)]] var materials : texture_2d<f32>;
79             [[stage(fragment)]] fn main() -> [[location(0)]] vec4<f32> {
80                 let foo : vec2<i32> = textureDimensions(materials);
81                 return vec4<f32>(1.0, 0.0, 0.0, 1.0);
82             }
83         )");
84         mPipeline = device.CreateRenderPipeline(&pipelineDesc);
85     }
86 
87   private:
Step()88     void Step() override {
89         const SubresourceTrackingParams& params = GetParam();
90 
91         uint32_t layerUploaded = params.arrayLayerCount / 2;
92 
93         wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
94 
95         // Copy into the layer of the material array.
96         {
97             wgpu::ImageCopyTexture sourceView;
98             sourceView.texture = mUploadTexture;
99 
100             wgpu::ImageCopyTexture destView;
101             destView.texture = mMaterials;
102             destView.origin.z = layerUploaded;
103 
104             wgpu::Extent3D copySize = {1u << (params.mipLevelCount - 1),
105                                        1u << (params.mipLevelCount - 1), 1};
106 
107             encoder.CopyTextureToTexture(&sourceView, &destView, &copySize);
108         }
109 
110         // Fake commands that would be used to create the mip levels.
111         for (uint32_t level = 1; level < params.mipLevelCount; level++) {
112             wgpu::TextureViewDescriptor rtViewDesc;
113             rtViewDesc.dimension = wgpu::TextureViewDimension::e2D;
114             rtViewDesc.baseMipLevel = level;
115             rtViewDesc.mipLevelCount = 1;
116             rtViewDesc.baseArrayLayer = layerUploaded;
117             rtViewDesc.arrayLayerCount = 1;
118             wgpu::TextureView rtView = mMaterials.CreateView(&rtViewDesc);
119 
120             wgpu::TextureViewDescriptor sampleViewDesc = rtViewDesc;
121             sampleViewDesc.baseMipLevel = level - 1;
122             wgpu::TextureView sampleView = mMaterials.CreateView(&sampleViewDesc);
123 
124             wgpu::BindGroup bindgroup =
125                 utils::MakeBindGroup(device, mPipeline.GetBindGroupLayout(0), {{0, sampleView}});
126 
127             utils::ComboRenderPassDescriptor renderPass({rtView});
128             wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
129             pass.SetPipeline(mPipeline);
130             pass.SetBindGroup(0, bindgroup);
131             pass.Draw(3);
132             pass.EndPass();
133         }
134 
135         wgpu::CommandBuffer commands = encoder.Finish();
136         queue.Submit(1, &commands);
137     }
138 
139     wgpu::Texture mUploadTexture;
140     wgpu::Texture mMaterials;
141     wgpu::RenderPipeline mPipeline;
142 };
143 
TEST_P(SubresourceTrackingPerf,Run)144 TEST_P(SubresourceTrackingPerf, Run) {
145     RunTest();
146 }
147 
148 DAWN_INSTANTIATE_TEST_P(SubresourceTrackingPerf,
149                         {D3D12Backend(), MetalBackend(), OpenGLBackend(), VulkanBackend()},
150                         {1, 4, 16, 256},
151                         {2, 3, 8});
152