• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
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 
16 #ifndef API_RENDER_SHADERS_COMMON_CORE_COMPATIBILITY_COMMON_H
17 #define API_RENDER_SHADERS_COMMON_CORE_COMPATIBILITY_COMMON_H
18 
19 // Math types compatibility with c/c++
20 #ifndef VULKAN
21 #include <cstdint>
22 
23 #include <base/math/matrix.h>
24 #include <base/math/vector.h>
25 #include <base/namespace.h>
26 using uint = uint32_t;
27 using ivec4 = int32_t[4]; // Vector4
28 using vec2 = BASE_NS::Math::Vec2;
29 using vec3 = BASE_NS::Math::Vec3;
30 using vec4 = BASE_NS::Math::Vec4;
31 using uvec2 = BASE_NS::Math::UVec2;
32 using uvec3 = BASE_NS::Math::UVec3;
33 using uvec4 = BASE_NS::Math::UVec4;
34 using mat4 = BASE_NS::Math::Mat4X4;
35 #endif
36 
37 // Compatibility macros/constants to handle top-left / bottom-left differences between Vulkan/OpenGL(ES)
38 #ifdef VULKAN
39 precision highp float;
40 precision highp int;
41 // CORE RELAXED PRECISION
42 #define CORE_RELAXEDP mediump
43 
44 #define CORE_BACKEND_TYPE_SPEC_ID 256
45 // 0 = vulkan  (NDC top-left origin, 0 - 1 depth)
46 // 1 = gl/gles (bottom-left origin, -1 - 1 depth)
47 layout(constant_id = CORE_BACKEND_TYPE_SPEC_ID) const uint CORE_BACKEND_TYPE = 0;
48 
49 #define CORE_BACKEND_TYPE_MASK 0xf
50 #define CORE_BACKEND_TRANSFORM_MASK 0xf0
51 #define CORE_BACKEND_TRANSFORM_OFFSET (1 << 4)
52 #define CORE_BACKEND_TRANSFORM_0 (1 << 4)
53 #define CORE_BACKEND_TRANSFORM_90 (1 << 5)
54 #define CORE_BACKEND_TRANSFORM_180 (1 << 6)
55 #define CORE_BACKEND_TRANSFORM_270 (1 << 7)
56 
57 // change from top-left NDC origin (vulkan) to bottom-left NDC origin (opengl)
58 // Our input data (post-projection / NDC coordinates) are in vulkan top-left.
59 // this constant_id will change to a normal uniform in GL/GLES and will change based on rendertarget.
60 layout(constant_id = 257) const float CORE_FLIP_NDC = 1.0;
61 
62 #define CORE_VERTEX_OUT(a)                                                                                           \
63     {                                                                                                                \
64         gl_Position = (a);                                                                                           \
65         if ((CORE_BACKEND_TYPE & CORE_BACKEND_TYPE_MASK) != 0) {                                                     \
66             gl_Position = vec4(                                                                                      \
67                 gl_Position.x, gl_Position.y * CORE_FLIP_NDC, (gl_Position.z * 2.0 - gl_Position.w), gl_Position.w); \
68         }                                                                                                            \
69     }
70 
GetFragCoordUv(vec2 fragCoord,vec2 inverseTexelSize)71 vec2 GetFragCoordUv(vec2 fragCoord, vec2 inverseTexelSize)
72 {
73     vec2 uv = fragCoord * inverseTexelSize;
74     if (CORE_FLIP_NDC < 0.0) {
75         uv = vec2(uv.x, 1.0 - uv.y);
76     }
77     return uv;
78 }
79 
80 // out uv, gl_FragCoord, inverse tex size (i.e. texel size)
81 #define CORE_GET_FRAGCOORD_UV(uv, fc, its) (uv = GetFragCoordUv(fc, its))
82 
PreRotateSurface(inout vec2 clipXy)83 void PreRotateSurface(inout vec2 clipXy)
84 {
85     if ((CORE_BACKEND_TYPE & CORE_BACKEND_TYPE_MASK) == 0) {
86         const uint rotate = CORE_BACKEND_TYPE & CORE_BACKEND_TRANSFORM_MASK;
87         if (rotate == CORE_BACKEND_TRANSFORM_90) {
88             const mat2 m = mat2(0.0, 1.0, -1.0, 0.0);
89             clipXy = m * clipXy;
90         } else if (rotate == CORE_BACKEND_TRANSFORM_180) {
91             const mat2 m = mat2(-1.0, 0.0, 0.0, -1.0);
92             clipXy = m * clipXy;
93         } else if (rotate == CORE_BACKEND_TRANSFORM_270) {
94             const mat2 m = mat2(0.0, -1.0, 1.0, 0.0);
95             clipXy = m * clipXy;
96         }
97     }
98 }
99 
100 #define CORE_PRE_ROTATE_SURFACE(clipXy) (PreRotateSurface(clipXy))
101 
102 #else
103 
104 static constexpr uint32_t CORE_BACKEND_TYPE_SPEC_ID { 256U };
105 static constexpr uint32_t CORE_BACKEND_TRANSFORM_OFFSET { 4U };
106 
107 #endif
108 
109 #endif // API_RENDER_SHADERS_COMMON_CORE_COMPATIBILITY_COMMON_H
110