VirtualBox

source: vbox/trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-internal.h@ 76553

Last change on this file since 76553 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 50.1 KB
Line 
1/* $Id: DevVGA-SVGA3d-internal.h 76553 2019-01-01 01:45:53Z vboxsync $ */
2/** @file
3 * DevVMWare - VMWare SVGA device - 3D part, internal header.
4 */
5
6/*
7 * Copyright (C) 2013-2019 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef ___DevVGA_SVGA3d_internal_h
19#define ___DevVGA_SVGA3d_internal_h
20#ifndef RT_WITHOUT_PRAGMA_ONCE
21# pragma once
22#endif
23
24/*
25 * Assert sane compilation environment.
26 */
27#ifndef IN_RING3
28# error "VMSVGA3D_INCL_INTERNALS is only for ring-3 code"
29#endif
30#ifdef VMSVGA3D_OPENGL
31# ifdef VMSVGA3D_DIRECT3D
32# error "Both VMSVGA3D_DIRECT3D and VMSVGA3D_OPENGL cannot be defined at the same time."
33# endif
34#elif !defined(VMSVGA3D_DIRECT3D)
35# error "Either VMSVGA3D_OPENGL or VMSVGA3D_DIRECT3D must be defined."
36#endif
37
38
39/*********************************************************************************************************************************
40* Header Files *
41*********************************************************************************************************************************/
42#include "DevVGA-SVGA3d.h"
43
44#if defined(VMSVGA3D_DYNAMIC_LOAD) && defined(VMSVGA3D_OPENGL)
45# include "DevVGA-SVGA3d-glLdr.h"
46#endif
47
48#ifdef RT_OS_WINDOWS
49# include <iprt/win/windows.h>
50# ifdef VMSVGA3D_DIRECT3D
51# include <d3d9.h>
52# include <iprt/avl.h>
53# else
54# include <GL/gl.h>
55# include "vmsvga_glext/wglext.h"
56# endif
57
58#elif defined(RT_OS_DARWIN)
59# include <OpenGL/OpenGL.h>
60# include <OpenGL/gl3.h>
61# include <OpenGL/gl3ext.h>
62# define GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED
63# include <OpenGL/gl.h>
64# include <OpenGL/glext.h>
65# include "DevVGA-SVGA3d-cocoa.h"
66/* work around conflicting definition of GLhandleARB in VMware's glext.h */
67//#define GL_ARB_shader_objects
68// HACK
69typedef void (APIENTRYP PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
70typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture);
71typedef void (APIENTRYP PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint *params);
72# define GL_RGBA_S3TC 0x83A2
73# define GL_ALPHA8_EXT 0x803c
74# define GL_LUMINANCE8_EXT 0x8040
75# define GL_LUMINANCE16_EXT 0x8042
76# define GL_LUMINANCE4_ALPHA4_EXT 0x8043
77# define GL_LUMINANCE8_ALPHA8_EXT 0x8045
78# define GL_INT_2_10_10_10_REV 0x8D9F
79
80#else
81# include <X11/Xlib.h>
82# include <X11/Xatom.h>
83# include <GL/gl.h>
84# include <GL/glx.h>
85# include <GL/glext.h>
86# define VBOX_VMSVGA3D_GL_HACK_LEVEL 0x103
87#endif
88
89#include "vmsvga/svga3d_shaderdefs.h"
90#ifdef VMSVGA3D_OPENGL
91# include "vmsvga_glext/glext.h"
92# include "shaderlib/shaderlib.h"
93#endif
94
95
96/*********************************************************************************************************************************
97* Defined Constants And Macros *
98*********************************************************************************************************************************/
99#ifdef VMSVGA3D_OPENGL
100/** OpenGL: Create a dedicated context for handling surfaces in, thus
101 * avoiding orphaned surfaces after context destruction.
102 *
103 * This cures, for instance, an assertion on fedora 21 that happens in
104 * vmsvga3dSurfaceStretchBlt if the login screen and the desktop has different
105 * sizes. The context of the login screen seems to have just been destroyed
106 * earlier and I believe the driver/X/whoever is attemting to strech the old
107 * screen content onto the new sized screen.
108 *
109 * @remarks This probably comes at a slight preformance expense, as we currently
110 * switches context when setting up the surface the first time. Not sure
111 * if we really need to, but as this is an experiment, I'm playing it safe.
112 * @remarks The define has been made default, thus should no longer be used.
113 */
114# define VMSVGA3D_OGL_WITH_SHARED_CTX
115/** Fake surface ID for the shared context. */
116# define VMSVGA3D_SHARED_CTX_ID UINT32_C(0xffffeeee)
117
118/** @def VBOX_VMSVGA3D_GL_HACK_LEVEL
119 * Turns out that on Linux gl.h may often define the first 2-4 OpenGL versions
120 * worth of extensions, but missing out on a function pointer of fifteen. This
121 * causes headache for us when we use the function pointers below. This hack
122 * changes the code to call the known problematic functions directly.
123 * The value is ((x)<<16 | (y)) where x and y are taken from the GL_VERSION_x_y.
124 */
125# ifndef VBOX_VMSVGA3D_GL_HACK_LEVEL
126# define VBOX_VMSVGA3D_GL_HACK_LEVEL 0
127# endif
128
129/** Invalid OpenGL ID. */
130# define OPENGL_INVALID_ID 0
131
132# define VMSVGA3D_CLEAR_CURRENT_CONTEXT(pState) \
133 do { (pState)->idActiveContext = OPENGL_INVALID_ID; } while (0)
134
135/** @def VMSVGA3D_SET_CURRENT_CONTEXT
136 * Makes sure the @a pContext is the active OpenGL context.
137 * @parm pState The VMSVGA3d state.
138 * @parm pContext The new context.
139 */
140# ifdef RT_OS_WINDOWS
141# define VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext) \
142 do { \
143 if ((pState)->idActiveContext != (pContext)->id) \
144 { \
145 BOOL fMakeCurrentRc = wglMakeCurrent((pContext)->hdc, (pContext)->hglrc); \
146 Assert(fMakeCurrentRc == TRUE); RT_NOREF_PV(fMakeCurrentRc); \
147 LogFlowFunc(("Changing context: %#x -> %#x\n", (pState)->idActiveContext, (pContext)->id)); \
148 (pState)->idActiveContext = (pContext)->id; \
149 } \
150 } while (0)
151
152# elif defined(RT_OS_DARWIN)
153# define VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext) \
154 do { \
155 if ((pState)->idActiveContext != (pContext)->id) \
156 { \
157 vmsvga3dCocoaViewMakeCurrentContext((pContext)->cocoaView, (pContext)->cocoaContext); \
158 LogFlowFunc(("Changing context: %#x -> %#x\n", (pState)->idActiveContext, (pContext)->id)); \
159 (pState)->idActiveContext = (pContext)->id; \
160 } \
161 } while (0)
162# else
163# define VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext) \
164 do { \
165 if ((pState)->idActiveContext != (pContext)->id) \
166 { \
167 Bool fMakeCurrentRc = glXMakeCurrent((pState)->display, \
168 (pContext)->window, \
169 (pContext)->glxContext); \
170 Assert(fMakeCurrentRc == True); RT_NOREF_PV(fMakeCurrentRc); \
171 LogFlowFunc(("Changing context: %#x -> %#x\n", (pState)->idActiveContext, (pContext)->id)); \
172 (pState)->idActiveContext = (pContext)->id; \
173 } \
174 } while (0)
175# endif
176
177/** @def VMSVGA3D_CLEAR_GL_ERRORS
178 * Clears all pending OpenGL errors.
179 *
180 * If I understood this correctly, OpenGL maintains a bitmask internally and
181 * glGetError gets the next bit (clearing it) from the bitmap and translates it
182 * into a GL_XXX constant value which it then returns. A single OpenGL call can
183 * set more than one bit, and they stick around across calls, from what I
184 * understand.
185 *
186 * So in order to be able to use glGetError to check whether a function
187 * succeeded, we need to call glGetError until all error bits have been cleared.
188 * This macro does that (in all types of builds).
189 *
190 * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS
191 */
192# define VMSVGA3D_CLEAR_GL_ERRORS() \
193 do { \
194 if (RT_UNLIKELY(glGetError() != GL_NO_ERROR)) /* predict no errors pending */ \
195 { \
196 uint32_t iErrorClearingLoopsLeft = 64; \
197 while (glGetError() != GL_NO_ERROR && iErrorClearingLoopsLeft > 0) \
198 iErrorClearingLoopsLeft--; \
199 } \
200 } while (0)
201
202/** @def VMSVGA3D_GET_LAST_GL_ERROR
203 * Gets the last OpenGL error, stores it in a_pContext->lastError and returns
204 * it.
205 *
206 * @returns Same as glGetError.
207 * @param a_pContext The context to store the error in.
208 *
209 * @sa VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN
210 */
211# define VMSVGA3D_GET_GL_ERROR(a_pContext) ((a_pContext)->lastError = glGetError())
212
213/** @def VMSVGA3D_GL_SUCCESS
214 * Checks whether VMSVGA3D_GET_LAST_GL_ERROR() return GL_NO_ERROR.
215 *
216 * Will call glGetError() and store the result in a_pContext->lastError.
217 * Will predict GL_NO_ERROR outcome.
218 *
219 * @returns True on success, false on error.
220 * @parm a_pContext The context to store the error in.
221 *
222 * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_COMPLAIN
223 */
224# define VMSVGA3D_GL_IS_SUCCESS(a_pContext) RT_LIKELY((((a_pContext)->lastError = glGetError()) == GL_NO_ERROR))
225
226/** @def VMSVGA3D_GL_COMPLAIN
227 * Complains about one or more OpenGL errors (first in a_pContext->lastError).
228 *
229 * Strict builds will trigger an assertion, while other builds will put the
230 * first few occurences in the release log.
231 *
232 * All GL errors will be cleared after invocation. Assumes lastError
233 * is an error, will not check for GL_NO_ERROR.
234 *
235 * @param a_pState The 3D state structure.
236 * @param a_pContext The context that holds the first error.
237 * @param a_LogRelDetails Argument list for LogRel or similar that describes
238 * the operation in greater detail.
239 *
240 * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS
241 */
242# ifdef VBOX_STRICT
243# define VMSVGA3D_GL_COMPLAIN(a_pState, a_pContext, a_LogRelDetails) \
244 do { \
245 AssertMsg((a_pState)->idActiveContext == (a_pContext)->id, \
246 ("idActiveContext=%#x id=%x\n", (a_pState)->idActiveContext, (a_pContext)->id)); \
247 RTAssertMsg2Weak a_LogRelDetails; \
248 GLenum iNextError; \
249 while ((iNextError = glGetError()) != GL_NO_ERROR) \
250 RTAssertMsg2Weak("next error: %#x\n", iNextError); \
251 AssertMsgFailed(("first error: %#x (idActiveContext=%#x)\n", (a_pContext)->lastError, (a_pContext)->id)); \
252 } while (0)
253# else
254# define VMSVGA3D_GL_COMPLAIN(a_pState, a_pContext, a_LogRelDetails) \
255 do { \
256 LogRelMax(32, ("VMSVGA3d: OpenGL error %#x (idActiveContext=%#x) on line %u ", (a_pContext)->lastError, (a_pContext)->id)); \
257 GLenum iNextError; \
258 while ((iNextError = glGetError()) != GL_NO_ERROR) \
259 LogRelMax(32, (" - also error %#x ", iNextError)); \
260 LogRelMax(32, a_LogRelDetails); \
261 } while (0)
262# endif
263
264/** @def VMSVGA3D_GL_GET_AND_COMPLAIN
265 * Combination of VMSVGA3D_GET_GL_ERROR and VMSVGA3D_GL_COMPLAIN, assuming that
266 * there is a pending error.
267 *
268 * @param a_pState The 3D state structure.
269 * @param a_pContext The context that holds the first error.
270 * @param a_LogRelDetails Argument list for LogRel or similar that describes
271 * the operation in greater detail.
272 *
273 * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN
274 */
275# define VMSVGA3D_GL_GET_AND_COMPLAIN(a_pState, a_pContext, a_LogRelDetails) \
276 do { \
277 VMSVGA3D_GET_GL_ERROR(a_pContext); \
278 VMSVGA3D_GL_COMPLAIN(a_pState, a_pContext, a_LogRelDetails); \
279 } while (0)
280
281/** @def VMSVGA3D_GL_ASSERT_SUCCESS
282 * Asserts that VMSVGA3D_GL_IS_SUCCESS is true, complains if not.
283 *
284 * Uses VMSVGA3D_GL_COMPLAIN for complaining, so check it out wrt to release
285 * logging in non-strict builds.
286 *
287 * @param a_pState The 3D state structure.
288 * @param a_pContext The context that holds the first error.
289 * @param a_LogRelDetails Argument list for LogRel or similar that describes
290 * the operation in greater detail.
291 *
292 * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN
293 */
294# define VMSVGA3D_GL_ASSERT_SUCCESS(a_pState, a_pContext, a_LogRelDetails) \
295 if (VMSVGA3D_GL_IS_SUCCESS(a_pContext)) \
296 { /* likely */ } \
297 else do { \
298 VMSVGA3D_GL_COMPLAIN(a_pState, a_pContext, a_LogRelDetails); \
299 } while (0)
300
301/** @def VMSVGA3D_ASSERT_GL_CALL_EX
302 * Executes the specified OpenGL API call and asserts that it succeeded, variant
303 * with extra logging flexibility.
304 *
305 * ASSUMES no GL errors pending prior to invocation - caller should use
306 * VMSVGA3D_CLEAR_GL_ERRORS if uncertain.
307 *
308 * Uses VMSVGA3D_GL_COMPLAIN for complaining, so check it out wrt to release
309 * logging in non-strict builds.
310 *
311 * @param a_GlCall Expression making an OpenGL call.
312 * @param a_pState The 3D state structure.
313 * @param a_pContext The context that holds the first error.
314 * @param a_LogRelDetails Argument list for LogRel or similar that describes
315 * the operation in greater detail.
316 *
317 * @sa VMSVGA3D_ASSERT_GL_CALL, VMSVGA3D_GL_ASSERT_SUCCESS,
318 * VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN
319 */
320# define VMSVGA3D_ASSERT_GL_CALL_EX(a_GlCall, a_pState, a_pContext, a_LogRelDetails) \
321 do { \
322 (a_GlCall); \
323 VMSVGA3D_GL_ASSERT_SUCCESS(a_pState, a_pContext, a_LogRelDetails); \
324 } while (0)
325
326/** @def VMSVGA3D_ASSERT_GL_CALL
327 * Executes the specified OpenGL API call and asserts that it succeeded.
328 *
329 * ASSUMES no GL errors pending prior to invocation - caller should use
330 * VMSVGA3D_CLEAR_GL_ERRORS if uncertain.
331 *
332 * Uses VMSVGA3D_GL_COMPLAIN for complaining, so check it out wrt to release
333 * logging in non-strict builds.
334 *
335 * @param a_GlCall Expression making an OpenGL call.
336 * @param a_pState The 3D state structure.
337 * @param a_pContext The context that holds the first error.
338 *
339 * @sa VMSVGA3D_ASSERT_GL_CALL_EX, VMSVGA3D_GL_ASSERT_SUCCESS,
340 * VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN
341 */
342# define VMSVGA3D_ASSERT_GL_CALL(a_GlCall, a_pState, a_pContext) \
343 VMSVGA3D_ASSERT_GL_CALL_EX(a_GlCall, a_pState, a_pContext, ("%s\n", #a_GlCall))
344
345
346/** @def VMSVGA3D_CHECK_LAST_ERROR
347 * Checks that the last OpenGL error code indicates success.
348 *
349 * Will assert and return VERR_INTERNAL_ERROR in strict builds, in other
350 * builds it will do nothing and is a NOOP.
351 *
352 * @parm pState The VMSVGA3d state.
353 * @parm pContext The context.
354 *
355 * @todo Replace with proper error handling, it's crazy to return
356 * VERR_INTERNAL_ERROR in strict builds and just barge on ahead in
357 * release builds.
358 */
359# ifdef VBOX_STRICT
360# define VMSVGA3D_CHECK_LAST_ERROR(pState, pContext) do { \
361 Assert((pState)->idActiveContext == (pContext)->id); \
362 (pContext)->lastError = glGetError(); \
363 AssertMsgReturn((pContext)->lastError == GL_NO_ERROR, \
364 ("%s (%d): last error 0x%x\n", __FUNCTION__, __LINE__, (pContext)->lastError), \
365 VERR_INTERNAL_ERROR); \
366 } while (0)
367# else
368# define VMSVGA3D_CHECK_LAST_ERROR(pState, pContext) do { } while (0)
369# endif
370
371/** @def VMSVGA3D_CHECK_LAST_ERROR_WARN
372 * Checks that the last OpenGL error code indicates success.
373 *
374 * Will assert in strict builds, otherwise it's a NOOP.
375 *
376 * @parm pState The VMSVGA3d state.
377 * @parm pContext The new context.
378 */
379# ifdef VBOX_STRICT
380# define VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext) do { \
381 Assert((pState)->idActiveContext == (pContext)->id); \
382 (pContext)->lastError = glGetError(); \
383 AssertMsg((pContext)->lastError == GL_NO_ERROR, ("%s (%d): last error 0x%x\n", __FUNCTION__, __LINE__, (pContext)->lastError)); \
384 } while (0)
385# else
386# define VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext) do { } while (0)
387# endif
388
389#endif /* VMSVGA3D_OPENGL */
390
391#ifdef VMSVGA3D_DIRECT3D
392/* Enable to use Wine to convert D3D to opengl */
393//#define VBOX_VMSVGA3D_WITH_WINE_OPENGL
394#endif
395
396
397/*********************************************************************************************************************************
398* Structures and Typedefs *
399*********************************************************************************************************************************/
400/**
401 * Mipmap level.
402 */
403typedef struct VMSVGA3DMIPMAPLEVEL
404{
405 /** The mipmap size: width, height and depth. */
406 SVGA3dSize mipmapSize;
407 /** Width in blocks: (width + cxBlock - 1) / cxBlock. SSM: not saved, recalculated on load. */
408 uint32_t cBlocksX;
409 /** Height in blocks: (height + cyBlock - 1) / cyBlock. SSM: not saved, recalculated on load. */
410 uint32_t cBlocksY;
411 /** The scanline/pitch size in bytes: at least cBlocksX * cbBlock. */
412 uint32_t cbSurfacePitch;
413 /** The size (in bytes) of the mipmap plane: cbSurfacePitch * cBlocksY */
414 uint32_t cbSurfacePlane;
415 /** The size (in bytes) of the mipmap data when using the format the surface was
416 * defined with: cbSurfacePlane * mipmapSize.z */
417 uint32_t cbSurface;
418 /** Pointer to the mipmap bytes (cbSurface). Often NULL. If the surface has
419 * been realized in hardware, this may be outdated. */
420 void *pSurfaceData;
421 /** Set if pvSurfaceData contains data not realized in hardware or pushed to the
422 * hardware surface yet. */
423 bool fDirty;
424} VMSVGA3DMIPMAPLEVEL;
425/** Pointer to a mipmap level. */
426typedef VMSVGA3DMIPMAPLEVEL *PVMSVGA3DMIPMAPLEVEL;
427
428
429#ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
430/**
431 * SSM descriptor table for the VMSVGA3DMIPMAPLEVEL structure.
432 */
433static SSMFIELD const g_aVMSVGA3DMIPMAPLEVELFields[] =
434{
435 SSMFIELD_ENTRY( VMSVGA3DMIPMAPLEVEL, mipmapSize),
436 SSMFIELD_ENTRY( VMSVGA3DMIPMAPLEVEL, cbSurface),
437 SSMFIELD_ENTRY( VMSVGA3DMIPMAPLEVEL, cbSurfacePitch),
438 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DMIPMAPLEVEL, pSurfaceData),
439 SSMFIELD_ENTRY_IGNORE( VMSVGA3DMIPMAPLEVEL, fDirty),
440 SSMFIELD_ENTRY_TERM()
441};
442#endif
443
444typedef struct VMSVGATRANSFORMSTATE
445{
446 bool fValid;
447 float matrix[16];
448} VMSVGATRANSFORMSTATE;
449typedef VMSVGATRANSFORMSTATE *PVMSVGATRANSFORMSTATE;
450
451typedef struct VMSVGAMATERIALSTATE
452{
453 bool fValid;
454 SVGA3dMaterial material;
455} VMSVGAMATERIALSTATE;
456typedef VMSVGAMATERIALSTATE *PVMSVGAMATERIALSTATE;
457
458typedef struct VMSVGACLIPPLANESTATE
459{
460 bool fValid;
461 float plane[4];
462} VMSVGACLIPPLANESTATE;
463typedef VMSVGACLIPPLANESTATE *PVMSVGACLIPPLANESTATE;
464
465typedef struct VMSVGALIGHTSTATE
466{
467 bool fEnabled;
468 bool fValidData;
469 SVGA3dLightData data;
470} VMSVGALIGHTSTATE;
471typedef VMSVGALIGHTSTATE *PVMSVGALIGHTSTATE;
472
473typedef struct VMSVGASHADERCONST
474{
475 bool fValid;
476 SVGA3dShaderConstType ctype;
477 uint32_t value[4];
478} VMSVGASHADERCONST;
479typedef VMSVGASHADERCONST *PVMSVGASHADERCONST;
480
481#ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
482/**
483 * SSM descriptor table for the VMSVGASHADERCONST structure.
484 */
485static SSMFIELD const g_aVMSVGASHADERCONSTFields[] =
486{
487 SSMFIELD_ENTRY( VMSVGASHADERCONST, fValid),
488 SSMFIELD_ENTRY( VMSVGASHADERCONST, ctype),
489 SSMFIELD_ENTRY( VMSVGASHADERCONST, value),
490 SSMFIELD_ENTRY_TERM()
491};
492#endif
493
494#ifdef VMSVGA3D_DIRECT3D
495
496/* What kind of Direct3D resource has been created for the VMSVGA3D surface. */
497typedef enum VMSVGA3DD3DRESTYPE
498{
499 VMSVGA3D_D3DRESTYPE_NONE = 0,
500 VMSVGA3D_D3DRESTYPE_SURFACE = 1,
501 VMSVGA3D_D3DRESTYPE_TEXTURE = 2,
502 VMSVGA3D_D3DRESTYPE_CUBE_TEXTURE = 3,
503 VMSVGA3D_D3DRESTYPE_VOLUME_TEXTURE = 4,
504 VMSVGA3D_D3DRESTYPE_VERTEX_BUFFER = 5,
505 VMSVGA3D_D3DRESTYPE_INDEX_BUFFER = 6
506} VMSVGA3DD3DRESTYPE;
507
508/**
509 *
510 */
511typedef struct
512{
513 /** Key is context id. */
514 AVLU32NODECORE Core;
515 union
516 {
517 IDirect3DSurface9 *pSurface;
518 IDirect3DTexture9 *pTexture;
519 IDirect3DCubeTexture9 *pCubeTexture;
520 IDirect3DVolumeTexture9 *pVolumeTexture;
521 } u;
522} VMSVGA3DSHAREDSURFACE;
523typedef VMSVGA3DSHAREDSURFACE *PVMSVGA3DSHAREDSURFACE;
524#endif /* VMSVGA3D_DIRECT3D */
525
526/**
527 * VMSVGA3d surface.
528 */
529typedef struct VMSVGA3DSURFACE
530{
531 uint32_t id;
532#ifdef VMSVGA3D_OPENGL
533 uint32_t idWeakContextAssociation;
534#else
535 uint32_t idAssociatedContext;
536#endif
537 uint32_t surfaceFlags;
538 SVGA3dSurfaceFormat format;
539#ifdef VMSVGA3D_OPENGL
540 GLint internalFormatGL;
541 GLint formatGL;
542 GLint typeGL;
543 union
544 {
545 GLuint texture;
546 GLuint buffer;
547 GLuint renderbuffer;
548 } oglId;
549 GLenum targetGL; /* GL_TEXTURE_* */
550 GLenum bindingGL; /* GL_TEXTURE_BINDING_* */
551#endif
552 SVGA3dSurfaceFace faces[SVGA3D_MAX_SURFACE_FACES];
553 uint32_t cFaces;
554 uint32_t cMipmapLevels;
555 PVMSVGA3DMIPMAPLEVEL pMipmapLevels;
556 uint32_t multiSampleCount;
557 SVGA3dTextureFilter autogenFilter;
558#ifdef VMSVGA3D_DIRECT3D
559 D3DFORMAT formatD3D;
560 DWORD fUsageD3D;
561 D3DMULTISAMPLE_TYPE multiSampleTypeD3D;
562#endif
563
564 uint32_t cbBlock; /* block/pixel size in bytes */
565 /* Dimensions of the surface block, usually 1x1 except for compressed formats. */
566 uint32_t cxBlock; /* Block width in pixels. SSM: not saved, recalculated on load. */
567 uint32_t cyBlock; /* Block height in pixels. SSM: not saved, recalculated on load. */
568
569 /* Dirty state; surface was manually updated. */
570 bool fDirty;
571
572#ifdef VMSVGA3D_DIRECT3D
573 /* Handle for shared objects (currently only textures & render targets). */
574 HANDLE hSharedObject;
575 /** Event query inserted after each GPU operation that updates or uses this surface. */
576 IDirect3DQuery9 *pQuery;
577 /* The type of actually created D3D resource. */
578 VMSVGA3DD3DRESTYPE enmD3DResType;
579 union
580 {
581 IDirect3DSurface9 *pSurface;
582 IDirect3DTexture9 *pTexture;
583 IDirect3DCubeTexture9 *pCubeTexture;
584 IDirect3DVolumeTexture9 *pVolumeTexture;
585 IDirect3DVertexBuffer9 *pVertexBuffer;
586 IDirect3DIndexBuffer9 *pIndexBuffer;
587 } u;
588 union
589 {
590 IDirect3DTexture9 *pTexture;
591 IDirect3DCubeTexture9 *pCubeTexture;
592 IDirect3DVolumeTexture9 *pVolumeTexture;
593 } bounce;
594 /** AVL tree containing VMSVGA3DSHAREDSURFACE structures. */
595 AVLU32TREE pSharedObjectTree;
596 bool fStencilAsTexture;
597#endif
598} VMSVGA3DSURFACE;
599/** Pointer to a 3d surface. */
600typedef VMSVGA3DSURFACE *PVMSVGA3DSURFACE;
601
602#ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
603/**
604 * SSM descriptor table for the VMSVGA3DSURFACE structure.
605 */
606static SSMFIELD const g_aVMSVGA3DSURFACEFields[] =
607{
608 SSMFIELD_ENTRY( VMSVGA3DSURFACE, id),
609# ifdef VMSVGA3D_OPENGL
610 SSMFIELD_ENTRY( VMSVGA3DSURFACE, idWeakContextAssociation),
611# else
612 SSMFIELD_ENTRY( VMSVGA3DSURFACE, idAssociatedContext),
613# endif
614 SSMFIELD_ENTRY( VMSVGA3DSURFACE, surfaceFlags),
615 SSMFIELD_ENTRY( VMSVGA3DSURFACE, format),
616# ifdef VMSVGA3D_OPENGL
617 SSMFIELD_ENTRY( VMSVGA3DSURFACE, internalFormatGL),
618 SSMFIELD_ENTRY( VMSVGA3DSURFACE, formatGL),
619 SSMFIELD_ENTRY( VMSVGA3DSURFACE, typeGL),
620 SSMFIELD_ENTRY_IGNORE( VMSVGA3DSURFACE, id),
621# endif
622 SSMFIELD_ENTRY( VMSVGA3DSURFACE, faces),
623 SSMFIELD_ENTRY( VMSVGA3DSURFACE, cFaces),
624 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DSURFACE, pMipmapLevels),
625 SSMFIELD_ENTRY( VMSVGA3DSURFACE, multiSampleCount),
626 SSMFIELD_ENTRY( VMSVGA3DSURFACE, autogenFilter),
627# ifdef VMSVGA3D_DIRECT3D
628 SSMFIELD_ENTRY( VMSVGA3DSURFACE, format), /** @todo format duplicated. */
629 SSMFIELD_ENTRY_IGNORE( VMSVGA3DSURFACE, formatD3D),
630 SSMFIELD_ENTRY_IGNORE( VMSVGA3DSURFACE, fUsageD3D),
631 SSMFIELD_ENTRY_IGNORE( VMSVGA3DSURFACE, multiSampleTypeD3D),
632# endif
633 SSMFIELD_ENTRY( VMSVGA3DSURFACE, cbBlock),
634 SSMFIELD_ENTRY_IGNORE( VMSVGA3DSURFACE, fDirty),
635# ifdef VMSVGA3D_DIRECT3D
636 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DSURFACE, hSharedObject),
637 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DSURFACE, pQuery),
638 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DSURFACE, u.pSurface),
639 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DSURFACE, bounce.pTexture),
640 SSMFIELD_ENTRY_IGNORE( VMSVGA3DSURFACE, pSharedObjectTree),
641 SSMFIELD_ENTRY_IGNORE( VMSVGA3DSURFACE, fStencilAsTexture),
642# endif
643 SSMFIELD_ENTRY_TERM()
644};
645#endif
646
647/** Mask we frequently apply to VMSVGA3DSURFACE::flags for decing what kind
648 * of surface we're dealing. */
649#define VMSVGA3D_SURFACE_HINT_SWITCH_MASK \
650 ( SVGA3D_SURFACE_HINT_INDEXBUFFER | SVGA3D_SURFACE_HINT_VERTEXBUFFER \
651 | SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET \
652 | SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_CUBEMAP )
653
654/** @def VMSVGA3DSURFACE_HAS_HW_SURFACE
655 * Checks whether the surface has a host hardware/library surface.
656 * @returns true/false
657 * @param a_pSurface The VMSVGA3d surface.
658 */
659#ifdef VMSVGA3D_DIRECT3D
660# define VMSVGA3DSURFACE_HAS_HW_SURFACE(a_pSurface) ((a_pSurface)->u.pSurface != NULL)
661#else
662# define VMSVGA3DSURFACE_HAS_HW_SURFACE(a_pSurface) ((a_pSurface)->oglId.texture != OPENGL_INVALID_ID)
663#endif
664
665
666
667typedef struct VMSVGA3DSHADER
668{
669 uint32_t id;
670 uint32_t cid;
671 SVGA3dShaderType type;
672 uint32_t cbData;
673 void *pShaderProgram;
674 union
675 {
676#ifdef VMSVGA3D_DIRECT3D
677 IDirect3DVertexShader9 *pVertexShader;
678 IDirect3DPixelShader9 *pPixelShader;
679#else
680 void *pVertexShader;
681 void *pPixelShader;
682#endif
683 void *pv;
684 } u;
685} VMSVGA3DSHADER;
686typedef VMSVGA3DSHADER *PVMSVGA3DSHADER;
687
688#ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
689/**
690 * SSM descriptor table for the VMSVGA3DSHADER structure.
691 */
692static SSMFIELD const g_aVMSVGA3DSHADERFields[] =
693{
694 SSMFIELD_ENTRY( VMSVGA3DSHADER, id),
695 SSMFIELD_ENTRY( VMSVGA3DSHADER, cid),
696 SSMFIELD_ENTRY( VMSVGA3DSHADER, type),
697 SSMFIELD_ENTRY( VMSVGA3DSHADER, cbData),
698 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DSHADER, pShaderProgram),
699 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DSHADER, u.pv),
700 SSMFIELD_ENTRY_TERM()
701};
702#endif
703
704/** @name VMSVGA3D_UPDATE_XXX - ...
705 * @{ */
706#define VMSVGA3D_UPDATE_SCISSORRECT RT_BIT_32(0)
707#define VMSVGA3D_UPDATE_ZRANGE RT_BIT_32(1)
708#define VMSVGA3D_UPDATE_VIEWPORT RT_BIT_32(2)
709#define VMSVGA3D_UPDATE_VERTEXSHADER RT_BIT_32(3)
710#define VMSVGA3D_UPDATE_PIXELSHADER RT_BIT_32(4)
711#define VMSVGA3D_UPDATE_TRANSFORM RT_BIT_32(5)
712#define VMSVGA3D_UPDATE_MATERIAL RT_BIT_32(6)
713/** @} */
714
715/* Query states. Mostly used for saved state. */
716typedef enum VMSVGA3DQUERYSTATE
717{
718 VMSVGA3DQUERYSTATE_NULL = 0, /* Not created. */
719 VMSVGA3DQUERYSTATE_SIGNALED = 1, /* Result obtained. The guest may or may not read the result yet. */
720 VMSVGA3DQUERYSTATE_BUILDING = 2, /* In process of collecting data. */
721 VMSVGA3DQUERYSTATE_ISSUED = 3, /* Data collected, but result is not yet obtained. */
722 VMSVGA3DQUERYSTATE_32BIT = 0x7fffffff
723} VMSVGA3DQUERYSTATE;
724AssertCompileSize(VMSVGA3DQUERYSTATE, sizeof(uint32_t));
725
726typedef struct VMSVGA3DQUERY
727{
728#ifdef VMSVGA3D_DIRECT3D
729 IDirect3DQuery9 *pQuery;
730#else /* VMSVGA3D_OPENGL */
731 GLuint idQuery;
732#endif
733 VMSVGA3DQUERYSTATE enmQueryState; /* VMSVGA3DQUERYSTATE_*. State is implicitly _NULL if pQuery is NULL. */
734 uint32_t u32QueryResult; /* Generic result. Enough for all VGPU9 queries. */
735} VMSVGA3DQUERY;
736
737#ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
738/**
739 * SSM descriptor table for the VMSVGA3DQUERY structure.
740 */
741static SSMFIELD const g_aVMSVGA3DQUERYFields[] =
742{
743#ifdef VMSVGA3D_DIRECT3D
744 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DQUERY, pQuery),
745#else /* VMSVGA3D_OPENGL */
746 SSMFIELD_ENTRY_IGNORE( VMSVGA3DQUERY, idQuery),
747#endif
748 SSMFIELD_ENTRY( VMSVGA3DQUERY, enmQueryState),
749 SSMFIELD_ENTRY( VMSVGA3DQUERY, u32QueryResult),
750 SSMFIELD_ENTRY_TERM()
751};
752#endif
753
754#ifdef VMSVGA3D_DIRECT3D
755#define VMSVGA3DQUERY_EXISTS(p) ((p)->pQuery && (p)->enmQueryState != VMSVGA3DQUERYSTATE_NULL)
756#else
757#define VMSVGA3DQUERY_EXISTS(p) ((p)->idQuery && (p)->enmQueryState != VMSVGA3DQUERYSTATE_NULL)
758#endif
759
760/**
761 * VMSVGA3d context.
762 */
763typedef struct VMSVGA3DCONTEXT
764{
765 uint32_t id;
766#ifdef RT_OS_WINDOWS
767# ifdef VMSVGA3D_DIRECT3D
768# ifdef VBOX_VMSVGA3D_WITH_WINE_OPENGL
769 IDirect3DDevice9 *pDevice;
770# else
771 IDirect3DDevice9Ex *pDevice;
772# endif
773# else
774 /* Device context of the context window. */
775 HDC hdc;
776 /* OpenGL rendering context handle. */
777 HGLRC hglrc;
778# endif
779 /* Device context window handle. */
780 HWND hwnd;
781#elif defined(RT_OS_DARWIN)
782 /* OpenGL rendering context */
783 NativeNSOpenGLContextRef cocoaContext;
784 NativeNSViewRef cocoaView;
785 bool fOtherProfile;
786#else
787 /** XGL rendering context handle */
788 GLXContext glxContext;
789 /** Device context window handle */
790 Window window;
791#endif
792
793#ifdef VMSVGA3D_OPENGL
794 /* Framebuffer object associated with this context. */
795 GLuint idFramebuffer;
796 /* Read and draw framebuffer objects for various operations. */
797 GLuint idReadFramebuffer;
798 GLuint idDrawFramebuffer;
799 /* Last GL error recorded. */
800 GLenum lastError;
801 void *pShaderContext;
802#endif
803
804 /* Current selected texture surfaces (if any) */
805 uint32_t aSidActiveTextures[SVGA3D_MAX_SAMPLERS];
806 /* Per context pixel and vertex shaders. */
807 uint32_t cPixelShaders;
808 PVMSVGA3DSHADER paPixelShader;
809 uint32_t cVertexShaders;
810 PVMSVGA3DSHADER paVertexShader;
811 /* Keep track of the internal state to be able to recreate the context properly (save/restore, window resize). */
812 struct
813 {
814 /** VMSVGA3D_UPDATE_XXX */
815 uint32_t u32UpdateFlags;
816
817 SVGA3dRenderState aRenderState[SVGA3D_RS_MAX];
818 /* aTextureStates contains both TextureStageStates and SamplerStates, therefore [SVGA3D_MAX_SAMPLERS]. */
819 SVGA3dTextureState aTextureStates[SVGA3D_MAX_SAMPLERS][SVGA3D_TS_MAX];
820 VMSVGATRANSFORMSTATE aTransformState[SVGA3D_TRANSFORM_MAX];
821 VMSVGAMATERIALSTATE aMaterial[SVGA3D_FACE_MAX];
822 VMSVGACLIPPLANESTATE aClipPlane[SVGA3D_CLIPPLANE_MAX];
823 VMSVGALIGHTSTATE aLightData[SVGA3D_MAX_LIGHTS];
824
825 uint32_t aRenderTargets[SVGA3D_RT_MAX];
826 SVGA3dRect RectScissor;
827 SVGA3dRect RectViewPort;
828 SVGA3dZRange zRange;
829 uint32_t shidPixel;
830 uint32_t shidVertex;
831
832 uint32_t cPixelShaderConst;
833 PVMSVGASHADERCONST paPixelShaderConst;
834 uint32_t cVertexShaderConst;
835 PVMSVGASHADERCONST paVertexShaderConst;
836 } state;
837
838 /* Occlusion query. */
839 VMSVGA3DQUERY occlusion;
840
841#ifdef VMSVGA3D_DIRECT3D
842 /* State which is currently applied to the D3D device. It is recreated as needed and not saved.
843 * The purpose is to remember the currently applied state and do not re-apply it if it has not changed.
844 * Unnecessary state changes are very bad for performance.
845 */
846 struct
847 {
848 /* Vertex declaration. */
849 IDirect3DVertexDeclaration9 *pVertexDecl;
850 uint32_t cVertexElements;
851 D3DVERTEXELEMENT9 aVertexElements[SVGA3D_MAX_VERTEX_ARRAYS + 1];
852 } d3dState;
853#endif
854} VMSVGA3DCONTEXT;
855/** Pointer to a VMSVGA3d context. */
856typedef VMSVGA3DCONTEXT *PVMSVGA3DCONTEXT;
857
858#ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
859/**
860 * SSM descriptor table for the VMSVGA3DCONTEXT structure.
861 */
862static SSMFIELD const g_aVMSVGA3DCONTEXTFields[] =
863{
864 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, id),
865
866# ifdef RT_OS_WINDOWS
867# ifdef VMSVGA3D_DIRECT3D
868 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DCONTEXT, pDevice),
869# else
870 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, hdc),
871 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, hglrc),
872# endif
873 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, hwnd),
874# elif defined(RT_OS_DARWIN)
875 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, cocoaContext),
876 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, cocoaView),
877 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, fOtherProfile),
878# else
879 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, glxContext),
880 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, window),
881# endif
882
883#ifdef VMSVGA3D_OPENGL
884 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, idFramebuffer),
885 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, idReadFramebuffer),
886 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, idDrawFramebuffer),
887 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, lastError),
888 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DCONTEXT, pShaderContext),
889#endif
890
891 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, aSidActiveTextures),
892 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, cPixelShaders),
893 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DCONTEXT, paPixelShader),
894 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, cVertexShaders),
895 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DCONTEXT, paVertexShader),
896 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.u32UpdateFlags),
897
898 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.aRenderState),
899 SSMFIELD_ENTRY_OLD( state.aTextureStates,
900 sizeof(SVGA3dTextureState) * /*SVGA3D_MAX_TEXTURE_STAGE=*/ 8 * /*SVGA3D_TS_MAX=*/ 30),
901 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.aTransformState),
902 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.aMaterial),
903 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.aClipPlane),
904 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.aLightData),
905
906 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.aRenderTargets),
907 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.RectScissor),
908 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.RectViewPort),
909 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.zRange),
910 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.shidPixel),
911 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.shidVertex),
912 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.cPixelShaderConst),
913 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DCONTEXT, state.paPixelShaderConst),
914 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.cVertexShaderConst),
915 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DCONTEXT, state.paVertexShaderConst),
916 SSMFIELD_ENTRY_TERM()
917};
918#endif /* VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS */
919
920
921/**
922 * VMSVGA3d state data.
923 *
924 * Allocated on the heap and pointed to by VMSVGAState::p3dState.
925 */
926typedef struct VMSVGA3DSTATE
927{
928 /** The size of papContexts. */
929 uint32_t cContexts;
930 /** The size of papSurfaces. */
931 uint32_t cSurfaces;
932 /** Contexts indexed by ID. Grown as needed. */
933 PVMSVGA3DCONTEXT *papContexts;
934 /** Surfaces indexed by ID. Grown as needed. */
935 PVMSVGA3DSURFACE *papSurfaces;
936
937#ifdef RT_OS_WINDOWS
938# ifdef VMSVGA3D_DIRECT3D
939# ifdef VBOX_VMSVGA3D_WITH_WINE_OPENGL
940 IDirect3D9 *pD3D9;
941# else
942 IDirect3D9Ex *pD3D9;
943# endif
944 D3DCAPS9 caps;
945 bool fSupportedSurfaceINTZ;
946 bool fSupportedSurfaceNULL;
947# endif
948 /** Window Thread. */
949 R3PTRTYPE(RTTHREAD) pWindowThread;
950 DWORD idWindowThread;
951 HMODULE hInstance;
952 /** Window request semaphore. */
953 RTSEMEVENT WndRequestSem;
954#elif defined(RT_OS_DARWIN)
955#else
956 /* The X display */
957 Display *display;
958 R3PTRTYPE(RTTHREAD) pWindowThread;
959 bool bTerminate;
960#endif
961
962#ifdef VMSVGA3D_OPENGL
963 float rsGLVersion;
964 /* Current active context. */
965 uint32_t idActiveContext;
966
967 struct
968 {
969 PFNGLISRENDERBUFFERPROC glIsRenderbuffer;
970 PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer;
971 PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers;
972 PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers;
973 PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage;
974 PFNGLGETRENDERBUFFERPARAMETERIVPROC glGetRenderbufferParameteriv;
975 PFNGLISFRAMEBUFFERPROC glIsFramebuffer;
976 PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
977 PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
978 PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
979 PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
980 PFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D;
981 PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
982 PFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D;
983 PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer;
984 PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glGetFramebufferAttachmentParameteriv;
985 PFNGLGENERATEMIPMAPPROC glGenerateMipmap;
986 PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer;
987 PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample;
988 PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer;
989 PFNGLPOINTPARAMETERFPROC glPointParameterf;
990#if VBOX_VMSVGA3D_GL_HACK_LEVEL < 0x102
991 PFNGLBLENDCOLORPROC glBlendColor;
992 PFNGLBLENDEQUATIONPROC glBlendEquation;
993#endif
994 PFNGLBLENDEQUATIONSEPARATEPROC glBlendEquationSeparate;
995 PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate;
996 PFNGLSTENCILOPSEPARATEPROC glStencilOpSeparate;
997 PFNGLSTENCILFUNCSEPARATEPROC glStencilFuncSeparate;
998 PFNGLBINDBUFFERPROC glBindBuffer;
999 PFNGLDELETEBUFFERSPROC glDeleteBuffers;
1000 PFNGLGENBUFFERSPROC glGenBuffers;
1001 PFNGLBUFFERDATAPROC glBufferData;
1002 PFNGLMAPBUFFERPROC glMapBuffer;
1003 PFNGLUNMAPBUFFERPROC glUnmapBuffer;
1004 PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
1005 PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
1006 PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer;
1007 PFNGLFOGCOORDPOINTERPROC glFogCoordPointer;
1008 PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glDrawElementsInstancedBaseVertex;
1009 PFNGLDRAWELEMENTSBASEVERTEXPROC glDrawElementsBaseVertex;
1010 PFNGLACTIVETEXTUREPROC glActiveTexture;
1011#if VBOX_VMSVGA3D_GL_HACK_LEVEL < 0x103
1012 PFNGLCLIENTACTIVETEXTUREPROC glClientActiveTexture;
1013#endif
1014 PFNGLGETPROGRAMIVARBPROC glGetProgramivARB;
1015 PFNGLPROVOKINGVERTEXPROC glProvokingVertex;
1016 PFNGLGENQUERIESPROC glGenQueries;
1017 PFNGLDELETEQUERIESPROC glDeleteQueries;
1018 PFNGLBEGINQUERYPROC glBeginQuery;
1019 PFNGLENDQUERYPROC glEndQuery;
1020 PFNGLGETQUERYOBJECTUIVPROC glGetQueryObjectuiv;
1021 PFNGLTEXIMAGE3DPROC glTexImage3D;
1022 PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor;
1023 PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced;
1024 PFNGLDRAWELEMENTSINSTANCEDPROC glDrawElementsInstanced;
1025 PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D;
1026 PFNGLCOMPRESSEDTEXIMAGE3DPROC glCompressedTexImage3D;
1027 PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glCompressedTexSubImage2D;
1028 } ext;
1029
1030 struct
1031 {
1032 GLint maxActiveLights;
1033 GLint maxTextures;
1034 GLint maxClipDistances;
1035 GLint maxColorAttachments;
1036 GLint maxRectangleTextureSize;
1037 GLint maxTextureAnisotropy;
1038 GLint maxVertexShaderInstructions;
1039 GLint maxFragmentShaderInstructions;
1040 GLint maxVertexShaderTemps;
1041 GLint maxFragmentShaderTemps;
1042 GLfloat flPointSize[2];
1043 SVGA3dPixelShaderVersion fragmentShaderVersion;
1044 SVGA3dVertexShaderVersion vertexShaderVersion;
1045 bool fS3TCSupported;
1046 } caps;
1047
1048 /** The GL_EXTENSIONS value (space padded) for the default OpenGL profile.
1049 * Free with RTStrFree. */
1050 R3PTRTYPE(char *) pszExtensions;
1051
1052 /** The GL_EXTENSIONS value (space padded) for the other OpenGL profile.
1053 * Free with RTStrFree.
1054 *
1055 * This is used to detect shader model version since some implementations
1056 * (darwin) hides extensions that have made it into core and probably a
1057 * bunch of others when using a OpenGL core profile instead of a legacy one */
1058 R3PTRTYPE(char *) pszOtherExtensions;
1059 /** The version of the other GL profile. */
1060 float rsOtherGLVersion;
1061
1062 /** Shader talk back interface. */
1063 VBOXVMSVGASHADERIF ShaderIf;
1064
1065# ifdef VMSVGA3D_OPENGL
1066 /** The shared context. */
1067 VMSVGA3DCONTEXT SharedCtx;
1068# endif
1069#endif /* VMSVGA3D_OPENGL */
1070} VMSVGA3DSTATE;
1071
1072#ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
1073/**
1074 * SSM descriptor table for the VMSVGA3DSTATE structure.
1075 *
1076 * @remarks This isn't a complete structure markup, only fields with state.
1077 */
1078static SSMFIELD const g_aVMSVGA3DSTATEFields[] =
1079{
1080# ifdef VMSVGA3D_OPENGL
1081 SSMFIELD_ENTRY( VMSVGA3DSTATE, rsGLVersion), /** @todo Why are we saving the GL version?? */
1082# endif
1083 SSMFIELD_ENTRY( VMSVGA3DSTATE, cContexts),
1084 SSMFIELD_ENTRY( VMSVGA3DSTATE, cSurfaces),
1085 SSMFIELD_ENTRY_TERM()
1086};
1087#endif /* VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS */
1088
1089
1090#ifdef VMSVGA3D_DIRECT3D
1091D3DFORMAT vmsvga3dSurfaceFormat2D3D(SVGA3dSurfaceFormat format);
1092D3DMULTISAMPLE_TYPE vmsvga3dMultipeSampleCount2D3D(uint32_t multisampleCount);
1093DECLCALLBACK(int) vmsvga3dSharedSurfaceDestroyTree(PAVLU32NODECORE pNode, void *pvParam);
1094int vmsvga3dSurfaceFlush(PVGASTATE pThis, PVMSVGA3DSURFACE pSurface);
1095#endif /* VMSVGA3D_DIRECT3D */
1096
1097
1098#ifdef VMSVGA3D_OPENGL
1099/** Save and setup everything. */
1100# define VMSVGA3D_PARANOID_TEXTURE_PACKING
1101
1102/**
1103 * Saved texture packing parameters (shared by both pack and unpack).
1104 */
1105typedef struct VMSVGAPACKPARAMS
1106{
1107 GLint iAlignment;
1108 GLint cxRow;
1109# ifdef VMSVGA3D_PARANOID_TEXTURE_PACKING
1110 GLint cyImage;
1111 GLboolean fSwapBytes;
1112 GLboolean fLsbFirst;
1113 GLint cSkipRows;
1114 GLint cSkipPixels;
1115 GLint cSkipImages;
1116# endif
1117} VMSVGAPACKPARAMS;
1118/** Pointer to saved texture packing parameters. */
1119typedef VMSVGAPACKPARAMS *PVMSVGAPACKPARAMS;
1120/** Pointer to const saved texture packing parameters. */
1121typedef VMSVGAPACKPARAMS const *PCVMSVGAPACKPARAMS;
1122
1123void vmsvga3dOglSetPackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
1124 PVMSVGAPACKPARAMS pSave);
1125void vmsvga3dOglRestorePackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
1126 PCVMSVGAPACKPARAMS pSave);
1127void vmsvga3dOglSetUnpackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
1128 PVMSVGAPACKPARAMS pSave);
1129void vmsvga3dOglRestoreUnpackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
1130 PCVMSVGAPACKPARAMS pSave);
1131
1132/** @name VMSVGA3D_DEF_CTX_F_XXX - vmsvga3dContextDefineOgl flags.
1133 * @{ */
1134/** When clear, the context is created using the default OpenGL profile.
1135 * When set, it's created using the alternative profile. The latter is only
1136 * allowed if the VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE is set. */
1137# define VMSVGA3D_DEF_CTX_F_OTHER_PROFILE RT_BIT_32(0)
1138/** Defining the shared context. */
1139# define VMSVGA3D_DEF_CTX_F_SHARED_CTX RT_BIT_32(1)
1140/** Defining the init time context (EMT). */
1141# define VMSVGA3D_DEF_CTX_F_INIT RT_BIT_32(2)
1142/** @} */
1143int vmsvga3dContextDefineOgl(PVGASTATE pThis, uint32_t cid, uint32_t fFlags);
1144void vmsvga3dSurfaceFormat2OGL(PVMSVGA3DSURFACE pSurface, SVGA3dSurfaceFormat format);
1145
1146#endif /* VMSVGA3D_OPENGL */
1147
1148
1149/* DevVGA-SVGA3d-shared.cpp: */
1150int vmsvga3dSaveShaderConst(PVMSVGA3DCONTEXT pContext, uint32_t reg, SVGA3dShaderType type, SVGA3dShaderConstType ctype,
1151 uint32_t val1, uint32_t val2, uint32_t val3, uint32_t val4);
1152
1153
1154
1155/* Command implementation workers. */
1156void vmsvga3dBackSurfaceDestroy(PVMSVGA3DSTATE pState, PVMSVGA3DSURFACE pSurface);
1157int vmsvga3dBackSurfaceStretchBlt(PVGASTATE pThis, PVMSVGA3DSTATE pState,
1158 PVMSVGA3DSURFACE pDstSurface, uint32_t uDstFace, uint32_t uDstMipmap, SVGA3dBox const *pDstBox,
1159 PVMSVGA3DSURFACE pSrcSurface, uint32_t uSrcFace, uint32_t uSrcMipmap, SVGA3dBox const *pSrcBox,
1160 SVGA3dStretchBltMode enmMode, PVMSVGA3DCONTEXT pContext);
1161int vmsvga3dBackSurfaceDMACopyBox(PVGASTATE pThis, PVMSVGA3DSTATE pState, PVMSVGA3DSURFACE pSurface,
1162 PVMSVGA3DMIPMAPLEVEL pMipLevel, uint32_t uHostFace, uint32_t uHostMipmap,
1163 SVGAGuestPtr GuestPtr, uint32_t cbGuestPitch, SVGA3dTransferType transfer,
1164 SVGA3dCopyBox const *pBox, PVMSVGA3DCONTEXT pContext, int rc, int iBox);
1165
1166int vmsvga3dBackCreateTexture(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, uint32_t idAssociatedContext,
1167 PVMSVGA3DSURFACE pSurface);
1168
1169DECLINLINE(int) vmsvga3dContextFromCid(PVMSVGA3DSTATE pState, uint32_t cid, PVMSVGA3DCONTEXT *ppContext)
1170{
1171 /** @todo stricter checks for associated context */
1172 if ( cid >= pState->cContexts
1173 || pState->papContexts[cid]->id != cid)
1174 {
1175 Log(("vmsvga3dSurfaceCopy invalid context id!\n"));
1176 return VERR_INVALID_PARAMETER;
1177 }
1178
1179 *ppContext = pState->papContexts[cid];
1180 return VINF_SUCCESS;
1181}
1182
1183DECLINLINE(int) vmsvga3dSurfaceFromSid(PVMSVGA3DSTATE pState, uint32_t sid, PVMSVGA3DSURFACE *ppSurface)
1184{
1185 Assert(sid < SVGA3D_MAX_SURFACE_IDS);
1186 AssertReturn(sid < pState->cSurfaces, VERR_INVALID_PARAMETER);
1187 PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
1188 AssertReturn(pSurface && pSurface->id == sid, VERR_INVALID_PARAMETER);
1189 *ppSurface = pSurface;
1190 return VINF_SUCCESS;
1191}
1192
1193DECLINLINE(int) vmsvga3dMipmapLevel(PVMSVGA3DSURFACE pSurface, uint32_t face, uint32_t mipmap,
1194 PVMSVGA3DMIPMAPLEVEL *ppMipmapLevel)
1195{
1196 /* Can use faces[0].numMipLevels, because numMipLevels is the same for all faces. */
1197 const uint32_t numMipLevels = pSurface->faces[0].numMipLevels;
1198
1199 AssertMsgReturn(face < pSurface->cFaces,
1200 ("cFaces %d, face %d\n", pSurface->cFaces, face),
1201 VERR_INVALID_PARAMETER);
1202 AssertMsgReturn(mipmap < numMipLevels,
1203 ("numMipLevels %d, mipmap %d", numMipLevels, mipmap),
1204 VERR_INVALID_PARAMETER);
1205
1206 *ppMipmapLevel = &pSurface->pMipmapLevels[face * numMipLevels + mipmap];
1207 return VINF_SUCCESS;
1208}
1209
1210#ifdef VMSVGA3D_DIRECT3D
1211DECLINLINE(D3DCUBEMAP_FACES) vmsvga3dCubemapFaceFromIndex(uint32_t iFace)
1212{
1213 D3DCUBEMAP_FACES Face;
1214 switch (iFace)
1215 {
1216 case 0: Face = D3DCUBEMAP_FACE_POSITIVE_X; break;
1217 case 1: Face = D3DCUBEMAP_FACE_NEGATIVE_X; break;
1218 case 2: Face = D3DCUBEMAP_FACE_POSITIVE_Y; break;
1219 case 3: Face = D3DCUBEMAP_FACE_NEGATIVE_Y; break;
1220 case 4: Face = D3DCUBEMAP_FACE_POSITIVE_Z; break;
1221 default:
1222 case 5: Face = D3DCUBEMAP_FACE_NEGATIVE_Z; break;
1223 }
1224 return Face;
1225}
1226#else /* VMSVGA3D_OPENGL */
1227DECLINLINE(GLenum) vmsvga3dCubemapFaceFromIndex(uint32_t iFace)
1228{
1229 GLint Face;
1230 switch (iFace)
1231 {
1232 case 0: Face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; break;
1233 case 1: Face = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; break;
1234 case 2: Face = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; break;
1235 case 3: Face = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; break;
1236 case 4: Face = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; break;
1237 default:
1238 case 5: Face = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; break;
1239 }
1240 return Face;
1241}
1242#endif
1243
1244int vmsvga3dOcclusionQueryCreate(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext);
1245int vmsvga3dOcclusionQueryDelete(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext);
1246int vmsvga3dOcclusionQueryBegin(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext);
1247int vmsvga3dOcclusionQueryEnd(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext);
1248int vmsvga3dOcclusionQueryGetData(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, uint32_t *pu32Pixels);
1249
1250void vmsvga3dInfoSurfaceToBitmap(PCDBGFINFOHLP pHlp, PVMSVGA3DSURFACE pSurface,
1251 const char *pszPath, const char *pszNamePrefix, const char *pszNameSuffix);
1252
1253#endif
1254
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette