summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/Graphics/DevVGA-SVGA3d-internal.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/VBox/Devices/Graphics/DevVGA-SVGA3d-internal.h1446
1 files changed, 1446 insertions, 0 deletions
diff --git a/src/VBox/Devices/Graphics/DevVGA-SVGA3d-internal.h b/src/VBox/Devices/Graphics/DevVGA-SVGA3d-internal.h
new file mode 100644
index 00000000..c3f8e57b
--- /dev/null
+++ b/src/VBox/Devices/Graphics/DevVGA-SVGA3d-internal.h
@@ -0,0 +1,1446 @@
+/* $Id: DevVGA-SVGA3d-internal.h $ */
+/** @file
+ * DevVMWare - VMWare SVGA device - 3D part, internal header.
+ */
+
+/*
+ * Copyright (C) 2013-2023 Oracle and/or its affiliates.
+ *
+ * This file is part of VirtualBox base platform packages, as
+ * available from https://www.virtualbox.org.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, in version 3 of the
+ * License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#ifndef VBOX_INCLUDED_SRC_Graphics_DevVGA_SVGA3d_internal_h
+#define VBOX_INCLUDED_SRC_Graphics_DevVGA_SVGA3d_internal_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+/*
+ * Assert sane compilation environment.
+ */
+#ifndef IN_RING3
+# error "VMSVGA3D_INCL_INTERNALS is only for ring-3 code"
+#endif
+#ifdef VMSVGA3D_OPENGL
+# if defined(VMSVGA3D_DIRECT3D)
+# error "Both VMSVGA3D_DIRECT3D and VMSVGA3D_OPENGL cannot be defined at the same time."
+# endif
+#elif !defined(VMSVGA3D_DIRECT3D)
+# error "Either VMSVGA3D_OPENGL or VMSVGA3D_DIRECT3D must be defined."
+#endif
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include "DevVGA-SVGA3d.h"
+
+#if defined(VMSVGA3D_DYNAMIC_LOAD) && defined(VMSVGA3D_OPENGL)
+# include "DevVGA-SVGA3d-glLdr.h"
+#endif
+
+#ifdef RT_OS_WINDOWS
+# include <iprt/win/windows.h>
+# ifdef VMSVGA3D_DIRECT3D
+# include <d3d9.h>
+# include <iprt/avl.h>
+# else
+# include <GL/gl.h>
+# include "vmsvga_glext/wglext.h"
+# endif
+
+#elif defined(RT_OS_DARWIN)
+# include <OpenGL/OpenGL.h>
+# include <OpenGL/gl3.h>
+# include <OpenGL/gl3ext.h>
+# define GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED
+# include <OpenGL/gl.h>
+# include "DevVGA-SVGA3d-cocoa.h"
+/* work around conflicting definition of GLhandleARB in VMware's glext.h */
+//#define GL_ARB_shader_objects
+// HACK
+typedef void (APIENTRYP PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture);
+typedef void (APIENTRYP PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint *params);
+# if 0
+# define GL_RGBA_S3TC 0x83A2
+# define GL_ALPHA8_EXT 0x803c
+# define GL_LUMINANCE8_EXT 0x8040
+# define GL_LUMINANCE16_EXT 0x8042
+# define GL_LUMINANCE4_ALPHA4_EXT 0x8043
+# define GL_LUMINANCE8_ALPHA8_EXT 0x8045
+# define GL_INT_2_10_10_10_REV 0x8D9F
+# endif
+
+#else
+# include <X11/Xlib.h>
+# include <X11/Xatom.h>
+# include <GL/gl.h>
+# include <GL/glx.h>
+# define VBOX_VMSVGA3D_GL_HACK_LEVEL 0x103
+#endif
+
+#ifdef VMSVGA3D_OPENGL
+# ifndef __glext_h__
+# undef GL_GLEXT_VERSION /** @todo r=bird: We include GL/glext.h above which also defines this and we'll end up with
+ * a clash if the system one does not use the same header guard as ours. So, I'm wondering
+ * whether this include is really needed, and if it is, whether we should use a unique header
+ * guard macro on it, so we'll have the same problems everywhere... */
+# endif
+# include "vmsvga_glext/glext.h"
+# include "shaderlib/shaderlib.h"
+#endif
+
+#ifdef VMSVGA3D_DX
+#include "DevVGA-SVGA3d-dx-shader.h"
+#endif
+
+
+/*********************************************************************************************************************************
+* Defined Constants And Macros *
+*********************************************************************************************************************************/
+#ifdef VMSVGA3D_OPENGL
+/** OpenGL: Create a dedicated context for handling surfaces in, thus
+ * avoiding orphaned surfaces after context destruction.
+ *
+ * This cures, for instance, an assertion on fedora 21 that happens in
+ * vmsvga3dSurfaceStretchBlt if the login screen and the desktop has different
+ * sizes. The context of the login screen seems to have just been destroyed
+ * earlier and I believe the driver/X/whoever is attemting to strech the old
+ * screen content onto the new sized screen.
+ *
+ * @remarks This probably comes at a slight preformance expense, as we currently
+ * switches context when setting up the surface the first time. Not sure
+ * if we really need to, but as this is an experiment, I'm playing it safe.
+ * @remarks The define has been made default, thus should no longer be used.
+ */
+# define VMSVGA3D_OGL_WITH_SHARED_CTX
+/** Fake surface ID for the shared context. */
+# define VMSVGA3D_SHARED_CTX_ID UINT32_C(0xffffeeee)
+
+/** @def VBOX_VMSVGA3D_GL_HACK_LEVEL
+ * Turns out that on Linux gl.h may often define the first 2-4 OpenGL versions
+ * worth of extensions, but missing out on a function pointer of fifteen. This
+ * causes headache for us when we use the function pointers below. This hack
+ * changes the code to call the known problematic functions directly.
+ * The value is ((x)<<16 | (y)) where x and y are taken from the GL_VERSION_x_y.
+ */
+# ifndef VBOX_VMSVGA3D_GL_HACK_LEVEL
+# define VBOX_VMSVGA3D_GL_HACK_LEVEL 0
+# endif
+
+/** Invalid OpenGL ID. */
+# define OPENGL_INVALID_ID 0
+
+# define VMSVGA3D_CLEAR_CURRENT_CONTEXT(pState) \
+ do { (pState)->idActiveContext = OPENGL_INVALID_ID; } while (0)
+
+/** @def VMSVGA3D_SET_CURRENT_CONTEXT
+ * Makes sure the @a pContext is the active OpenGL context.
+ * @parm pState The VMSVGA3d state.
+ * @parm pContext The new context.
+ */
+# ifdef RT_OS_WINDOWS
+# define VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext) \
+ do { \
+ if ((pState)->idActiveContext != (pContext)->id) \
+ { \
+ BOOL fMakeCurrentRc = wglMakeCurrent((pContext)->hdc, (pContext)->hglrc); \
+ Assert(fMakeCurrentRc == TRUE); RT_NOREF_PV(fMakeCurrentRc); \
+ LogFlowFunc(("Changing context: %#x -> %#x\n", (pState)->idActiveContext, (pContext)->id)); \
+ (pState)->idActiveContext = (pContext)->id; \
+ } \
+ } while (0)
+
+# elif defined(RT_OS_DARWIN)
+# define VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext) \
+ do { \
+ if ((pState)->idActiveContext != (pContext)->id) \
+ { \
+ vmsvga3dCocoaViewMakeCurrentContext((pContext)->cocoaView, (pContext)->cocoaContext); \
+ LogFlowFunc(("Changing context: %#x -> %#x\n", (pState)->idActiveContext, (pContext)->id)); \
+ (pState)->idActiveContext = (pContext)->id; \
+ } \
+ } while (0)
+# else
+# define VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext) \
+ do { \
+ if ((pState)->idActiveContext != (pContext)->id) \
+ { \
+ Bool fMakeCurrentRc = glXMakeCurrent((pState)->display, \
+ (pContext)->window, \
+ (pContext)->glxContext); \
+ Assert(fMakeCurrentRc == True); RT_NOREF_PV(fMakeCurrentRc); \
+ LogFlowFunc(("Changing context: %#x -> %#x\n", (pState)->idActiveContext, (pContext)->id)); \
+ (pState)->idActiveContext = (pContext)->id; \
+ } \
+ } while (0)
+# endif
+
+/** @def VMSVGA3D_CLEAR_GL_ERRORS
+ * Clears all pending OpenGL errors.
+ *
+ * If I understood this correctly, OpenGL maintains a bitmask internally and
+ * glGetError gets the next bit (clearing it) from the bitmap and translates it
+ * into a GL_XXX constant value which it then returns. A single OpenGL call can
+ * set more than one bit, and they stick around across calls, from what I
+ * understand.
+ *
+ * So in order to be able to use glGetError to check whether a function
+ * succeeded, we need to call glGetError until all error bits have been cleared.
+ * This macro does that (in all types of builds).
+ *
+ * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS
+ */
+# define VMSVGA3D_CLEAR_GL_ERRORS() \
+ do { \
+ if (RT_UNLIKELY(glGetError() != GL_NO_ERROR)) /* predict no errors pending */ \
+ { \
+ uint32_t iErrorClearingLoopsLeft = 64; \
+ while (glGetError() != GL_NO_ERROR && iErrorClearingLoopsLeft > 0) \
+ iErrorClearingLoopsLeft--; \
+ } \
+ } while (0)
+
+/** @def VMSVGA3D_GET_LAST_GL_ERROR
+ * Gets the last OpenGL error, stores it in a_pContext->lastError and returns
+ * it.
+ *
+ * @returns Same as glGetError.
+ * @param a_pContext The context to store the error in.
+ *
+ * @sa VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN
+ */
+# define VMSVGA3D_GET_GL_ERROR(a_pContext) ((a_pContext)->lastError = glGetError())
+
+/** @def VMSVGA3D_GL_SUCCESS
+ * Checks whether VMSVGA3D_GET_LAST_GL_ERROR() return GL_NO_ERROR.
+ *
+ * Will call glGetError() and store the result in a_pContext->lastError.
+ * Will predict GL_NO_ERROR outcome.
+ *
+ * @returns True on success, false on error.
+ * @parm a_pContext The context to store the error in.
+ *
+ * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_COMPLAIN
+ */
+# define VMSVGA3D_GL_IS_SUCCESS(a_pContext) RT_LIKELY((((a_pContext)->lastError = glGetError()) == GL_NO_ERROR))
+
+/** @def VMSVGA3D_GL_COMPLAIN
+ * Complains about one or more OpenGL errors (first in a_pContext->lastError).
+ *
+ * Strict builds will trigger an assertion, while other builds will put the
+ * first few occurences in the release log.
+ *
+ * All GL errors will be cleared after invocation. Assumes lastError
+ * is an error, will not check for GL_NO_ERROR.
+ *
+ * @param a_pState The 3D state structure.
+ * @param a_pContext The context that holds the first error.
+ * @param a_LogRelDetails Argument list for LogRel or similar that describes
+ * the operation in greater detail.
+ *
+ * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS
+ */
+# ifdef VBOX_STRICT
+# define VMSVGA3D_GL_COMPLAIN(a_pState, a_pContext, a_LogRelDetails) \
+ do { \
+ AssertMsg((a_pState)->idActiveContext == (a_pContext)->id, \
+ ("idActiveContext=%#x id=%x\n", (a_pState)->idActiveContext, (a_pContext)->id)); \
+ RTAssertMsg2Weak a_LogRelDetails; \
+ GLenum iNextError; \
+ while ((iNextError = glGetError()) != GL_NO_ERROR) \
+ RTAssertMsg2Weak("next error: %#x\n", iNextError); \
+ AssertMsgFailed(("first error: %#x (idActiveContext=%#x)\n", (a_pContext)->lastError, (a_pContext)->id)); \
+ } while (0)
+# else
+# define VMSVGA3D_GL_COMPLAIN(a_pState, a_pContext, a_LogRelDetails) \
+ do { \
+ LogRelMax(32, ("VMSVGA3d: OpenGL error %#x (idActiveContext=%#x) on line %u ", (a_pContext)->lastError, (a_pContext)->id, __LINE__)); \
+ GLenum iNextError; \
+ while ((iNextError = glGetError()) != GL_NO_ERROR) \
+ LogRelMax(32, (" - also error %#x ", iNextError)); \
+ LogRelMax(32, a_LogRelDetails); \
+ } while (0)
+# endif
+
+/** @def VMSVGA3D_GL_GET_AND_COMPLAIN
+ * Combination of VMSVGA3D_GET_GL_ERROR and VMSVGA3D_GL_COMPLAIN, assuming that
+ * there is a pending error.
+ *
+ * @param a_pState The 3D state structure.
+ * @param a_pContext The context that holds the first error.
+ * @param a_LogRelDetails Argument list for LogRel or similar that describes
+ * the operation in greater detail.
+ *
+ * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN
+ */
+# define VMSVGA3D_GL_GET_AND_COMPLAIN(a_pState, a_pContext, a_LogRelDetails) \
+ do { \
+ VMSVGA3D_GET_GL_ERROR(a_pContext); \
+ VMSVGA3D_GL_COMPLAIN(a_pState, a_pContext, a_LogRelDetails); \
+ } while (0)
+
+/** @def VMSVGA3D_GL_ASSERT_SUCCESS
+ * Asserts that VMSVGA3D_GL_IS_SUCCESS is true, complains if not.
+ *
+ * Uses VMSVGA3D_GL_COMPLAIN for complaining, so check it out wrt to release
+ * logging in non-strict builds.
+ *
+ * @param a_pState The 3D state structure.
+ * @param a_pContext The context that holds the first error.
+ * @param a_LogRelDetails Argument list for LogRel or similar that describes
+ * the operation in greater detail.
+ *
+ * @sa VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN
+ */
+# define VMSVGA3D_GL_ASSERT_SUCCESS(a_pState, a_pContext, a_LogRelDetails) \
+ if (VMSVGA3D_GL_IS_SUCCESS(a_pContext)) \
+ { /* likely */ } \
+ else do { \
+ VMSVGA3D_GL_COMPLAIN(a_pState, a_pContext, a_LogRelDetails); \
+ } while (0)
+
+/** @def VMSVGA3D_ASSERT_GL_CALL_EX
+ * Executes the specified OpenGL API call and asserts that it succeeded, variant
+ * with extra logging flexibility.
+ *
+ * ASSUMES no GL errors pending prior to invocation - caller should use
+ * VMSVGA3D_CLEAR_GL_ERRORS if uncertain.
+ *
+ * Uses VMSVGA3D_GL_COMPLAIN for complaining, so check it out wrt to release
+ * logging in non-strict builds.
+ *
+ * @param a_GlCall Expression making an OpenGL call.
+ * @param a_pState The 3D state structure.
+ * @param a_pContext The context that holds the first error.
+ * @param a_LogRelDetails Argument list for LogRel or similar that describes
+ * the operation in greater detail.
+ *
+ * @sa VMSVGA3D_ASSERT_GL_CALL, VMSVGA3D_GL_ASSERT_SUCCESS,
+ * VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN
+ */
+# define VMSVGA3D_ASSERT_GL_CALL_EX(a_GlCall, a_pState, a_pContext, a_LogRelDetails) \
+ do { \
+ (a_GlCall); \
+ VMSVGA3D_GL_ASSERT_SUCCESS(a_pState, a_pContext, a_LogRelDetails); \
+ } while (0)
+
+/** @def VMSVGA3D_ASSERT_GL_CALL
+ * Executes the specified OpenGL API call and asserts that it succeeded.
+ *
+ * ASSUMES no GL errors pending prior to invocation - caller should use
+ * VMSVGA3D_CLEAR_GL_ERRORS if uncertain.
+ *
+ * Uses VMSVGA3D_GL_COMPLAIN for complaining, so check it out wrt to release
+ * logging in non-strict builds.
+ *
+ * @param a_GlCall Expression making an OpenGL call.
+ * @param a_pState The 3D state structure.
+ * @param a_pContext The context that holds the first error.
+ *
+ * @sa VMSVGA3D_ASSERT_GL_CALL_EX, VMSVGA3D_GL_ASSERT_SUCCESS,
+ * VMSVGA3D_GET_GL_ERROR, VMSVGA3D_GL_IS_SUCCESS, VMSVGA3D_GL_COMPLAIN
+ */
+# define VMSVGA3D_ASSERT_GL_CALL(a_GlCall, a_pState, a_pContext) \
+ VMSVGA3D_ASSERT_GL_CALL_EX(a_GlCall, a_pState, a_pContext, ("%s\n", #a_GlCall))
+
+
+/** @def VMSVGA3D_CHECK_LAST_ERROR
+ * Checks that the last OpenGL error code indicates success.
+ *
+ * Will assert and return VERR_INTERNAL_ERROR in strict builds, in other
+ * builds it will do nothing and is a NOOP.
+ *
+ * @parm pState The VMSVGA3d state.
+ * @parm pContext The context.
+ *
+ * @todo Replace with proper error handling, it's crazy to return
+ * VERR_INTERNAL_ERROR in strict builds and just barge on ahead in
+ * release builds.
+ */
+/** @todo Rename to VMSVGA3D_CHECK_LAST_ERROR_RETURN */
+# ifdef VBOX_STRICT
+# define VMSVGA3D_CHECK_LAST_ERROR(pState, pContext) do { \
+ Assert((pState)->idActiveContext == (pContext)->id); \
+ (pContext)->lastError = glGetError(); \
+ AssertMsgReturn((pContext)->lastError == GL_NO_ERROR, \
+ ("%s (%d): last error 0x%x\n", __FUNCTION__, __LINE__, (pContext)->lastError), \
+ VERR_INTERNAL_ERROR); \
+ } while (0)
+# else
+# define VMSVGA3D_CHECK_LAST_ERROR(pState, pContext) do { } while (0)
+# endif
+
+/** @def VMSVGA3D_CHECK_LAST_ERROR_WARN
+ * Checks that the last OpenGL error code indicates success.
+ *
+ * Will assert in strict builds, otherwise it's a NOOP.
+ *
+ * @parm pState The VMSVGA3d state.
+ * @parm pContext The new context.
+ */
+# ifdef VBOX_STRICT
+# define VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext) do { \
+ Assert((pState)->idActiveContext == (pContext)->id); \
+ (pContext)->lastError = glGetError(); \
+ AssertMsg((pContext)->lastError == GL_NO_ERROR, ("%s (%d): last error 0x%x\n", __FUNCTION__, __LINE__, (pContext)->lastError)); \
+ } while (0)
+# else
+# define VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext) do { } while (0)
+# endif
+
+#endif /* VMSVGA3D_OPENGL */
+
+
+/*********************************************************************************************************************************
+* Structures and Typedefs *
+*********************************************************************************************************************************/
+/**
+ * Mipmap level.
+ */
+typedef struct VMSVGA3DMIPMAPLEVEL
+{
+ /** The mipmap size: width, height and depth. */
+ SVGA3dSize mipmapSize;
+ /** Width in blocks: (width + cxBlock - 1) / cxBlock. SSM: not saved, recalculated on load. */
+ uint32_t cBlocksX;
+ /** Height in blocks: (height + cyBlock - 1) / cyBlock. SSM: not saved, recalculated on load. */
+ uint32_t cBlocksY;
+ /** Number of blocks: cBlocksX * cBlocksY * mipmapSize.depth. SSM: not saved, recalculated on load. */
+ uint32_t cBlocks;
+ /** The scanline/pitch size in bytes: at least cBlocksX * cbBlock. */
+ uint32_t cbSurfacePitch;
+ /** The size (in bytes) of the mipmap plane: cbSurfacePitch * cBlocksY */
+ uint32_t cbSurfacePlane;
+ /** The size (in bytes) of the mipmap data when using the format the surface was
+ * defined with: cbSurfacePlane * mipmapSize.z */
+ uint32_t cbSurface;
+ /** Pointer to the mipmap bytes (cbSurface). Often NULL. If the surface has
+ * been realized in hardware, this may be outdated. */
+ void *pSurfaceData;
+ /** Set if pvSurfaceData contains data not realized in hardware or pushed to the
+ * hardware surface yet. */
+ bool fDirty;
+} VMSVGA3DMIPMAPLEVEL;
+/** Pointer to a mipmap level. */
+typedef VMSVGA3DMIPMAPLEVEL *PVMSVGA3DMIPMAPLEVEL;
+
+
+#ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
+/**
+ * SSM descriptor table for the VMSVGA3DMIPMAPLEVEL structure.
+ */
+static SSMFIELD const g_aVMSVGA3DMIPMAPLEVELFields[] =
+{
+ SSMFIELD_ENTRY( VMSVGA3DMIPMAPLEVEL, mipmapSize),
+ SSMFIELD_ENTRY( VMSVGA3DMIPMAPLEVEL, cbSurface),
+ SSMFIELD_ENTRY( VMSVGA3DMIPMAPLEVEL, cbSurfacePitch),
+ SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DMIPMAPLEVEL, pSurfaceData),
+ SSMFIELD_ENTRY_IGNORE( VMSVGA3DMIPMAPLEVEL, fDirty),
+ SSMFIELD_ENTRY_TERM()
+};
+#endif
+
+typedef struct VMSVGATRANSFORMSTATE
+{
+ bool fValid;
+ float matrix[16];
+} VMSVGATRANSFORMSTATE;
+typedef VMSVGATRANSFORMSTATE *PVMSVGATRANSFORMSTATE;
+
+typedef struct VMSVGAMATERIALSTATE
+{
+ bool fValid;
+ SVGA3dMaterial material;
+} VMSVGAMATERIALSTATE;
+typedef VMSVGAMATERIALSTATE *PVMSVGAMATERIALSTATE;
+
+typedef struct VMSVGACLIPPLANESTATE
+{
+ bool fValid;
+ float plane[4];
+} VMSVGACLIPPLANESTATE;
+typedef VMSVGACLIPPLANESTATE *PVMSVGACLIPPLANESTATE;
+
+typedef struct VMSVGALIGHTSTATE
+{
+ bool fEnabled;
+ bool fValidData;
+ SVGA3dLightData data;
+} VMSVGALIGHTSTATE;
+typedef VMSVGALIGHTSTATE *PVMSVGALIGHTSTATE;
+
+typedef struct VMSVGASHADERCONST
+{
+ bool fValid;
+ SVGA3dShaderConstType ctype;
+ uint32_t value[4];
+} VMSVGASHADERCONST;
+typedef VMSVGASHADERCONST *PVMSVGASHADERCONST;
+
+#ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
+/**
+ * SSM descriptor table for the VMSVGASHADERCONST structure.
+ */
+static SSMFIELD const g_aVMSVGASHADERCONSTFields[] =
+{
+ SSMFIELD_ENTRY( VMSVGASHADERCONST, fValid),
+ SSMFIELD_ENTRY( VMSVGASHADERCONST, ctype),
+ SSMFIELD_ENTRY( VMSVGASHADERCONST, value),
+ SSMFIELD_ENTRY_TERM()
+};
+#endif
+
+#ifdef VMSVGA3D_DIRECT3D
+
+/* What kind of Direct3D resource has been created for the VMSVGA3D surface. */
+typedef enum VMSVGA3DD3DRESTYPE
+{
+ VMSVGA3D_D3DRESTYPE_NONE = 0,
+ VMSVGA3D_D3DRESTYPE_SURFACE = 1,
+ VMSVGA3D_D3DRESTYPE_TEXTURE = 2,
+ VMSVGA3D_D3DRESTYPE_CUBE_TEXTURE = 3,
+ VMSVGA3D_D3DRESTYPE_VOLUME_TEXTURE = 4,
+ VMSVGA3D_D3DRESTYPE_VERTEX_BUFFER = 5,
+ VMSVGA3D_D3DRESTYPE_INDEX_BUFFER = 6
+} VMSVGA3DD3DRESTYPE;
+
+/**
+ *
+ */
+typedef struct
+{
+ /** Key is context id. */
+ AVLU32NODECORE Core;
+ union
+ {
+ IDirect3DTexture9 *pTexture;
+ IDirect3DCubeTexture9 *pCubeTexture;
+ IDirect3DVolumeTexture9 *pVolumeTexture;
+ } u;
+} VMSVGA3DSHAREDSURFACE;
+typedef VMSVGA3DSHAREDSURFACE *PVMSVGA3DSHAREDSURFACE;
+#endif /* VMSVGA3D_DIRECT3D */
+
+#ifdef VMSVGA3D_OPENGL
+/* What kind of OpenGL resource has been created for the VMSVGA3D surface. */
+typedef enum VMSVGA3DOGLRESTYPE
+{
+ VMSVGA3D_OGLRESTYPE_NONE = 0,
+ VMSVGA3D_OGLRESTYPE_BUFFER = 1,
+ VMSVGA3D_OGLRESTYPE_TEXTURE = 2,
+ VMSVGA3D_OGLRESTYPE_RENDERBUFFER = 3
+} VMSVGA3DOGLRESTYPE;
+#endif
+
+/* The 3D backend surface. The actual structure is 3D API specific. */
+typedef struct VMSVGA3DBACKENDSURFACE *PVMSVGA3DBACKENDSURFACE;
+
+/**
+ * VMSVGA3d surface.
+ */
+typedef struct VMSVGA3DSURFACE
+{
+ PVMSVGA3DBACKENDSURFACE pBackendSurface;
+
+ uint32_t id; /** @todo sid */
+ /* Which context created the corresponding resource.
+ * SVGA_ID_INVALID means that resource has not been created yet.
+ * A resource has been created if VMSVGA3DSURFACE_HAS_HW_SURFACE is true.
+ *
+ */
+ uint32_t idAssociatedContext;
+
+ /** @todo Only numArrayElements field is used currently. The code uses old fields cLevels, etc for anything else. */
+ VMSVGA3D_SURFACE_DESC surfaceDesc;
+
+ union
+ {
+ struct
+ {
+ SVGA3dSurface1Flags surface1Flags;
+ SVGA3dSurface2Flags surface2Flags;
+ } s;
+ SVGA3dSurfaceAllFlags surfaceFlags;
+ } f;
+ SVGA3dSurfaceFormat format;
+#ifdef VMSVGA3D_OPENGL
+ GLint internalFormatGL;
+ GLint formatGL;
+ GLint typeGL;
+ VMSVGA3DOGLRESTYPE enmOGLResType; /* Which resource was created for the surface. */
+ union
+ {
+ GLuint texture;
+ GLuint buffer;
+ GLuint renderbuffer;
+ } oglId;
+ GLenum targetGL; /* GL_TEXTURE_* */
+ GLenum bindingGL; /* GL_TEXTURE_BINDING_* */
+ /* Emulated formats */
+ bool fEmulated; /* Whether the texture format is emulated. */
+ GLuint idEmulated; /* GL name of the intermediate texture. */
+#endif
+ uint32_t cFaces; /* Number of faces: 6 for cubemaps, 1 for everything else. */
+ uint32_t cLevels; /* Number of mipmap levels per face. */
+ PVMSVGA3DMIPMAPLEVEL paMipmapLevels; /* surfaceDesc.numArrayElements * cLevels elements. */
+ uint32_t multiSampleCount;
+ SVGA3dTextureFilter autogenFilter;
+#ifdef VMSVGA3D_DIRECT3D
+ D3DFORMAT formatD3D;
+ DWORD fUsageD3D;
+ D3DMULTISAMPLE_TYPE multiSampleTypeD3D;
+#endif
+
+ uint32_t cbBlock; /* block/pixel size in bytes */
+ /* Dimensions of the surface block, usually 1x1 except for compressed formats. */
+ uint32_t cxBlock; /* Block width in pixels. SSM: not saved, recalculated on load. */
+ uint32_t cyBlock; /* Block height in pixels. SSM: not saved, recalculated on load. */
+#ifdef VMSVGA3D_OPENGL
+ uint32_t cbBlockGL; /* Block size of the OpenGL texture, same as cbBlock for not-emulated formats. */
+#endif
+
+ /* Dirty state; surface was manually updated. */
+ bool fDirty;
+
+#ifdef VMSVGA3D_DIRECT3D
+ /* Handle for shared objects (currently only textures & render targets). */
+ HANDLE hSharedObject;
+ /** Event query inserted after each GPU operation that updates or uses this surface. */
+ IDirect3DQuery9 *pQuery;
+ /** The context id where the query has been created. */
+ uint32_t idQueryContext;
+ /** The type of actually created D3D resource. */
+ VMSVGA3DD3DRESTYPE enmD3DResType;
+ union
+ {
+ IDirect3DSurface9 *pSurface;
+ IDirect3DTexture9 *pTexture;
+ IDirect3DCubeTexture9 *pCubeTexture;
+ IDirect3DVolumeTexture9 *pVolumeTexture;
+ IDirect3DVertexBuffer9 *pVertexBuffer;
+ IDirect3DIndexBuffer9 *pIndexBuffer;
+ } u;
+ union
+ {
+ IDirect3DTexture9 *pTexture;
+ IDirect3DCubeTexture9 *pCubeTexture;
+ IDirect3DVolumeTexture9 *pVolumeTexture;
+ } bounce;
+ /** AVL tree containing VMSVGA3DSHAREDSURFACE structures. */
+ AVLU32TREE pSharedObjectTree;
+ bool fStencilAsTexture;
+ D3DFORMAT d3dfmtRequested;
+ union
+ {
+ IDirect3DTexture9 *pTexture;
+ IDirect3DCubeTexture9 *pCubeTexture;
+ IDirect3DVolumeTexture9 *pVolumeTexture;
+ } emulated;
+#endif
+} VMSVGA3DSURFACE;
+/** Pointer to a 3d surface. */
+typedef VMSVGA3DSURFACE *PVMSVGA3DSURFACE;
+
+#ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
+/**
+ * SSM descriptor table for the VMSVGA3DSURFACE structure.
+ */
+static SSMFIELD const g_aVMSVGA3DSURFACEFields[] =
+{
+ SSMFIELD_ENTRY( VMSVGA3DSURFACE, id),
+ SSMFIELD_ENTRY( VMSVGA3DSURFACE, idAssociatedContext),
+ SSMFIELD_ENTRY( VMSVGA3DSURFACE, f.s.surface1Flags),
+ SSMFIELD_ENTRY_VER( VMSVGA3DSURFACE, f.s.surface2Flags, VGA_SAVEDSTATE_VERSION_VMSVGA_DX_SFLAGS),
+ SSMFIELD_ENTRY( VMSVGA3DSURFACE, format),
+# ifdef VMSVGA3D_OPENGL
+ SSMFIELD_ENTRY( VMSVGA3DSURFACE, internalFormatGL),
+ SSMFIELD_ENTRY( VMSVGA3DSURFACE, formatGL),
+ SSMFIELD_ENTRY( VMSVGA3DSURFACE, typeGL),
+# endif
+ SSMFIELD_ENTRY( VMSVGA3DSURFACE, cFaces),
+ SSMFIELD_ENTRY( VMSVGA3DSURFACE, cLevels),
+ SSMFIELD_ENTRY( VMSVGA3DSURFACE, multiSampleCount),
+ SSMFIELD_ENTRY( VMSVGA3DSURFACE, autogenFilter),
+ SSMFIELD_ENTRY( VMSVGA3DSURFACE, cbBlock),
+ SSMFIELD_ENTRY_TERM()
+};
+#endif
+
+/** Mask we frequently apply to VMSVGA3DSURFACE::flags for decing what kind
+ * of surface we're dealing. */
+#define VMSVGA3D_SURFACE_HINT_SWITCH_MASK \
+ ( SVGA3D_SURFACE_HINT_INDEXBUFFER | SVGA3D_SURFACE_HINT_VERTEXBUFFER \
+ | SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET \
+ | SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_CUBEMAP )
+
+/** @def VMSVGA3DSURFACE_HAS_HW_SURFACE
+ * Checks whether the surface has a host hardware/library surface.
+ * @returns true/false
+ * @param a_pSurface The VMSVGA3d surface.
+ */
+#ifdef VMSVGA3D_DIRECT3D
+# define VMSVGA3DSURFACE_HAS_HW_SURFACE(a_pSurface) ((a_pSurface)->pBackendSurface != NULL || (a_pSurface)->u.pSurface != NULL)
+#else
+# define VMSVGA3DSURFACE_HAS_HW_SURFACE(a_pSurface) ((a_pSurface)->pBackendSurface != NULL || (a_pSurface)->oglId.texture != OPENGL_INVALID_ID)
+#endif
+
+/** @def VMSVGA3DSURFACE_NEEDS_DATA
+ * Checks whether SurfaceDMA transfers must always update pSurfaceData,
+ * even if the surface has a host hardware resource.
+ * @returns true/false
+ * @param a_pSurface The VMSVGA3d surface.
+ */
+#ifdef VMSVGA3D_DIRECT3D
+# define VMSVGA3DSURFACE_NEEDS_DATA(a_pSurface) \
+ ( (a_pSurface)->enmD3DResType == VMSVGA3D_D3DRESTYPE_VERTEX_BUFFER \
+ || (a_pSurface)->enmD3DResType == VMSVGA3D_D3DRESTYPE_INDEX_BUFFER)
+#else
+# define VMSVGA3DSURFACE_NEEDS_DATA(a_pSurface) \
+ ((a_pSurface)->enmOGLResType == VMSVGA3D_OGLRESTYPE_BUFFER)
+#endif
+
+
+typedef struct VMSVGA3DSHADER
+{
+ uint32_t id; /** @todo Rename to shid. */
+ uint32_t cid;
+ SVGA3dShaderType type;
+ uint32_t cbData;
+ void *pShaderProgram;
+ union
+ {
+#ifdef VMSVGA3D_DIRECT3D
+ IDirect3DVertexShader9 *pVertexShader;
+ IDirect3DPixelShader9 *pPixelShader;
+#else
+ void *pVertexShader;
+ void *pPixelShader;
+#endif
+ } u;
+} VMSVGA3DSHADER;
+typedef VMSVGA3DSHADER *PVMSVGA3DSHADER;
+
+#ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
+/**
+ * SSM descriptor table for the VMSVGA3DSHADER structure.
+ */
+static SSMFIELD const g_aVMSVGA3DSHADERFields[] =
+{
+ SSMFIELD_ENTRY( VMSVGA3DSHADER, id),
+ SSMFIELD_ENTRY( VMSVGA3DSHADER, cid),
+ SSMFIELD_ENTRY( VMSVGA3DSHADER, type),
+ SSMFIELD_ENTRY( VMSVGA3DSHADER, cbData),
+ SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DSHADER, pShaderProgram),
+ SSMFIELD_ENTRY_TERM()
+};
+#endif
+
+/** @name VMSVGA3D_UPDATE_XXX - ...
+ * @{ */
+#define VMSVGA3D_UPDATE_SCISSORRECT RT_BIT_32(0)
+#define VMSVGA3D_UPDATE_ZRANGE RT_BIT_32(1)
+#define VMSVGA3D_UPDATE_VIEWPORT RT_BIT_32(2)
+#define VMSVGA3D_UPDATE_VERTEXSHADER RT_BIT_32(3)
+#define VMSVGA3D_UPDATE_PIXELSHADER RT_BIT_32(4)
+#define VMSVGA3D_UPDATE_TRANSFORM RT_BIT_32(5)
+#define VMSVGA3D_UPDATE_MATERIAL RT_BIT_32(6)
+/** @} */
+
+/* Query states. Mostly used for saved state. */
+typedef enum VMSVGA3DQUERYSTATE
+{
+ VMSVGA3DQUERYSTATE_NULL = 0, /* Not created. */
+ VMSVGA3DQUERYSTATE_SIGNALED = 1, /* Result obtained. The guest may or may not read the result yet. */
+ VMSVGA3DQUERYSTATE_BUILDING = 2, /* In process of collecting data. */
+ VMSVGA3DQUERYSTATE_ISSUED = 3, /* Data collected, but result is not yet obtained. */
+ VMSVGA3DQUERYSTATE_32BIT = 0x7fffffff
+} VMSVGA3DQUERYSTATE;
+AssertCompileSize(VMSVGA3DQUERYSTATE, sizeof(uint32_t));
+
+typedef struct VMSVGA3DQUERY
+{
+#ifdef VMSVGA3D_DIRECT3D
+ IDirect3DQuery9 *pQuery;
+#else /* VMSVGA3D_OPENGL */
+ GLuint idQuery;
+#endif
+ VMSVGA3DQUERYSTATE enmQueryState; /* VMSVGA3DQUERYSTATE_*. State is implicitly _NULL if pQuery is NULL. */
+ uint32_t u32QueryResult; /* Generic result. Enough for all VGPU9 queries. */
+} VMSVGA3DQUERY;
+
+#ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
+/**
+ * SSM descriptor table for the VMSVGA3DQUERY structure.
+ */
+static SSMFIELD const g_aVMSVGA3DQUERYFields[] =
+{
+#ifdef VMSVGA3D_DIRECT3D
+ SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DQUERY, pQuery),
+#else /* VMSVGA3D_OPENGL */
+ SSMFIELD_ENTRY_IGNORE( VMSVGA3DQUERY, idQuery),
+#endif
+ SSMFIELD_ENTRY( VMSVGA3DQUERY, enmQueryState),
+ SSMFIELD_ENTRY( VMSVGA3DQUERY, u32QueryResult),
+ SSMFIELD_ENTRY_TERM()
+};
+#endif
+
+#ifdef VMSVGA3D_DIRECT3D
+#define VMSVGA3DQUERY_EXISTS(p) ((p)->pQuery && (p)->enmQueryState != VMSVGA3DQUERYSTATE_NULL)
+#else
+#define VMSVGA3DQUERY_EXISTS(p) ((p)->idQuery && (p)->enmQueryState != VMSVGA3DQUERYSTATE_NULL)
+#endif
+
+/**
+ * VMSVGA3d context.
+ */
+typedef struct VMSVGA3DCONTEXT
+{
+ /** @todo Legacy contexts with DX backend. */
+
+ uint32_t id;
+#ifdef RT_OS_WINDOWS
+# ifdef VMSVGA3D_DIRECT3D
+ IDirect3DDevice9Ex *pDevice;
+# else
+ /* Device context of the context window. */
+ HDC hdc;
+ /* OpenGL rendering context handle. */
+ HGLRC hglrc;
+# endif
+ /* Device context window handle. */
+ HWND hwnd;
+#elif defined(RT_OS_DARWIN)
+ /* OpenGL rendering context */
+ NativeNSOpenGLContextRef cocoaContext;
+ NativeNSViewRef cocoaView;
+ bool fOtherProfile;
+#else
+ /** XGL rendering context handle */
+ GLXContext glxContext;
+ /** Device context window handle */
+ Window window;
+#endif
+
+#ifdef VMSVGA3D_OPENGL
+ /* Framebuffer object associated with this context. */
+ GLuint idFramebuffer;
+ /* Read and draw framebuffer objects for various operations. */
+ GLuint idReadFramebuffer;
+ GLuint idDrawFramebuffer;
+ /* Last GL error recorded. */
+ GLenum lastError;
+ void *pShaderContext;
+#endif
+
+ /* Current selected texture surfaces (if any) */
+ uint32_t aSidActiveTextures[SVGA3D_MAX_SAMPLERS];
+ /* Per context pixel and vertex shaders. */
+ uint32_t cPixelShaders;
+ PVMSVGA3DSHADER paPixelShader;
+ uint32_t cVertexShaders;
+ PVMSVGA3DSHADER paVertexShader;
+ /* Keep track of the internal state to be able to recreate the context properly (save/restore, window resize). */
+ struct
+ {
+ /** VMSVGA3D_UPDATE_XXX */
+ uint32_t u32UpdateFlags;
+
+ SVGA3dRenderState aRenderState[SVGA3D_RS_MAX];
+ /* aTextureStates contains both TextureStageStates and SamplerStates, therefore [SVGA3D_MAX_SAMPLERS]. */
+ SVGA3dTextureState aTextureStates[SVGA3D_MAX_SAMPLERS][SVGA3D_TS_MAX];
+ VMSVGATRANSFORMSTATE aTransformState[SVGA3D_TRANSFORM_MAX];
+ VMSVGAMATERIALSTATE aMaterial[SVGA3D_FACE_MAX];
+ /* The aClipPlane array has a wrong (greater) size. Keep it for now because the array is a part of the saved state. */
+ /** @todo Replace SVGA3D_CLIPPLANE_5 with SVGA3D_NUM_CLIPPLANES and increase the saved state version. */
+ VMSVGACLIPPLANESTATE aClipPlane[SVGA3D_CLIPPLANE_5];
+ VMSVGALIGHTSTATE aLightData[SVGA3D_MAX_LIGHTS];
+
+ uint32_t aRenderTargets[SVGA3D_RT_MAX];
+ SVGA3dRect RectScissor;
+ SVGA3dRect RectViewPort;
+ SVGA3dZRange zRange;
+ uint32_t shidPixel;
+ uint32_t shidVertex;
+
+ uint32_t cPixelShaderConst;
+ PVMSVGASHADERCONST paPixelShaderConst;
+ uint32_t cVertexShaderConst;
+ PVMSVGASHADERCONST paVertexShaderConst;
+ } state;
+
+ /* Occlusion query. */
+ VMSVGA3DQUERY occlusion;
+
+#ifdef VMSVGA3D_DIRECT3D
+ /* State which is currently applied to the D3D device. It is recreated as needed and not saved.
+ * The purpose is to remember the currently applied state and do not re-apply it if it has not changed.
+ * Unnecessary state changes are very bad for performance.
+ */
+ struct
+ {
+ /* Vertex declaration. */
+ IDirect3DVertexDeclaration9 *pVertexDecl;
+ uint32_t cVertexElements;
+ D3DVERTEXELEMENT9 aVertexElements[SVGA3D_MAX_VERTEX_ARRAYS + 1];
+ } d3dState;
+#endif
+} VMSVGA3DCONTEXT;
+/** Pointer to a VMSVGA3d context. */
+typedef VMSVGA3DCONTEXT *PVMSVGA3DCONTEXT;
+
+#ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
+/* Verify that constants did not change for the legacy context saved state data. */
+AssertCompile(SVGA3D_RS_MAX == 99);
+AssertCompile(SVGA3D_TRANSFORM_MAX == 15);
+AssertCompile(SVGA3D_FACE_MAX == 5);
+AssertCompile(SVGA3D_CLIPPLANE_5 == (1 << 5));
+AssertCompile(SVGA3D_MAX_LIGHTS == 32);
+AssertCompile(SVGA3D_RT_MAX == 10);
+
+/**
+ * SSM descriptor table for the VMSVGA3DCONTEXT structure.
+ */
+static SSMFIELD const g_aVMSVGA3DCONTEXTFields[] =
+{
+ SSMFIELD_ENTRY( VMSVGA3DCONTEXT, id),
+
+# ifdef RT_OS_WINDOWS
+# ifdef VMSVGA3D_DIRECT3D
+ SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DCONTEXT, pDevice),
+# else
+ SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, hdc),
+ SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, hglrc),
+# endif
+ SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, hwnd),
+# elif defined(RT_OS_DARWIN)
+ SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, cocoaContext),
+ SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, cocoaView),
+ SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, fOtherProfile),
+# else
+ SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, glxContext),
+ SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, window),
+# endif
+
+#ifdef VMSVGA3D_OPENGL
+ SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, idFramebuffer),
+ SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, idReadFramebuffer),
+ SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, idDrawFramebuffer),
+ SSMFIELD_ENTRY( VMSVGA3DCONTEXT, lastError),
+ SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DCONTEXT, pShaderContext),
+#endif
+
+ SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, aSidActiveTextures),
+ SSMFIELD_ENTRY( VMSVGA3DCONTEXT, cPixelShaders),
+ SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DCONTEXT, paPixelShader),
+ SSMFIELD_ENTRY( VMSVGA3DCONTEXT, cVertexShaders),
+ SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DCONTEXT, paVertexShader),
+ SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.u32UpdateFlags),
+
+ SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.aRenderState),
+ SSMFIELD_ENTRY_OLD( state.aTextureStates,
+ sizeof(SVGA3dTextureState) * /*SVGA3D_MAX_TEXTURE_STAGE=*/ 8 * /*SVGA3D_TS_MAX=*/ 30),
+ SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.aTransformState),
+ SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.aMaterial),
+ SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.aClipPlane),
+ SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.aLightData),
+
+ SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.aRenderTargets),
+ SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.RectScissor),
+ SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.RectViewPort),
+ SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.zRange),
+ SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.shidPixel),
+ SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.shidVertex),
+ SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.cPixelShaderConst),
+ SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DCONTEXT, state.paPixelShaderConst),
+ SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.cVertexShaderConst),
+ SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DCONTEXT, state.paVertexShaderConst),
+ SSMFIELD_ENTRY_TERM()
+};
+#endif /* VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS */
+
+
+#ifdef VMSVGA3D_DX
+/* The 3D backend DX context. The actual structure is 3D API specific. */
+typedef struct VMSVGA3DBACKENDDXCONTEXT *PVMSVGA3DBACKENDDXCONTEXT;
+
+/**
+ * VMSVGA3D DX context (VGPU10+). DX contexts ids are a separate namespace from legacy context ids.
+ */
+typedef struct VMSVGA3DDXCONTEXT
+{
+ /** The DX context id. */
+ uint32_t cid;
+ /** . */
+ uint32_t u32Reserved;
+ /** . */
+ uint32_t cRenderTargets;
+ /** Backend specific data. */
+ PVMSVGA3DBACKENDDXCONTEXT pBackendDXContext;
+ /** Copy of the guest memory for this context. The guest will be updated on unbind. */
+ SVGADXContextMobFormat svgaDXContext;
+ /* Context-Object Tables bound to this context. */
+ PVMSVGAMOB aCOTMobs[SVGA_COTABLE_MAX];
+ struct
+ {
+ SVGACOTableDXRTViewEntry *paRTView;
+ SVGACOTableDXDSViewEntry *paDSView;
+ SVGACOTableDXSRViewEntry *paSRView;
+ SVGACOTableDXElementLayoutEntry *paElementLayout;
+ SVGACOTableDXBlendStateEntry *paBlendState;
+ SVGACOTableDXDepthStencilEntry *paDepthStencil;
+ SVGACOTableDXRasterizerStateEntry *paRasterizerState;
+ SVGACOTableDXSamplerEntry *paSampler;
+ SVGACOTableDXStreamOutputEntry *paStreamOutput;
+ SVGACOTableDXQueryEntry *paQuery;
+ SVGACOTableDXShaderEntry *paShader;
+ SVGACOTableDXUAViewEntry *paUAView;
+ uint32_t cRTView;
+ uint32_t cDSView;
+ uint32_t cSRView;
+ uint32_t cElementLayout;
+ uint32_t cBlendState;
+ uint32_t cDepthStencil;
+ uint32_t cRasterizerState;
+ uint32_t cSampler;
+ uint32_t cStreamOutput;
+ uint32_t cQuery;
+ uint32_t cShader;
+ uint32_t cUAView;
+ } cot;
+} VMSVGA3DDXCONTEXT;
+/** Pointer to a VMSVGA3D DX context. */
+typedef VMSVGA3DDXCONTEXT *PVMSVGA3DDXCONTEXT;
+#endif /* VMSVGA3D_DX */
+
+
+#ifdef VMSVGA3D_OPENGL
+typedef struct VMSVGA3DFORMATCONVERTER *PVMSVGA3DFORMATCONVERTER;
+#endif
+
+/* The 3D backend. The actual structure is 3D API specific. */
+typedef struct VMSVGA3DBACKEND *PVMSVGA3DBACKEND;
+
+/**
+ * VMSVGA3d state data.
+ *
+ * Allocated on the heap and pointed to by VMSVGAState::p3dState.
+ */
+typedef struct VMSVGA3DSTATE
+{
+ /** Backend specific data. */
+ PVMSVGA3DBACKEND pBackend;
+
+ /** The size of papContexts. */
+ uint32_t cContexts;
+ /** The size of papSurfaces. */
+ uint32_t cSurfaces;
+#ifdef VMSVGA3D_DX
+ /** The size of papDXContexts. */
+ uint32_t cDXContexts;
+ /** Reserved. */
+ uint32_t u32Reserved;
+#endif
+ /** Contexts indexed by ID. Grown as needed. */
+ PVMSVGA3DCONTEXT *papContexts;
+ /** Surfaces indexed by ID. Grown as needed. */
+ PVMSVGA3DSURFACE *papSurfaces;
+#ifdef VMSVGA3D_DX
+ /** DX contexts indexed by ID. Grown as needed. */
+ PVMSVGA3DDXCONTEXT *papDXContexts;
+#endif
+
+#ifdef RT_OS_WINDOWS
+# ifdef VMSVGA3D_DIRECT3D
+ IDirect3D9Ex *pD3D9;
+ D3DCAPS9 caps;
+ bool fSupportedSurfaceINTZ;
+ bool fSupportedSurfaceNULL;
+ bool fSupportedFormatUYVY : 1;
+ bool fSupportedFormatYUY2 : 1;
+ bool fSupportedFormatA8B8G8R8 : 1;
+# endif
+ /** Window Thread. */
+ R3PTRTYPE(RTTHREAD) pWindowThread;
+ DWORD idWindowThread;
+ HMODULE hInstance;
+ /** Window request semaphore. */
+ RTSEMEVENT WndRequestSem;
+#elif defined(RT_OS_DARWIN)
+#else
+ /* The X display */
+ Display *display;
+ R3PTRTYPE(RTTHREAD) pWindowThread;
+ bool bTerminate;
+#endif
+
+#ifdef VMSVGA3D_OPENGL
+ float rsGLVersion;
+ /* Current active context. */
+ uint32_t idActiveContext;
+
+ struct
+ {
+ PFNGLISRENDERBUFFERPROC glIsRenderbuffer;
+ PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer;
+ PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers;
+ PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers;
+ PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage;
+ PFNGLGETRENDERBUFFERPARAMETERIVPROC glGetRenderbufferParameteriv;
+ PFNGLISFRAMEBUFFERPROC glIsFramebuffer;
+ PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
+ PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
+ PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
+ PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
+ PFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D;
+ PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
+ PFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D;
+ PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer;
+ PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glGetFramebufferAttachmentParameteriv;
+ PFNGLGENERATEMIPMAPPROC glGenerateMipmap;
+ PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer;
+ PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample;
+ PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer;
+ PFNGLPOINTPARAMETERFPROC glPointParameterf;
+#if VBOX_VMSVGA3D_GL_HACK_LEVEL < 0x102
+ PFNGLBLENDCOLORPROC glBlendColor;
+ PFNGLBLENDEQUATIONPROC glBlendEquation;
+#endif
+ PFNGLBLENDEQUATIONSEPARATEPROC glBlendEquationSeparate;
+ PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate;
+ PFNGLSTENCILOPSEPARATEPROC glStencilOpSeparate;
+ PFNGLSTENCILFUNCSEPARATEPROC glStencilFuncSeparate;
+ PFNGLBINDBUFFERPROC glBindBuffer;
+ PFNGLDELETEBUFFERSPROC glDeleteBuffers;
+ PFNGLGENBUFFERSPROC glGenBuffers;
+ PFNGLBUFFERDATAPROC glBufferData;
+ PFNGLMAPBUFFERPROC glMapBuffer;
+ PFNGLUNMAPBUFFERPROC glUnmapBuffer;
+ PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
+ PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
+ PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer;
+ PFNGLFOGCOORDPOINTERPROC glFogCoordPointer;
+ PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glDrawElementsInstancedBaseVertex;
+ PFNGLDRAWELEMENTSBASEVERTEXPROC glDrawElementsBaseVertex;
+ PFNGLACTIVETEXTUREPROC glActiveTexture;
+#if VBOX_VMSVGA3D_GL_HACK_LEVEL < 0x103
+ PFNGLCLIENTACTIVETEXTUREPROC glClientActiveTexture;
+#endif
+ PFNGLGETPROGRAMIVARBPROC glGetProgramivARB;
+ PFNGLPROVOKINGVERTEXPROC glProvokingVertex;
+ PFNGLGENQUERIESPROC glGenQueries;
+ PFNGLDELETEQUERIESPROC glDeleteQueries;
+ PFNGLBEGINQUERYPROC glBeginQuery;
+ PFNGLENDQUERYPROC glEndQuery;
+ PFNGLGETQUERYOBJECTUIVPROC glGetQueryObjectuiv;
+ PFNGLTEXIMAGE3DPROC glTexImage3D;
+ PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D;
+ PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor;
+ PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced;
+ PFNGLDRAWELEMENTSINSTANCEDPROC glDrawElementsInstanced;
+ PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage;
+ PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D;
+ PFNGLCOMPRESSEDTEXIMAGE3DPROC glCompressedTexImage3D;
+ PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glCompressedTexSubImage2D;
+ PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glCompressedTexSubImage3D;
+ PFNGLDRAWBUFFERSPROC glDrawBuffers;
+ PFNGLCREATESHADERPROC glCreateShader;
+ PFNGLSHADERSOURCEPROC glShaderSource;
+ PFNGLCOMPILESHADERPROC glCompileShader;
+ PFNGLGETSHADERIVPROC glGetShaderiv;
+ PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
+ PFNGLCREATEPROGRAMPROC glCreateProgram;
+ PFNGLATTACHSHADERPROC glAttachShader;
+ PFNGLLINKPROGRAMPROC glLinkProgram;
+ PFNGLGETPROGRAMIVPROC glGetProgramiv;
+ PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
+ PFNGLUSEPROGRAMPROC glUseProgram;
+ PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
+ PFNGLUNIFORM1IPROC glUniform1i;
+ PFNGLUNIFORM4FVPROC glUniform4fv;
+ PFNGLDETACHSHADERPROC glDetachShader;
+ PFNGLDELETESHADERPROC glDeleteShader;
+ PFNGLDELETEPROGRAMPROC glDeleteProgram;
+ PFNGLVERTEXATTRIB4FVPROC glVertexAttrib4fv;
+ PFNGLVERTEXATTRIB4UBVPROC glVertexAttrib4ubv;
+ PFNGLVERTEXATTRIB4NUBVPROC glVertexAttrib4Nubv;
+ PFNGLVERTEXATTRIB4SVPROC glVertexAttrib4sv;
+ PFNGLVERTEXATTRIB4NSVPROC glVertexAttrib4Nsv;
+ PFNGLVERTEXATTRIB4NUSVPROC glVertexAttrib4Nusv;
+ } ext;
+
+ struct
+ {
+ bool fS3TCSupported : 1;
+ bool fTextureFilterAnisotropicSupported : 1;
+ GLint maxActiveLights;
+ GLint maxTextures;
+ GLint maxClipDistances;
+ GLint maxColorAttachments;
+ GLint maxRectangleTextureSize;
+ GLint maxTextureAnisotropy;
+ GLint maxVertexShaderInstructions;
+ GLint maxFragmentShaderInstructions;
+ GLint maxVertexShaderTemps;
+ GLint maxFragmentShaderTemps;
+ GLfloat flPointSize[2];
+ SVGA3dPixelShaderVersion fragmentShaderVersion;
+ SVGA3dVertexShaderVersion vertexShaderVersion;
+ } caps;
+
+ /** The GL_EXTENSIONS value (space padded) for the default OpenGL profile.
+ * Free with RTStrFree. */
+ R3PTRTYPE(char *) pszExtensions;
+
+ /** The GL_EXTENSIONS value (space padded) for the other OpenGL profile.
+ * Free with RTStrFree.
+ *
+ * This is used to detect shader model version since some implementations
+ * (darwin) hides extensions that have made it into core and probably a
+ * bunch of others when using a OpenGL core profile instead of a legacy one */
+ R3PTRTYPE(char *) pszOtherExtensions;
+ /** The version of the other GL profile. */
+ float rsOtherGLVersion;
+
+ /** Shader talk back interface. */
+ VBOXVMSVGASHADERIF ShaderIf;
+
+# ifdef VMSVGA3D_OPENGL
+ /** The shared context. */
+ VMSVGA3DCONTEXT SharedCtx;
+
+ /** Conversion of emulated formats. Resources are created on the SharedCtx. */
+ PVMSVGA3DFORMATCONVERTER pConv;
+# endif
+#endif /* VMSVGA3D_OPENGL */
+} VMSVGA3DSTATE;
+
+#ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
+/**
+ * SSM descriptor table for the VMSVGA3DSTATE structure.
+ *
+ * @remarks This isn't a complete structure markup, only fields with state.
+ */
+static SSMFIELD const g_aVMSVGA3DSTATEFields[] =
+{
+# ifdef VMSVGA3D_OPENGL
+ SSMFIELD_ENTRY( VMSVGA3DSTATE, rsGLVersion), /** @todo Why are we saving the GL version?? */
+# endif
+ SSMFIELD_ENTRY( VMSVGA3DSTATE, cContexts),
+ SSMFIELD_ENTRY( VMSVGA3DSTATE, cSurfaces),
+ SSMFIELD_ENTRY_TERM()
+};
+#endif /* VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS */
+
+
+#ifdef VMSVGA3D_DIRECT3D
+D3DFORMAT vmsvga3dSurfaceFormat2D3D(SVGA3dSurfaceFormat format);
+D3DMULTISAMPLE_TYPE vmsvga3dMultipeSampleCount2D3D(uint32_t multisampleCount);
+DECLCALLBACK(int) vmsvga3dSharedSurfaceDestroyTree(PAVLU32NODECORE pNode, void *pvParam);
+int vmsvga3dSurfaceFlush(PVMSVGA3DSURFACE pSurface);
+#endif /* VMSVGA3D_DIRECT3D */
+
+
+#ifdef VMSVGA3D_OPENGL
+/** Save and setup everything. */
+# define VMSVGA3D_PARANOID_TEXTURE_PACKING
+
+/** @name VMSVGAPACKPARAMS_* - which packing parameters were set.
+ * @{ */
+# define VMSVGAPACKPARAMS_ALIGNMENT RT_BIT_32(0)
+# define VMSVGAPACKPARAMS_ROW_LENGTH RT_BIT_32(1)
+# define VMSVGAPACKPARAMS_IMAGE_HEIGHT RT_BIT_32(2)
+# define VMSVGAPACKPARAMS_SWAP_BYTES RT_BIT_32(3)
+# define VMSVGAPACKPARAMS_LSB_FIRST RT_BIT_32(4)
+# define VMSVGAPACKPARAMS_SKIP_ROWS RT_BIT_32(5)
+# define VMSVGAPACKPARAMS_SKIP_PIXELS RT_BIT_32(6)
+# define VMSVGAPACKPARAMS_SKIP_IMAGES RT_BIT_32(7)
+/** @} */
+
+/**
+ * Saved texture packing parameters (shared by both pack and unpack).
+ */
+typedef struct VMSVGAPACKPARAMS
+{
+ uint32_t fChanged;
+ GLint iAlignment;
+ GLint cxRow;
+ GLint cyImage;
+# ifdef VMSVGA3D_PARANOID_TEXTURE_PACKING
+ GLboolean fSwapBytes;
+ GLboolean fLsbFirst;
+ GLint cSkipRows;
+ GLint cSkipPixels;
+ GLint cSkipImages;
+# endif
+} VMSVGAPACKPARAMS;
+/** Pointer to saved texture packing parameters. */
+typedef VMSVGAPACKPARAMS *PVMSVGAPACKPARAMS;
+/** Pointer to const saved texture packing parameters. */
+typedef VMSVGAPACKPARAMS const *PCVMSVGAPACKPARAMS;
+
+void vmsvga3dOglSetPackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
+ PVMSVGAPACKPARAMS pSave);
+void vmsvga3dOglRestorePackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
+ PCVMSVGAPACKPARAMS pSave);
+void vmsvga3dOglSetUnpackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, GLint cxRow, GLint cyImage,
+ PVMSVGAPACKPARAMS pSave);
+void vmsvga3dOglRestoreUnpackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext,
+ PCVMSVGAPACKPARAMS pSave);
+
+/** @name VMSVGA3D_DEF_CTX_F_XXX - vmsvga3dContextDefineOgl flags.
+ * @{ */
+/** When clear, the context is created using the default OpenGL profile.
+ * When set, it's created using the alternative profile. The latter is only
+ * allowed if the VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE is set. */
+# define VMSVGA3D_DEF_CTX_F_OTHER_PROFILE RT_BIT_32(0)
+/** Defining the shared context. */
+# define VMSVGA3D_DEF_CTX_F_SHARED_CTX RT_BIT_32(1)
+/** Defining the init time context (EMT). */
+# define VMSVGA3D_DEF_CTX_F_INIT RT_BIT_32(2)
+/** @} */
+int vmsvga3dContextDefineOgl(PVGASTATECC pThisCC, uint32_t cid, uint32_t fFlags);
+void vmsvga3dSurfaceFormat2OGL(PVMSVGA3DSURFACE pSurface, SVGA3dSurfaceFormat format);
+
+#endif /* VMSVGA3D_OPENGL */
+
+
+/* DevVGA-SVGA3d-shared.cpp: */
+int vmsvga3dSaveShaderConst(PVMSVGA3DCONTEXT pContext, uint32_t reg, SVGA3dShaderType type, SVGA3dShaderConstType ctype,
+ uint32_t val1, uint32_t val2, uint32_t val3, uint32_t val4);
+
+
+DECLINLINE(int) vmsvga3dContextFromCid(PVMSVGA3DSTATE pState, uint32_t cid, PVMSVGA3DCONTEXT *ppContext)
+{
+ AssertReturn(cid < pState->cContexts, VERR_INVALID_PARAMETER);
+ PVMSVGA3DCONTEXT const pContext = pState->papContexts[cid];
+ if (RT_LIKELY(pContext && pContext->id == cid))
+ {
+ *ppContext = pContext;
+ return VINF_SUCCESS;
+ }
+ LogRelMax(64, ("VMSVGA: unknown cid=%u (%s cid=%u)\n", cid, pContext ? "expected" : "null", pContext ? pContext->id : -1));
+ return VERR_INVALID_PARAMETER;
+}
+
+#ifdef VMSVGA3D_DX
+DECLINLINE(int) vmsvga3dDXContextFromCid(PVMSVGA3DSTATE pState, uint32_t cid, PVMSVGA3DDXCONTEXT *ppDXContext)
+{
+ *ppDXContext = NULL;
+ AssertReturn(cid < pState->cDXContexts, VERR_INVALID_PARAMETER);
+ PVMSVGA3DDXCONTEXT const pDXContext = pState->papDXContexts[cid];
+ if (RT_LIKELY(pDXContext && pDXContext->cid == cid))
+ {
+ *ppDXContext = pDXContext;
+ return VINF_SUCCESS;
+ }
+ LogRelMax(64, ("VMSVGA: unknown DX cid=%u (%s cid=%u)\n", cid, pDXContext ? "expected" : "null", pDXContext ? pDXContext->cid : -1));
+ return VERR_INVALID_PARAMETER;
+}
+#endif
+
+DECLINLINE(int) vmsvga3dSurfaceFromSid(PVMSVGA3DSTATE pState, uint32_t sid, PVMSVGA3DSURFACE *ppSurface)
+{
+ AssertReturn(sid < pState->cSurfaces, VERR_INVALID_PARAMETER);
+ PVMSVGA3DSURFACE const pSurface = pState->papSurfaces[sid];
+ if (RT_LIKELY(pSurface && pSurface->id == sid))
+ {
+ *ppSurface = pSurface;
+ return VINF_SUCCESS;
+ }
+ LogRelMax(64, ("VMSVGA: unknown sid=%u (%s sid=%u)\n", sid, pSurface ? "expected" : "null", pSurface ? pSurface->id : -1));
+ return VERR_INVALID_PARAMETER;
+}
+
+DECLINLINE(int) vmsvga3dMipmapLevel(PVMSVGA3DSURFACE pSurface, uint32_t iArrayElement, uint32_t mipmap,
+ PVMSVGA3DMIPMAPLEVEL *ppMipmapLevel)
+{
+ AssertMsgReturn(iArrayElement < pSurface->surfaceDesc.numArrayElements,
+ ("numArrayElements %d, iArrayElement %d\n", pSurface->surfaceDesc.numArrayElements, iArrayElement),
+ VERR_INVALID_PARAMETER);
+ AssertMsgReturn(mipmap < pSurface->cLevels,
+ ("numMipLevels %d, mipmap %d", pSurface->cLevels, mipmap),
+ VERR_INVALID_PARAMETER);
+
+ *ppMipmapLevel = &pSurface->paMipmapLevels[iArrayElement * pSurface->cLevels + mipmap];
+ return VINF_SUCCESS;
+}
+
+void vmsvga3dInfoSurfaceToBitmap(PCDBGFINFOHLP pHlp, PVMSVGA3DSURFACE pSurface,
+ const char *pszPath, const char *pszNamePrefix, const char *pszNameSuffix);
+
+void vmsvga3dSurfaceMapInit(VMSVGA3D_MAPPED_SURFACE *pMap, VMSVGA3D_SURFACE_MAP enmMapType, SVGA3dBox const *pBox,
+ PVMSVGA3DSURFACE pSurface, void *pvData, uint32_t cbRowPitch, uint32_t cbDepthPitch);
+
+#if defined(RT_OS_WINDOWS)
+#define D3D_RELEASE(ptr) do { \
+ if (ptr) \
+ { \
+ (ptr)->Release(); \
+ (ptr) = 0; \
+ } \
+} while (0)
+#endif
+
+#if defined(VMSVGA3D_DIRECT3D)
+HRESULT D3D9UpdateTexture(PVMSVGA3DCONTEXT pContext,
+ PVMSVGA3DSURFACE pSurface);
+HRESULT D3D9GetRenderTargetData(PVMSVGA3DCONTEXT pContext,
+ PVMSVGA3DSURFACE pSurface,
+ uint32_t uFace,
+ uint32_t uMipmap);
+HRESULT D3D9GetSurfaceLevel(PVMSVGA3DSURFACE pSurface,
+ uint32_t uFace,
+ uint32_t uMipmap,
+ bool fBounce,
+ IDirect3DSurface9 **ppD3DSurface);
+D3DFORMAT D3D9GetActualFormat(PVMSVGA3DSTATE pState,
+ D3DFORMAT d3dfmt);
+bool D3D9CheckDeviceFormat(IDirect3D9 *pD3D9,
+ DWORD Usage,
+ D3DRESOURCETYPE RType,
+ D3DFORMAT CheckFormat);
+#endif
+
+#ifdef VMSVGA3D_OPENGL
+void vmsvga3dOnSharedContextDefine(PVMSVGA3DSTATE pState);
+void vmsvga3dOnSharedContextDestroy(PVMSVGA3DSTATE pState);
+
+DECLINLINE(GLuint) GLTextureId(PVMSVGA3DSURFACE pSurface)
+{
+ return pSurface->fEmulated ? pSurface->idEmulated : pSurface->oglId.texture;
+}
+
+void FormatConvUpdateTexture(PVMSVGA3DSTATE pState,
+ PVMSVGA3DCONTEXT pCurrentContext,
+ PVMSVGA3DSURFACE pSurface,
+ uint32_t iMipmap);
+void FormatConvReadTexture(PVMSVGA3DSTATE pState,
+ PVMSVGA3DCONTEXT pCurrentContext,
+ PVMSVGA3DSURFACE pSurface,
+ uint32_t iMipmap);
+#endif
+
+int vmsvga3dShaderParse(SVGA3dShaderType type, uint32_t cbShaderData, uint32_t *pShaderData);
+void vmsvga3dShaderLogRel(char const *pszMsg, SVGA3dShaderType type, uint32_t cbShaderData, uint32_t const *pShaderData);
+
+#endif /* !VBOX_INCLUDED_SRC_Graphics_DevVGA_SVGA3d_internal_h */
+