VirtualBox

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

Last change on this file since 72816 was 69922, checked in by vboxsync, 7 years ago

Devices/Graphics: VMSVGA: info vmsvga3dsurf debugger command.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 49.3 KB
Line 
1/* $Id: DevVGA-SVGA3d-internal.h 69922 2017-12-04 18:24:57Z 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#endif
543 SVGA3dSurfaceFace faces[SVGA3D_MAX_SURFACE_FACES];
544 uint32_t cFaces;
545 uint32_t cMipmapLevels;
546 PVMSVGA3DMIPMAPLEVEL pMipmapLevels;
547 uint32_t multiSampleCount;
548 SVGA3dTextureFilter autogenFilter;
549#ifdef VMSVGA3D_DIRECT3D
550 D3DFORMAT formatD3D;
551 DWORD fUsageD3D;
552 D3DMULTISAMPLE_TYPE multiSampleTypeD3D;
553#endif
554
555 uint32_t cbBlock; /* block/pixel size in bytes */
556 /* Dimensions of the surface block, usually 1x1 except for compressed formats. */
557 uint32_t cxBlock; /* Block width in pixels. SSM: not saved, recalculated on load. */
558 uint32_t cyBlock; /* Block height in pixels. SSM: not saved, recalculated on load. */
559
560 /* Dirty state; surface was manually updated. */
561 bool fDirty;
562
563#ifdef VMSVGA3D_DIRECT3D
564 /* Handle for shared objects (currently only textures & render targets). */
565 HANDLE hSharedObject;
566 /** Event query inserted after each GPU operation that updates or uses this surface. */
567 IDirect3DQuery9 *pQuery;
568 /* The type of actually created D3D resource. */
569 VMSVGA3DD3DRESTYPE enmD3DResType;
570 union
571 {
572 IDirect3DSurface9 *pSurface;
573 IDirect3DTexture9 *pTexture;
574 IDirect3DCubeTexture9 *pCubeTexture;
575 IDirect3DVolumeTexture9 *pVolumeTexture;
576 IDirect3DVertexBuffer9 *pVertexBuffer;
577 IDirect3DIndexBuffer9 *pIndexBuffer;
578 } u;
579 union
580 {
581 IDirect3DTexture9 *pTexture;
582 IDirect3DCubeTexture9 *pCubeTexture;
583 IDirect3DVolumeTexture9 *pVolumeTexture;
584 } bounce;
585 /** AVL tree containing VMSVGA3DSHAREDSURFACE structures. */
586 AVLU32TREE pSharedObjectTree;
587 bool fStencilAsTexture;
588#endif
589} VMSVGA3DSURFACE;
590/** Pointer to a 3d surface. */
591typedef VMSVGA3DSURFACE *PVMSVGA3DSURFACE;
592
593#ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
594/**
595 * SSM descriptor table for the VMSVGA3DSURFACE structure.
596 */
597static SSMFIELD const g_aVMSVGA3DSURFACEFields[] =
598{
599 SSMFIELD_ENTRY( VMSVGA3DSURFACE, id),
600# ifdef VMSVGA3D_OPENGL
601 SSMFIELD_ENTRY( VMSVGA3DSURFACE, idWeakContextAssociation),
602# else
603 SSMFIELD_ENTRY( VMSVGA3DSURFACE, idAssociatedContext),
604# endif
605 SSMFIELD_ENTRY( VMSVGA3DSURFACE, surfaceFlags),
606 SSMFIELD_ENTRY( VMSVGA3DSURFACE, format),
607# ifdef VMSVGA3D_OPENGL
608 SSMFIELD_ENTRY( VMSVGA3DSURFACE, internalFormatGL),
609 SSMFIELD_ENTRY( VMSVGA3DSURFACE, formatGL),
610 SSMFIELD_ENTRY( VMSVGA3DSURFACE, typeGL),
611 SSMFIELD_ENTRY_IGNORE( VMSVGA3DSURFACE, id),
612# endif
613 SSMFIELD_ENTRY( VMSVGA3DSURFACE, faces),
614 SSMFIELD_ENTRY( VMSVGA3DSURFACE, cFaces),
615 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DSURFACE, pMipmapLevels),
616 SSMFIELD_ENTRY( VMSVGA3DSURFACE, multiSampleCount),
617 SSMFIELD_ENTRY( VMSVGA3DSURFACE, autogenFilter),
618# ifdef VMSVGA3D_DIRECT3D
619 SSMFIELD_ENTRY( VMSVGA3DSURFACE, format), /** @todo format duplicated. */
620 SSMFIELD_ENTRY_IGNORE( VMSVGA3DSURFACE, formatD3D),
621 SSMFIELD_ENTRY_IGNORE( VMSVGA3DSURFACE, fUsageD3D),
622 SSMFIELD_ENTRY_IGNORE( VMSVGA3DSURFACE, multiSampleTypeD3D),
623# endif
624 SSMFIELD_ENTRY( VMSVGA3DSURFACE, cbBlock),
625 SSMFIELD_ENTRY_IGNORE( VMSVGA3DSURFACE, fDirty),
626# ifdef VMSVGA3D_DIRECT3D
627 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DSURFACE, hSharedObject),
628 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DSURFACE, pQuery),
629 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DSURFACE, u.pSurface),
630 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DSURFACE, bounce.pTexture),
631 SSMFIELD_ENTRY_IGNORE( VMSVGA3DSURFACE, pSharedObjectTree),
632 SSMFIELD_ENTRY_IGNORE( VMSVGA3DSURFACE, fStencilAsTexture),
633# endif
634 SSMFIELD_ENTRY_TERM()
635};
636#endif
637
638/** Mask we frequently apply to VMSVGA3DSURFACE::flags for decing what kind
639 * of surface we're dealing. */
640#define VMSVGA3D_SURFACE_HINT_SWITCH_MASK \
641 ( SVGA3D_SURFACE_HINT_INDEXBUFFER | SVGA3D_SURFACE_HINT_VERTEXBUFFER \
642 | SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET \
643 | SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_CUBEMAP )
644
645/** @def VMSVGA3DSURFACE_HAS_HW_SURFACE
646 * Checks whether the surface has a host hardware/library surface.
647 * @returns true/false
648 * @param a_pSurface The VMSVGA3d surface.
649 */
650#ifdef VMSVGA3D_DIRECT3D
651# define VMSVGA3DSURFACE_HAS_HW_SURFACE(a_pSurface) ((a_pSurface)->u.pSurface != NULL)
652#else
653# define VMSVGA3DSURFACE_HAS_HW_SURFACE(a_pSurface) ((a_pSurface)->oglId.texture != OPENGL_INVALID_ID)
654#endif
655
656
657
658typedef struct VMSVGA3DSHADER
659{
660 uint32_t id;
661 uint32_t cid;
662 SVGA3dShaderType type;
663 uint32_t cbData;
664 void *pShaderProgram;
665 union
666 {
667#ifdef VMSVGA3D_DIRECT3D
668 IDirect3DVertexShader9 *pVertexShader;
669 IDirect3DPixelShader9 *pPixelShader;
670#else
671 void *pVertexShader;
672 void *pPixelShader;
673#endif
674 void *pv;
675 } u;
676} VMSVGA3DSHADER;
677typedef VMSVGA3DSHADER *PVMSVGA3DSHADER;
678
679#ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
680/**
681 * SSM descriptor table for the VMSVGA3DSHADER structure.
682 */
683static SSMFIELD const g_aVMSVGA3DSHADERFields[] =
684{
685 SSMFIELD_ENTRY( VMSVGA3DSHADER, id),
686 SSMFIELD_ENTRY( VMSVGA3DSHADER, cid),
687 SSMFIELD_ENTRY( VMSVGA3DSHADER, type),
688 SSMFIELD_ENTRY( VMSVGA3DSHADER, cbData),
689 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DSHADER, pShaderProgram),
690 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DSHADER, u.pv),
691 SSMFIELD_ENTRY_TERM()
692};
693#endif
694
695/** @name VMSVGA3D_UPDATE_XXX - ...
696 * @{ */
697#define VMSVGA3D_UPDATE_SCISSORRECT RT_BIT_32(0)
698#define VMSVGA3D_UPDATE_ZRANGE RT_BIT_32(1)
699#define VMSVGA3D_UPDATE_VIEWPORT RT_BIT_32(2)
700#define VMSVGA3D_UPDATE_VERTEXSHADER RT_BIT_32(3)
701#define VMSVGA3D_UPDATE_PIXELSHADER RT_BIT_32(4)
702#define VMSVGA3D_UPDATE_TRANSFORM RT_BIT_32(5)
703#define VMSVGA3D_UPDATE_MATERIAL RT_BIT_32(6)
704/** @} */
705
706/* Query states. Mostly used for saved state. */
707typedef enum VMSVGA3DQUERYSTATE
708{
709 VMSVGA3DQUERYSTATE_NULL = 0, /* Not created. */
710 VMSVGA3DQUERYSTATE_SIGNALED = 1, /* Result obtained. The guest may or may not read the result yet. */
711 VMSVGA3DQUERYSTATE_BUILDING = 2, /* In process of collecting data. */
712 VMSVGA3DQUERYSTATE_ISSUED = 3, /* Data collected, but result is not yet obtained. */
713 VMSVGA3DQUERYSTATE_32BIT = 0x7fffffff
714} VMSVGA3DQUERYSTATE;
715AssertCompileSize(VMSVGA3DQUERYSTATE, sizeof(uint32_t));
716
717typedef struct VMSVGA3DQUERY
718{
719#ifdef VMSVGA3D_DIRECT3D
720 IDirect3DQuery9 *pQuery;
721#else /* VMSVGA3D_OPENGL */
722 GLuint idQuery;
723#endif
724 VMSVGA3DQUERYSTATE enmQueryState; /* VMSVGA3DQUERYSTATE_*. State is implicitly _NULL if pQuery is NULL. */
725 uint32_t u32QueryResult; /* Generic result. Enough for all VGPU9 queries. */
726} VMSVGA3DQUERY;
727
728#ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
729/**
730 * SSM descriptor table for the VMSVGA3DQUERY structure.
731 */
732static SSMFIELD const g_aVMSVGA3DQUERYFields[] =
733{
734#ifdef VMSVGA3D_DIRECT3D
735 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DQUERY, pQuery),
736#else /* VMSVGA3D_OPENGL */
737 SSMFIELD_ENTRY_IGNORE( VMSVGA3DQUERY, idQuery),
738#endif
739 SSMFIELD_ENTRY( VMSVGA3DQUERY, enmQueryState),
740 SSMFIELD_ENTRY( VMSVGA3DQUERY, u32QueryResult),
741 SSMFIELD_ENTRY_TERM()
742};
743#endif
744
745#ifdef VMSVGA3D_DIRECT3D
746#define VMSVGA3DQUERY_EXISTS(p) ((p)->pQuery && (p)->enmQueryState != VMSVGA3DQUERYSTATE_NULL)
747#else
748#define VMSVGA3DQUERY_EXISTS(p) ((p)->idQuery && (p)->enmQueryState != VMSVGA3DQUERYSTATE_NULL)
749#endif
750
751/**
752 * VMSVGA3d context.
753 */
754typedef struct VMSVGA3DCONTEXT
755{
756 uint32_t id;
757#ifdef RT_OS_WINDOWS
758# ifdef VMSVGA3D_DIRECT3D
759# ifdef VBOX_VMSVGA3D_WITH_WINE_OPENGL
760 IDirect3DDevice9 *pDevice;
761# else
762 IDirect3DDevice9Ex *pDevice;
763# endif
764# else
765 /* Device context of the context window. */
766 HDC hdc;
767 /* OpenGL rendering context handle. */
768 HGLRC hglrc;
769# endif
770 /* Device context window handle. */
771 HWND hwnd;
772#elif defined(RT_OS_DARWIN)
773 /* OpenGL rendering context */
774 NativeNSOpenGLContextRef cocoaContext;
775 NativeNSViewRef cocoaView;
776 bool fOtherProfile;
777#else
778 /** XGL rendering context handle */
779 GLXContext glxContext;
780 /** Device context window handle */
781 Window window;
782 /** flag whether the window is mapped (=visible) */
783 bool fMapped;
784#endif
785
786#ifdef VMSVGA3D_OPENGL
787 /* Framebuffer object associated with this context. */
788 GLuint idFramebuffer;
789 /* Read and draw framebuffer objects for various operations. */
790 GLuint idReadFramebuffer;
791 GLuint idDrawFramebuffer;
792 /* Last GL error recorded. */
793 GLenum lastError;
794 void *pShaderContext;
795#endif
796
797 /* Current selected texture surfaces (if any) */
798 uint32_t aSidActiveTextures[SVGA3D_MAX_SAMPLERS];
799 /* Per context pixel and vertex shaders. */
800 uint32_t cPixelShaders;
801 PVMSVGA3DSHADER paPixelShader;
802 uint32_t cVertexShaders;
803 PVMSVGA3DSHADER paVertexShader;
804 /* Keep track of the internal state to be able to recreate the context properly (save/restore, window resize). */
805 struct
806 {
807 /** VMSVGA3D_UPDATE_XXX */
808 uint32_t u32UpdateFlags;
809
810 SVGA3dRenderState aRenderState[SVGA3D_RS_MAX];
811 /* aTextureStates contains both TextureStageStates and SamplerStates, therefore [SVGA3D_MAX_SAMPLERS]. */
812 SVGA3dTextureState aTextureStates[SVGA3D_MAX_SAMPLERS][SVGA3D_TS_MAX];
813 VMSVGATRANSFORMSTATE aTransformState[SVGA3D_TRANSFORM_MAX];
814 VMSVGAMATERIALSTATE aMaterial[SVGA3D_FACE_MAX];
815 VMSVGACLIPPLANESTATE aClipPlane[SVGA3D_CLIPPLANE_MAX];
816 VMSVGALIGHTSTATE aLightData[SVGA3D_MAX_LIGHTS];
817
818 uint32_t aRenderTargets[SVGA3D_RT_MAX];
819 SVGA3dRect RectScissor;
820 SVGA3dRect RectViewPort;
821 SVGA3dZRange zRange;
822 uint32_t shidPixel;
823 uint32_t shidVertex;
824
825 uint32_t cPixelShaderConst;
826 PVMSVGASHADERCONST paPixelShaderConst;
827 uint32_t cVertexShaderConst;
828 PVMSVGASHADERCONST paVertexShaderConst;
829 } state;
830
831 /* Occlusion query. */
832 VMSVGA3DQUERY occlusion;
833
834#ifdef VMSVGA3D_DIRECT3D
835 /* State which is currently applied to the D3D device. It is recreated as needed and not saved.
836 * The purpose is to remember the currently applied state and do not re-apply it if it has not changed.
837 * Unnecessary state changes are very bad for performance.
838 */
839 struct
840 {
841 /* Vertex declaration. */
842 IDirect3DVertexDeclaration9 *pVertexDecl;
843 uint32_t cVertexElements;
844 D3DVERTEXELEMENT9 aVertexElements[SVGA3D_MAX_VERTEX_ARRAYS + 1];
845 } d3dState;
846#endif
847} VMSVGA3DCONTEXT;
848/** Pointer to a VMSVGA3d context. */
849typedef VMSVGA3DCONTEXT *PVMSVGA3DCONTEXT;
850
851#ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
852/**
853 * SSM descriptor table for the VMSVGA3DCONTEXT structure.
854 */
855static SSMFIELD const g_aVMSVGA3DCONTEXTFields[] =
856{
857 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, id),
858
859# ifdef RT_OS_WINDOWS
860# ifdef VMSVGA3D_DIRECT3D
861 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DCONTEXT, pDevice),
862# else
863 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, hdc),
864 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, hglrc),
865# endif
866 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, hwnd),
867# elif defined(RT_OS_DARWIN)
868 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, cocoaContext),
869 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, cocoaView),
870 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, fOtherProfile),
871# else
872 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, glxContext),
873 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, window),
874 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, fMapped),
875# endif
876
877#ifdef VMSVGA3D_OPENGL
878 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, idFramebuffer),
879 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, idReadFramebuffer),
880 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, idDrawFramebuffer),
881 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, lastError),
882 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DCONTEXT, pShaderContext),
883#endif
884
885 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, aSidActiveTextures),
886 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, cPixelShaders),
887 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DCONTEXT, paPixelShader),
888 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, cVertexShaders),
889 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DCONTEXT, paVertexShader),
890 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.u32UpdateFlags),
891
892 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.aRenderState),
893 SSMFIELD_ENTRY_OLD( state.aTextureStates,
894 sizeof(SVGA3dTextureState) * /*SVGA3D_MAX_TEXTURE_STAGE=*/ 8 * /*SVGA3D_TS_MAX=*/ 30),
895 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.aTransformState),
896 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.aMaterial),
897 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.aClipPlane),
898 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.aLightData),
899
900 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.aRenderTargets),
901 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.RectScissor),
902 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.RectViewPort),
903 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.zRange),
904 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.shidPixel),
905 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.shidVertex),
906 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.cPixelShaderConst),
907 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DCONTEXT, state.paPixelShaderConst),
908 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.cVertexShaderConst),
909 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DCONTEXT, state.paVertexShaderConst),
910 SSMFIELD_ENTRY_TERM()
911};
912#endif /* VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS */
913
914
915/**
916 * VMSVGA3d state data.
917 *
918 * Allocated on the heap and pointed to by VMSVGAState::p3dState.
919 */
920typedef struct VMSVGA3DSTATE
921{
922 /** The size of papContexts. */
923 uint32_t cContexts;
924 /** The size of papSurfaces. */
925 uint32_t cSurfaces;
926 /** Contexts indexed by ID. Grown as needed. */
927 PVMSVGA3DCONTEXT *papContexts;
928 /** Surfaces indexed by ID. Grown as needed. */
929 PVMSVGA3DSURFACE *papSurfaces;
930
931#ifdef RT_OS_WINDOWS
932# ifdef VMSVGA3D_DIRECT3D
933# ifdef VBOX_VMSVGA3D_WITH_WINE_OPENGL
934 IDirect3D9 *pD3D9;
935# else
936 IDirect3D9Ex *pD3D9;
937# endif
938 D3DCAPS9 caps;
939 bool fSupportedSurfaceINTZ;
940 bool fSupportedSurfaceNULL;
941# endif
942 /** Window Thread. */
943 R3PTRTYPE(RTTHREAD) pWindowThread;
944 DWORD idWindowThread;
945 HMODULE hInstance;
946 /** Window request semaphore. */
947 RTSEMEVENT WndRequestSem;
948#elif defined(RT_OS_DARWIN)
949#else
950 /* The X display */
951 Display *display;
952 R3PTRTYPE(RTTHREAD) pWindowThread;
953 bool bTerminate;
954#endif
955
956#ifdef VMSVGA3D_OPENGL
957 float rsGLVersion;
958 /* Current active context. */
959 uint32_t idActiveContext;
960
961 struct
962 {
963 PFNGLISRENDERBUFFERPROC glIsRenderbuffer;
964 PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer;
965 PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers;
966 PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers;
967 PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage;
968 PFNGLGETRENDERBUFFERPARAMETERIVPROC glGetRenderbufferParameteriv;
969 PFNGLISFRAMEBUFFERPROC glIsFramebuffer;
970 PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
971 PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
972 PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
973 PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
974 PFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D;
975 PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
976 PFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D;
977 PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer;
978 PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glGetFramebufferAttachmentParameteriv;
979 PFNGLGENERATEMIPMAPPROC glGenerateMipmap;
980 PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer;
981 PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample;
982 PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer;
983 PFNGLPOINTPARAMETERFPROC glPointParameterf;
984#if VBOX_VMSVGA3D_GL_HACK_LEVEL < 0x102
985 PFNGLBLENDCOLORPROC glBlendColor;
986 PFNGLBLENDEQUATIONPROC glBlendEquation;
987#endif
988 PFNGLBLENDEQUATIONSEPARATEPROC glBlendEquationSeparate;
989 PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate;
990 PFNGLSTENCILOPSEPARATEPROC glStencilOpSeparate;
991 PFNGLSTENCILFUNCSEPARATEPROC glStencilFuncSeparate;
992 PFNGLBINDBUFFERPROC glBindBuffer;
993 PFNGLDELETEBUFFERSPROC glDeleteBuffers;
994 PFNGLGENBUFFERSPROC glGenBuffers;
995 PFNGLBUFFERDATAPROC glBufferData;
996 PFNGLMAPBUFFERPROC glMapBuffer;
997 PFNGLUNMAPBUFFERPROC glUnmapBuffer;
998 PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
999 PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
1000 PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer;
1001 PFNGLFOGCOORDPOINTERPROC glFogCoordPointer;
1002 PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glDrawElementsInstancedBaseVertex;
1003 PFNGLDRAWELEMENTSBASEVERTEXPROC glDrawElementsBaseVertex;
1004 PFNGLACTIVETEXTUREPROC glActiveTexture;
1005#if VBOX_VMSVGA3D_GL_HACK_LEVEL < 0x103
1006 PFNGLCLIENTACTIVETEXTUREPROC glClientActiveTexture;
1007#endif
1008 PFNGLGETPROGRAMIVARBPROC glGetProgramivARB;
1009 PFNGLPROVOKINGVERTEXPROC glProvokingVertex;
1010 bool fEXT_stencil_two_side;
1011 PFNGLGENQUERIESPROC glGenQueries;
1012 PFNGLDELETEQUERIESPROC glDeleteQueries;
1013 PFNGLBEGINQUERYPROC glBeginQuery;
1014 PFNGLENDQUERYPROC glEndQuery;
1015 PFNGLGETQUERYOBJECTUIVPROC glGetQueryObjectuiv;
1016 } ext;
1017
1018 struct
1019 {
1020 GLint maxActiveLights;
1021 GLint maxTextureBufferSize;
1022 GLint maxTextures;
1023 GLint maxClipDistances;
1024 GLint maxColorAttachments;
1025 GLint maxRectangleTextureSize;
1026 GLint maxTextureAnisotropy;
1027 GLint maxVertexShaderInstructions;
1028 GLint maxFragmentShaderInstructions;
1029 GLint maxVertexShaderTemps;
1030 GLint maxFragmentShaderTemps;
1031 GLfloat flPointSize[2];
1032 SVGA3dPixelShaderVersion fragmentShaderVersion;
1033 SVGA3dVertexShaderVersion vertexShaderVersion;
1034 bool fS3TCSupported;
1035 } caps;
1036
1037 /** The GL_EXTENSIONS value (space padded) for the default OpenGL profile.
1038 * Free with RTStrFree. */
1039 R3PTRTYPE(char *) pszExtensions;
1040
1041 /** The GL_EXTENSIONS value (space padded) for the other OpenGL profile.
1042 * Free with RTStrFree.
1043 *
1044 * This is used to detect shader model version since some implementations
1045 * (darwin) hides extensions that have made it into core and probably a
1046 * bunch of others when using a OpenGL core profile instead of a legacy one */
1047 R3PTRTYPE(char *) pszOtherExtensions;
1048 /** The version of the other GL profile. */
1049 float rsOtherGLVersion;
1050
1051 /** Shader talk back interface. */
1052 VBOXVMSVGASHADERIF ShaderIf;
1053
1054# ifdef VMSVGA3D_OPENGL
1055 /** The shared context. */
1056 VMSVGA3DCONTEXT SharedCtx;
1057# endif
1058#endif /* VMSVGA3D_OPENGL */
1059} VMSVGA3DSTATE;
1060
1061#ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
1062/**
1063 * SSM descriptor table for the VMSVGA3DSTATE structure.
1064 *
1065 * @remarks This isn't a complete structure markup, only fields with state.
1066 */
1067static SSMFIELD const g_aVMSVGA3DSTATEFields[] =
1068{
1069# ifdef VMSVGA3D_OPENGL
1070 SSMFIELD_ENTRY( VMSVGA3DSTATE, rsGLVersion), /** @todo Why are we saving the GL version?? */
1071# endif
1072 SSMFIELD_ENTRY( VMSVGA3DSTATE, cContexts),
1073 SSMFIELD_ENTRY( VMSVGA3DSTATE, cSurfaces),
1074 SSMFIELD_ENTRY_TERM()
1075};
1076#endif /* VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS */
1077
1078
1079#ifdef VMSVGA3D_DIRECT3D
1080D3DFORMAT vmsvga3dSurfaceFormat2D3D(SVGA3dSurfaceFormat format);
1081D3DMULTISAMPLE_TYPE vmsvga3dMultipeSampleCount2D3D(uint32_t multisampleCount);
1082DECLCALLBACK(int) vmsvga3dSharedSurfaceDestroyTree(PAVLU32NODECORE pNode, void *pvParam);
1083int vmsvga3dSurfaceFlush(PVGASTATE pThis, PVMSVGA3DSURFACE pSurface);
1084#endif /* VMSVGA3D_DIRECT3D */
1085
1086
1087#ifdef VMSVGA3D_OPENGL
1088/** Save and setup everything. */
1089# define VMSVGA3D_PARANOID_TEXTURE_PACKING
1090
1091/**
1092 * Saved texture packing parameters (shared by both pack and unpack).
1093 */
1094typedef struct VMSVGAPACKPARAMS
1095{
1096 GLint iAlignment;
1097 GLint cxRow;
1098# ifdef VMSVGA3D_PARANOID_TEXTURE_PACKING
1099 GLint cyImage;
1100 GLboolean fSwapBytes;
1101 GLboolean fLsbFirst;
1102 GLint cSkipRows;
1103 GLint cSkipPixels;
1104 GLint cSkipImages;
1105# endif
1106} VMSVGAPACKPARAMS;
1107/** Pointer to saved texture packing parameters. */
1108typedef VMSVGAPACKPARAMS *PVMSVGAPACKPARAMS;
1109/** Pointer to const saved texture packing parameters. */
1110typedef VMSVGAPACKPARAMS const *PCVMSVGAPACKPARAMS;
1111
1112void vmsvga3dOglSetPackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
1113 PVMSVGAPACKPARAMS pSave);
1114void vmsvga3dOglRestorePackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
1115 PCVMSVGAPACKPARAMS pSave);
1116void vmsvga3dOglSetUnpackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
1117 PVMSVGAPACKPARAMS pSave);
1118void vmsvga3dOglRestoreUnpackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
1119 PCVMSVGAPACKPARAMS pSave);
1120
1121/** @name VMSVGA3D_DEF_CTX_F_XXX - vmsvga3dContextDefineOgl flags.
1122 * @{ */
1123/** When clear, the context is created using the default OpenGL profile.
1124 * When set, it's created using the alternative profile. The latter is only
1125 * allowed if the VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE is set. */
1126# define VMSVGA3D_DEF_CTX_F_OTHER_PROFILE RT_BIT_32(0)
1127/** Defining the shared context. */
1128# define VMSVGA3D_DEF_CTX_F_SHARED_CTX RT_BIT_32(1)
1129/** Defining the init time context (EMT). */
1130# define VMSVGA3D_DEF_CTX_F_INIT RT_BIT_32(2)
1131/** @} */
1132int vmsvga3dContextDefineOgl(PVGASTATE pThis, uint32_t cid, uint32_t fFlags);
1133void vmsvga3dSurfaceFormat2OGL(PVMSVGA3DSURFACE pSurface, SVGA3dSurfaceFormat format);
1134
1135#endif /* VMSVGA3D_OPENGL */
1136
1137
1138/* DevVGA-SVGA3d-shared.cpp: */
1139int vmsvga3dSaveShaderConst(PVMSVGA3DCONTEXT pContext, uint32_t reg, SVGA3dShaderType type, SVGA3dShaderConstType ctype,
1140 uint32_t val1, uint32_t val2, uint32_t val3, uint32_t val4);
1141
1142
1143
1144/* Command implementation workers. */
1145void vmsvga3dBackSurfaceDestroy(PVMSVGA3DSTATE pState, PVMSVGA3DSURFACE pSurface);
1146int vmsvga3dBackSurfaceStretchBlt(PVGASTATE pThis, PVMSVGA3DSTATE pState,
1147 PVMSVGA3DSURFACE pDstSurface, uint32_t uDstFace, uint32_t uDstMipmap, SVGA3dBox const *pDstBox,
1148 PVMSVGA3DSURFACE pSrcSurface, uint32_t uSrcFace, uint32_t uSrcMipmap, SVGA3dBox const *pSrcBox,
1149 SVGA3dStretchBltMode enmMode, PVMSVGA3DCONTEXT pContext);
1150int vmsvga3dBackSurfaceDMACopyBox(PVGASTATE pThis, PVMSVGA3DSTATE pState, PVMSVGA3DSURFACE pSurface,
1151 PVMSVGA3DMIPMAPLEVEL pMipLevel, uint32_t uHostFace, uint32_t uHostMipmap,
1152 SVGAGuestPtr GuestPtr, uint32_t cbGuestPitch, SVGA3dTransferType transfer,
1153 SVGA3dCopyBox const *pBox, PVMSVGA3DCONTEXT pContext, int rc, int iBox);
1154
1155int vmsvga3dBackCreateTexture(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, uint32_t idAssociatedContext,
1156 PVMSVGA3DSURFACE pSurface);
1157
1158void vmsvgaClipCopyBox(const SVGA3dSize *pSizeSrc,
1159 const SVGA3dSize *pSizeDest,
1160 SVGA3dCopyBox *pBox);
1161void vmsvgaClipBox(const SVGA3dSize *pSize,
1162 SVGA3dBox *pBox);
1163
1164DECLINLINE(int) vmsvga3dContextFromCid(PVMSVGA3DSTATE pState, uint32_t cid, PVMSVGA3DCONTEXT *ppContext)
1165{
1166 /** @todo stricter checks for associated context */
1167 if ( cid >= pState->cContexts
1168 || pState->papContexts[cid]->id != cid)
1169 {
1170 Log(("vmsvga3dSurfaceCopy invalid context id!\n"));
1171 return VERR_INVALID_PARAMETER;
1172 }
1173
1174 *ppContext = pState->papContexts[cid];
1175 return VINF_SUCCESS;
1176}
1177
1178DECLINLINE(int) vmsvga3dSurfaceFromSid(PVMSVGA3DSTATE pState, uint32_t sid, PVMSVGA3DSURFACE *ppSurface)
1179{
1180 Assert(sid < SVGA3D_MAX_SURFACE_IDS);
1181 AssertReturn(sid < pState->cSurfaces, VERR_INVALID_PARAMETER);
1182 PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
1183 AssertReturn(pSurface && pSurface->id == sid, VERR_INVALID_PARAMETER);
1184 *ppSurface = pSurface;
1185 return VINF_SUCCESS;
1186}
1187
1188DECLINLINE(int) vmsvga3dMipmapLevel(PVMSVGA3DSURFACE pSurface, uint32_t face, uint32_t mipmap,
1189 PVMSVGA3DMIPMAPLEVEL *ppMipmapLevel)
1190{
1191 /* Can use faces[0].numMipLevels, because numMipLevels is the same for all faces. */
1192 const uint32_t numMipLevels = pSurface->faces[0].numMipLevels;
1193
1194 AssertMsgReturn(face < pSurface->cFaces,
1195 ("cFaces %d, face %d\n", pSurface->cFaces, face),
1196 VERR_INVALID_PARAMETER);
1197 AssertMsgReturn(mipmap < numMipLevels,
1198 ("numMipLevels %d, mipmap %d", numMipLevels, mipmap),
1199 VERR_INVALID_PARAMETER);
1200
1201 *ppMipmapLevel = &pSurface->pMipmapLevels[face * numMipLevels + mipmap];
1202 return VINF_SUCCESS;
1203}
1204
1205#ifdef VMSVGA3D_DIRECT3D
1206DECLINLINE(D3DCUBEMAP_FACES) vmsvga3dCubemapFaceFromIndex(uint32_t iFace)
1207{
1208 D3DCUBEMAP_FACES Face;
1209 switch (iFace)
1210 {
1211 case 0: Face = D3DCUBEMAP_FACE_POSITIVE_X; break;
1212 case 1: Face = D3DCUBEMAP_FACE_NEGATIVE_X; break;
1213 case 2: Face = D3DCUBEMAP_FACE_POSITIVE_Y; break;
1214 case 3: Face = D3DCUBEMAP_FACE_NEGATIVE_Y; break;
1215 case 4: Face = D3DCUBEMAP_FACE_POSITIVE_Z; break;
1216 default:
1217 case 5: Face = D3DCUBEMAP_FACE_NEGATIVE_Z; break;
1218 }
1219 return Face;
1220}
1221#endif /* VMSVGA3D_DIRECT3D */
1222
1223int vmsvga3dOcclusionQueryCreate(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext);
1224int vmsvga3dOcclusionQueryDelete(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext);
1225int vmsvga3dOcclusionQueryBegin(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext);
1226int vmsvga3dOcclusionQueryEnd(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext);
1227int vmsvga3dOcclusionQueryGetData(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, uint32_t *pu32Pixels);
1228
1229void vmsvga3dInfoSurfaceToBitmap(PCDBGFINFOHLP pHlp, PVMSVGA3DSURFACE pSurface,
1230 const char *pszPath, const char *pszNamePrefix, const char *pszNameSuffix);
1231
1232#endif
1233
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