VirtualBox

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

Last change on this file since 88787 was 88787, checked in by vboxsync, 4 years ago

Devices/Graphics: a few DX commands. bugref:9830

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