1 /*
2 * Copyright (c) 2024 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