2 * Copyright (c) 2022 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 // Enable debug log for test coverage
19 #define DEBUG_ENABLED 1
21 // Disable this UTC until shader definition factory refactorize
22 #define ENABLE_SHADER_DEFINITION_FACTORY_UTC 0
24 #include <dali-test-suite-utils.h>
26 #include <string_view>
27 #include "dali-scene3d/public-api/loader/gltf2-loader.h"
28 #include "dali-scene3d/public-api/loader/node-definition.h"
29 #include "dali-scene3d/public-api/loader/resource-bundle.h"
30 #include "dali-scene3d/public-api/loader/shader-definition-factory.h"
33 using namespace Dali::Scene3D::Loader;
37 #if ENABLE_SHADER_DEFINITION_FACTORY_UTC
38 MaterialDefinition& NewMaterialDefinition(ResourceBundle& resources)
40 resources.mMaterials.push_back({});
41 return resources.mMaterials.back().first;
44 MeshDefinition& NewMeshDefinition(ResourceBundle& resources)
46 resources.mMeshes.push_back({});
47 return resources.mMeshes.back().first;
50 void ClearMeshesAndMaterials(ResourceBundle& resources)
52 resources.mMaterials.clear();
53 resources.mMeshes.clear();
59 ResourceBundle resources;
60 ShaderDefinitionFactory factory;
64 factory.SetResources(resources);
68 #if ENABLE_SHADER_DEFINITION_FACTORY_UTC
69 struct ShaderParameters
71 MeshDefinition& meshDef;
72 MaterialDefinition& materialDef;
73 NodeDefinition& nodeDef;
78 using ConfigureFn = void (*)(ShaderParameters&);
80 ConfigureFn configureFn;
82 std::set<std::string> defines;
83 RendererState::Type rendererStateSet = 0;
84 RendererState::Type rendererStateClear = 0;
89 std::vector<const Permutation*> permutations;
96 int UtcDaliShaderDefinitionFactoryProduceShaderInvalid(void)
100 NodeDefinition nodeDef;
101 std::unique_ptr<NodeDefinition::Renderable> renderable = std::unique_ptr<NodeDefinition::Renderable>(new NodeDefinition::Renderable());
102 nodeDef.mRenderables.push_back(std::move(renderable));
104 DALI_TEST_CHECK(ctx.resources.mShaders.empty());
109 int UtcDaliShaderDefinitionFactoryProduceShader(void)
111 #if ENABLE_SHADER_DEFINITION_FACTORY_UTC
113 ctx.resources.mMaterials.push_back({});
114 ctx.resources.mMeshes.push_back({});
116 Permutation permutations[]{
118 [](ShaderParameters& p) {},
120 RendererState::DEPTH_TEST | RendererState::DEPTH_WRITE | RendererState::CULL_BACK,
123 [](ShaderParameters& p) {
124 p.materialDef.mFlags |= MaterialDefinition::TRANSPARENCY;
127 RendererState::ALPHA_BLEND,
128 RendererState::DEPTH_WRITE,
130 {[](ShaderParameters& p) {
131 p.materialDef.mFlags |= MaterialDefinition::ALBEDO;
132 p.materialDef.mTextureStages.push_back({MaterialDefinition::ALBEDO, {}});
134 {"THREE_TEX", "BASECOLOR_TEX"}},
135 {[](ShaderParameters& p) {
136 p.materialDef.mTextureStages.push_back({MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS, {}});
138 {"THREE_TEX", "METALLIC_ROUGHNESS_TEX"}},
139 {[](ShaderParameters& p) {
140 p.materialDef.mFlags |= MaterialDefinition::NORMAL;
141 p.materialDef.mTextureStages.push_back({MaterialDefinition::NORMAL, {}});
143 {"THREE_TEX", "NORMAL_TEX"}},
144 {[](ShaderParameters& p) {
145 p.materialDef.mFlags |= MaterialDefinition::SUBSURFACE;
148 {[](ShaderParameters& p) {
149 p.materialDef.SetAlphaCutoff(.5f);
152 {[](ShaderParameters& p) {
153 p.materialDef.SetAlphaCutoff(1.f);
156 {[](ShaderParameters& p) {
157 p.materialDef.mFlags |= MaterialDefinition::GLTF_CHANNELS;
160 {[](ShaderParameters& p) {
161 p.meshDef.mJoints0.mBlob.mOffset = 0;
162 p.meshDef.mWeights0.mBlob.mOffset = 0;
165 {[](ShaderParameters& p) {
166 p.meshDef.mFlags |= MeshDefinition::FLIP_UVS_VERTICAL;
170 [](ShaderParameters& p) {
171 p.meshDef.mBlendShapes.push_back({});
174 {[](ShaderParameters& p) {
175 p.meshDef.mBlendShapes.back().deltas.mBlob.mOffset = 0;
177 {"MORPH_POSITION", "MORPH"}},
178 {[](ShaderParameters& p) {
179 p.meshDef.mBlendShapes.back().normals.mBlob.mOffset = 0;
181 {"MORPH_NORMAL", "MORPH"}},
182 {[](ShaderParameters& p) {
183 p.meshDef.mBlendShapes.back().tangents.mBlob.mOffset = 0;
185 {"MORPH_TANGENT", "MORPH"}},
186 {[](ShaderParameters& p) {
187 auto& blendShapes = p.meshDef.mBlendShapes;
188 DALI_ASSERT_ALWAYS(!blendShapes.empty() &&
189 (blendShapes.back().deltas.mBlob.mOffset != MeshDefinition::INVALID ||
190 blendShapes.back().normals.mBlob.mOffset != MeshDefinition::INVALID ||
191 blendShapes.back().tangents.mBlob.mOffset != MeshDefinition::INVALID));
192 p.meshDef.mBlendShapeVersion = BlendShapes::Version::VERSION_2_0;
194 {"MORPH_VERSION_2_0"}},
196 {[](ShaderParameters& p) {
197 p.materialDef.mFlags |= MaterialDefinition::OCCLUSION;
202 {[](ShaderParameters& p) {
203 p.meshDef.mColors.mBlob.mOffset = 0;
205 {"COLOR_ATTRIBUTE"}},
206 {[](ShaderParameters& p) {
207 p.meshDef.mTangentType = Property::VECTOR4;
212 PermutationSet permSets[]{
214 {{&permutations[0]}, 0},
217 {{&permutations[0], &permutations[1]}, 1},
219 // three-texture setups
220 {{&permutations[0], &permutations[2]}, 2},
221 {{&permutations[0], &permutations[3]}, 2},
222 {{&permutations[0], &permutations[4]}, 2},
223 {{&permutations[0], &permutations[2], &permutations[3]}, 2},
224 {{&permutations[0], &permutations[3], &permutations[4]}, 2},
225 {{&permutations[0], &permutations[4], &permutations[2]}, 2},
226 {{&permutations[0], &permutations[2], &permutations[3], &permutations[4]}, 2},
228 // subsurface scattering
229 {{&permutations[0], &permutations[5]}, 3},
232 {{&permutations[0], &permutations[6]}, 4},
233 {{&permutations[0], &permutations[7]}, 4},
236 {{&permutations[0], &permutations[8]}, 5},
239 {{&permutations[0], &permutations[9]}, 6},
242 {{&permutations[0], &permutations[10]}, 7},
245 {{&permutations[0], &permutations[11], &permutations[12]}, 8},
246 {{&permutations[0], &permutations[11], &permutations[13]}, 9},
247 {{&permutations[0], &permutations[11], &permutations[14]}, 10},
248 {{&permutations[0], &permutations[11], &permutations[12], &permutations[13]}, 11},
249 {{&permutations[0], &permutations[11], &permutations[13], &permutations[14]}, 12},
250 {{&permutations[0], &permutations[11], &permutations[14], &permutations[12]}, 13},
251 {{&permutations[0], &permutations[11], &permutations[12], &permutations[13], &permutations[14]}, 14},
253 {{&permutations[0], &permutations[11], &permutations[12], &permutations[15]}, 15},
254 {{&permutations[0], &permutations[11], &permutations[13], &permutations[15]}, 16},
255 {{&permutations[0], &permutations[11], &permutations[14], &permutations[15]}, 17},
256 {{&permutations[0], &permutations[11], &permutations[12], &permutations[13], &permutations[15]}, 18},
257 {{&permutations[0], &permutations[11], &permutations[13], &permutations[14], &permutations[15]}, 19},
258 {{&permutations[0], &permutations[11], &permutations[14], &permutations[12], &permutations[15]}, 20},
259 {{&permutations[0], &permutations[11], &permutations[12], &permutations[13], &permutations[14], &permutations[15]}, 21},
262 {{&permutations[0], &permutations[1], &permutations[2]}, 1},
263 {{&permutations[0], &permutations[1], &permutations[3]}, 1},
264 {{&permutations[0], &permutations[1], &permutations[2], &permutations[3]}, 1},
267 {{&permutations[0], &permutations[16]}, 22},
270 for(auto& ps : permSets)
273 tet_printf("Test %d's tc\n", ++tc);
274 auto modelRenderable = new ModelRenderable();
275 modelRenderable->mMeshIdx = 0;
276 modelRenderable->mMaterialIdx = 0;
278 NodeDefinition nodeDef;
279 std::unique_ptr<NodeDefinition::Renderable> renderable;
280 renderable.reset(modelRenderable);
281 nodeDef.mRenderables.push_back(std::move(renderable));
283 auto& meshDef = NewMeshDefinition(ctx.resources);
284 auto& materialDef = NewMaterialDefinition(ctx.resources);
285 ShaderParameters sp{meshDef, materialDef, nodeDef};
287 std::set<std::string> defines;
288 RendererState::Type rendererState = 0;
289 for(auto p : ps.permutations)
292 defines.insert(p->defines.begin(), p->defines.end());
293 rendererState = (rendererState | p->rendererStateSet) & ~p->rendererStateClear;
296 for(auto& renderable : nodeDef.mRenderables)
298 auto shaderIdx = ctx.factory.ProduceShader(*renderable);
299 DALI_TEST_EQUAL(ps.shaderIdx, shaderIdx);
301 auto& shaderDef = ctx.resources.mShaders[shaderIdx].first;
302 DALI_TEST_EQUAL(shaderDef.mRendererState, rendererState);
304 uint32_t definesUnmatched = shaderDef.mDefines.size();
305 for(auto& define : shaderDef.mDefines)
307 auto iFind = defines.find(define);
308 if(iFind != defines.end())
310 defines.erase(iFind);
320 std::ostringstream oss;
321 oss << "Need to check below defines :\n";
322 for(auto& it : defines)
326 tet_printf("%s\n", oss.str().c_str());
329 DALI_TEST_CHECK(defines.empty());
330 DALI_TEST_EQUAL(0, definesUnmatched);
332 auto uMaxLOD = shaderDef.mUniforms["uMaxLOD"];
333 DALI_TEST_EQUAL(uMaxLOD.GetType(), Property::FLOAT);
335 auto uCubeMatrix = shaderDef.mUniforms["uCubeMatrix"];
336 DALI_TEST_EQUAL(uCubeMatrix.GetType(), Property::MATRIX);
339 ClearMeshesAndMaterials(ctx.resources);
342 DALI_TEST_CHECK(true);