VirtualBox

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

Last change on this file since 69304 was 69163, checked in by vboxsync, 7 years ago

Devices/Graphics: VMSVGA: texture and sampler states.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 46.3 KB
Line 
1/* $Id: DevVGA-SVGA3d-internal.h 69163 2017-10-23 11:54:35Z 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/**
707 * VMSVGA3d context.
708 */
709typedef struct VMSVGA3DCONTEXT
710{
711 uint32_t id;
712#ifdef RT_OS_WINDOWS
713# ifdef VMSVGA3D_DIRECT3D
714# ifdef VBOX_VMSVGA3D_WITH_WINE_OPENGL
715 IDirect3DDevice9 *pDevice;
716# else
717 IDirect3DDevice9Ex *pDevice;
718# endif
719# else
720 /* Device context of the context window. */
721 HDC hdc;
722 /* OpenGL rendering context handle. */
723 HGLRC hglrc;
724# endif
725 /* Device context window handle. */
726 HWND hwnd;
727#elif defined(RT_OS_DARWIN)
728 /* OpenGL rendering context */
729 NativeNSOpenGLContextRef cocoaContext;
730 NativeNSViewRef cocoaView;
731 bool fOtherProfile;
732#else
733 /** XGL rendering context handle */
734 GLXContext glxContext;
735 /** Device context window handle */
736 Window window;
737 /** flag whether the window is mapped (=visible) */
738 bool fMapped;
739#endif
740
741#ifdef VMSVGA3D_OPENGL
742 /* Framebuffer object associated with this context. */
743 GLuint idFramebuffer;
744 /* Read and draw framebuffer objects for various operations. */
745 GLuint idReadFramebuffer;
746 GLuint idDrawFramebuffer;
747 /* Last GL error recorded. */
748 GLenum lastError;
749 void *pShaderContext;
750#endif
751
752 /* Current active render target (if any) */
753 uint32_t sidRenderTarget;
754 /* Current selected texture surfaces (if any) */
755 uint32_t aSidActiveTextures[SVGA3D_MAX_SAMPLERS];
756 /* Per context pixel and vertex shaders. */
757 uint32_t cPixelShaders;
758 PVMSVGA3DSHADER paPixelShader;
759 uint32_t cVertexShaders;
760 PVMSVGA3DSHADER paVertexShader;
761 /* Keep track of the internal state to be able to recreate the context properly (save/restore, window resize). */
762 struct
763 {
764 /** VMSVGA3D_UPDATE_XXX */
765 uint32_t u32UpdateFlags;
766
767 SVGA3dRenderState aRenderState[SVGA3D_RS_MAX];
768 /* aTextureStates contains both TextureStageStates and SamplerStates, therefore [SVGA3D_MAX_SAMPLERS]. */
769 SVGA3dTextureState aTextureStates[SVGA3D_MAX_SAMPLERS][SVGA3D_TS_MAX];
770 VMSVGATRANSFORMSTATE aTransformState[SVGA3D_TRANSFORM_MAX];
771 VMSVGAMATERIALSTATE aMaterial[SVGA3D_FACE_MAX];
772 VMSVGACLIPPLANESTATE aClipPlane[SVGA3D_CLIPPLANE_MAX];
773 VMSVGALIGHTSTATE aLightData[SVGA3D_MAX_LIGHTS];
774
775 uint32_t aRenderTargets[SVGA3D_RT_MAX];
776 SVGA3dRect RectScissor;
777 SVGA3dRect RectViewPort;
778 SVGA3dZRange zRange;
779 uint32_t shidPixel;
780 uint32_t shidVertex;
781
782 uint32_t cPixelShaderConst;
783 PVMSVGASHADERCONST paPixelShaderConst;
784 uint32_t cVertexShaderConst;
785 PVMSVGASHADERCONST paVertexShaderConst;
786 } state;
787} VMSVGA3DCONTEXT;
788/** Pointer to a VMSVGA3d context. */
789typedef VMSVGA3DCONTEXT *PVMSVGA3DCONTEXT;
790
791#ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
792/**
793 * SSM descriptor table for the VMSVGA3DCONTEXT structure.
794 */
795static SSMFIELD const g_aVMSVGA3DCONTEXTFields[] =
796{
797 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, id),
798
799# ifdef RT_OS_WINDOWS
800# ifdef VMSVGA3D_DIRECT3D
801 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DCONTEXT, pDevice),
802# else
803 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, hdc),
804 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, hglrc),
805# endif
806 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, hwnd),
807# elif defined(RT_OS_DARWIN)
808 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, cocoaContext),
809 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, cocoaView),
810 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, fOtherProfile),
811# else
812 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, glxContext),
813 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, window),
814 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, fMapped),
815# endif
816
817#ifdef VMSVGA3D_OPENGL
818 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, idFramebuffer),
819 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, idReadFramebuffer),
820 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, idDrawFramebuffer),
821 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, lastError),
822 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DCONTEXT, pShaderContext),
823#endif
824
825 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, sidRenderTarget),
826 SSMFIELD_ENTRY_IGNORE( VMSVGA3DCONTEXT, aSidActiveTextures),
827 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, cPixelShaders),
828 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DCONTEXT, paPixelShader),
829 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, cVertexShaders),
830 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DCONTEXT, paVertexShader),
831 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.u32UpdateFlags),
832
833 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.aRenderState),
834 SSMFIELD_ENTRY_OLD( state.aTextureStates,
835 sizeof(SVGA3dTextureState) * /*SVGA3D_MAX_TEXTURE_STAGE=*/ 8 * /*SVGA3D_TS_MAX=*/ 30),
836 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.aTransformState),
837 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.aMaterial),
838 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.aClipPlane),
839 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.aLightData),
840
841 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.aRenderTargets),
842 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.RectScissor),
843 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.RectViewPort),
844 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.zRange),
845 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.shidPixel),
846 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.shidVertex),
847 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.cPixelShaderConst),
848 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DCONTEXT, state.paPixelShaderConst),
849 SSMFIELD_ENTRY( VMSVGA3DCONTEXT, state.cVertexShaderConst),
850 SSMFIELD_ENTRY_IGN_HCPTR( VMSVGA3DCONTEXT, state.paVertexShaderConst),
851 SSMFIELD_ENTRY_TERM()
852};
853#endif /* VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS */
854
855
856/**
857 * VMSVGA3d state data.
858 *
859 * Allocated on the heap and pointed to by VMSVGAState::p3dState.
860 */
861typedef struct VMSVGA3DSTATE
862{
863 /** The size of papContexts. */
864 uint32_t cContexts;
865 /** The size of papSurfaces. */
866 uint32_t cSurfaces;
867 /** Contexts indexed by ID. Grown as needed. */
868 PVMSVGA3DCONTEXT *papContexts;
869 /** Surfaces indexed by ID. Grown as needed. */
870 PVMSVGA3DSURFACE *papSurfaces;
871
872#ifdef RT_OS_WINDOWS
873# ifdef VMSVGA3D_DIRECT3D
874# ifdef VBOX_VMSVGA3D_WITH_WINE_OPENGL
875 IDirect3D9 *pD3D9;
876# else
877 IDirect3D9Ex *pD3D9;
878# endif
879 D3DCAPS9 caps;
880 bool fSupportedSurfaceINTZ;
881 bool fSupportedSurfaceNULL;
882# endif
883 /** Window Thread. */
884 R3PTRTYPE(RTTHREAD) pWindowThread;
885 DWORD idWindowThread;
886 HMODULE hInstance;
887 /** Window request semaphore. */
888 RTSEMEVENT WndRequestSem;
889#elif defined(RT_OS_DARWIN)
890#else
891 /* The X display */
892 Display *display;
893 R3PTRTYPE(RTTHREAD) pWindowThread;
894 bool bTerminate;
895#endif
896
897#ifdef VMSVGA3D_OPENGL
898 float rsGLVersion;
899 /* Current active context. */
900 uint32_t idActiveContext;
901
902 struct
903 {
904 PFNGLISRENDERBUFFERPROC glIsRenderbuffer;
905 PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer;
906 PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers;
907 PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers;
908 PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage;
909 PFNGLGETRENDERBUFFERPARAMETERIVPROC glGetRenderbufferParameteriv;
910 PFNGLISFRAMEBUFFERPROC glIsFramebuffer;
911 PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
912 PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
913 PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
914 PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
915 PFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D;
916 PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
917 PFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D;
918 PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer;
919 PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glGetFramebufferAttachmentParameteriv;
920 PFNGLGENERATEMIPMAPPROC glGenerateMipmap;
921 PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer;
922 PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample;
923 PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer;
924 PFNGLPOINTPARAMETERFPROC glPointParameterf;
925#if VBOX_VMSVGA3D_GL_HACK_LEVEL < 0x102
926 PFNGLBLENDCOLORPROC glBlendColor;
927 PFNGLBLENDEQUATIONPROC glBlendEquation;
928#endif
929 PFNGLBLENDEQUATIONSEPARATEPROC glBlendEquationSeparate;
930 PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate;
931 PFNGLSTENCILOPSEPARATEPROC glStencilOpSeparate;
932 PFNGLSTENCILFUNCSEPARATEPROC glStencilFuncSeparate;
933 PFNGLBINDBUFFERPROC glBindBuffer;
934 PFNGLDELETEBUFFERSPROC glDeleteBuffers;
935 PFNGLGENBUFFERSPROC glGenBuffers;
936 PFNGLBUFFERDATAPROC glBufferData;
937 PFNGLMAPBUFFERPROC glMapBuffer;
938 PFNGLUNMAPBUFFERPROC glUnmapBuffer;
939 PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
940 PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
941 PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer;
942 PFNGLFOGCOORDPOINTERPROC glFogCoordPointer;
943 PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glDrawElementsInstancedBaseVertex;
944 PFNGLDRAWELEMENTSBASEVERTEXPROC glDrawElementsBaseVertex;
945 PFNGLACTIVETEXTUREPROC glActiveTexture;
946#if VBOX_VMSVGA3D_GL_HACK_LEVEL < 0x103
947 PFNGLCLIENTACTIVETEXTUREPROC glClientActiveTexture;
948#endif
949 PFNGLGETPROGRAMIVARBPROC glGetProgramivARB;
950 PFNGLPROVOKINGVERTEXPROC glProvokingVertex;
951 bool fEXT_stencil_two_side;
952 } ext;
953
954 struct
955 {
956 GLint maxActiveLights;
957 GLint maxTextureBufferSize;
958 GLint maxTextures;
959 GLint maxClipDistances;
960 GLint maxColorAttachments;
961 GLint maxRectangleTextureSize;
962 GLint maxTextureAnisotropy;
963 GLint maxVertexShaderInstructions;
964 GLint maxFragmentShaderInstructions;
965 GLint maxVertexShaderTemps;
966 GLint maxFragmentShaderTemps;
967 GLfloat flPointSize[2];
968 SVGA3dPixelShaderVersion fragmentShaderVersion;
969 SVGA3dVertexShaderVersion vertexShaderVersion;
970 bool fS3TCSupported;
971 } caps;
972
973 /** The GL_EXTENSIONS value (space padded) for the default OpenGL profile.
974 * Free with RTStrFree. */
975 R3PTRTYPE(char *) pszExtensions;
976
977 /** The GL_EXTENSIONS value (space padded) for the other OpenGL profile.
978 * Free with RTStrFree.
979 *
980 * This is used to detect shader model version since some implementations
981 * (darwin) hides extensions that have made it into core and probably a
982 * bunch of others when using a OpenGL core profile instead of a legacy one */
983 R3PTRTYPE(char *) pszOtherExtensions;
984 /** The version of the other GL profile. */
985 float rsOtherGLVersion;
986
987 /** Shader talk back interface. */
988 VBOXVMSVGASHADERIF ShaderIf;
989
990# ifdef VMSVGA3D_OPENGL
991 /** The shared context. */
992 VMSVGA3DCONTEXT SharedCtx;
993# endif
994#endif /* VMSVGA3D_OPENGL */
995} VMSVGA3DSTATE;
996
997#ifdef VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
998/**
999 * SSM descriptor table for the VMSVGA3DSTATE structure.
1000 *
1001 * @remarks This isn't a complete structure markup, only fields with state.
1002 */
1003static SSMFIELD const g_aVMSVGA3DSTATEFields[] =
1004{
1005# ifdef VMSVGA3D_OPENGL
1006 SSMFIELD_ENTRY( VMSVGA3DSTATE, rsGLVersion), /** @todo Why are we saving the GL version?? */
1007# endif
1008 SSMFIELD_ENTRY( VMSVGA3DSTATE, cContexts),
1009 SSMFIELD_ENTRY( VMSVGA3DSTATE, cSurfaces),
1010 SSMFIELD_ENTRY_TERM()
1011};
1012#endif /* VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS */
1013
1014
1015#ifdef VMSVGA3D_DIRECT3D
1016D3DFORMAT vmsvga3dSurfaceFormat2D3D(SVGA3dSurfaceFormat format);
1017D3DMULTISAMPLE_TYPE vmsvga3dMultipeSampleCount2D3D(uint32_t multisampleCount);
1018DECLCALLBACK(int) vmsvga3dSharedSurfaceDestroyTree(PAVLU32NODECORE pNode, void *pvParam);
1019int vmsvga3dSurfaceFlush(PVGASTATE pThis, PVMSVGA3DSURFACE pSurface);
1020#endif /* VMSVGA3D_DIRECT3D */
1021
1022
1023#ifdef VMSVGA3D_OPENGL
1024/** Save and setup everything. */
1025# define VMSVGA3D_PARANOID_TEXTURE_PACKING
1026
1027/**
1028 * Saved texture packing parameters (shared by both pack and unpack).
1029 */
1030typedef struct VMSVGAPACKPARAMS
1031{
1032 GLint iAlignment;
1033 GLint cxRow;
1034# ifdef VMSVGA3D_PARANOID_TEXTURE_PACKING
1035 GLint cyImage;
1036 GLboolean fSwapBytes;
1037 GLboolean fLsbFirst;
1038 GLint cSkipRows;
1039 GLint cSkipPixels;
1040 GLint cSkipImages;
1041# endif
1042} VMSVGAPACKPARAMS;
1043/** Pointer to saved texture packing parameters. */
1044typedef VMSVGAPACKPARAMS *PVMSVGAPACKPARAMS;
1045/** Pointer to const saved texture packing parameters. */
1046typedef VMSVGAPACKPARAMS const *PCVMSVGAPACKPARAMS;
1047
1048void vmsvga3dOglSetPackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
1049 PVMSVGAPACKPARAMS pSave);
1050void vmsvga3dOglRestorePackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
1051 PCVMSVGAPACKPARAMS pSave);
1052void vmsvga3dOglSetUnpackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
1053 PVMSVGAPACKPARAMS pSave);
1054void vmsvga3dOglRestoreUnpackParams(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, PVMSVGA3DSURFACE pSurface,
1055 PCVMSVGAPACKPARAMS pSave);
1056
1057/** @name VMSVGA3D_DEF_CTX_F_XXX - vmsvga3dContextDefineOgl flags.
1058 * @{ */
1059/** When clear, the context is created using the default OpenGL profile.
1060 * When set, it's created using the alternative profile. The latter is only
1061 * allowed if the VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE is set. */
1062# define VMSVGA3D_DEF_CTX_F_OTHER_PROFILE RT_BIT_32(0)
1063/** Defining the shared context. */
1064# define VMSVGA3D_DEF_CTX_F_SHARED_CTX RT_BIT_32(1)
1065/** Defining the init time context (EMT). */
1066# define VMSVGA3D_DEF_CTX_F_INIT RT_BIT_32(2)
1067/** @} */
1068int vmsvga3dContextDefineOgl(PVGASTATE pThis, uint32_t cid, uint32_t fFlags);
1069void vmsvga3dSurfaceFormat2OGL(PVMSVGA3DSURFACE pSurface, SVGA3dSurfaceFormat format);
1070
1071#endif /* VMSVGA3D_OPENGL */
1072
1073
1074/* DevVGA-SVGA3d-shared.cpp: */
1075int vmsvga3dSaveShaderConst(PVMSVGA3DCONTEXT pContext, uint32_t reg, SVGA3dShaderType type, SVGA3dShaderConstType ctype,
1076 uint32_t val1, uint32_t val2, uint32_t val3, uint32_t val4);
1077
1078
1079
1080/* Command implementation workers. */
1081void vmsvga3dBackSurfaceDestroy(PVMSVGA3DSTATE pState, PVMSVGA3DSURFACE pSurface);
1082int vmsvga3dBackSurfaceStretchBlt(PVGASTATE pThis, PVMSVGA3DSTATE pState,
1083 PVMSVGA3DSURFACE pDstSurface, uint32_t uDstFace, uint32_t uDstMipmap, SVGA3dBox const *pDstBox,
1084 PVMSVGA3DSURFACE pSrcSurface, uint32_t uSrcFace, uint32_t uSrcMipmap, SVGA3dBox const *pSrcBox,
1085 SVGA3dStretchBltMode enmMode, PVMSVGA3DCONTEXT pContext);
1086int vmsvga3dBackSurfaceDMACopyBox(PVGASTATE pThis, PVMSVGA3DSTATE pState, PVMSVGA3DSURFACE pSurface,
1087 PVMSVGA3DMIPMAPLEVEL pMipLevel, uint32_t uHostFace, uint32_t uHostMipmap,
1088 SVGAGuestPtr GuestPtr, uint32_t cbGuestPitch, SVGA3dTransferType transfer,
1089 SVGA3dCopyBox const *pBox, PVMSVGA3DCONTEXT pContext, int rc, int iBox);
1090
1091int vmsvga3dBackCreateTexture(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, uint32_t idAssociatedContext,
1092 PVMSVGA3DSURFACE pSurface);
1093
1094void vmsvgaClipCopyBox(const SVGA3dSize *pSizeSrc,
1095 const SVGA3dSize *pSizeDest,
1096 SVGA3dCopyBox *pBox);
1097void vmsvgaClipBox(const SVGA3dSize *pSize,
1098 SVGA3dBox *pBox);
1099
1100DECLINLINE(int) vmsvga3dContextFromCid(PVMSVGA3DSTATE pState, uint32_t cid, PVMSVGA3DCONTEXT *ppContext)
1101{
1102 /** @todo stricter checks for associated context */
1103 if ( cid >= pState->cContexts
1104 || pState->papContexts[cid]->id != cid)
1105 {
1106 Log(("vmsvga3dSurfaceCopy invalid context id!\n"));
1107 return VERR_INVALID_PARAMETER;
1108 }
1109
1110 *ppContext = pState->papContexts[cid];
1111 return VINF_SUCCESS;
1112}
1113
1114DECLINLINE(int) vmsvga3dSurfaceFromSid(PVMSVGA3DSTATE pState, uint32_t sid, PVMSVGA3DSURFACE *ppSurface)
1115{
1116 Assert(sid < SVGA3D_MAX_SURFACE_IDS);
1117 AssertReturn(sid < pState->cSurfaces, VERR_INVALID_PARAMETER);
1118 PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
1119 AssertReturn(pSurface && pSurface->id == sid, VERR_INVALID_PARAMETER);
1120 *ppSurface = pSurface;
1121 return VINF_SUCCESS;
1122}
1123
1124DECLINLINE(int) vmsvga3dMipmapLevel(PVMSVGA3DSURFACE pSurface, uint32_t face, uint32_t mipmap,
1125 PVMSVGA3DMIPMAPLEVEL *ppMipmapLevel)
1126{
1127 /* Can use faces[0].numMipLevels, because numMipLevels is the same for all faces. */
1128 const uint32_t numMipLevels = pSurface->faces[0].numMipLevels;
1129
1130 AssertMsgReturn(face < pSurface->cFaces,
1131 ("cFaces %d, face %d\n", pSurface->cFaces, face),
1132 VERR_INVALID_PARAMETER);
1133 AssertMsgReturn(mipmap < numMipLevels,
1134 ("numMipLevels %d, mipmap %d", numMipLevels, mipmap),
1135 VERR_INVALID_PARAMETER);
1136
1137 *ppMipmapLevel = &pSurface->pMipmapLevels[face * numMipLevels + mipmap];
1138 return VINF_SUCCESS;
1139}
1140
1141#ifdef VMSVGA3D_DIRECT3D
1142DECLINLINE(D3DCUBEMAP_FACES) vmsvga3dCubemapFaceFromIndex(uint32_t iFace)
1143{
1144 D3DCUBEMAP_FACES Face;
1145 switch (iFace)
1146 {
1147 case 0: Face = D3DCUBEMAP_FACE_POSITIVE_X; break;
1148 case 1: Face = D3DCUBEMAP_FACE_NEGATIVE_X; break;
1149 case 2: Face = D3DCUBEMAP_FACE_POSITIVE_Y; break;
1150 case 3: Face = D3DCUBEMAP_FACE_NEGATIVE_Y; break;
1151 case 4: Face = D3DCUBEMAP_FACE_POSITIVE_Z; break;
1152 default:
1153 case 5: Face = D3DCUBEMAP_FACE_NEGATIVE_Z; break;
1154 }
1155 return Face;
1156}
1157#endif /* VMSVGA3D_DIRECT3D */
1158
1159#endif
1160
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