VirtualBox

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

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

DevVGA-SVGA3d-ogl.cpp: fixed handling of stencil render states (untested).

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