• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 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 "utils/ComboRenderPipelineDescriptor.h"
18 #include "utils/DawnHelpers.h"
19 
20 #include <array>
21 
22 constexpr static unsigned int kRTSize = 16;
23 
24 class DrawQuad {
25     public:
DrawQuad()26         DrawQuad() {}
DrawQuad(dawn::Device device,const char * vsSource,const char * fsSource)27         DrawQuad(dawn::Device device, const char* vsSource, const char* fsSource)
28             : device(device) {
29             vsModule = utils::CreateShaderModule(device, utils::ShaderStage::Vertex, vsSource);
30             fsModule = utils::CreateShaderModule(device, utils::ShaderStage::Fragment, fsSource);
31 
32             pipelineLayout = utils::MakeBasicPipelineLayout(device, nullptr);
33             }
34 
Draw(dawn::RenderPassEncoder * pass)35         void Draw(dawn::RenderPassEncoder* pass) {
36 
37             utils::ComboRenderPipelineDescriptor descriptor(device);
38             descriptor.layout = pipelineLayout;
39             descriptor.cVertexStage.module = vsModule;
40             descriptor.cFragmentStage.module = fsModule;
41 
42             auto renderPipeline = device.CreateRenderPipeline(&descriptor);
43 
44             pass->SetPipeline(renderPipeline);
45             pass->Draw(6, 1, 0, 0);
46         }
47 
48     private:
49         dawn::Device device;
50         dawn::ShaderModule vsModule = {};
51         dawn::ShaderModule fsModule = {};
52         dawn::PipelineLayout pipelineLayout = {};
53 };
54 
55 class RenderPassLoadOpTests : public DawnTest {
56     protected:
SetUp()57         void SetUp() override {
58             DawnTest::SetUp();
59 
60             dawn::TextureDescriptor descriptor;
61             descriptor.dimension = dawn::TextureDimension::e2D;
62             descriptor.size.width = kRTSize;
63             descriptor.size.height = kRTSize;
64             descriptor.size.depth = 1;
65             descriptor.arrayLayerCount = 1;
66             descriptor.sampleCount = 1;
67             descriptor.format = dawn::TextureFormat::RGBA8Unorm;
68             descriptor.mipLevelCount = 1;
69             descriptor.usage =
70                 dawn::TextureUsageBit::OutputAttachment | dawn::TextureUsageBit::CopySrc;
71             renderTarget = device.CreateTexture(&descriptor);
72 
73             renderTargetView = renderTarget.CreateDefaultView();
74 
75             RGBA8 zero(0, 0, 0, 0);
76             std::fill(expectZero.begin(), expectZero.end(), zero);
77 
78             RGBA8 green(0, 255, 0, 255);
79             std::fill(expectGreen.begin(), expectGreen.end(), green);
80 
81             RGBA8 blue(0, 0, 255, 255);
82             std::fill(expectBlue.begin(), expectBlue.end(), blue);
83 
84             // draws a blue quad on the right half of the screen
85             const char* vsSource = R"(
86                 #version 450
87                 void main() {
88                     const vec2 pos[6] = vec2[6](
89                         vec2(0, -1), vec2(1, -1), vec2(0, 1),
90                         vec2(0,  1), vec2(1, -1), vec2(1, 1));
91                     gl_Position = vec4(pos[gl_VertexIndex], 0.f, 1.f);
92                 }
93                 )";
94             const char* fsSource = R"(
95                 #version 450
96                 layout(location = 0) out vec4 color;
97                 void main() {
98                     color = vec4(0.f, 0.f, 1.f, 1.f);
99                 }
100                 )";
101             blueQuad = DrawQuad(device, vsSource, fsSource);
102         }
103 
104         dawn::Texture renderTarget;
105         dawn::TextureView renderTargetView;
106 
107         std::array<RGBA8, kRTSize * kRTSize> expectZero;
108         std::array<RGBA8, kRTSize * kRTSize> expectGreen;
109         std::array<RGBA8, kRTSize * kRTSize> expectBlue;
110 
111         DrawQuad blueQuad = {};
112 };
113 
114 // Tests clearing, loading, and drawing into color attachments
TEST_P(RenderPassLoadOpTests,ColorClearThenLoadAndDraw)115 TEST_P(RenderPassLoadOpTests, ColorClearThenLoadAndDraw) {
116     // Part 1: clear once, check to make sure it's cleared
117     utils::ComboRenderPassDescriptor renderPassClearZero({renderTargetView});
118     auto commandsClearZeroEncoder = device.CreateCommandEncoder();
119     auto clearZeroPass = commandsClearZeroEncoder.BeginRenderPass(&renderPassClearZero);
120     clearZeroPass.EndPass();
121     auto commandsClearZero = commandsClearZeroEncoder.Finish();
122 
123     utils::ComboRenderPassDescriptor renderPassClearGreen({renderTargetView});
124     renderPassClearGreen.cColorAttachmentsInfoPtr[0]->clearColor = {0.0f, 1.0f, 0.0f, 1.0f};
125     auto commandsClearGreenEncoder = device.CreateCommandEncoder();
126     auto clearGreenPass = commandsClearGreenEncoder.BeginRenderPass(&renderPassClearGreen);
127     clearGreenPass.EndPass();
128     auto commandsClearGreen = commandsClearGreenEncoder.Finish();
129 
130     queue.Submit(1, &commandsClearZero);
131     EXPECT_TEXTURE_RGBA8_EQ(expectZero.data(), renderTarget, 0, 0, kRTSize, kRTSize, 0, 0);
132 
133     queue.Submit(1, &commandsClearGreen);
134     EXPECT_TEXTURE_RGBA8_EQ(expectGreen.data(), renderTarget, 0, 0, kRTSize, kRTSize, 0, 0);
135 
136     // Part 2: draw a blue quad into the right half of the render target, and check result
137     utils::ComboRenderPassDescriptor renderPassLoad({renderTargetView});
138     renderPassLoad.cColorAttachmentsInfoPtr[0]->loadOp = dawn::LoadOp::Load;
139     dawn::CommandBuffer commandsLoad;
140     {
141         auto encoder = device.CreateCommandEncoder();
142         auto pass = encoder.BeginRenderPass(&renderPassLoad);
143         blueQuad.Draw(&pass);
144         pass.EndPass();
145         commandsLoad = encoder.Finish();
146     }
147 
148     queue.Submit(1, &commandsLoad);
149     // Left half should still be green
150     EXPECT_TEXTURE_RGBA8_EQ(expectGreen.data(), renderTarget, 0, 0, kRTSize / 2, kRTSize, 0, 0);
151     // Right half should now be blue
152     EXPECT_TEXTURE_RGBA8_EQ(expectBlue.data(), renderTarget, kRTSize / 2, 0, kRTSize / 2, kRTSize, 0, 0);
153 }
154 
155 DAWN_INSTANTIATE_TEST(RenderPassLoadOpTests, D3D12Backend, MetalBackend, OpenGLBackend, VulkanBackend);
156