Merge gerrit/vulkan-cts-1.0.1 into gerrit/vulkan-cts-1.0-dev
[platform/upstream/VK-GL-CTS.git] / framework / opengl / gluRenderContext.hpp
1 #ifndef _GLURENDERCONTEXT_HPP
2 #define _GLURENDERCONTEXT_HPP
3 /*-------------------------------------------------------------------------
4  * drawElements Quality Program OpenGL ES Utilities
5  * ------------------------------------------------
6  *
7  * Copyright 2014 The Android Open Source Project
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief OpenGL ES rendering context.
24  *//*--------------------------------------------------------------------*/
25
26 #include "tcuDefs.hpp"
27
28 namespace tcu
29 {
30 class CommandLine;
31 class Platform;
32 class RenderTarget;
33 }
34
35 namespace glw
36 {
37 class Functions;
38 class FunctionLoader;
39 }
40
41 namespace glu
42 {
43
44 class ContextType;
45 class ContextInfo;
46
47 enum Profile
48 {
49         PROFILE_ES = 0,                 //!< OpenGL ES
50         PROFILE_CORE,                   //!< OpenGL Core Profile
51         PROFILE_COMPATIBILITY,  //!< OpenGL Compatibility Profile
52
53         PROFILE_LAST
54 };
55
56 enum ContextFlags
57 {
58         CONTEXT_ROBUST                          = (1<<0),       //!< Robust context
59         CONTEXT_DEBUG                           = (1<<1),       //!< Debug context
60         CONTEXT_FORWARD_COMPATIBLE      = (1<<2)        //!< Forward-compatible context
61 };
62
63 inline ContextFlags     operator| (ContextFlags a, ContextFlags b)      { return ContextFlags((deUint32)a|(deUint32)b); }
64 inline ContextFlags     operator& (ContextFlags a, ContextFlags b)      { return ContextFlags((deUint32)a&(deUint32)b); }
65 inline ContextFlags     operator~ (ContextFlags a)                                      { return ContextFlags(~(deUint32)a);                    }
66
67 /*--------------------------------------------------------------------*//*!
68  * \brief Rendering API version and profile.
69  *//*--------------------------------------------------------------------*/
70 class ApiType
71 {
72 public:
73                                                 ApiType                 (void) : m_bits(pack(0, 0, PROFILE_LAST)) {}
74                                                 ApiType                 (int major, int minor, Profile profile) : m_bits(pack(major, minor, profile)) {}
75
76         int                                     getMajorVersion (void) const    { return int((m_bits>>MAJOR_SHIFT)                      & ((1u<<MAJOR_BITS)-1u));       }
77         int                                     getMinorVersion (void) const    { return int((m_bits>>MINOR_SHIFT)                      & ((1u<<MINOR_BITS)-1u));       }
78         Profile                         getProfile              (void) const    { return Profile((m_bits>>PROFILE_SHIFT)        & ((1u<<PROFILE_BITS)-1u));     }
79
80         bool                            operator==              (ApiType other) const   { return m_bits == other.m_bits;                                                }
81         bool                            operator!=              (ApiType other) const   { return m_bits != other.m_bits;                                                }
82
83         deUint32                        getPacked               (void) const    { return m_bits;                                                                                                }
84
85         // Shorthands
86         static ApiType          es                              (int major, int minor)  { return ApiType(major, minor, PROFILE_ES);                             }
87         static ApiType          core                    (int major, int minor)  { return ApiType(major, minor, PROFILE_CORE);                   }
88         static ApiType          compatibility   (int major, int minor)  { return ApiType(major, minor, PROFILE_COMPATIBILITY);  }
89
90 protected:
91                                                 ApiType                 (deUint32 bits) : m_bits(bits) {}
92         static ApiType          fromBits                (deUint32 bits) { return ApiType(bits); }
93
94         static deUint32         pack                    (int major, int minor, Profile profile);
95
96         deUint32                        m_bits;
97
98         enum
99         {
100                 MAJOR_BITS              = 4,
101                 MINOR_BITS              = 4,
102                 PROFILE_BITS    = 2,
103                 TOTAL_API_BITS  = MAJOR_BITS+MINOR_BITS+PROFILE_BITS,
104
105                 MAJOR_SHIFT             = 0,
106                 MINOR_SHIFT             = MAJOR_SHIFT+MAJOR_BITS,
107                 PROFILE_SHIFT   = MINOR_SHIFT+MINOR_BITS
108         };
109 } DE_WARN_UNUSED_TYPE;
110
111 inline deUint32 ApiType::pack (int major, int minor, Profile profile)
112 {
113         deUint32 bits = 0;
114
115         DE_ASSERT((deUint32(major) & ~((1<<MAJOR_BITS)-1)) == 0);
116         DE_ASSERT((deUint32(minor) & ~((1<<MINOR_BITS)-1)) == 0);
117         DE_ASSERT((deUint32(profile) & ~((1<<PROFILE_BITS)-1)) == 0);
118
119         bits |= deUint32(major) << MAJOR_SHIFT;
120         bits |= deUint32(minor) << MINOR_SHIFT;
121         bits |= deUint32(profile) << PROFILE_SHIFT;
122
123         return bits;
124 }
125
126 /*--------------------------------------------------------------------*//*!
127  * \brief Rendering context type.
128  *
129  * ContextType differs from API type by adding context flags. They are
130  * crucial in for example determining when GL core context supports
131  * certain API version (forward-compatible bit).
132  *
133  * \note You should NEVER compare ContextTypes against each other, as
134  *       you most likely don't want to take flags into account. For example
135  *       the test code almost certainly doesn't want to check that you have
136  *       EXACTLY ES3.1 context with debug, but without for example robustness.
137  *//*--------------------------------------------------------------------*/
138 class ContextType : private ApiType
139 {
140 public:
141                                                 ContextType             (void) {}
142                                                 ContextType             (int major, int minor, Profile profile, ContextFlags flags = ContextFlags(0));
143         explicit                        ContextType             (ApiType apiType, ContextFlags flags = ContextFlags(0));
144
145         ApiType                         getAPI                  (void) const    { return ApiType::fromBits(m_bits & ((1u<<TOTAL_API_BITS)-1u));                 }
146         ContextFlags            getFlags                (void) const    { return ContextFlags((m_bits>>FLAGS_SHIFT)     & ((1u<<FLAGS_BITS)-1u));       }
147
148         using ApiType::getMajorVersion;
149         using ApiType::getMinorVersion;
150         using ApiType::getProfile;
151
152 protected:
153         static deUint32         pack                    (deUint32 apiBits, ContextFlags flags);
154
155         enum
156         {
157                 FLAGS_BITS                      = 3,
158                 TOTAL_CONTEXT_BITS      = TOTAL_API_BITS+FLAGS_BITS,
159                 FLAGS_SHIFT                     = TOTAL_API_BITS
160         };
161 } DE_WARN_UNUSED_TYPE;
162
163 inline ContextType::ContextType (int major, int minor, Profile profile, ContextFlags flags)
164         : ApiType(major, minor, profile)
165 {
166         m_bits = pack(m_bits, flags);
167 }
168
169 inline ContextType::ContextType (ApiType apiType, ContextFlags flags)
170         : ApiType(apiType)
171 {
172         m_bits = pack(m_bits, flags);
173 }
174
175 inline deUint32 ContextType::pack (deUint32 apiBits, ContextFlags flags)
176 {
177         deUint32 bits = apiBits;
178
179         DE_ASSERT((deUint32(flags) & ~((1<<FLAGS_BITS)-1)) == 0);
180         bits |= deUint32(flags) << FLAGS_SHIFT;
181
182         return bits;
183 }
184
185 inline bool             isContextTypeES                         (ContextType type)      { return type.getAPI().getProfile() == PROFILE_ES;                              }
186 inline bool             isContextTypeGLCore                     (ContextType type)      { return type.getAPI().getProfile() == PROFILE_CORE;                    }
187 inline bool             isContextTypeGLCompatibility(ContextType type)  { return type.getAPI().getProfile() == PROFILE_COMPATIBILITY;   }
188 bool                    contextSupports                         (ContextType ctxType, ApiType requiredApiType);
189
190 /*--------------------------------------------------------------------*//*!
191  * \brief Rendering context abstraction.
192  *//*--------------------------------------------------------------------*/
193 class RenderContext
194 {
195 public:
196                                                                                 RenderContext                   (void) {}
197         virtual                                                         ~RenderContext                  (void) {}
198
199         //! Get context type. Must match to type given to ContextFactory::createContext().
200         virtual ContextType                                     getType                                 (void) const    = DE_NULL;
201
202         //! Get GL function table. Should be filled with all core entry points for context type.
203         virtual const glw::Functions&           getFunctions                    (void) const    = DE_NULL;
204
205         //! Get render target information.
206         virtual const tcu::RenderTarget&        getRenderTarget                 (void) const    = DE_NULL;
207
208         //! Do post-render actions (swap buffers for example).
209         virtual void                                            postIterate                             (void)                  = DE_NULL;
210
211         //! Get default framebuffer.
212         virtual deUint32                                        getDefaultFramebuffer   (void) const { return 0; }
213
214 private:
215                                                                                 RenderContext                   (const RenderContext& other); // Not allowed!
216         RenderContext&                                          operator=                               (const RenderContext& other); // Not allowed!
217 };
218
219 // Utilities
220
221 RenderContext*          createDefaultRenderContext              (tcu::Platform& platform, const tcu::CommandLine& cmdLine, ApiType apiType);
222
223 void                            initCoreFunctions                               (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType);
224 void                            initExtensionFunctions                  (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType, int numExtensions, const char* const* extensions);
225
226 // \note initFunctions() and initExtensionFunctions() without explicit extension list
227 //               use glGetString* to query list of extensions, so it needs current GL context.
228 void                            initFunctions                                   (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType);
229 void                            initExtensionFunctions                  (glw::Functions* dst, const glw::FunctionLoader* loader, ApiType apiType);
230
231 bool                            hasExtension                                    (const glw::Functions& gl, ApiType apiType, const std::string& extension);
232
233 } // glu
234
235 #endif // _GLURENDERCONTEXT_HPP