Merge "Added shader support to pipeline cache" into devel/master
[platform/core/uifw/dali-adaptor.git] / automated-tests / src / dali-graphics / utc-Dali-GraphicsProgram.cpp
1 /*
2  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <dali-test-suite-utils.h>
18 #include <dali/dali.h>
19
20 #include <dali/internal/graphics/gles-impl/egl-graphics-controller.h>
21 #include <test-actor-utils.h>
22 #include <test-graphics-application.h>
23 #include <test-graphics-sampler.h>
24
25 using namespace Dali;
26
27 void utc_dali_program_startup(void)
28 {
29   test_return_value = TET_UNDEF;
30 }
31 void utc_dali_program_cleanup(void)
32 {
33   test_return_value = TET_PASS;
34 }
35
36 namespace
37 {
38 const std::string VERT_SHADER_SOURCE = "myVertShaderSource";
39
40 const std::string VERT_SHADER_SOURCE2 =
41   "\n"
42   "in vec3 aPosition;\n"
43   "in vec3 aTexCoord;\n"
44   "out vec2 vTexCoord;\n"
45   "main()\n"
46   "{\n"
47   "  gl_Position=aPosition;\n"
48   "  vTexCoord = aTexCoord;\n"
49   "}\n";
50
51 const std::string FRAG_SHADER_SOURCE =
52   "\n"
53   "uniform sampler2D sAlbedo;\n"
54   "uniform sampler2D sMetalRoughness;\n"
55   "uniform sampler2D sNormals;\n"
56   "uniform sampler2D sAmbientOcclusion;\n"
57   "uniform mediump vec3 lightDirection;\n"
58   "in mediump vec2 vTexCoord;\n"
59   "main()\n"
60   "{\n"
61   "  gl_fragColor = texture2d(sAlbedo, vTexCoord) + lightDirection*texture2d(sNormals, vTexCoord);\n"
62   "}\n";
63
64 const std::string FRAG_SHADER_SOURCE2 =
65   "\n"
66   "uniform sampler2D sTextures[4];\n"
67   "uniform mediump vec3 lightDirection;\n"
68   "in mediump vec2 vTexCoord;\n"
69   "main()\n"
70   "{\n"
71   "  gl_fragColor = texture2d(sTextures[0], vTexCoord) + lightDirection*texture2d(sTextures[2], vTexCoord);\n"
72   "}\n";
73
74 } //anonymous namespace
75
76 int UtcDaliGraphicsProgram01(void)
77 {
78   TestGraphicsApplication app;
79   tet_infoline("UtcDaliProgram - check that right sampler uniforms are bound for textures");
80
81   Texture normals        = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
82   Texture metalroughness = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
83   Texture ao             = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
84   Texture albedo         = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
85
86   TextureSet textureSet = TextureSet::New();
87   textureSet.SetTexture(0, albedo);
88   textureSet.SetTexture(1, metalroughness);
89   textureSet.SetTexture(2, normals);
90   textureSet.SetTexture(3, ao);
91
92   Actor actor = CreateRenderableActor2(textureSet, VERT_SHADER_SOURCE, FRAG_SHADER_SOURCE);
93   app.GetScene().Add(actor);
94
95   auto& gl             = app.GetGlAbstraction();
96   auto& glUniformTrace = gl.GetSetUniformTrace();
97   glUniformTrace.Enable(true);
98   glUniformTrace.EnableLogging(true);
99
100   std::vector<ActiveUniform> activeUniforms{
101     {"sAlbedo", GL_SAMPLER_2D, 1},
102     {"sAmbientOcclusion", GL_SAMPLER_2D, 1},
103     {"sNormals", GL_SAMPLER_2D, 1},
104     {"sMetalRoughness", GL_SAMPLER_2D, 1}};
105   gl.SetActiveUniforms(activeUniforms);
106
107   app.SendNotification();
108   app.Render(16); // The above actor will get rendered and drawn once.
109
110   // Check what uniform values were set:
111   int value;
112   DALI_TEST_CHECK(gl.GetUniformValue("sAlbedo", value)); // First in frag shader
113   DALI_TEST_EQUALS(value, 0, TEST_LOCATION);
114   DALI_TEST_CHECK(gl.GetUniformValue("sAmbientOcclusion", value)); // 4th
115   DALI_TEST_EQUALS(value, 3, TEST_LOCATION);
116   DALI_TEST_CHECK(gl.GetUniformValue("sNormals", value)); // 3rd
117   DALI_TEST_EQUALS(value, 2, TEST_LOCATION);
118   DALI_TEST_CHECK(gl.GetUniformValue("sMetalRoughness", value)); // 2nd
119   DALI_TEST_EQUALS(value, 1, TEST_LOCATION);
120
121   END_TEST;
122 }
123
124 int UtcDaliGraphicsProgram02(void)
125 {
126   TestGraphicsApplication app;
127   tet_infoline("UtcDaliProgram - check that sampler arrays are handled and bound to textures");
128
129   Texture normals        = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
130   Texture metalroughness = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
131   Texture ao             = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
132   Texture albedo         = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
133
134   TextureSet textureSet = TextureSet::New();
135   textureSet.SetTexture(0, albedo);
136   textureSet.SetTexture(1, metalroughness);
137   textureSet.SetTexture(2, normals);
138   textureSet.SetTexture(3, ao);
139
140   Actor actor = CreateRenderableActor2(textureSet, VERT_SHADER_SOURCE, FRAG_SHADER_SOURCE2);
141   app.GetScene().Add(actor);
142
143   auto& gl             = app.GetGlAbstraction();
144   auto& glUniformTrace = gl.GetSetUniformTrace();
145   glUniformTrace.Enable(true);
146   glUniformTrace.EnableLogging(true);
147   gl.GetShaderTrace().Enable(true);
148   gl.GetShaderTrace().EnableLogging(true);
149
150   std::vector<ActiveUniform> activeUniforms{
151     {"uLightDir", GL_FLOAT_VEC4, 1},
152     {"sTextures[0]", GL_SAMPLER_2D, 4}}; // Array of 4 samplers
153   gl.SetActiveUniforms(activeUniforms);
154
155   app.SendNotification();
156   app.Render(16); // The above actor will get rendered and drawn once.
157
158   // Check what uniform values were set:
159   int value;
160   DALI_TEST_CHECK(gl.GetUniformValue("sTextures[0]", value)); // First in frag shader
161   DALI_TEST_EQUALS(value, 0, TEST_LOCATION);
162   DALI_TEST_CHECK(gl.GetUniformValue("sTextures[3]", value)); // 4th
163   DALI_TEST_EQUALS(value, 3, TEST_LOCATION);
164   DALI_TEST_CHECK(gl.GetUniformValue("sTextures[2]", value)); // 3rd
165   DALI_TEST_EQUALS(value, 2, TEST_LOCATION);
166   DALI_TEST_CHECK(gl.GetUniformValue("sTextures[1]", value)); // 2nd
167   DALI_TEST_EQUALS(value, 1, TEST_LOCATION);
168
169   END_TEST;
170 }
171
172 int UtcDaliGraphicsShaderNew(void)
173 {
174   TestGraphicsApplication app;
175   tet_infoline("UtcDaliProgram - check that multiple shaders from same source only create 1 program");
176
177   Texture diffuse = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
178
179   // Creates 3 Dali::Shaders
180   Actor actor1 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE, FRAG_SHADER_SOURCE);
181   Actor actor2 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE, FRAG_SHADER_SOURCE);
182   Actor actor3 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE, FRAG_SHADER_SOURCE);
183
184   app.GetScene().Add(actor1);
185   app.GetScene().Add(actor2);
186   app.GetScene().Add(actor3);
187
188   auto& gl            = app.GetGlAbstraction();
189   auto& glShaderTrace = gl.GetShaderTrace();
190   glShaderTrace.Enable(true);
191   glShaderTrace.EnableLogging(true);
192
193   app.SendNotification();
194   app.Render(16); // The above actors will get rendered and drawn once, only 2 shaders should be created
195
196   DALI_TEST_EQUALS(glShaderTrace.CountMethod("CreateShader"), 2, TEST_LOCATION);
197
198   END_TEST;
199 }
200
201 int UtcDaliGraphicsShaderNew02(void)
202 {
203   TestGraphicsApplication app;
204   tet_infoline("UtcDaliProgram - check that mixed up multiple shaders from same source don't create dups");
205
206   Texture diffuse = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
207
208   // Creates 3 Dali::Shaders
209   Actor actor1 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE, FRAG_SHADER_SOURCE);
210   Actor actor2 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE2, FRAG_SHADER_SOURCE2);
211   Actor actor3 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE, FRAG_SHADER_SOURCE2);
212   Actor actor4 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE2, FRAG_SHADER_SOURCE);
213
214   app.GetScene().Add(actor1);
215   app.GetScene().Add(actor2);
216   app.GetScene().Add(actor3);
217   app.GetScene().Add(actor4);
218
219   auto& gl            = app.GetGlAbstraction();
220   auto& glShaderTrace = gl.GetShaderTrace();
221   glShaderTrace.Enable(true);
222   glShaderTrace.EnableLogging(true);
223
224   app.SendNotification();
225   app.Render(16); // The above actors will get rendered and drawn once, only 2 shaders should be created
226
227   // Should only be 4 shaders, not 8.
228   DALI_TEST_EQUALS(glShaderTrace.CountMethod("CreateShader"), 4, TEST_LOCATION);
229
230   END_TEST;
231 }
232
233 int UtcDaliGraphicsShaderFlush(void)
234 {
235   TestGraphicsApplication app;
236   tet_infoline("UtcDaliProgram - check that unused shaders are flushed");
237
238   Texture diffuse       = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
239   auto&   gl            = app.GetGlAbstraction();
240   auto&   glShaderTrace = gl.GetShaderTrace();
241   glShaderTrace.Enable(true);
242   glShaderTrace.EnableLogging(true);
243
244   {
245     // Creates 3 Dali::Shaders
246     Actor actor1 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE, FRAG_SHADER_SOURCE);
247     Actor actor2 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE2, FRAG_SHADER_SOURCE2);
248     Actor actor3 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE, FRAG_SHADER_SOURCE2);
249     Actor actor4 = CreateRenderableActor(diffuse, VERT_SHADER_SOURCE2, FRAG_SHADER_SOURCE);
250
251     app.GetScene().Add(actor1);
252     app.GetScene().Add(actor2);
253     app.GetScene().Add(actor3);
254     app.GetScene().Add(actor4);
255
256     app.SendNotification();
257     app.Render(16); // The above actors will get rendered and drawn once
258
259     // Should only be 4 shaders, not 8.
260     DALI_TEST_EQUALS(glShaderTrace.CountMethod("CreateShader"), 4, TEST_LOCATION);
261
262     UnparentAndReset(actor1);
263     UnparentAndReset(actor2);
264     UnparentAndReset(actor3);
265     UnparentAndReset(actor4);
266   }
267
268   for(int i = 0; i < 1199; ++i) // 3 flushes per frame
269   {
270     app.SendNotification();
271     app.Render(16);
272     DALI_TEST_EQUALS(glShaderTrace.CountMethod("DeleteShader"), 0, TEST_LOCATION);
273   }
274   app.SendNotification();
275   app.Render(16);
276   DALI_TEST_EQUALS(glShaderTrace.CountMethod("DeleteShader"), 4, TEST_LOCATION);
277
278   END_TEST;
279 }