1 //
2 // Copyright 2024 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 #include "test_utils/ANGLETest.h"
8 #include "test_utils/gl_raii.h"
9
10 namespace angle
11 {
12 class TiledRenderingTest : public ANGLETest<>
13 {
14 protected:
TiledRenderingTest()15 TiledRenderingTest()
16 {
17 setWindowWidth(128);
18 setWindowHeight(128);
19 setConfigRedBits(8);
20 setConfigGreenBits(8);
21 setConfigBlueBits(8);
22 setConfigAlphaBits(8);
23 }
24 };
25
26 // Validate that the extension entry points generate errors when the extension is not available.
TEST_P(TiledRenderingTest,ExtensionDisabled)27 TEST_P(TiledRenderingTest, ExtensionDisabled)
28 {
29 ANGLE_SKIP_TEST_IF(IsGLExtensionEnabled("GL_QCOM_tiled_rendering"));
30 glStartTilingQCOM(0, 0, 1, 1, GL_COLOR_BUFFER_BIT0_QCOM);
31 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
32 glEndTilingQCOM(GL_COLOR_BUFFER_BIT0_QCOM);
33 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
34 }
35
36 // Test that tiled rendering can be stared and stopped. Verify that only pixels in bounds are
37 // written.
TEST_P(TiledRenderingTest,BasicUsage)38 TEST_P(TiledRenderingTest, BasicUsage)
39 {
40 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_tiled_rendering"));
41
42 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Blue());
43
44 glClearColor(0, 0, 0, 0);
45 glClear(GL_COLOR_BUFFER_BIT);
46
47 glStartTilingQCOM(10, 12, 15, 17, GL_COLOR_BUFFER_BIT0_QCOM);
48
49 drawQuad(program, essl1_shaders::PositionAttrib(), 0);
50
51 glEndTilingQCOM(GL_COLOR_BUFFER_BIT0_QCOM);
52
53 const int w = getWindowWidth();
54 const int h = getWindowHeight();
55
56 EXPECT_PIXEL_RECT_EQ(10, 12, 15, 17, GLColor::blue);
57 EXPECT_PIXEL_RECT_EQ(0, 0, w, 12, GLColor::transparentBlack);
58 EXPECT_PIXEL_RECT_EQ(0, 12 + 17, w, h - 12 - 17, GLColor::transparentBlack);
59 EXPECT_PIXEL_RECT_EQ(0, 0, 10, h, GLColor::transparentBlack);
60 EXPECT_PIXEL_RECT_EQ(10 + 15, 0, w - 10 - 15, h, GLColor::transparentBlack);
61 }
62
63 // Test that changing the framebuffer implicitly ends tiled rendering.
TEST_P(TiledRenderingTest,ImplicitEnd)64 TEST_P(TiledRenderingTest, ImplicitEnd)
65 {
66 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_tiled_rendering"));
67
68 GLTexture tex1;
69 glBindTexture(GL_TEXTURE_2D, tex1);
70 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
71
72 GLFramebuffer fbo1;
73 glBindFramebuffer(GL_FRAMEBUFFER, fbo1);
74 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex1, 0);
75
76 GLTexture tex2;
77 glBindTexture(GL_TEXTURE_2D, tex2);
78 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
79
80 GLFramebuffer fbo2;
81 glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
82 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex2, 0);
83
84 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Blue());
85
86 glClearColor(0, 0, 0, 0);
87
88 glBindFramebuffer(GL_FRAMEBUFFER, fbo1);
89 glClear(GL_COLOR_BUFFER_BIT);
90 glStartTilingQCOM(0, 0, 8, 8, GL_COLOR_BUFFER_BIT0_QCOM);
91 EXPECT_GL_NO_ERROR();
92
93 drawQuad(program, essl1_shaders::PositionAttrib(), 0);
94
95 // Switch framebuffer bindings. Tiling is implicitly ended and start can be called again without
96 // errors.
97 glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
98 glClear(GL_COLOR_BUFFER_BIT);
99 glStartTilingQCOM(8, 8, 8, 8, GL_COLOR_BUFFER_BIT0_QCOM);
100 EXPECT_GL_NO_ERROR();
101
102 drawQuad(program, essl1_shaders::PositionAttrib(), 0);
103
104 glEndTilingQCOM(GL_COLOR_BUFFER_BIT0_QCOM);
105
106 // Test that the correct tiling regions were used
107 glBindFramebuffer(GL_FRAMEBUFFER, fbo1);
108 EXPECT_PIXEL_COLOR_EQ(4, 4, GLColor::blue);
109
110 glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
111 EXPECT_PIXEL_COLOR_EQ(12, 12, GLColor::blue);
112
113 // Qualcomm drivers do not implicitly end tiling when changing the texture bound to the
114 // framebuffer so ANGLE inherits this behaviour. Validate that tiling is not ended.
115 glBindTexture(GL_TEXTURE_2D, tex1);
116 glBindFramebuffer(GL_FRAMEBUFFER, fbo1);
117 glClear(GL_COLOR_BUFFER_BIT);
118 glStartTilingQCOM(4, 4, 4, 4, GL_COLOR_BUFFER_BIT0_QCOM);
119 EXPECT_GL_NO_ERROR();
120
121 drawQuad(program, essl1_shaders::PositionAttrib(), 0);
122
123 // Redefine to 8x8 with red data
124 std::vector<GLColor> redData(8 * 8, GLColor::red);
125 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, redData.data());
126
127 // If tiling is still continuing from before, should only draw to [4, 4] to (8, 8)
128 drawQuad(program, essl1_shaders::PositionAttrib(), 0);
129
130 glStartTilingQCOM(4, 4, 4, 4, GL_COLOR_BUFFER_BIT0_QCOM);
131 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
132
133 glEndTilingQCOM(GL_COLOR_BUFFER_BIT0_QCOM);
134 EXPECT_GL_NO_ERROR();
135
136 EXPECT_PIXEL_RECT_EQ(0, 0, 4, 4, GLColor::red);
137 EXPECT_PIXEL_RECT_EQ(4, 4, 4, 4, GLColor::blue);
138 }
139
140 // Test that the only written areas are the intersection of scissor and tiled rendering area
TEST_P(TiledRenderingTest,Scissor)141 TEST_P(TiledRenderingTest, Scissor)
142 {
143 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_tiled_rendering"));
144
145 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Blue());
146
147 glClearColor(0, 0, 0, 0);
148 glClear(GL_COLOR_BUFFER_BIT);
149
150 glEnable(GL_SCISSOR_TEST);
151 glScissor(0, 0, 12, 12);
152
153 glStartTilingQCOM(8, 8, 8, 8, GL_COLOR_BUFFER_BIT0_QCOM);
154
155 // Scissor and tile intersect from [8, 8] to [12, 12]
156
157 drawQuad(program, essl1_shaders::PositionAttrib(), 0);
158
159 glEndTilingQCOM(GL_COLOR_BUFFER_BIT0_QCOM);
160
161 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::transparentBlack);
162 EXPECT_PIXEL_COLOR_EQ(6, 6, GLColor::transparentBlack);
163 EXPECT_PIXEL_RECT_EQ(8, 8, 4, 4, GLColor::blue);
164 EXPECT_PIXEL_COLOR_EQ(14, 14, GLColor::transparentBlack);
165 EXPECT_PIXEL_COLOR_EQ(18, 18, GLColor::transparentBlack);
166 }
167
168 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(TiledRenderingTest);
169
170 } // namespace angle
171