VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/VBoxGLSupportInfo.cpp@ 43138

Last change on this file since 43138 was 36386, checked in by vboxsync, 13 years ago

FE/VirtualBox: Use VBoxOGLTest program on FreeBSD

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 24.2 KB
Line 
1/* $Id: VBoxGLSupportInfo.cpp 36386 2011-03-24 06:51:19Z vboxsync $ */
2/** @file
3 *
4 * VBox frontends: Qt GUI ("VirtualBox"):
5 * OpenGL support info used for 2D support detection
6 */
7
8/*
9 * Copyright (C) 2009 Oracle Corporation
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 */
19
20#ifdef VBOX_WITH_PRECOMPILED_HEADERS
21# include "precomp.h"
22#else /* !VBOX_WITH_PRECOMPILED_HEADERS */
23#include <iprt/assert.h>
24#include <iprt/log.h>
25#include <iprt/err.h>
26#include <iprt/env.h>
27#include <iprt/param.h>
28#include <iprt/path.h>
29#include <iprt/process.h>
30#include <iprt/string.h>
31#include <iprt/time.h>
32#include <iprt/thread.h>
33
34#include <QGLWidget>
35#include <QGLContext>
36
37#include <VBox/VBoxGL2D.h>
38#include "VBoxFBOverlayCommon.h"
39#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
40
41/*****************/
42
43/* functions */
44
45PFNVBOXVHWA_ACTIVE_TEXTURE vboxglActiveTexture = NULL;
46PFNVBOXVHWA_MULTI_TEX_COORD2I vboxglMultiTexCoord2i = NULL;
47PFNVBOXVHWA_MULTI_TEX_COORD2D vboxglMultiTexCoord2d = NULL;
48PFNVBOXVHWA_MULTI_TEX_COORD2F vboxglMultiTexCoord2f = NULL;
49
50
51PFNVBOXVHWA_CREATE_SHADER vboxglCreateShader = NULL;
52PFNVBOXVHWA_SHADER_SOURCE vboxglShaderSource = NULL;
53PFNVBOXVHWA_COMPILE_SHADER vboxglCompileShader = NULL;
54PFNVBOXVHWA_DELETE_SHADER vboxglDeleteShader = NULL;
55
56PFNVBOXVHWA_CREATE_PROGRAM vboxglCreateProgram = NULL;
57PFNVBOXVHWA_ATTACH_SHADER vboxglAttachShader = NULL;
58PFNVBOXVHWA_DETACH_SHADER vboxglDetachShader = NULL;
59PFNVBOXVHWA_LINK_PROGRAM vboxglLinkProgram = NULL;
60PFNVBOXVHWA_USE_PROGRAM vboxglUseProgram = NULL;
61PFNVBOXVHWA_DELETE_PROGRAM vboxglDeleteProgram = NULL;
62
63PFNVBOXVHWA_IS_SHADER vboxglIsShader = NULL;
64PFNVBOXVHWA_GET_SHADERIV vboxglGetShaderiv = NULL;
65PFNVBOXVHWA_IS_PROGRAM vboxglIsProgram = NULL;
66PFNVBOXVHWA_GET_PROGRAMIV vboxglGetProgramiv = NULL;
67PFNVBOXVHWA_GET_ATTACHED_SHADERS vboxglGetAttachedShaders = NULL;
68PFNVBOXVHWA_GET_SHADER_INFO_LOG vboxglGetShaderInfoLog = NULL;
69PFNVBOXVHWA_GET_PROGRAM_INFO_LOG vboxglGetProgramInfoLog = NULL;
70
71PFNVBOXVHWA_GET_UNIFORM_LOCATION vboxglGetUniformLocation = NULL;
72
73PFNVBOXVHWA_UNIFORM1F vboxglUniform1f = NULL;
74PFNVBOXVHWA_UNIFORM2F vboxglUniform2f = NULL;
75PFNVBOXVHWA_UNIFORM3F vboxglUniform3f = NULL;
76PFNVBOXVHWA_UNIFORM4F vboxglUniform4f = NULL;
77
78PFNVBOXVHWA_UNIFORM1I vboxglUniform1i = NULL;
79PFNVBOXVHWA_UNIFORM2I vboxglUniform2i = NULL;
80PFNVBOXVHWA_UNIFORM3I vboxglUniform3i = NULL;
81PFNVBOXVHWA_UNIFORM4I vboxglUniform4i = NULL;
82
83PFNVBOXVHWA_GEN_BUFFERS vboxglGenBuffers = NULL;
84PFNVBOXVHWA_DELETE_BUFFERS vboxglDeleteBuffers = NULL;
85PFNVBOXVHWA_BIND_BUFFER vboxglBindBuffer = NULL;
86PFNVBOXVHWA_BUFFER_DATA vboxglBufferData = NULL;
87PFNVBOXVHWA_MAP_BUFFER vboxglMapBuffer = NULL;
88PFNVBOXVHWA_UNMAP_BUFFER vboxglUnmapBuffer = NULL;
89
90PFNVBOXVHWA_IS_FRAMEBUFFER vboxglIsFramebuffer = NULL;
91PFNVBOXVHWA_BIND_FRAMEBUFFER vboxglBindFramebuffer = NULL;
92PFNVBOXVHWA_DELETE_FRAMEBUFFERS vboxglDeleteFramebuffers = NULL;
93PFNVBOXVHWA_GEN_FRAMEBUFFERS vboxglGenFramebuffers = NULL;
94PFNVBOXVHWA_CHECK_FRAMEBUFFER_STATUS vboxglCheckFramebufferStatus = NULL;
95PFNVBOXVHWA_FRAMEBUFFER_TEXTURE1D vboxglFramebufferTexture1D = NULL;
96PFNVBOXVHWA_FRAMEBUFFER_TEXTURE2D vboxglFramebufferTexture2D = NULL;
97PFNVBOXVHWA_FRAMEBUFFER_TEXTURE3D vboxglFramebufferTexture3D = NULL;
98PFNVBOXVHWA_GET_FRAMEBUFFER_ATTACHMENT_PARAMETRIV vboxglGetFramebufferAttachmentParameteriv = NULL;
99
100#define VBOXVHWA_GETPROCADDRESS(_c, _t, _n) ((_t)(uintptr_t)(_c).getProcAddress(QString(_n)))
101
102#define VBOXVHWA_PFNINIT_SAME(_c, _t, _v, _rc) \
103 do { \
104 if((vboxgl##_v = VBOXVHWA_GETPROCADDRESS(_c, _t, "gl"#_v)) == NULL) \
105 { \
106 VBOXQGLLOGREL(("ERROR: '%s' function not found\n", "gl"#_v));\
107 AssertBreakpoint(); \
108 if((vboxgl##_v = VBOXVHWA_GETPROCADDRESS(_c, _t, "gl"#_v"ARB")) == NULL) \
109 { \
110 VBOXQGLLOGREL(("ERROR: '%s' function not found\n", "gl"#_v"ARB"));\
111 AssertBreakpoint(); \
112 if((vboxgl##_v = VBOXVHWA_GETPROCADDRESS(_c, _t, "gl"#_v"EXT")) == NULL) \
113 { \
114 VBOXQGLLOGREL(("ERROR: '%s' function not found\n", "gl"#_v"EXT"));\
115 AssertBreakpoint(); \
116 (_rc)++; \
117 } \
118 } \
119 } \
120 }while(0)
121
122#define VBOXVHWA_PFNINIT(_c, _t, _v, _f,_rc) \
123 do { \
124 if((vboxgl##_v = VBOXVHWA_GETPROCADDRESS(_c, _t, "gl"#_f)) == NULL) \
125 { \
126 VBOXQGLLOGREL(("ERROR: '%s' function is not found\n", "gl"#_f));\
127 AssertBreakpoint(); \
128 (_rc)++; \
129 } \
130 }while(0)
131
132#define VBOXVHWA_PFNINIT_OBJECT_ARB(_c, _t, _v, _rc) \
133 do { \
134 if((vboxgl##_v = VBOXVHWA_GETPROCADDRESS(_c, _t, "gl"#_v"ObjectARB")) == NULL) \
135 { \
136 VBOXQGLLOGREL(("ERROR: '%s' function is not found\n", "gl"#_v"ObjectARB"));\
137 AssertBreakpoint(); \
138 (_rc)++; \
139 } \
140 }while(0)
141
142#define VBOXVHWA_PFNINIT_ARB(_c, _t, _v, _rc) \
143 do { \
144 if((vboxgl##_v = VBOXVHWA_GETPROCADDRESS(_c, _t, "gl"#_v"ARB")) == NULL) \
145 { \
146 VBOXQGLLOGREL(("ERROR: '%s' function is not found\n", "gl"#_v"ARB"));\
147 AssertBreakpoint(); \
148 (_rc)++; \
149 } \
150 }while(0)
151
152#define VBOXVHWA_PFNINIT_EXT(_c, _t, _v, _rc) \
153 do { \
154 if((vboxgl##_v = VBOXVHWA_GETPROCADDRESS(_c, _t, "gl"#_v"EXT")) == NULL) \
155 { \
156 VBOXQGLLOGREL(("ERROR: '%s' function is not found\n", "gl"#_v"EXT"));\
157 AssertBreakpoint(); \
158 (_rc)++; \
159 } \
160 }while(0)
161
162static int vboxVHWAGlParseSubver(const GLubyte * ver, const GLubyte ** pNext, bool bSpacePrefixAllowed)
163{
164 int val = 0;
165
166 for(;;++ver)
167 {
168 if(*ver >= '0' && *ver <= '9')
169 {
170 if(!val)
171 {
172 if(*ver == '0')
173 continue;
174 }
175 else
176 {
177 val *= 10;
178 }
179 val += *ver - '0';
180 }
181 else if(*ver == '.')
182 {
183 *pNext = ver+1;
184 break;
185 }
186 else if(*ver == '\0')
187 {
188 *pNext = NULL;
189 break;
190 }
191 else if(*ver == ' ' || *ver == '\t' || *ver == 0x0d || *ver == 0x0a)
192 {
193 if(bSpacePrefixAllowed)
194 {
195 if(!val)
196 {
197 continue;
198 }
199 }
200
201 /* treat this as the end ov version string */
202 *pNext = NULL;
203 break;
204 }
205 else
206 {
207 Assert(0);
208 val = -1;
209 break;
210 }
211 }
212
213 return val;
214}
215
216/* static */
217int VBoxGLInfo::parseVersion(const GLubyte * ver)
218{
219 int iVer = vboxVHWAGlParseSubver(ver, &ver, true);
220 if(iVer)
221 {
222 iVer <<= 16;
223 if(ver)
224 {
225 int tmp = vboxVHWAGlParseSubver(ver, &ver, false);
226 if(tmp >= 0)
227 {
228 iVer |= tmp << 8;
229 if(ver)
230 {
231 tmp = vboxVHWAGlParseSubver(ver, &ver, false);
232 if(tmp >= 0)
233 {
234 iVer |= tmp;
235 }
236 else
237 {
238 Assert(0);
239 iVer = -1;
240 }
241 }
242 }
243 else
244 {
245 Assert(0);
246 iVer = -1;
247 }
248 }
249 }
250 return iVer;
251}
252
253void VBoxGLInfo::init(const QGLContext * pContext)
254{
255 if(mInitialized)
256 return;
257
258 mInitialized = true;
259
260 if (!QGLFormat::hasOpenGL())
261 {
262 VBOXQGLLOGREL (("no gl support available\n"));
263 return;
264 }
265
266// pContext->makeCurrent();
267
268 const GLubyte * str;
269 VBOXQGL_CHECKERR(
270 str = glGetString(GL_VERSION);
271 );
272
273 if(str)
274 {
275 VBOXQGLLOGREL (("gl version string: 0%s\n", str));
276
277 mGLVersion = parseVersion (str);
278 Assert(mGLVersion > 0);
279 if(mGLVersion < 0)
280 {
281 mGLVersion = 0;
282 }
283 else
284 {
285 VBOXQGLLOGREL (("gl version: 0x%x\n", mGLVersion));
286 VBOXQGL_CHECKERR(
287 str = glGetString (GL_EXTENSIONS);
288 );
289
290 VBOXQGLLOGREL (("gl extensions: %s\n", str));
291
292 const char * pos = strstr((const char *)str, "GL_ARB_multitexture");
293 m_GL_ARB_multitexture = pos != NULL;
294 VBOXQGLLOGREL (("GL_ARB_multitexture: %d\n", m_GL_ARB_multitexture));
295
296 pos = strstr((const char *)str, "GL_ARB_shader_objects");
297 m_GL_ARB_shader_objects = pos != NULL;
298 VBOXQGLLOGREL (("GL_ARB_shader_objects: %d\n", m_GL_ARB_shader_objects));
299
300 pos = strstr((const char *)str, "GL_ARB_fragment_shader");
301 m_GL_ARB_fragment_shader = pos != NULL;
302 VBOXQGLLOGREL (("GL_ARB_fragment_shader: %d\n", m_GL_ARB_fragment_shader));
303
304 pos = strstr((const char *)str, "GL_ARB_pixel_buffer_object");
305 m_GL_ARB_pixel_buffer_object = pos != NULL;
306 VBOXQGLLOGREL (("GL_ARB_pixel_buffer_object: %d\n", m_GL_ARB_pixel_buffer_object));
307
308 pos = strstr((const char *)str, "GL_ARB_texture_rectangle");
309 m_GL_ARB_texture_rectangle = pos != NULL;
310 VBOXQGLLOGREL (("GL_ARB_texture_rectangle: %d\n", m_GL_ARB_texture_rectangle));
311
312 pos = strstr((const char *)str, "GL_EXT_texture_rectangle");
313 m_GL_EXT_texture_rectangle = pos != NULL;
314 VBOXQGLLOGREL (("GL_EXT_texture_rectangle: %d\n", m_GL_EXT_texture_rectangle));
315
316 pos = strstr((const char *)str, "GL_NV_texture_rectangle");
317 m_GL_NV_texture_rectangle = pos != NULL;
318 VBOXQGLLOGREL (("GL_NV_texture_rectangle: %d\n", m_GL_NV_texture_rectangle));
319
320 pos = strstr((const char *)str, "GL_ARB_texture_non_power_of_two");
321 m_GL_ARB_texture_non_power_of_two = pos != NULL;
322 VBOXQGLLOGREL (("GL_ARB_texture_non_power_of_two: %d\n", m_GL_ARB_texture_non_power_of_two));
323
324 pos = strstr((const char *)str, "GL_EXT_framebuffer_object");
325 m_GL_EXT_framebuffer_object = pos != NULL;
326 VBOXQGLLOGREL (("GL_EXT_framebuffer_object: %d\n", m_GL_EXT_framebuffer_object));
327
328
329 initExtSupport(*pContext);
330 }
331 }
332 else
333 {
334 VBOXQGLLOGREL (("failed to make the context current, treating as unsupported\n"));
335 }
336}
337
338void VBoxGLInfo::initExtSupport(const QGLContext & context)
339{
340 int rc = 0;
341 do
342 {
343 rc = 0;
344 mMultiTexNumSupported = 1; /* default, 1 means not supported */
345 if(mGLVersion >= 0x010201) /* ogl >= 1.2.1 */
346 {
347 VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_ACTIVE_TEXTURE, ActiveTexture, rc);
348 VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_MULTI_TEX_COORD2I, MultiTexCoord2i, rc);
349 VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_MULTI_TEX_COORD2D, MultiTexCoord2d, rc);
350 VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_MULTI_TEX_COORD2F, MultiTexCoord2f, rc);
351 }
352 else if(m_GL_ARB_multitexture)
353 {
354 VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_ACTIVE_TEXTURE, ActiveTexture, rc);
355 VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_MULTI_TEX_COORD2I, MultiTexCoord2i, rc);
356 VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_MULTI_TEX_COORD2D, MultiTexCoord2d, rc);
357 VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_MULTI_TEX_COORD2F, MultiTexCoord2f, rc);
358 }
359 else
360 {
361 break;
362 }
363
364 if(RT_FAILURE(rc))
365 break;
366
367 GLint maxCoords, maxUnits;
368 glGetIntegerv(GL_MAX_TEXTURE_COORDS, &maxCoords);
369 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxUnits);
370
371 VBOXQGLLOGREL(("Max Tex Coords (%d), Img Units (%d)\n", maxCoords, maxUnits));
372 /* take the minimum of those */
373 if(maxUnits < maxCoords)
374 maxCoords = maxUnits;
375 if(maxUnits < 2)
376 {
377 VBOXQGLLOGREL(("Max Tex Coord or Img Units < 2 disabling MultiTex support\n"));
378 break;
379 }
380
381 mMultiTexNumSupported = maxUnits;
382 }while(0);
383
384
385 do
386 {
387 rc = 0;
388 mPBOSupported = false;
389
390 if(m_GL_ARB_pixel_buffer_object)
391 {
392 VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_GEN_BUFFERS, GenBuffers, rc);
393 VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_DELETE_BUFFERS, DeleteBuffers, rc);
394 VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_BIND_BUFFER, BindBuffer, rc);
395 VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_BUFFER_DATA, BufferData, rc);
396 VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_MAP_BUFFER, MapBuffer, rc);
397 VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNMAP_BUFFER, UnmapBuffer, rc);
398 }
399 else
400 {
401 break;
402 }
403
404 if(RT_FAILURE(rc))
405 break;
406
407 mPBOSupported = true;
408 } while(0);
409
410 do
411 {
412 rc = 0;
413 mFragmentShaderSupported = false;
414
415 if(mGLVersion >= 0x020000) /* if ogl >= 2.0*/
416 {
417 VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_CREATE_SHADER, CreateShader, rc);
418 VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_SHADER_SOURCE, ShaderSource, rc);
419 VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_COMPILE_SHADER, CompileShader, rc);
420 VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_DELETE_SHADER, DeleteShader, rc);
421
422 VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_CREATE_PROGRAM, CreateProgram, rc);
423 VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_ATTACH_SHADER, AttachShader, rc);
424 VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_DETACH_SHADER, DetachShader, rc);
425 VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_LINK_PROGRAM, LinkProgram, rc);
426 VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_USE_PROGRAM, UseProgram, rc);
427 VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_DELETE_PROGRAM, DeleteProgram, rc);
428
429 VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_IS_SHADER, IsShader, rc);
430 VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_GET_SHADERIV, GetShaderiv, rc);
431 VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_IS_PROGRAM, IsProgram, rc);
432 VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_GET_PROGRAMIV, GetProgramiv, rc);
433 VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_GET_ATTACHED_SHADERS, GetAttachedShaders, rc);
434 VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_GET_SHADER_INFO_LOG, GetShaderInfoLog, rc);
435 VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_GET_PROGRAM_INFO_LOG, GetProgramInfoLog, rc);
436
437 VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_GET_UNIFORM_LOCATION, GetUniformLocation, rc);
438
439 VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM1F, Uniform1f, rc);
440 VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM2F, Uniform2f, rc);
441 VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM3F, Uniform3f, rc);
442 VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM4F, Uniform4f, rc);
443
444 VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM1I, Uniform1i, rc);
445 VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM2I, Uniform2i, rc);
446 VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM3I, Uniform3i, rc);
447 VBOXVHWA_PFNINIT_SAME(context, PFNVBOXVHWA_UNIFORM4I, Uniform4i, rc);
448 }
449 else if(m_GL_ARB_shader_objects && m_GL_ARB_fragment_shader)
450 {
451 VBOXVHWA_PFNINIT_OBJECT_ARB(context, PFNVBOXVHWA_CREATE_SHADER, CreateShader, rc);
452 VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_SHADER_SOURCE, ShaderSource, rc);
453 VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_COMPILE_SHADER, CompileShader, rc);
454 VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_DELETE_SHADER, DeleteShader, DeleteObjectARB, rc);
455
456 VBOXVHWA_PFNINIT_OBJECT_ARB(context, PFNVBOXVHWA_CREATE_PROGRAM, CreateProgram, rc);
457 VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_ATTACH_SHADER, AttachShader, AttachObjectARB, rc);
458 VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_DETACH_SHADER, DetachShader, DetachObjectARB, rc);
459 VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_LINK_PROGRAM, LinkProgram, rc);
460 VBOXVHWA_PFNINIT_OBJECT_ARB(context, PFNVBOXVHWA_USE_PROGRAM, UseProgram, rc);
461 VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_DELETE_PROGRAM, DeleteProgram, DeleteObjectARB, rc);
462
463 //TODO: VBOXVHWA_PFNINIT(PFNVBOXVHWA_IS_SHADER, IsShader, rc);
464 VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_GET_SHADERIV, GetShaderiv, GetObjectParameterivARB, rc);
465 //TODO: VBOXVHWA_PFNINIT(PFNVBOXVHWA_IS_PROGRAM, IsProgram, rc);
466 VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_GET_PROGRAMIV, GetProgramiv, GetObjectParameterivARB, rc);
467 VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_GET_ATTACHED_SHADERS, GetAttachedShaders, GetAttachedObjectsARB, rc);
468 VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_GET_SHADER_INFO_LOG, GetShaderInfoLog, GetInfoLogARB, rc);
469 VBOXVHWA_PFNINIT(context, PFNVBOXVHWA_GET_PROGRAM_INFO_LOG, GetProgramInfoLog, GetInfoLogARB, rc);
470
471 VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_GET_UNIFORM_LOCATION, GetUniformLocation, rc);
472
473 VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM1F, Uniform1f, rc);
474 VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM2F, Uniform2f, rc);
475 VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM3F, Uniform3f, rc);
476 VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM4F, Uniform4f, rc);
477
478 VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM1I, Uniform1i, rc);
479 VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM2I, Uniform2i, rc);
480 VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM3I, Uniform3i, rc);
481 VBOXVHWA_PFNINIT_ARB(context, PFNVBOXVHWA_UNIFORM4I, Uniform4i, rc);
482 }
483 else
484 {
485 break;
486 }
487
488 if(RT_FAILURE(rc))
489 break;
490
491 mFragmentShaderSupported = true;
492 } while(0);
493
494 do
495 {
496 rc = 0;
497 mFBOSupported = false;
498
499 if(m_GL_EXT_framebuffer_object)
500 {
501 VBOXVHWA_PFNINIT_EXT(context, PFNVBOXVHWA_IS_FRAMEBUFFER, IsFramebuffer, rc);
502 VBOXVHWA_PFNINIT_EXT(context, PFNVBOXVHWA_BIND_FRAMEBUFFER, BindFramebuffer, rc);
503 VBOXVHWA_PFNINIT_EXT(context, PFNVBOXVHWA_DELETE_FRAMEBUFFERS, DeleteFramebuffers, rc);
504 VBOXVHWA_PFNINIT_EXT(context, PFNVBOXVHWA_GEN_FRAMEBUFFERS, GenFramebuffers, rc);
505 VBOXVHWA_PFNINIT_EXT(context, PFNVBOXVHWA_CHECK_FRAMEBUFFER_STATUS, CheckFramebufferStatus, rc);
506 VBOXVHWA_PFNINIT_EXT(context, PFNVBOXVHWA_FRAMEBUFFER_TEXTURE1D, FramebufferTexture1D, rc);
507 VBOXVHWA_PFNINIT_EXT(context, PFNVBOXVHWA_FRAMEBUFFER_TEXTURE2D, FramebufferTexture2D, rc);
508 VBOXVHWA_PFNINIT_EXT(context, PFNVBOXVHWA_FRAMEBUFFER_TEXTURE3D, FramebufferTexture3D, rc);
509 VBOXVHWA_PFNINIT_EXT(context, PFNVBOXVHWA_GET_FRAMEBUFFER_ATTACHMENT_PARAMETRIV, GetFramebufferAttachmentParameteriv, rc);
510 }
511 else
512 {
513 break;
514 }
515
516 if(RT_FAILURE(rc))
517 break;
518
519 mFBOSupported = true;
520 } while(0);
521
522 if(m_GL_ARB_texture_rectangle || m_GL_EXT_texture_rectangle || m_GL_NV_texture_rectangle)
523 {
524 mTextureRectangleSupported = true;
525 }
526 else
527 {
528 mTextureRectangleSupported = false;
529 }
530
531 mTextureNP2Supported = m_GL_ARB_texture_non_power_of_two;
532}
533
534void VBoxVHWAInfo::init(const QGLContext * pContext)
535{
536 if(mInitialized)
537 return;
538
539 mInitialized = true;
540
541 mglInfo.init(pContext);
542
543 if(mglInfo.isFragmentShaderSupported() && mglInfo.isTextureRectangleSupported())
544 {
545 uint32_t num = 0;
546 mFourccSupportedList[num++] = FOURCC_AYUV;
547 mFourccSupportedList[num++] = FOURCC_UYVY;
548 mFourccSupportedList[num++] = FOURCC_YUY2;
549 if(mglInfo.getMultiTexNumSupported() >= 4)
550 {
551 /* YV12 currently requires 3 units (for each color component)
552 * + 1 unit for dst texture for color-keying + 3 units for each color component
553 * TODO: we could store YV12 data in one texture to eliminate this requirement*/
554 mFourccSupportedList[num++] = FOURCC_YV12;
555 }
556
557 Assert(num <= VBOXVHWA_NUMFOURCC);
558 mFourccSupportedCount = num;
559 }
560 else
561 {
562 mFourccSupportedCount = 0;
563 }
564}
565
566bool VBoxVHWAInfo::isVHWASupported() const
567{
568 if(mglInfo.getGLVersion() <= 0)
569 {
570 /* error occurred while gl info initialization */
571 VBOXQGLLOGREL(("2D not supported: gl version info not initialized properly\n"));
572 return false;
573 }
574
575#ifndef DEBUGVHWASTRICT
576 /* in case we do not support shaders & multitexturing we can not support dst colorkey,
577 * no sense to report Video Acceleration supported */
578 if(!mglInfo.isFragmentShaderSupported())
579 {
580 VBOXQGLLOGREL(("2D not supported: fragment shader unsupported\n"));
581 return false;
582 }
583#endif
584 if(mglInfo.getMultiTexNumSupported() < 2)
585 {
586 VBOXQGLLOGREL(("2D not supported: multitexture unsupported\n"));
587 return false;
588 }
589
590 /* color conversion now supported only GL_TEXTURE_RECTANGLE
591 * in this case only stretching is accelerated
592 * report as unsupported, TODO: probably should report as supported for stretch acceleration */
593 if(!mglInfo.isTextureRectangleSupported())
594 {
595 VBOXQGLLOGREL(("2D not supported: texture rectangle unsupported\n"));
596 return false;
597 }
598
599 VBOXQGLLOGREL(("2D is supported!\n"));
600 return true;
601}
602
603/* static */
604bool VBoxVHWAInfo::checkVHWASupport()
605{
606#if defined(RT_OS_WINDOWS) || defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD)
607 static char pszVBoxPath[RTPATH_MAX];
608 const char *papszArgs[] = { NULL, "-test", "2D", NULL};
609 int rc;
610 RTPROCESS Process;
611 RTPROCSTATUS ProcStatus;
612 uint64_t StartTS;
613
614 rc = RTPathExecDir(pszVBoxPath, RTPATH_MAX); AssertRCReturn(rc, false);
615#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
616 rc = RTPathAppend(pszVBoxPath, RTPATH_MAX, "VBoxTestOGL.exe");
617#else
618 rc = RTPathAppend(pszVBoxPath, RTPATH_MAX, "VBoxTestOGL");
619#endif
620 papszArgs[0] = pszVBoxPath; /* argv[0] */
621 AssertRCReturn(rc, false);
622
623 rc = RTProcCreate(pszVBoxPath, papszArgs, RTENV_DEFAULT, 0, &Process);
624 if (RT_FAILURE(rc))
625 {
626 VBOXQGLLOGREL(("2D support test failed: failed to create a test process\n"));
627 return false;
628 }
629
630 StartTS = RTTimeMilliTS();
631
632 while (1)
633 {
634 rc = RTProcWait(Process, RTPROCWAIT_FLAGS_NOBLOCK, &ProcStatus);
635 if (rc != VERR_PROCESS_RUNNING)
636 break;
637
638 if (RTTimeMilliTS() - StartTS > 30*1000 /* 30 sec */)
639 {
640 RTProcTerminate(Process);
641 RTThreadSleep(100);
642 RTProcWait(Process, RTPROCWAIT_FLAGS_NOBLOCK, &ProcStatus);
643 VBOXQGLLOGREL(("2D support test failed: the test did not complete within 30 sec\n"));
644 return false;
645 }
646 RTThreadSleep(100);
647 }
648
649 if (RT_SUCCESS(rc))
650 {
651 if ((ProcStatus.enmReason==RTPROCEXITREASON_NORMAL) && (ProcStatus.iStatus==0))
652 {
653 VBOXQGLLOGREL(("2D support test succeeded\n"));
654 return true;
655 }
656 }
657
658 VBOXQGLLOGREL(("2D support test failed: err code (%Rra)\n", rc));
659
660 return false;
661#else
662 /* @todo: test & enable external app approach*/
663 VBoxGLTmpContext ctx;
664 const QGLContext *pContext = ctx.makeCurrent();
665 Assert(pContext);
666 if(pContext)
667 {
668 VBoxVHWAInfo info;
669 info.init(pContext);
670 return info.isVHWASupported();
671 }
672 return false;
673#endif
674}
675
676VBoxGLTmpContext::VBoxGLTmpContext()
677{
678 if(QGLFormat::hasOpenGL())
679 {
680 mWidget = new QGLWidget();
681 }
682 else
683 {
684 mWidget = NULL;
685 }
686}
687
688VBoxGLTmpContext::~VBoxGLTmpContext()
689{
690 if(mWidget)
691 delete mWidget;
692}
693
694const class QGLContext * VBoxGLTmpContext::makeCurrent()
695{
696 if(mWidget)
697 {
698 mWidget->makeCurrent();
699 return mWidget->context();
700 }
701 return NULL;
702}
703
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use