VirtualBox

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

Last change on this file was 102714, checked in by vboxsync, 5 months ago

Devices/Graphics: simplified vertex and index buffers tracking.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use