summaryrefslogtreecommitdiffstats
path: root/src/VBox/Additions/common/crOpenGL/pack
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 03:01:46 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 03:01:46 +0000
commitf8fe689a81f906d1b91bb3220acde2a4ecb14c5b (patch)
tree26484e9d7e2c67806c2d1760196ff01aaa858e8c /src/VBox/Additions/common/crOpenGL/pack
parentInitial commit. (diff)
downloadvirtualbox-upstream.tar.xz
virtualbox-upstream.zip
Adding upstream version 6.0.4-dfsg.upstream/6.0.4-dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Additions/common/crOpenGL/pack')
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/Makefile.kup0
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/pack.def6
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/pack/pack.py57
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu.h185
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu.rc69
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/pack/packspu_beginend.py177
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_bufferobject.c160
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_client.c910
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_config.c60
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_context.c617
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/pack/packspu_flush.py42
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_flush_special9
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_framebuffer.c143
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/pack/packspu_get.py250
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_getshaders.c214
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_getstring.c211
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_glsl.c275
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_init.c152
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_misc.c856
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_net.c284
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_pixel.c727
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/pack/packspu_proto.py50
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_special138
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_swapbuf.c102
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_texture.c70
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_unimplemented_special4
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_vertex_special28
27 files changed, 5796 insertions, 0 deletions
diff --git a/src/VBox/Additions/common/crOpenGL/pack/Makefile.kup b/src/VBox/Additions/common/crOpenGL/pack/Makefile.kup
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/Makefile.kup
diff --git a/src/VBox/Additions/common/crOpenGL/pack/pack.def b/src/VBox/Additions/common/crOpenGL/pack/pack.def
new file mode 100644
index 00000000..9edc7163
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/pack.def
@@ -0,0 +1,6 @@
+; Copyright (c) 2001, Stanford University
+; All rights reserved.
+;
+; See the file LICENSE.txt for information on redistributing this software.
+EXPORTS
+SPULoad
diff --git a/src/VBox/Additions/common/crOpenGL/pack/pack.py b/src/VBox/Additions/common/crOpenGL/pack/pack.py
new file mode 100755
index 00000000..e25066be
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/pack.py
@@ -0,0 +1,57 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+from __future__ import print_function
+import sys
+
+import apiutil
+
+
+keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
+
+
+apiutil.CopyrightC()
+
+print("""
+/* DO NOT EDIT - THIS FILE AUTOMATICALLY GENERATED BY pack.py SCRIPT */
+#include <stdio.h>
+#include "cr_string.h"
+#include "cr_spu.h"
+#include "packspu.h"
+#include "cr_packfunctions.h"
+#include "packspu_proto.h"
+""")
+
+num_funcs = len(keys) - len(apiutil.AllSpecials('packspu_unimplemented'))
+print('SPUNamedFunctionTable _cr_pack_table[%d];' % (num_funcs+1))
+
+print("""
+static void __fillin(int offset, char *name, SPUGenericFunction func)
+{
+ _cr_pack_table[offset].name = crStrdup(name);
+ _cr_pack_table[offset].fn = func;
+}""")
+
+pack_specials = []
+
+for func_name in keys:
+ if ("get" in apiutil.Properties(func_name) or
+ apiutil.FindSpecial( "packspu", func_name ) or
+ apiutil.FindSpecial( "packspu_flush", func_name ) or
+ apiutil.FindSpecial( "packspu_vertex", func_name )):
+ pack_specials.append( func_name )
+
+print('\nvoid packspuCreateFunctions( void )')
+print('{')
+for index in range(len(keys)):
+ func_name = keys[index]
+ if apiutil.FindSpecial( "packspu_unimplemented", func_name ):
+ continue
+ if func_name in pack_specials:
+ print('\t__fillin(%3d, "%s", (SPUGenericFunction) packspu_%s);' % (index, func_name, func_name ))
+ else:
+ print('\t__fillin(%3d, "%s", (SPUGenericFunction) (pack_spu.swap ? crPack%sSWAP : crPack%s));' % (index, func_name, func_name, func_name ))
+print('\t__fillin(%3d, NULL, NULL);' % num_funcs)
+print('}')
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu.h b/src/VBox/Additions/common/crOpenGL/pack/packspu.h
new file mode 100644
index 00000000..9774e35b
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu.h
@@ -0,0 +1,185 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved.
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#ifndef GA_INCLUDED_SRC_common_crOpenGL_pack_packspu_h
+#define GA_INCLUDED_SRC_common_crOpenGL_pack_packspu_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#ifdef WINDOWS
+#define PACKSPU_APIENTRY __stdcall
+#else
+#define PACKSPU_APIENTRY
+#endif
+
+#include "cr_glstate.h"
+#include "cr_netserver.h"
+#include "cr_pack.h"
+#include "cr_spu.h"
+#include "cr_threads.h"
+#include "state/cr_client.h"
+#ifdef VBOX_WITH_CRPACKSPU_DUMPER
+# include "cr_dump.h"
+#endif
+
+extern uint32_t g_u32VBoxHostCaps;
+
+typedef struct thread_info_t ThreadInfo;
+typedef struct context_info_t ContextInfo;
+typedef struct zvabuffer_info_t ZvaBufferInfo;
+
+struct zvabuffer_info_t
+{
+ /* GL_ARRAY_BUFFER_ARB buffer */
+ GLuint idBuffer;
+ /* buffer length */
+ GLuint cbBuffer;
+ /* number of values stored in the buffer currently */
+ GLuint cValues;
+ /* current buffer value */
+ union
+ {
+ GLfloat f[4];
+ GLuint ui[4];
+ GLubyte ub[4];
+ GLshort s[4];
+ GLushort us[4];
+ } Value;
+};
+
+struct thread_info_t {
+ unsigned long id;
+ CRNetServer netServer;
+ CRPackBuffer buffer;
+ CRPackBuffer normBuffer;
+ CRPackBuffer BeginEndBuffer;
+ GLenum BeginEndMode;
+ int BeginEndState;
+ ContextInfo *currentContext;
+ CRPackContext *packer;
+ int writeback;
+ GLboolean bInjectThread;
+ GLboolean inUse;
+};
+
+struct context_info_t {
+ CRContext *clientState; /* used to store client-side GL state */
+ GLint serverCtx; /* context ID returned by server */
+ GLboolean fAutoFlush;
+ GLboolean fCheckZerroVertAttr;
+ ThreadInfo *currentThread;
+ ZvaBufferInfo zvaBufferInfo;
+ GLubyte glVersion[100]; /* GL_VERSION string */
+ GLubyte pszRealVendor[100];
+ GLubyte pszRealVersion[100];
+ GLubyte pszRealRenderer[100];
+};
+
+typedef struct {
+ int id;
+ int swap;
+
+ /* config options */
+ int emit_GATHER_POST_SWAPBUFFERS;
+ int swapbuffer_sync;
+
+ int ReadPixels;
+
+ char *name;
+ int buffer_size;
+
+ int numThreads; /*number of used threads in the next array, doesn't need to be cont*/
+ ThreadInfo thread[MAX_THREADS];
+ int idxThreadInUse; /*index of any used thread*/
+
+#if defined(WINDOWS) && defined(VBOX_WITH_WDDM)
+ bool bIsWDDMCrHgsmi;
+#endif
+
+ SPUDispatchTable self;
+
+#ifdef VBOX_WITH_CRPACKSPU_DUMPER
+ CR_RECORDER Recorder;
+ CR_DBGPRINT_DUMPER Dumper;
+#endif
+
+ int numContexts;
+ ContextInfo context[CR_MAX_CONTEXTS];
+} PackSPU;
+
+extern PackSPU pack_spu;
+
+#define THREAD_OFFSET_MAGIC 2000
+
+#ifdef CHROMIUM_THREADSAFE
+extern CRmutex _PackMutex;
+extern CRtsd _PackTSD;
+#define GET_THREAD_VAL() (crGetTSD(&_PackTSD))
+#define GET_THREAD_IDX(_id) ((_id) - THREAD_OFFSET_MAGIC)
+#define GET_THREAD_VAL_ID(_id) (&(pack_spu.thread[GET_THREAD_IDX(_id)]))
+#else
+#define GET_THREAD_VAL() (&(pack_spu.thread[0]))
+#endif
+#define GET_THREAD(T) ThreadInfo *T = GET_THREAD_VAL()
+#define GET_THREAD_ID(T, _id) ThreadInfo *T = GET_THREAD_VAL_ID(_id)
+
+
+
+#define GET_CONTEXT(C) \
+ GET_THREAD(thread); \
+ ContextInfo *C = thread->currentContext
+
+#ifdef DEBUG_misha
+# define CRPACKSPU_WRITEBACK_ASSERT_ZERO(_writeback) Assert(!(_writeback))
+#else
+# define CRPACKSPU_WRITEBACK_ASSERT_ZERO(_writeback) do {} while (0)
+#endif
+
+#define CRPACKSPU_WRITEBACK_WAIT(_thread, _writeback) do {\
+ if (g_u32VBoxHostCaps & CR_VBOX_CAP_CMDVBVA) { \
+ CRPACKSPU_WRITEBACK_ASSERT_ZERO(_writeback); \
+ (_writeback) = 0; \
+ break; \
+ } \
+ CR_WRITEBACK_WAIT((_thread)->netServer.conn, _writeback); \
+ } while (0)
+
+#if defined(WINDOWS) && defined(VBOX_WITH_WDDM) && defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+# define CRPACKSPU_IS_WDDM_CRHGSMI() (pack_spu.bIsWDDMCrHgsmi)
+#else
+# define CRPACKSPU_IS_WDDM_CRHGSMI() (GL_FALSE)
+#endif
+
+extern void packspuCreateFunctions( void );
+extern void packspuSetVBoxConfiguration( const SPU *child_spu );
+extern void packspuConnectToServer( CRNetServer *server
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ , struct VBOXUHGSMI *pHgsmi
+#endif
+ );
+extern void packspuFlush( void *arg );
+extern void packspuHuge( CROpcode opcode, void *buf );
+
+extern void packspuInitStrings(void);
+
+extern GLboolean packspuSyncOnFlushes(void);
+
+extern ThreadInfo *packspuNewThread(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ struct VBOXUHGSMI *pHgsmi
+#else
+ void
+#endif
+ );
+
+extern ThreadInfo *packspuNewCtxThread( struct VBOXUHGSMI *pHgsmi );
+
+
+
+#define MAGIC_OFFSET 3000
+
+#endif /* !GA_INCLUDED_SRC_common_crOpenGL_pack_packspu_h */
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu.rc b/src/VBox/Additions/common/crOpenGL/pack/packspu.rc
new file mode 100644
index 00000000..b120f236
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu.rc
@@ -0,0 +1,69 @@
+/* $Id: packspu.rc $ */
+/** @file
+ * VBoxOGLpackspu - Resource file containing version info and icon.
+ */
+
+/*
+ * Copyright (C) 2009-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_RC_FILE_VERSION
+ PRODUCTVERSION VBOX_RC_FILE_VERSION
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS VBOX_RC_FILE_FLAGS
+ FILEOS VBOX_RC_FILE_OS
+ FILETYPE VBOX_RC_TYPE_DRV
+ FILESUBTYPE VFT2_DRV_DISPLAY
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "FileDescription", "VirtualBox crOpenGL ICD\0"
+ VALUE "InternalName", "VBoxOGLpackspu\0"
+#ifdef VBOX_WDDM_WOW64
+ VALUE "OriginalFilename", "VBoxOGLpackspu-x86.dll\0"
+#else
+ VALUE "OriginalFilename", "VBoxOGLpackspu.dll\0"
+#endif
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileVersion", VBOX_RC_FILE_VERSION_STR
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "ProductName", VBOX_RC_PRODUCT_NAME_GA_STR
+ VALUE "ProductVersion", VBOX_RC_PRODUCT_VERSION_STR
+ VBOX_RC_MORE_STRINGS
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+1 RCDATA
+BEGIN
+// Machine dependent parameters
+ 17, // Height of vertical thumb
+ 17, // Width of horizontal thumb
+ 2, // Icon horiz compression factor
+ 2, // Icon vert compression factor
+ 1, // Cursor horz compression factor
+ 1, // Cursor vert compression factor
+ 0, // Kanji window height
+ 1, // cxBorder (thickness of vertical lines)
+ 1 // cyBorder (thickness of horizontal lines)
+END
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_beginend.py b/src/VBox/Additions/common/crOpenGL/pack/packspu_beginend.py
new file mode 100755
index 00000000..2195cab5
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_beginend.py
@@ -0,0 +1,177 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+from __future__ import print_function
+import sys
+
+import apiutil
+
+
+apiutil.CopyrightC()
+
+print("""/* DO NOT EDIT - AUTOMATICALLY GENERATED BY packspu_beginend.py */
+#include "packspu.h"
+#include "assert.h"
+#include "cr_packfunctions.h"
+#include "packspu_proto.h"
+
+void PACKSPU_APIENTRY packspu_Begin( GLenum mode )
+{
+ CRPackBuffer *buf;
+#if CR_ARB_vertex_buffer_object
+ GET_CONTEXT(ctx);
+#else
+ GET_THREAD(thread);
+#endif
+
+ buf = &thread->BeginEndBuffer;
+
+ /* XXX comparing mode >= 0 here is not needed since mode is unsigned */
+ CRASSERT( /*mode >= GL_POINTS && */mode <= GL_POLYGON );
+
+#if CR_ARB_vertex_buffer_object
+ {
+ GLboolean serverArrays = GL_FALSE;
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object)
+ serverArrays = crStateUseServerArrays();
+ if (serverArrays) {
+ CRClientState *clientState = &(ctx->clientState->client);
+ if (clientState->array.locked && !clientState->array.synced)
+ {
+ crPackLockArraysEXT(clientState->array.lockFirst, clientState->array.lockCount);
+ clientState->array.synced = GL_TRUE;
+ }
+ }
+ }
+#endif
+
+ if (pack_spu.swap)
+ {
+ crPackBeginSWAP( mode );
+ }
+ else
+ {
+ crPackBegin( mode );
+ }
+
+ if ( thread->netServer.conn->Barf ) {
+ thread->BeginEndMode = mode;
+ thread->BeginEndState = -1;
+ if ( mode == GL_LINES || mode == GL_TRIANGLES || mode == GL_QUADS || mode == GL_POLYGON )
+ {
+ CRASSERT(!buf->pack);
+
+ crPackReleaseBuffer( thread->packer );
+ buf->pack = crNetAlloc( thread->netServer.conn );
+ crPackInitBuffer( buf, buf->pack, thread->netServer.conn->buffer_size, thread->netServer.conn->mtu );
+ buf->holds_BeginEnd = 1;
+ buf->in_BeginEnd = 1;
+ crPackSetBuffer( thread->packer, buf );
+
+ thread->BeginEndState = 0;
+ }
+ }
+}
+
+void PACKSPU_APIENTRY packspu_End( void )
+{
+ GET_THREAD(thread);
+ CRPackBuffer *buf = &thread->BeginEndBuffer;
+
+ if ( thread->netServer.conn->Barf &&
+ (thread->BeginEndMode == GL_LINES
+ || thread->BeginEndMode == GL_TRIANGLES
+ || thread->BeginEndMode == GL_QUADS
+ || thread->BeginEndMode == GL_POLYGON ) )
+ {
+ CRASSERT(buf->pack);
+
+ crPackReleaseBuffer( thread->packer );
+ crPackSetBuffer( thread->packer, &thread->normBuffer );
+ if ( !crPackCanHoldBuffer( buf ) )
+ packspuFlush( (void *) thread );
+
+ crPackAppendBuffer( buf );
+ crNetFree( thread->netServer.conn, buf->pack );
+ buf->pack = NULL;
+ }
+
+ if (pack_spu.swap)
+ {
+ crPackEndSWAP();
+ }
+ else
+ {
+ crPackEnd();
+ }
+}
+
+static void DoVertex( void )
+{
+ GET_THREAD(thread);
+ CRPackBuffer *buf = &thread->BeginEndBuffer;
+ CRPackBuffer *gbuf = &thread->normBuffer;
+ int num_data;
+ int num_opcode;
+
+ /*crDebug( "really doing Vertex" );*/
+ crPackReleaseBuffer( thread->packer );
+ num_data = buf->data_current - buf->data_start;
+ num_opcode = buf->opcode_start - buf->opcode_current;
+ crPackSetBuffer( thread->packer, gbuf );
+ if ( !crPackCanHoldBuffer( buf ) )
+ /* doesn't hold, first flush gbuf*/
+ packspuFlush( (void *) thread );
+
+ crPackAppendBuffer( buf );
+ crPackReleaseBuffer( thread->packer );
+ crPackSetBuffer( thread->packer, buf );
+ crPackResetPointers(thread->packer);
+}
+
+static void RunState( void )
+{
+ GET_THREAD(thread);
+ if (! thread->netServer.conn->Barf ) return;
+ if (thread->BeginEndState == -1) return;
+ switch(thread->BeginEndMode) {
+ case GL_POLYGON:
+ return;
+ case GL_LINES:
+ thread->BeginEndState = (thread->BeginEndState + 1) % 2;
+ if (thread->BeginEndState)
+ return;
+ break;
+ case GL_TRIANGLES:
+ thread->BeginEndState = (thread->BeginEndState + 1) % 3;
+ if (thread->BeginEndState)
+ return;
+ break;
+ case GL_QUADS:
+ thread->BeginEndState = (thread->BeginEndState + 1) % 4;
+ if (thread->BeginEndState)
+ return;
+ break;
+ }
+ DoVertex();
+}
+""")
+
+keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
+
+for func_name in apiutil.AllSpecials( "packspu_vertex" ):
+ params = apiutil.Parameters(func_name)
+ print('void PACKSPU_APIENTRY packspu_%s(%s)' % ( func_name, apiutil.MakeDeclarationString(params) ))
+ print('{')
+ print('\tif (pack_spu.swap)')
+ print('\t{')
+ print('\t\tcrPack%sSWAP(%s);' % ( func_name, apiutil.MakeCallString( params ) ))
+ print('\t}')
+ print('\telse')
+ print('\t{')
+ print('\t\tcrPack%s(%s);' % ( func_name, apiutil.MakeCallString( params ) ))
+ print('\t}')
+ print('\tRunState();')
+ print('}')
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_bufferobject.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_bufferobject.c
new file mode 100644
index 00000000..65f64bd7
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_bufferobject.c
@@ -0,0 +1,160 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include "cr_error.h"
+#include "cr_mem.h"
+#include "cr_string.h"
+#include "packspu.h"
+#include "packspu_proto.h"
+
+static void packspu_GetHostBufferSubDataARB( GLenum target, GLintptrARB offset, GLsizeiptrARB size, void * data )
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+
+ crPackGetBufferSubDataARB(target, offset, size, data, &writeback);
+
+ packspuFlush((void *) thread);
+
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+}
+
+void * PACKSPU_APIENTRY
+packspu_MapBufferARB( GLenum target, GLenum access )
+{
+ GET_CONTEXT(ctx);
+ void *buffer;
+ CRBufferObject *pBufObj;
+
+ CRASSERT(GL_TRUE == ctx->clientState->bufferobject.retainBufferData);
+ buffer = crStateMapBufferARB(target, access);
+
+#ifdef CR_ARB_pixel_buffer_object
+ if (buffer)
+ {
+ pBufObj = crStateGetBoundBufferObject(target, &ctx->clientState->bufferobject);
+ CRASSERT(pBufObj);
+
+ if (pBufObj->bResyncOnRead &&
+ access != GL_WRITE_ONLY_ARB)
+ {
+ /*fetch data from host side*/
+ packspu_GetHostBufferSubDataARB(target, 0, pBufObj->size, buffer);
+ }
+ }
+#endif
+
+ return buffer;
+}
+
+void PACKSPU_APIENTRY packspu_GetBufferSubDataARB( GLenum target, GLintptrARB offset, GLsizeiptrARB size, void * data )
+{
+ GET_CONTEXT(ctx);
+
+#ifdef CR_ARB_pixel_buffer_object
+ CRBufferObject *pBufObj;
+
+ pBufObj = crStateGetBoundBufferObject(target, &ctx->clientState->bufferobject);
+
+ if (pBufObj && pBufObj->bResyncOnRead)
+ {
+ packspu_GetHostBufferSubDataARB(target, offset, size, data);
+ return;
+ }
+#endif
+
+ crStateGetBufferSubDataARB(target, offset, size, data);
+}
+
+
+GLboolean PACKSPU_APIENTRY
+packspu_UnmapBufferARB( GLenum target )
+{
+ GET_CONTEXT(ctx);
+
+#if CR_ARB_vertex_buffer_object
+ CRBufferObject *bufObj;
+
+ bufObj = crStateGetBoundBufferObject(target, &ctx->clientState->bufferobject);
+
+ /* send new buffer contents to server */
+ crPackBufferDataARB( target, bufObj->size, bufObj->pointer, bufObj->usage );
+#endif
+
+ CRASSERT(GL_TRUE == ctx->clientState->bufferobject.retainBufferData);
+ crStateUnmapBufferARB( target );
+
+ return GL_TRUE;
+}
+
+
+void PACKSPU_APIENTRY
+packspu_BufferDataARB(GLenum target, GLsizeiptrARB size, const GLvoid * data, GLenum usage)
+{
+ /*crDebug("packspu_BufferDataARB size:%d", size);*/
+ crStateBufferDataARB(target, size, data, usage);
+ crPackBufferDataARB(target, size, data, usage);
+}
+
+void PACKSPU_APIENTRY
+packspu_BufferSubDataARB(GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid * data)
+{
+ /*crDebug("packspu_BufferSubDataARB size:%d", size);*/
+ crStateBufferSubDataARB(target, offset, size, data);
+ crPackBufferSubDataARB(target, offset, size, data);
+}
+
+
+void PACKSPU_APIENTRY
+packspu_GetBufferPointervARB(GLenum target, GLenum pname, GLvoid **params)
+{
+ crStateGetBufferPointervARB( target, pname, params );
+}
+
+
+void PACKSPU_APIENTRY
+packspu_GetBufferParameterivARB( GLenum target, GLenum pname, GLint * params )
+{
+ crStateGetBufferParameterivARB( target, pname, params );
+}
+
+/*
+ * Need to update our local state for vertex arrays.
+ */
+void PACKSPU_APIENTRY
+packspu_BindBufferARB( GLenum target, GLuint buffer )
+{
+ crStateBindBufferARB(target, buffer);
+ crPackBindBufferARB(target, buffer);
+}
+
+void PACKSPU_APIENTRY packspu_GenBuffersARB( GLsizei n, GLuint * buffer )
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI() && !(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))
+ {
+ crError( "packspu_GenBuffersARB doesn't work when there's no actual network involved!\nTry using the simplequery SPU in your chain!" );
+ }
+ if (pack_spu.swap)
+ {
+ crPackGenBuffersARBSWAP( n, buffer, &writeback );
+ }
+ else
+ {
+ crPackGenBuffersARB( n, buffer, &writeback );
+ }
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ crStateRegBuffers(n, buffer);
+}
+
+void PACKSPU_APIENTRY packspu_DeleteBuffersARB( GLsizei n, const GLuint * buffer )
+{
+ crStateDeleteBuffersARB( n, buffer );
+ crPackDeleteBuffersARB(n, buffer);
+}
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_client.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_client.c
new file mode 100644
index 00000000..19c11880
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_client.c
@@ -0,0 +1,910 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include "packspu.h"
+#include "cr_packfunctions.h"
+#include "cr_glstate.h"
+#include "packspu_proto.h"
+#include "cr_mem.h"
+
+void PACKSPU_APIENTRY packspu_FogCoordPointerEXT( GLenum type, GLsizei stride, const GLvoid *pointer )
+{
+#if CR_ARB_vertex_buffer_object
+ GET_CONTEXT(ctx);
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
+ if (pack_spu.swap)
+ crPackFogCoordPointerEXTSWAP( type, stride, pointer );
+ else
+ crPackFogCoordPointerEXT( type, stride, pointer );
+ }
+#endif
+ crStateFogCoordPointerEXT( type, stride, pointer );
+}
+
+void PACKSPU_APIENTRY packspu_ColorPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer )
+{
+#if CR_ARB_vertex_buffer_object
+ GET_CONTEXT(ctx);
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
+ if (pack_spu.swap)
+ crPackColorPointerSWAP( size, type, stride, pointer );
+ else
+ crPackColorPointer( size, type, stride, pointer );
+ }
+#endif
+ crStateColorPointer( size, type, stride, pointer );
+}
+
+void PACKSPU_APIENTRY packspu_SecondaryColorPointerEXT( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer )
+{
+#if CR_ARB_vertex_buffer_object
+ GET_CONTEXT(ctx);
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
+ if (pack_spu.swap)
+ crPackSecondaryColorPointerEXTSWAP( size, type, stride, pointer );
+ else
+ crPackSecondaryColorPointerEXT( size, type, stride, pointer );
+ }
+#endif
+ crStateSecondaryColorPointerEXT( size, type, stride, pointer );
+}
+
+void PACKSPU_APIENTRY packspu_VertexPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer )
+{
+#if CR_ARB_vertex_buffer_object
+ GET_CONTEXT(ctx);
+ CRASSERT(ctx->clientState->extensions.ARB_vertex_buffer_object);
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
+ if (pack_spu.swap)
+ crPackVertexPointerSWAP( size, type, stride, pointer );
+ else
+ crPackVertexPointer( size, type, stride, pointer );
+ }
+#endif
+ crStateVertexPointer( size, type, stride, pointer );
+}
+
+void PACKSPU_APIENTRY packspu_TexCoordPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer )
+{
+#if CR_ARB_vertex_buffer_object
+ GET_CONTEXT(ctx);
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
+ if (pack_spu.swap)
+ crPackTexCoordPointerSWAP( size, type, stride, pointer );
+ else
+ crPackTexCoordPointer( size, type, stride, pointer );
+ }
+#endif
+ crStateTexCoordPointer( size, type, stride, pointer );
+}
+
+void PACKSPU_APIENTRY packspu_NormalPointer( GLenum type, GLsizei stride, const GLvoid *pointer )
+{
+#if CR_ARB_vertex_buffer_object
+ GET_CONTEXT(ctx);
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
+ if (pack_spu.swap)
+ crPackNormalPointerSWAP( type, stride, pointer );
+ else
+ crPackNormalPointer( type, stride, pointer );
+ }
+#endif
+ crStateNormalPointer( type, stride, pointer );
+}
+
+void PACKSPU_APIENTRY packspu_EdgeFlagPointer( GLsizei stride, const GLvoid *pointer )
+{
+#if CR_ARB_vertex_buffer_object
+ GET_CONTEXT(ctx);
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
+ if (pack_spu.swap)
+ crPackEdgeFlagPointerSWAP( stride, pointer );
+ else
+ crPackEdgeFlagPointer( stride, pointer );
+ }
+#endif
+ crStateEdgeFlagPointer( stride, pointer );
+}
+
+void PACKSPU_APIENTRY packspu_VertexAttribPointerARB( GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer )
+{
+#if CR_ARB_vertex_buffer_object
+ GET_CONTEXT(ctx);
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
+ if (pack_spu.swap)
+ crPackVertexAttribPointerARBSWAP( index, size, type, normalized, stride, pointer );
+ else
+ crPackVertexAttribPointerARB( index, size, type, normalized, stride, pointer );
+ }
+#endif
+ crStateVertexAttribPointerARB( index, size, type, normalized, stride, pointer );
+}
+
+void PACKSPU_APIENTRY packspu_VertexAttribPointerNV( GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer )
+{
+#if CR_ARB_vertex_buffer_object
+ GET_CONTEXT(ctx);
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
+ if (pack_spu.swap)
+ crPackVertexAttribPointerNVSWAP( index, size, type, stride, pointer );
+ else
+ crPackVertexAttribPointerNV( index, size, type, stride, pointer );
+ }
+#endif
+ crStateVertexAttribPointerNV( index, size, type, stride, pointer );
+}
+
+void PACKSPU_APIENTRY packspu_IndexPointer( GLenum type, GLsizei stride, const GLvoid *pointer )
+{
+#if CR_ARB_vertex_buffer_object
+ GET_CONTEXT(ctx);
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
+ if (pack_spu.swap)
+ crPackIndexPointerSWAP( type, stride, pointer );
+ else
+ crPackIndexPointer( type, stride, pointer );
+ }
+#endif
+ crStateIndexPointer(type, stride, pointer);
+}
+
+void PACKSPU_APIENTRY packspu_GetPointerv( GLenum pname, GLvoid **params )
+{
+ crStateGetPointerv( pname, params );
+}
+
+void PACKSPU_APIENTRY packspu_InterleavedArrays( GLenum format, GLsizei stride, const GLvoid *pointer )
+{
+#if CR_ARB_vertex_buffer_object
+ GET_CONTEXT(ctx);
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
+ if (pack_spu.swap)
+ crPackInterleavedArraysSWAP( format, stride, pointer );
+ else
+ crPackInterleavedArrays( format, stride, pointer );
+ }
+#endif
+
+ /*crDebug("packspu_InterleavedArrays");*/
+
+ crStateInterleavedArrays( format, stride, pointer );
+}
+
+#ifdef DEBUG_misha
+/* debugging */
+//# define CR_FORCE_ZVA_SERVER_ARRAY
+#endif
+# define CR_FORCE_ZVA_EXPAND
+
+
+static GLboolean packspuZvaCreate(ContextInfo *pCtx, const GLfloat *pValue, GLuint cValues)
+{
+ ZvaBufferInfo *pInfo = &pCtx->zvaBufferInfo;
+ GLuint cbValue = 4 * sizeof (*pValue);
+ GLuint cbValues = cValues * cbValue;
+ GLfloat *pBuffer;
+ uint8_t *pu8Buf;
+ GLuint i;
+
+ /* quickly sort out if we can use the current value */
+ if (pInfo->idBuffer
+ && pInfo->cValues >= cValues
+ && !crMemcmp(pValue, &pInfo->Value, cbValue))
+ return GL_FALSE;
+
+ pBuffer = (GLfloat*)crAlloc(cbValues);
+ if (!pBuffer)
+ {
+ WARN(("crAlloc for pBuffer failed"));
+ return GL_FALSE;
+ }
+
+ pu8Buf = (uint8_t *)pBuffer;
+ for (i = 0; i < cValues; ++i)
+ {
+ crMemcpy(pu8Buf, pValue, cbValue);
+ pu8Buf += cbValue;
+ }
+
+ /* */
+ if (!pInfo->idBuffer)
+ {
+ pack_spu.self.GenBuffersARB(1, &pInfo->idBuffer);
+ Assert(pInfo->idBuffer);
+ }
+
+ pack_spu.self.BindBufferARB(GL_ARRAY_BUFFER_ARB, pInfo->idBuffer);
+
+ if (pInfo->cbBuffer < cbValues)
+ {
+ pack_spu.self.BufferDataARB(GL_ARRAY_BUFFER_ARB, cbValues, pBuffer, GL_DYNAMIC_DRAW_ARB);
+ pInfo->cbBuffer = cbValues;
+ }
+ else
+ {
+ pack_spu.self.BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, cbValues, pBuffer);
+ }
+
+ pInfo->cValues = cValues;
+ crMemcpy(&pInfo->Value, pValue, cbValue);
+
+ crFree(pBuffer);
+
+ return GL_TRUE;
+}
+
+typedef struct
+{
+ ContextInfo *pCtx;
+ GLuint idBuffer;
+ CRClientPointer cp;
+} CR_ZVA_RESTORE_CTX;
+
+static void packspuZvaEnable(ContextInfo *pCtx, const GLfloat *pValue, GLuint cValues, CR_ZVA_RESTORE_CTX *pRestoreCtx)
+{
+ CRContext *g = pCtx->clientState;
+
+ Assert(0);
+
+#ifdef DEBUG
+ {
+ CRContext *pCurState = crStateGetCurrent();
+
+ Assert(g == pCurState);
+ }
+#endif
+
+ pRestoreCtx->pCtx = pCtx;
+ pRestoreCtx->idBuffer = g->bufferobject.arrayBuffer ? g->bufferobject.arrayBuffer->id : 0;
+ pRestoreCtx->cp = g->client.array.a[0];
+
+ Assert(!pRestoreCtx->cp.enabled);
+
+ /* buffer ref count mechanism does not work actually atm,
+ * still ensure the buffer does not get destroyed if we fix it in the future */
+ if (pRestoreCtx->cp.buffer)
+ pRestoreCtx->cp.buffer->refCount++;
+
+ packspuZvaCreate(pCtx, pValue, cValues);
+
+ pack_spu.self.BindBufferARB(GL_ARRAY_BUFFER_ARB, pCtx->zvaBufferInfo.idBuffer);
+
+ pack_spu.self.VertexAttribPointerARB(0, 4, GL_FLOAT,
+ GL_FALSE, /*normalized*/
+ 0, /*stride*/
+ NULL /*addr*/);
+
+ pack_spu.self.EnableVertexAttribArrayARB(0);
+}
+
+static void packspuZvaDisable(CR_ZVA_RESTORE_CTX *pRestoreCtx)
+{
+ if (pRestoreCtx->cp.buffer)
+ pack_spu.self.BindBufferARB(GL_ARRAY_BUFFER_ARB, pRestoreCtx->cp.buffer->id);
+ else
+ pack_spu.self.BindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
+
+ pack_spu.self.VertexAttribPointerARB(0, pRestoreCtx->cp.size, pRestoreCtx->cp.type,
+ pRestoreCtx->cp.normalized, /*normalized*/
+ pRestoreCtx->cp.stride, /*stride*/
+ pRestoreCtx->cp.p);
+
+ if (pRestoreCtx->cp.enabled)
+ pack_spu.self.EnableVertexAttribArrayARB(0);
+ else
+ pack_spu.self.DisableVertexAttribArrayARB(0);
+
+ if (pRestoreCtx->cp.buffer)
+ {
+ if (pRestoreCtx->cp.buffer->id != pRestoreCtx->idBuffer)
+ pack_spu.self.BindBufferARB(GL_ARRAY_BUFFER_ARB, pRestoreCtx->idBuffer);
+
+ /* we have increased the refcount above, decrease it back */
+ pRestoreCtx->cp.buffer->refCount--;
+ }
+ else
+ {
+ if (pRestoreCtx->idBuffer)
+ pack_spu.self.BindBufferARB(GL_ARRAY_BUFFER_ARB, pRestoreCtx->idBuffer);
+ }
+
+#ifdef DEBUG
+ {
+ CRContext *g = pRestoreCtx->pCtx->clientState;
+ CRContext *pCurState = crStateGetCurrent();
+
+ Assert(g == pCurState);
+
+ Assert(pRestoreCtx->cp.p == g->client.array.a[0].p);
+ Assert(pRestoreCtx->cp.size == g->client.array.a[0].size);
+ Assert(pRestoreCtx->cp.type == g->client.array.a[0].type);
+ Assert(pRestoreCtx->cp.stride == g->client.array.a[0].stride);
+ Assert(pRestoreCtx->cp.enabled == g->client.array.a[0].enabled);
+ Assert(pRestoreCtx->cp.normalized == g->client.array.a[0].normalized);
+ Assert(pRestoreCtx->cp.bytesPerIndex == g->client.array.a[0].bytesPerIndex);
+# ifdef CR_ARB_vertex_buffer_object
+ Assert(pRestoreCtx->cp.buffer == g->client.array.a[0].buffer);
+# endif
+# ifdef CR_EXT_compiled_vertex_array
+ Assert(pRestoreCtx->cp.locked == g->client.array.a[0].locked);
+# endif
+ Assert(pRestoreCtx->idBuffer == (g->bufferobject.arrayBuffer ? g->bufferobject.arrayBuffer->id : 0));
+ }
+#endif
+}
+
+void PACKSPU_APIENTRY
+packspu_ArrayElement( GLint index )
+{
+/** @todo cash guest/host pointers calculation and use appropriate path here without crStateUseServerArrays call*/
+#if 1
+ GLboolean serverArrays = GL_FALSE;
+ GLuint cZvaValues = 0;
+ GLfloat aAttrib[4];
+
+#if CR_ARB_vertex_buffer_object
+ {
+ GET_CONTEXT(ctx);
+ /*crDebug("packspu_ArrayElement index:%i", index);*/
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object)
+ {
+ serverArrays = crStateUseServerArrays();
+ if (ctx->fCheckZerroVertAttr)
+ cZvaValues = crStateNeedDummyZeroVertexArray(thread->currentContext->clientState, &thread->packer->current, aAttrib);
+ }
+ }
+#endif
+
+ if (serverArrays
+#ifdef CR_FORCE_ZVA_EXPAND
+ && !cZvaValues
+#endif
+ ) {
+ CR_ZVA_RESTORE_CTX RestoreCtx;
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ Assert(cZvaValues < UINT32_MAX/2);
+
+ /* LockArraysEXT can not be executed between glBegin/glEnd pair, it also
+ * leads to vertexpointers being adjusted on the host side between glBegin/glEnd calls which
+ * produces unpredictable results. Locking is done before the glBegin call instead.
+ */
+ CRASSERT(!clientState->array.locked || clientState->array.synced);
+
+ if (cZvaValues)
+ packspuZvaEnable(ctx, aAttrib, cZvaValues, &RestoreCtx);
+
+ /* Send the DrawArrays command over the wire */
+ if (pack_spu.swap)
+ crPackArrayElementSWAP( index );
+ else
+ crPackArrayElement( index );
+
+ if (cZvaValues)
+ packspuZvaDisable(&RestoreCtx);
+ }
+ else {
+ /* evaluate locally */
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+
+#ifdef CR_FORCE_ZVA_SERVER_ARRAY
+ CR_ZVA_RESTORE_CTX RestoreCtx;
+
+ if (cZvaValues && cZvaValues < UINT32_MAX/2)
+ packspuZvaEnable(ctx, aAttrib, cZvaValues, &RestoreCtx);
+#endif
+
+ if (pack_spu.swap)
+ crPackExpandArrayElementSWAP( index, clientState, cZvaValues ? aAttrib : NULL );
+ else
+ crPackExpandArrayElement( index, clientState, cZvaValues ? aAttrib : NULL );
+
+#ifdef CR_FORCE_ZVA_SERVER_ARRAY
+ if (cZvaValues && cZvaValues < UINT32_MAX/2)
+ packspuZvaDisable(&RestoreCtx);
+#endif
+ }
+#else
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+ crPackExpandArrayElement(index, clientState, NULL);
+#endif
+}
+
+/*#define CR_USE_LOCKARRAYS*/
+#ifdef CR_USE_LOCKARRAYS
+# error "check Zero Vertex Attrib hack is supported properly!"
+#endif
+
+void PACKSPU_APIENTRY
+packspu_DrawElements( GLenum mode, GLsizei count, GLenum type, const GLvoid *indices )
+{
+ GLboolean serverArrays = GL_FALSE;
+ GLuint cZvaValues = 0;
+ GLfloat aAttrib[4];
+
+#if CR_ARB_vertex_buffer_object
+ GLboolean lockedArrays = GL_FALSE;
+ CRBufferObject *elementsBuffer;
+ {
+ GET_CONTEXT(ctx);
+ elementsBuffer = crStateGetCurrent()->bufferobject.elementsBuffer;
+ /*crDebug("DrawElements count=%d, indices=%p", count, indices);*/
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object)
+ {
+ serverArrays = crStateUseServerArrays();
+ if (ctx->fCheckZerroVertAttr)
+ cZvaValues = crStateNeedDummyZeroVertexArray(thread->currentContext->clientState, &thread->packer->current, aAttrib);
+ }
+ }
+
+# ifdef CR_USE_LOCKARRAYS
+ if (!serverArrays && !ctx->clientState->client.array.locked && (count>3)
+ && (!elementsBuffer || !elementsBuffer->id))
+ {
+ GLuint min, max;
+ GLsizei i;
+
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ {
+ GLubyte *pIdx = (GLubyte *)indices;
+ min = max = pIdx[0];
+ for (i=0; i<count; ++i)
+ {
+ if (pIdx[i]<min) min = pIdx[i];
+ else if (pIdx[i]>max) max = pIdx[i];
+ }
+ break;
+ }
+ case GL_UNSIGNED_SHORT:
+ {
+ GLushort *pIdx = (GLushort *)indices;
+ min = max = pIdx[0];
+ for (i=0; i<count; ++i)
+ {
+ if (pIdx[i]<min) min = pIdx[i];
+ else if (pIdx[i]>max) max = pIdx[i];
+ }
+ break;
+ }
+ case GL_UNSIGNED_INT:
+ {
+ GLuint *pIdx = (GLuint *)indices;
+ min = max = pIdx[0];
+ for (i=0; i<count; ++i)
+ {
+ if (pIdx[i]<min) min = pIdx[i];
+ else if (pIdx[i]>max) max = pIdx[i];
+ }
+ break;
+ }
+ default: crError("Unknown type 0x%x", type);
+ }
+
+ if ((max-min)<(GLuint)(2*count))
+ {
+ crStateLockArraysEXT(min, max-min+1);
+
+ serverArrays = crStateUseServerArrays();
+ if (serverArrays)
+ {
+ lockedArrays = GL_TRUE;
+ }
+ else
+ {
+ crStateUnlockArraysEXT();
+ }
+ }
+ }
+# endif
+#endif
+
+ if (serverArrays
+#ifdef CR_FORCE_ZVA_EXPAND
+ && !cZvaValues
+#endif
+ ) {
+ CR_ZVA_RESTORE_CTX RestoreCtx;
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ Assert(cZvaValues < UINT32_MAX/2);
+
+ if (cZvaValues)
+ packspuZvaEnable(ctx, aAttrib, cZvaValues, &RestoreCtx);
+
+ /*Note the comment in packspu_LockArraysEXT*/
+ if (clientState->array.locked && !clientState->array.synced)
+ {
+ crPackLockArraysEXT(clientState->array.lockFirst, clientState->array.lockCount);
+ clientState->array.synced = GL_TRUE;
+ }
+
+ /* Send the DrawArrays command over the wire */
+ if (pack_spu.swap)
+ crPackDrawElementsSWAP( mode, count, type, indices );
+ else
+ crPackDrawElements( mode, count, type, indices );
+
+ if (cZvaValues)
+ packspuZvaDisable(&RestoreCtx);
+ }
+ else {
+ /* evaluate locally */
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+
+#ifdef CR_FORCE_ZVA_SERVER_ARRAY
+ CR_ZVA_RESTORE_CTX RestoreCtx;
+
+ if (cZvaValues && cZvaValues < UINT32_MAX/2)
+ packspuZvaEnable(ctx, aAttrib, cZvaValues, &RestoreCtx);
+#endif
+
+ if (pack_spu.swap)
+ crPackExpandDrawElementsSWAP( mode, count, type, indices, clientState, cZvaValues ? aAttrib : NULL );
+ else
+ {
+ //packspu_Begin(mode);
+ crPackExpandDrawElements( mode, count, type, indices, clientState, cZvaValues ? aAttrib : NULL );
+ //packspu_End();
+ }
+
+#ifdef CR_FORCE_ZVA_SERVER_ARRAY
+ if (cZvaValues && cZvaValues < UINT32_MAX/2)
+ packspuZvaDisable(&RestoreCtx);
+#endif
+ }
+
+#if CR_ARB_vertex_buffer_object
+ if (lockedArrays)
+ {
+ packspu_UnlockArraysEXT();
+ }
+#endif
+}
+
+
+void PACKSPU_APIENTRY
+packspu_DrawRangeElements( GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices )
+{
+ GLboolean serverArrays = GL_FALSE;
+ GLuint cZvaValues = 0;
+ GLfloat aAttrib[4];
+
+#if CR_ARB_vertex_buffer_object
+ {
+ GET_CONTEXT(ctx);
+ /*crDebug("DrawRangeElements count=%d", count);*/
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object)
+ {
+ serverArrays = crStateUseServerArrays();
+ if (ctx->fCheckZerroVertAttr)
+ cZvaValues = crStateNeedDummyZeroVertexArray(thread->currentContext->clientState, &thread->packer->current, aAttrib);
+ }
+ }
+#endif
+
+ if (serverArrays
+#ifdef CR_FORCE_ZVA_EXPAND
+ && !cZvaValues
+#endif
+ ) {
+ CR_ZVA_RESTORE_CTX RestoreCtx;
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ Assert(cZvaValues < UINT32_MAX/2);
+
+ if (cZvaValues)
+ packspuZvaEnable(ctx, aAttrib, cZvaValues, &RestoreCtx);
+
+ /*Note the comment in packspu_LockArraysEXT*/
+ if (clientState->array.locked && !clientState->array.synced)
+ {
+ crPackLockArraysEXT(clientState->array.lockFirst, clientState->array.lockCount);
+ clientState->array.synced = GL_TRUE;
+ }
+
+ /* Send the DrawRangeElements command over the wire */
+ if (pack_spu.swap)
+ crPackDrawRangeElementsSWAP( mode, start, end, count, type, indices );
+ else
+ crPackDrawRangeElements( mode, start, end, count, type, indices );
+
+ if (cZvaValues)
+ packspuZvaDisable(&RestoreCtx);
+ }
+ else {
+ /* evaluate locally */
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+#ifdef CR_FORCE_ZVA_SERVER_ARRAY
+ CR_ZVA_RESTORE_CTX RestoreCtx;
+
+ if (cZvaValues && cZvaValues < UINT32_MAX/2)
+ packspuZvaEnable(ctx, aAttrib, cZvaValues, &RestoreCtx);
+#endif
+
+ if (pack_spu.swap)
+ crPackExpandDrawRangeElementsSWAP( mode, start, end, count, type, indices, clientState, cZvaValues ? aAttrib : NULL );
+ else
+ {
+ crPackExpandDrawRangeElements( mode, start, end, count, type, indices, clientState, cZvaValues ? aAttrib : NULL );
+ }
+
+#ifdef CR_FORCE_ZVA_SERVER_ARRAY
+ if (cZvaValues && cZvaValues < UINT32_MAX/2)
+ packspuZvaDisable(&RestoreCtx);
+#endif
+ }
+}
+
+
+void PACKSPU_APIENTRY
+packspu_DrawArrays( GLenum mode, GLint first, GLsizei count )
+{
+ GLboolean serverArrays = GL_FALSE;
+ GLuint cZvaValues = 0;
+ GLfloat aAttrib[4];
+
+#if CR_ARB_vertex_buffer_object
+ GLboolean lockedArrays = GL_FALSE;
+ {
+ GET_CONTEXT(ctx);
+ /*crDebug("DrawArrays count=%d", count);*/
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object)
+ {
+ serverArrays = crStateUseServerArrays();
+ if (ctx->fCheckZerroVertAttr)
+ cZvaValues = crStateNeedDummyZeroVertexArray(thread->currentContext->clientState, &thread->packer->current, aAttrib);
+ }
+ }
+
+# ifdef CR_USE_LOCKARRAYS
+ if (!serverArrays && !ctx->clientState->client.array.locked && (count>3))
+ {
+ crStateLockArraysEXT(first, count);
+ serverArrays = crStateUseServerArrays();
+ if (serverArrays)
+ {
+ lockedArrays = GL_TRUE;
+ }
+ else
+ {
+ crStateUnlockArraysEXT();
+ }
+ }
+# endif
+#endif
+
+ if (serverArrays
+#ifdef CR_FORCE_ZVA_EXPAND
+ && !cZvaValues
+#endif
+ )
+ {
+ CR_ZVA_RESTORE_CTX RestoreCtx;
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ Assert(cZvaValues < UINT32_MAX/2);
+
+ if (cZvaValues)
+ packspuZvaEnable(ctx, aAttrib, cZvaValues, &RestoreCtx);
+
+ /*Note the comment in packspu_LockArraysEXT*/
+ if (clientState->array.locked && !clientState->array.synced)
+ {
+ crPackLockArraysEXT(clientState->array.lockFirst, clientState->array.lockCount);
+ clientState->array.synced = GL_TRUE;
+ }
+
+ /* Send the DrawArrays command over the wire */
+ if (pack_spu.swap)
+ crPackDrawArraysSWAP( mode, first, count );
+ else
+ crPackDrawArrays( mode, first, count );
+
+ if (cZvaValues)
+ packspuZvaDisable(&RestoreCtx);
+ }
+ else
+ {
+ /* evaluate locally */
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+#ifdef CR_FORCE_ZVA_SERVER_ARRAY
+ CR_ZVA_RESTORE_CTX RestoreCtx;
+
+ if (cZvaValues && cZvaValues < UINT32_MAX/2)
+ packspuZvaEnable(ctx, aAttrib, cZvaValues, &RestoreCtx);
+#endif
+
+ if (pack_spu.swap)
+ crPackExpandDrawArraysSWAP( mode, first, count, clientState, cZvaValues ? aAttrib : NULL );
+ else
+ crPackExpandDrawArrays( mode, first, count, clientState, cZvaValues ? aAttrib : NULL );
+
+#ifdef CR_FORCE_ZVA_SERVER_ARRAY
+ if (cZvaValues && cZvaValues < UINT32_MAX/2)
+ packspuZvaDisable(&RestoreCtx);
+#endif
+
+ }
+
+#if CR_ARB_vertex_buffer_object
+ if (lockedArrays)
+ {
+ packspu_UnlockArraysEXT();
+ }
+#endif
+}
+
+
+#ifdef CR_EXT_multi_draw_arrays
+void PACKSPU_APIENTRY packspu_MultiDrawArraysEXT( GLenum mode, GLint *first, GLsizei *count, GLsizei primcount )
+{
+ GLint i;
+ for (i = 0; i < primcount; i++) {
+ if (count[i] > 0) {
+ packspu_DrawArrays(mode, first[i], count[i]);
+ }
+ }
+}
+
+void PACKSPU_APIENTRY packspu_MultiDrawElementsEXT( GLenum mode, const GLsizei *count, GLenum type, const GLvoid **indices, GLsizei primcount )
+{
+ GLint i;
+ for (i = 0; i < primcount; i++) {
+ if (count[i] > 0) {
+ packspu_DrawElements(mode, count[i], type, indices[i]);
+ }
+ }
+}
+#endif
+
+
+void PACKSPU_APIENTRY packspu_EnableClientState( GLenum array )
+{
+ crStateEnableClientState(array);
+ crPackEnableClientState(array);
+}
+
+void PACKSPU_APIENTRY packspu_DisableClientState( GLenum array )
+{
+ crStateDisableClientState(array);
+ crPackDisableClientState(array);
+}
+
+void PACKSPU_APIENTRY packspu_ClientActiveTextureARB( GLenum texUnit )
+{
+ crStateClientActiveTextureARB(texUnit);
+ crPackClientActiveTextureARB(texUnit);
+}
+
+void PACKSPU_APIENTRY packspu_EnableVertexAttribArrayARB(GLuint index)
+{
+ crStateEnableVertexAttribArrayARB(index);
+ crPackEnableVertexAttribArrayARB(index);
+}
+
+
+void PACKSPU_APIENTRY packspu_DisableVertexAttribArrayARB(GLuint index)
+{
+ crStateDisableVertexAttribArrayARB(index);
+ crPackDisableVertexAttribArrayARB(index);
+}
+
+void PACKSPU_APIENTRY packspu_Enable( GLenum cap )
+{
+ if (cap!=GL_LIGHT_MODEL_TWO_SIDE)
+ {
+ crStateEnable(cap);
+
+ if (pack_spu.swap)
+ crPackEnableSWAP(cap);
+ else
+ crPackEnable(cap);
+ }
+ else
+ {
+ static int g_glmts1_warn=0;
+ if (!g_glmts1_warn)
+ {
+ crWarning("glEnable(GL_LIGHT_MODEL_TWO_SIDE) converted to valid glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,1)");
+ g_glmts1_warn=1;
+ }
+ crStateLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
+ crPackLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
+ }
+}
+
+
+void PACKSPU_APIENTRY packspu_Disable( GLenum cap )
+{
+ if (cap!=GL_LIGHT_MODEL_TWO_SIDE)
+ {
+ crStateDisable(cap);
+
+ if (pack_spu.swap)
+ crPackDisableSWAP(cap);
+ else
+ crPackDisable(cap);
+ }
+ else
+ {
+ static int g_glmts0_warn=0;
+ if (!g_glmts0_warn)
+ {
+ crWarning("glDisable(GL_LIGHT_MODEL_TWO_SIDE) converted to valid glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,0)");
+ g_glmts0_warn=1;
+ }
+ crStateLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
+ crPackLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
+ }
+}
+
+GLboolean PACKSPU_APIENTRY packspu_IsEnabled(GLenum cap)
+{
+ GLboolean res = crStateIsEnabled(cap);
+#ifdef DEBUG
+ {
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLboolean return_val = (GLboolean) 0;
+ crPackIsEnabled(cap, &return_val, &writeback);
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ CRASSERT(return_val==res);
+ }
+#endif
+
+ return res;
+}
+
+void PACKSPU_APIENTRY packspu_PushClientAttrib( GLbitfield mask )
+{
+ crStatePushClientAttrib(mask);
+ crPackPushClientAttrib(mask);
+}
+
+void PACKSPU_APIENTRY packspu_PopClientAttrib( void )
+{
+ crStatePopClientAttrib();
+ crPackPopClientAttrib();
+}
+
+void PACKSPU_APIENTRY packspu_LockArraysEXT(GLint first, GLint count)
+{
+ if (first>=0 && count>0)
+ {
+ crStateLockArraysEXT(first, count);
+ /*Note: this is a workaround for quake3 based apps.
+ It's modifying vertex data between glLockArraysEXT and glDrawElements calls,
+ so we'd pass data to host right before the glDrawSomething or glBegin call.
+ */
+ /*crPackLockArraysEXT(first, count);*/
+ }
+ else crDebug("Ignoring packspu_LockArraysEXT: first:%i, count:%i", first, count);
+}
+
+void PACKSPU_APIENTRY packspu_UnlockArraysEXT()
+{
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ if (clientState->array.locked && clientState->array.synced)
+ {
+ crPackUnlockArraysEXT();
+ }
+
+ crStateUnlockArraysEXT();
+}
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_config.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_config.c
new file mode 100644
index 00000000..70d6f01c
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_config.c
@@ -0,0 +1,60 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include "packspu.h"
+#include "cr_string.h"
+#include "cr_error.h"
+#include "cr_spu.h"
+#include "cr_mem.h"
+
+#include <stdio.h>
+
+static void __setDefaults( void )
+{
+ crMemZero(pack_spu.context, CR_MAX_CONTEXTS * sizeof(ContextInfo));
+ pack_spu.numContexts = 0;
+
+ crMemZero(pack_spu.thread, MAX_THREADS * sizeof(ThreadInfo));
+ pack_spu.numThreads = 0;
+}
+
+
+static void set_emit( void *foo, const char *response )
+{
+ RT_NOREF(foo);
+ sscanf( response, "%d", &(pack_spu.emit_GATHER_POST_SWAPBUFFERS) );
+}
+
+static void set_swapbuffer_sync( void *foo, const char *response )
+{
+ RT_NOREF(foo);
+ sscanf( response, "%d", &(pack_spu.swapbuffer_sync) );
+}
+
+
+
+/* No SPU options yet. Well.. not really..
+ */
+SPUOptions packSPUOptions[] = {
+ { "emit_GATHER_POST_SWAPBUFFERS", CR_BOOL, 1, "0", NULL, NULL,
+ "Emit a parameter after SwapBuffers", (SPUOptionCB)set_emit },
+
+ { "swapbuffer_sync", CR_BOOL, 1, "1", NULL, NULL,
+ "Sync on SwapBuffers", (SPUOptionCB) set_swapbuffer_sync },
+
+ { NULL, CR_BOOL, 0, NULL, NULL, NULL, NULL, NULL },
+};
+
+
+void packspuSetVBoxConfiguration( const SPU *child_spu )
+{
+ RT_NOREF(child_spu);
+ __setDefaults();
+ pack_spu.emit_GATHER_POST_SWAPBUFFERS = 0;
+ pack_spu.swapbuffer_sync = 0;
+ pack_spu.name = crStrdup("vboxhgcm://llp:7000");
+ pack_spu.buffer_size = 5 * 1024 * 1024;
+}
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_context.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_context.c
new file mode 100644
index 00000000..26e81dbd
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_context.c
@@ -0,0 +1,617 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include "packspu.h"
+#include "cr_mem.h"
+#include "cr_packfunctions.h"
+#include "cr_string.h"
+#include "packspu_proto.h"
+
+/*
+ * Allocate a new ThreadInfo structure, setup a connection to the
+ * server, allocate/init a packer context, bind this ThreadInfo to
+ * the calling thread with crSetTSD().
+ * We'll always call this function at least once even if we're not
+ * using threads.
+ */
+ThreadInfo *packspuNewThread(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ struct VBOXUHGSMI *pHgsmi
+#else
+ void
+#endif
+)
+{
+ ThreadInfo *thread=NULL;
+ int i;
+
+#ifdef CHROMIUM_THREADSAFE
+ crLockMutex(&_PackMutex);
+#else
+ CRASSERT(pack_spu.numThreads == 0);
+#endif
+
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ CRASSERT(!CRPACKSPU_IS_WDDM_CRHGSMI() == !pHgsmi);
+#endif
+
+ CRASSERT(pack_spu.numThreads < MAX_THREADS);
+ for (i=0; i<MAX_THREADS; ++i)
+ {
+ if (!pack_spu.thread[i].inUse)
+ {
+ thread = &pack_spu.thread[i];
+ break;
+ }
+ }
+ CRASSERT(thread);
+
+ thread->inUse = GL_TRUE;
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI())
+ thread->id = crThreadID();
+ else
+ thread->id = THREAD_OFFSET_MAGIC + i;
+ thread->currentContext = NULL;
+ thread->bInjectThread = GL_FALSE;
+
+ /* connect to the server */
+ thread->netServer.name = crStrdup( pack_spu.name );
+ thread->netServer.buffer_size = pack_spu.buffer_size;
+ packspuConnectToServer( &(thread->netServer)
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ , pHgsmi
+#endif
+ );
+ CRASSERT(thread->netServer.conn);
+ /* packer setup */
+ CRASSERT(thread->packer == NULL);
+ thread->packer = crPackNewContext( pack_spu.swap );
+ CRASSERT(thread->packer);
+ crPackInitBuffer( &(thread->buffer), crNetAlloc(thread->netServer.conn),
+ thread->netServer.conn->buffer_size, thread->netServer.conn->mtu );
+ thread->buffer.canBarf = thread->netServer.conn->Barf ? GL_TRUE : GL_FALSE;
+ crPackSetBuffer( thread->packer, &thread->buffer );
+ crPackFlushFunc( thread->packer, packspuFlush );
+ crPackFlushArg( thread->packer, (void *) thread );
+ crPackSendHugeFunc( thread->packer, packspuHuge );
+
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ crPackSetContext( thread->packer );
+ }
+
+
+#ifdef CHROMIUM_THREADSAFE
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ crSetTSD(&_PackTSD, thread);
+ }
+#endif
+
+ pack_spu.numThreads++;
+
+#ifdef CHROMIUM_THREADSAFE
+ crUnlockMutex(&_PackMutex);
+#endif
+ return thread;
+}
+
+GLint PACKSPU_APIENTRY
+packspu_VBoxConCreate(struct VBOXUHGSMI *pHgsmi)
+{
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ ThreadInfo * thread;
+ CRASSERT(CRPACKSPU_IS_WDDM_CRHGSMI());
+ CRASSERT(pHgsmi);
+
+ thread = packspuNewThread(pHgsmi);
+
+ if (thread)
+ {
+ CRASSERT(thread->id);
+ CRASSERT(thread->id - THREAD_OFFSET_MAGIC < RT_ELEMENTS(pack_spu.thread)
+ && GET_THREAD_VAL_ID(thread->id) == thread);
+ return thread->id;
+ }
+ crError("packspuNewThread failed");
+#else
+ RT_NOREF(pHgsmi);
+#endif
+ return 0;
+}
+
+void PACKSPU_APIENTRY
+packspu_VBoxConFlush(GLint con)
+{
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ GET_THREAD_ID(thread, con);
+ CRASSERT(con);
+ CRASSERT(CRPACKSPU_IS_WDDM_CRHGSMI());
+ CRASSERT(thread->packer);
+ packspuFlush((void *) thread);
+#else
+ RT_NOREF(con);
+ crError("VBoxConFlush not implemented!");
+#endif
+}
+
+void PACKSPU_APIENTRY
+packspu_VBoxConDestroy(GLint con)
+{
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ GET_THREAD_ID(thread, con);
+ CRASSERT(con);
+ CRASSERT(CRPACKSPU_IS_WDDM_CRHGSMI());
+ CRASSERT(pack_spu.numThreads>0);
+ CRASSERT(thread->packer);
+ packspuFlush((void *) thread);
+
+ crLockMutex(&_PackMutex);
+
+ crPackDeleteContext(thread->packer);
+
+ if (thread->buffer.pack)
+ {
+ crNetFree(thread->netServer.conn, thread->buffer.pack);
+ thread->buffer.pack = NULL;
+ }
+
+ crNetFreeConnection(thread->netServer.conn);
+
+ if (thread->netServer.name)
+ crFree(thread->netServer.name);
+
+ pack_spu.numThreads--;
+ /*note can't shift the array here, because other threads have TLS references to array elements*/
+ crMemZero(thread, sizeof(ThreadInfo));
+
+#if 0
+ if (&pack_spu.thread[pack_spu.idxThreadInUse]==thread)
+ {
+ int i;
+ crError("Should not be here since idxThreadInUse should be always 0 for the dummy connection created in packSPUInit!");
+ for (i=0; i<MAX_THREADS; ++i)
+ {
+ if (pack_spu.thread[i].inUse)
+ {
+ pack_spu.idxThreadInUse=i;
+ break;
+ }
+ }
+ }
+#endif
+ crUnlockMutex(&_PackMutex);
+#else
+ RT_NOREF(con);
+#endif
+}
+
+GLvoid PACKSPU_APIENTRY
+packspu_VBoxConChromiumParameteriCR(GLint con, GLenum param, GLint value)
+{
+ GET_THREAD(thread);
+ CRPackContext * curPacker = crPackGetContext();
+ ThreadInfo *curThread = thread;
+
+ CRASSERT(!curThread == !curPacker);
+ CRASSERT(!curThread || !curPacker || curThread->packer == curPacker);
+#ifdef CHROMIUM_THREADSAFE
+ crLockMutex(&_PackMutex);
+#endif
+
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ CRASSERT(!con == !CRPACKSPU_IS_WDDM_CRHGSMI());
+#endif
+
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ if (!con)
+ {
+ crError("connection should be specified!");
+ return;
+ }
+ thread = GET_THREAD_VAL_ID(con);
+ }
+ else
+ {
+ CRASSERT(!con);
+ if (!thread)
+ {
+ thread = packspuNewThread(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ NULL
+#endif
+ );
+ }
+ }
+ CRASSERT(thread);
+ CRASSERT(thread->packer);
+
+ crPackSetContext( thread->packer );
+
+ packspu_ChromiumParameteriCR(param, value);
+
+#ifdef CHROMIUM_THREADSAFE
+ crUnlockMutex(&_PackMutex);
+#endif
+
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ /* restore the packer context to the tls */
+ crPackSetContext(curPacker);
+ }
+}
+
+GLvoid PACKSPU_APIENTRY
+packspu_VBoxConChromiumParametervCR(GLint con, GLenum target, GLenum type, GLsizei count, const GLvoid *values)
+{
+ GET_THREAD(thread);
+ CRPackContext * curPacker = crPackGetContext();
+ ThreadInfo *curThread = thread;
+
+ CRASSERT(!curThread == !curPacker);
+ CRASSERT(!curThread || !curPacker || curThread->packer == curPacker);
+#ifdef CHROMIUM_THREADSAFE
+ crLockMutex(&_PackMutex);
+#endif
+
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ CRASSERT(!con == !CRPACKSPU_IS_WDDM_CRHGSMI());
+#endif
+
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ if (!con)
+ {
+ crError("connection should be specified!");
+ return;
+ }
+ thread = GET_THREAD_VAL_ID(con);
+ }
+ else
+ {
+ CRASSERT(!con);
+ if (!thread)
+ {
+ thread = packspuNewThread(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ NULL
+#endif
+ );
+ }
+ }
+ CRASSERT(thread);
+ CRASSERT(thread->packer);
+
+ crPackSetContext( thread->packer );
+
+ packspu_ChromiumParametervCR(target, type, count, values);
+
+#ifdef CHROMIUM_THREADSAFE
+ crUnlockMutex(&_PackMutex);
+#endif
+
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ /* restore the packer context to the tls */
+ crPackSetContext(curPacker);
+ }
+}
+
+GLint PACKSPU_APIENTRY
+packspu_VBoxCreateContext( GLint con, const char *dpyName, GLint visual, GLint shareCtx )
+{
+ GET_THREAD(thread);
+ CRPackContext * curPacker = crPackGetContext();
+ ThreadInfo *curThread = thread;
+ int writeback = 1;
+ GLint serverCtx = (GLint) -1;
+ int slot;
+
+ CRASSERT(!curThread == !curPacker);
+ CRASSERT(!curThread || !curPacker || curThread->packer == curPacker);
+#ifdef CHROMIUM_THREADSAFE
+ crLockMutex(&_PackMutex);
+#endif
+
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ CRASSERT(!con == !CRPACKSPU_IS_WDDM_CRHGSMI());
+#endif
+
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ if (!con)
+ {
+ crError("connection should be specified!");
+ return -1;
+ }
+ thread = GET_THREAD_VAL_ID(con);
+ }
+ else
+ {
+ CRASSERT(!con);
+ if (!thread)
+ {
+ thread = packspuNewThread(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ NULL
+#endif
+ );
+ }
+ }
+ CRASSERT(thread);
+ CRASSERT(thread->packer);
+
+ if (shareCtx > 0) {
+ /* translate to server ctx id */
+ shareCtx -= MAGIC_OFFSET;
+ if (shareCtx >= 0 && shareCtx < pack_spu.numContexts) {
+ shareCtx = pack_spu.context[shareCtx].serverCtx;
+ }
+ }
+
+ crPackSetContext( thread->packer );
+
+ /* Pack the command */
+ if (pack_spu.swap)
+ crPackCreateContextSWAP( dpyName, visual, shareCtx, &serverCtx, &writeback );
+ else
+ crPackCreateContext( dpyName, visual, shareCtx, &serverCtx, &writeback );
+
+ /* Flush buffer and get return value */
+ packspuFlush(thread);
+ if (!(thread->netServer.conn->actual_network))
+ {
+ /* HUMUNGOUS HACK TO MATCH SERVER NUMBERING
+ *
+ * The hack exists solely to make file networking work for now. This
+ * is totally gross, but since the server expects the numbers to start
+ * from 5000, we need to write them out this way. This would be
+ * marginally less gross if the numbers (500 and 5000) were maybe
+ * some sort of #define'd constants somewhere so the client and the
+ * server could be aware of how each other were numbering things in
+ * cases like file networking where they actually
+ * care.
+ *
+ * -Humper
+ *
+ */
+ serverCtx = 5000;
+ }
+ else {
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ if (pack_spu.swap) {
+ serverCtx = (GLint) SWAP32(serverCtx);
+ }
+ if (serverCtx < 0) {
+#ifdef CHROMIUM_THREADSAFE
+ crUnlockMutex(&_PackMutex);
+#endif
+ crWarning("Failure in packspu_CreateContext");
+
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ /* restore the packer context to the tls */
+ crPackSetContext(curPacker);
+ }
+ return -1; /* failed */
+ }
+ }
+
+ /* find an empty context slot */
+ for (slot = 0; slot < pack_spu.numContexts; slot++) {
+ if (!pack_spu.context[slot].clientState) {
+ /* found empty slot */
+ break;
+ }
+ }
+ if (slot == pack_spu.numContexts) {
+ pack_spu.numContexts++;
+ }
+
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ thread->currentContext = &pack_spu.context[slot];
+ pack_spu.context[slot].currentThread = thread;
+ }
+
+ /* Fill in the new context info */
+ /* XXX fix-up sharedCtx param here */
+ pack_spu.context[slot].clientState = crStateCreateContext(NULL, visual, NULL);
+ pack_spu.context[slot].clientState->bufferobject.retainBufferData = GL_TRUE;
+ pack_spu.context[slot].serverCtx = serverCtx;
+
+#ifdef CHROMIUM_THREADSAFE
+ crUnlockMutex(&_PackMutex);
+#endif
+
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ /* restore the packer context to the tls */
+ crPackSetContext(curPacker);
+ }
+
+ return MAGIC_OFFSET + slot;
+}
+
+GLint PACKSPU_APIENTRY
+packspu_CreateContext( const char *dpyName, GLint visual, GLint shareCtx )
+{
+ return packspu_VBoxCreateContext( 0, dpyName, visual, shareCtx );
+}
+
+
+void PACKSPU_APIENTRY packspu_DestroyContext( GLint ctx )
+{
+ GET_THREAD(thread);
+ ThreadInfo *curThread = thread;
+ const int slot = ctx - MAGIC_OFFSET;
+ ContextInfo *context, *curContext;
+ CRPackContext * curPacker = crPackGetContext();
+
+ CRASSERT(slot >= 0);
+ CRASSERT(slot < pack_spu.numContexts);
+
+ context = (slot >= 0 && slot < pack_spu.numContexts) ? &(pack_spu.context[slot]) : NULL;
+ curContext = curThread ? curThread->currentContext : NULL;
+
+ if (context)
+ {
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ thread = context->currentThread;
+ if (thread)
+ {
+ crPackSetContext(thread->packer);
+ CRASSERT(!(thread->packer == curPacker) == !(thread == curThread));
+ }
+ }
+
+ if (pack_spu.swap)
+ crPackDestroyContextSWAP( context->serverCtx );
+ else
+ crPackDestroyContext( context->serverCtx );
+
+ crStateDestroyContext( context->clientState );
+
+ context->clientState = NULL;
+ context->serverCtx = 0;
+ context->currentThread = NULL;
+
+ crMemset (&context->zvaBufferInfo, 0, sizeof (context->zvaBufferInfo));
+ }
+
+ if (curContext == context)
+ {
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ curThread->currentContext = NULL;
+ }
+ else
+ {
+ CRASSERT(thread == curThread);
+ crSetTSD(&_PackTSD, NULL);
+ crPackSetContext(NULL);
+ }
+ crStateMakeCurrent( NULL );
+ }
+ else
+ {
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ crPackSetContext(curPacker);
+ }
+ }
+}
+
+void PACKSPU_APIENTRY packspu_MakeCurrent( GLint window, GLint nativeWindow, GLint ctx )
+{
+ ThreadInfo *thread = NULL;
+ GLint serverCtx;
+ ContextInfo *newCtx = NULL;
+
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ thread = GET_THREAD_VAL();
+ if (!thread) {
+ thread = packspuNewThread(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ NULL
+#endif
+ );
+ }
+ CRASSERT(thread);
+ CRASSERT(thread->packer);
+ }
+
+ if (ctx) {
+ const int slot = ctx - MAGIC_OFFSET;
+
+ CRASSERT(slot >= 0);
+ CRASSERT(slot < pack_spu.numContexts);
+
+ newCtx = &pack_spu.context[slot];
+ CRASSERT(newCtx);
+ CRASSERT(newCtx->clientState); /* verify valid */
+
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ thread = newCtx->currentThread;
+ CRASSERT(thread);
+ crSetTSD(&_PackTSD, thread);
+ crPackSetContext( thread->packer );
+ }
+ else
+ {
+ CRASSERT(thread);
+ if (newCtx->fAutoFlush)
+ {
+ if (newCtx->currentThread && newCtx->currentThread != thread)
+ {
+ crLockMutex(&_PackMutex);
+ /* do a flush for the previously assigned thread
+ * to ensure all commands issued there are submitted */
+ if (newCtx->currentThread
+ && newCtx->currentThread->inUse
+ && newCtx->currentThread->netServer.conn
+ && newCtx->currentThread->packer && newCtx->currentThread->packer->currentBuffer)
+ {
+ packspuFlush((void *) newCtx->currentThread);
+ }
+ crUnlockMutex(&_PackMutex);
+ }
+ newCtx->currentThread = thread;
+ }
+
+ if (thread->currentContext && newCtx != thread->currentContext && thread->currentContext->fCheckZerroVertAttr)
+ crStateCurrentRecoverNew(thread->currentContext->clientState, &thread->packer->current);
+
+ thread->currentContext = newCtx;
+ crPackSetContext( thread->packer );
+ }
+
+ crStateMakeCurrent( newCtx->clientState );
+ //crStateSetCurrentPointers(newCtx->clientState, &thread->packer->current);
+ serverCtx = pack_spu.context[slot].serverCtx;
+ }
+ else {
+ crStateMakeCurrent( NULL );
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ thread = GET_THREAD_VAL();
+ if (!thread)
+ {
+ CRASSERT(crPackGetContext() == NULL);
+ return;
+ }
+ CRASSERT(thread->currentContext);
+ CRASSERT(thread->packer == crPackGetContext());
+ }
+ else
+ {
+ thread->currentContext = NULL;
+ }
+ newCtx = NULL;
+ serverCtx = 0;
+ }
+
+ if (pack_spu.swap)
+ crPackMakeCurrentSWAP( window, nativeWindow, serverCtx );
+ else
+ crPackMakeCurrent( window, nativeWindow, serverCtx );
+
+ if (serverCtx)
+ {
+ packspuInitStrings();
+ }
+
+ {
+ GET_THREAD(t);
+ (void) t;
+ CRASSERT(t);
+ }
+}
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_flush.py b/src/VBox/Additions/common/crOpenGL/pack/packspu_flush.py
new file mode 100755
index 00000000..5742bcb0
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_flush.py
@@ -0,0 +1,42 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+from __future__ import print_function
+import sys
+
+import apiutil
+
+
+apiutil.CopyrightC()
+
+print("""
+/* DO NOT EDIT - this file generated by packspu_flush.py script */
+
+/* These are otherwise ordinary functions which require that the buffer be
+ * flushed immediately after packing the function.
+ */
+#include "cr_glstate.h"
+#include "cr_packfunctions.h"
+#include "packspu.h"
+#include "packspu_proto.h"
+""")
+
+keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
+
+for func_name in apiutil.AllSpecials( "packspu_flush" ):
+ params = apiutil.Parameters(func_name)
+ print('void PACKSPU_APIENTRY packspu_%s(%s)' % ( func_name, apiutil.MakeDeclarationString(params)))
+ print('{')
+ print('\tGET_THREAD(thread);')
+ print('\tif (pack_spu.swap)')
+ print('\t{')
+ print('\t\tcrPack%sSWAP(%s);' % ( func_name, apiutil.MakeCallString( params ) ))
+ print('\t}')
+ print('\telse')
+ print('\t{')
+ print('\t\tcrPack%s(%s);' % ( func_name, apiutil.MakeCallString( params ) ))
+ print('\t}')
+ print('\tpackspuFlush( (void *) thread );')
+ print('}\n')
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_flush_special b/src/VBox/Additions/common/crOpenGL/pack/packspu_flush_special
new file mode 100644
index 00000000..a4896826
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_flush_special
@@ -0,0 +1,9 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+BarrierCreateCR
+BarrierExecCR
+SemaphoreCreateCR
+SemaphorePCR
+SemaphoreVCR
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_framebuffer.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_framebuffer.c
new file mode 100644
index 00000000..e94c0444
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_framebuffer.c
@@ -0,0 +1,143 @@
+/* $Id: packspu_framebuffer.c $ */
+
+/** @file
+ * VBox OpenGL FBO related functions
+ */
+
+/*
+ * Copyright (C) 2009-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include "packspu.h"
+#include "cr_packfunctions.h"
+#include "cr_net.h"
+#include "packspu_proto.h"
+
+void PACKSPU_APIENTRY
+packspu_FramebufferTexture1DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+{
+ crStateFramebufferTexture1DEXT(target, attachment, textarget, texture, level);
+ crPackFramebufferTexture1DEXT(target, attachment, textarget, texture, level);
+}
+
+void PACKSPU_APIENTRY
+packspu_FramebufferTexture2DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+{
+ crStateFramebufferTexture2DEXT(target, attachment, textarget, texture, level);
+ crPackFramebufferTexture2DEXT(target, attachment, textarget, texture, level);
+}
+
+void PACKSPU_APIENTRY
+packspu_FramebufferTexture3DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
+{
+ crStateFramebufferTexture3DEXT(target, attachment, textarget, texture, level, zoffset);
+ crPackFramebufferTexture3DEXT(target, attachment, textarget, texture, level, zoffset);
+}
+
+void PACKSPU_APIENTRY
+packspu_BindFramebufferEXT(GLenum target, GLuint framebuffer)
+{
+ crStateBindFramebufferEXT(target, framebuffer);
+ crPackBindFramebufferEXT(target, framebuffer);
+}
+
+void PACKSPU_APIENTRY
+packspu_DeleteFramebuffersEXT(GLsizei n, const GLuint * framebuffers)
+{
+ crStateDeleteFramebuffersEXT(n, framebuffers);
+ crPackDeleteFramebuffersEXT(n, framebuffers);
+}
+
+void PACKSPU_APIENTRY
+packspu_DeleteRenderbuffersEXT(GLsizei n, const GLuint * renderbuffers)
+{
+ crStateDeleteRenderbuffersEXT(n, renderbuffers);
+ crPackDeleteRenderbuffersEXT(n, renderbuffers);
+}
+
+void PACKSPU_APIENTRY
+packspu_FramebufferRenderbufferEXT(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+{
+ crStateFramebufferRenderbufferEXT(target, attachment, renderbuffertarget, renderbuffer);
+ crPackFramebufferRenderbufferEXT(target, attachment, renderbuffertarget, renderbuffer);
+}
+
+void PACKSPU_APIENTRY
+packspu_BindRenderbufferEXT(GLenum target, GLuint renderbuffer)
+{
+ crStateBindRenderbufferEXT(target, renderbuffer);
+ crPackBindRenderbufferEXT(target, renderbuffer);
+}
+
+GLenum PACKSPU_APIENTRY
+packspu_CheckFramebufferStatusEXT(GLenum target)
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLenum status = crStateCheckFramebufferStatusEXT(target);
+
+ if (status!=GL_FRAMEBUFFER_UNDEFINED)
+ {
+ return status;
+ }
+
+ crPackCheckFramebufferStatusEXT(target, &status, &writeback);
+
+ packspuFlush((void *) thread);
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ crStateSetFramebufferStatus(target, status);
+ return status;
+}
+
+void PACKSPU_APIENTRY packspu_GenFramebuffersEXT( GLsizei n, GLuint * framebuffers )
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI() && !(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))
+ {
+ crError( "packspu_GenFramebuffersEXT doesn't work when there's no actual network involved!\nTry using the simplequery SPU in your chain!" );
+ }
+ if (pack_spu.swap)
+ {
+ crPackGenFramebuffersEXTSWAP( n, framebuffers, &writeback );
+ }
+ else
+ {
+ crPackGenFramebuffersEXT( n, framebuffers, &writeback );
+ }
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ crStateRegFramebuffers(n, framebuffers);
+}
+
+void PACKSPU_APIENTRY packspu_GenRenderbuffersEXT( GLsizei n, GLuint * renderbuffers )
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI() && !(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))
+ {
+ crError( "packspu_GenRenderbuffersEXT doesn't work when there's no actual network involved!\nTry using the simplequery SPU in your chain!" );
+ }
+ if (pack_spu.swap)
+ {
+ crPackGenRenderbuffersEXTSWAP( n, renderbuffers, &writeback );
+ }
+ else
+ {
+ crPackGenRenderbuffersEXT( n, renderbuffers, &writeback );
+ }
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ crStateRegRenderbuffers(n, renderbuffers);
+}
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_get.py b/src/VBox/Additions/common/crOpenGL/pack/packspu_get.py
new file mode 100755
index 00000000..371abeaa
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_get.py
@@ -0,0 +1,250 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+from __future__ import print_function
+import sys
+
+import apiutil
+
+
+apiutil.CopyrightC()
+
+print("""
+/* DO NOT EDIT - THIS FILE AUTOMATICALLY GENERATED BY packspu_get.py SCRIPT */
+#include "packspu.h"
+#include "cr_packfunctions.h"
+#include "cr_net.h"
+#include "cr_mem.h"
+#include "packspu_proto.h"
+""")
+
+print("""
+static GLboolean crPackIsPixelStoreParm(GLenum pname)
+{
+ if (pname == GL_UNPACK_ALIGNMENT
+ || pname == GL_UNPACK_ROW_LENGTH
+ || pname == GL_UNPACK_SKIP_PIXELS
+ || pname == GL_UNPACK_LSB_FIRST
+ || pname == GL_UNPACK_SWAP_BYTES
+#ifdef CR_OPENGL_VERSION_1_2
+ || pname == GL_UNPACK_IMAGE_HEIGHT
+#endif
+ || pname == GL_UNPACK_SKIP_ROWS
+ || pname == GL_PACK_ALIGNMENT
+ || pname == GL_PACK_ROW_LENGTH
+ || pname == GL_PACK_SKIP_PIXELS
+ || pname == GL_PACK_LSB_FIRST
+ || pname == GL_PACK_SWAP_BYTES
+#ifdef CR_OPENGL_VERSION_1_2
+ || pname == GL_PACK_IMAGE_HEIGHT
+#endif
+ || pname == GL_PACK_SKIP_ROWS)
+ {
+ return GL_TRUE;
+ }
+ return GL_FALSE;
+}
+""")
+
+from get_sizes import *
+
+easy_swaps = {
+ 'GenTextures': '(unsigned int) n',
+ 'GetClipPlane': '4',
+ 'GetPolygonStipple': '0'
+}
+
+simple_funcs = [ 'GetIntegerv', 'GetFloatv', 'GetDoublev', 'GetBooleanv' ]
+simple_swaps = [ 'SWAP32', 'SWAPFLOAT', 'SWAPDOUBLE', '(GLboolean) SWAP32' ]
+
+vertattr_get_funcs = [ 'GetVertexAttribdv' 'GetVertexAttribfv' 'GetVertexAttribiv' ]
+
+hard_funcs = {
+ 'GetLightfv': 'SWAPFLOAT',
+ 'GetLightiv': 'SWAP32',
+ 'GetMaterialfv': 'SWAPFLOAT',
+ 'GetMaterialiv': 'SWAP32',
+ 'GetTexEnvfv': 'SWAPFLOAT',
+ 'GetTexEnviv': 'SWAP32',
+ 'GetTexGendv': 'SWAPDOUBLE',
+ 'GetTexGenfv': 'SWAPFLOAT',
+ 'GetTexGeniv': 'SWAP32',
+ 'GetTexLevelParameterfv': 'SWAPFLOAT',
+ 'GetTexLevelParameteriv': 'SWAP32',
+ 'GetTexParameterfv': 'SWAPFLOAT',
+ 'GetTexParameteriv': 'SWAP32' }
+
+keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
+
+for func_name in keys:
+ params = apiutil.Parameters(func_name)
+ return_type = apiutil.ReturnType(func_name)
+ if apiutil.FindSpecial( "packspu", func_name ):
+ continue
+
+ if "get" in apiutil.Properties(func_name):
+ print('%s PACKSPU_APIENTRY packspu_%s(%s)' % ( return_type, func_name, apiutil.MakeDeclarationString( params ) ))
+ print('{')
+ print('\tGET_THREAD(thread);')
+ print('\tint writeback = 1;')
+ if return_type != 'void':
+ print('\t%s return_val = (%s) 0;' % (return_type, return_type))
+ params.append( ("&return_val", "foo", 0) )
+ if (func_name in easy_swaps and easy_swaps[func_name] != '0') or func_name in simple_funcs or func_name in hard_funcs:
+ print('\tunsigned int i;')
+ print('\tif (!CRPACKSPU_IS_WDDM_CRHGSMI() && !(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))')
+ print('\t{')
+ print('\t\tcrError( "packspu_%s doesn\'t work when there\'s no actual network involved!\\nTry using the simplequery SPU in your chain!" );' % func_name)
+ print('\t}')
+ if func_name in simple_funcs:
+ print("""
+ if (crPackIsPixelStoreParm(pname)
+ || pname == GL_DRAW_BUFFER
+#ifdef CR_OPENGL_VERSION_1_3
+ || pname == GL_ACTIVE_TEXTURE
+#endif
+#ifdef CR_ARB_multitexture
+ || pname == GL_ACTIVE_TEXTURE_ARB
+#endif
+ || pname == GL_TEXTURE_BINDING_1D
+ || pname == GL_TEXTURE_BINDING_2D
+#ifdef CR_NV_texture_rectangle
+ || pname == GL_TEXTURE_BINDING_RECTANGLE_NV
+#endif
+#ifdef CR_ARB_texture_cube_map
+ || pname == GL_TEXTURE_BINDING_CUBE_MAP_ARB
+#endif
+#ifdef CR_ARB_vertex_program
+ || pname == GL_MAX_VERTEX_ATTRIBS_ARB
+#endif
+#ifdef GL_EXT_framebuffer_object
+ || pname == GL_FRAMEBUFFER_BINDING_EXT
+ || pname == GL_READ_FRAMEBUFFER_BINDING_EXT
+ || pname == GL_DRAW_FRAMEBUFFER_BINDING_EXT
+#endif
+ || pname == GL_ARRAY_BUFFER_BINDING
+ || pname == GL_ELEMENT_ARRAY_BUFFER_BINDING
+ || pname == GL_PIXEL_PACK_BUFFER_BINDING
+ || pname == GL_PIXEL_UNPACK_BUFFER_BINDING
+ )
+ {
+#ifdef DEBUG
+ if (!crPackIsPixelStoreParm(pname)
+#ifdef CR_ARB_vertex_program
+ && (pname!=GL_MAX_VERTEX_ATTRIBS_ARB)
+#endif
+ )
+ {
+ %s localparams;
+ localparams = (%s) crAlloc(__numValues(pname) * sizeof(*localparams));
+ crState%s(pname, localparams);
+ crPack%s(%s, &writeback);
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ for (i=0; i<__numValues(pname); ++i)
+ {
+ if (localparams[i] != params[i])
+ {
+ crWarning("Incorrect local state in %s for %%x param %%i", pname, i);
+ crWarning("Expected %%i but got %%i", (int)localparams[i], (int)params[i]);
+ }
+ }
+ crFree(localparams);
+ return;
+ }
+ else
+#endif
+ {
+ crState%s(pname, params);
+ return;
+ }
+
+ }
+ """ % (params[-1][1], params[-1][1], func_name, func_name, apiutil.MakeCallString(params), func_name, func_name))
+
+ if func_name in vertattr_get_funcs:
+ print("""
+ if (pname != GL_CURRENT_VERTEX_ATTRIB_ARB)
+ {
+#ifdef DEBUG
+ %s localparams;
+ localparams = (%s) crAlloc(__numValues(pname) * sizeof(*localparams));
+ crState%s(index, pname, localparams);
+ crPack%s(index, %s, &writeback);
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ for (i=0; i<crStateHlpComponentsCount(pname); ++i)
+ {
+ if (localparams[i] != params[i])
+ {
+ crWarning("Incorrect local state in %s for %%x param %%i", pname, i);
+ crWarning("Expected %%i but got %%i", (int)localparams[i], (int)params[i]);
+ }
+ }
+ crFree(localparams);
+#else
+ crState%s(pname, params);
+#endif
+ return;
+ }
+ """ % (params[-1][1], params[-1][1], func_name, func_name, apiutil.MakeCallString(params), func_name, func_name))
+
+ params.append( ("&writeback", "foo", 0) )
+ print('\tif (pack_spu.swap)')
+ print('\t{')
+ print('\t\tcrPack%sSWAP(%s);' % (func_name, apiutil.MakeCallString( params ) ))
+ print('\t}')
+ print('\telse')
+ print('\t{')
+ print('\t\tcrPack%s(%s);' % (func_name, apiutil.MakeCallString( params ) ))
+ print('\t}')
+ print('\tpackspuFlush( (void *) thread );')
+ print('\tCRPACKSPU_WRITEBACK_WAIT(thread, writeback);')
+
+
+
+ lastParamName = params[-2][0]
+ if return_type != 'void':
+ print('\tif (pack_spu.swap)')
+ print('\t{')
+ print('\t\treturn_val = (%s) SWAP32(return_val);' % return_type)
+ print('\t}')
+ print('\treturn return_val;')
+ if func_name in easy_swaps and easy_swaps[func_name] != '0':
+ limit = easy_swaps[func_name]
+ print('\tif (pack_spu.swap)')
+ print('\t{')
+ print('\t\tfor (i = 0; i < %s; i++)' % limit)
+ print('\t\t{')
+ if params[-2][1].find( "double" ) > -1:
+ print('\t\t\t%s[i] = SWAPDOUBLE(%s[i]);' % (lastParamName, lastParamName))
+ else:
+ print('\t\t\t%s[i] = SWAP32(%s[i]);' % (lastParamName, lastParamName))
+ print('\t\t}')
+ print('\t}')
+ for index in range(len(simple_funcs)):
+ if simple_funcs[index] == func_name:
+ print('\tif (pack_spu.swap)')
+ print('\t{')
+ print('\t\tfor (i = 0; i < __numValues(pname); i++)')
+ print('\t\t{')
+ if simple_swaps[index] == 'SWAPDOUBLE':
+ print('\t\t\t%s[i] = %s(%s[i]);' % (lastParamName, simple_swaps[index], lastParamName))
+ else:
+ print('\t\t\t((GLuint *) %s)[i] = %s(%s[i]);' % (lastParamName, simple_swaps[index], lastParamName))
+ print('\t\t}')
+ print('\t}')
+ if func_name in hard_funcs:
+ print('\tif (pack_spu.swap)')
+ print('\t{')
+ print('\t\tfor (i = 0; i < crStateHlpComponentsCount(pname); i++)')
+ print('\t\t{')
+ if hard_funcs[func_name] == 'SWAPDOUBLE':
+ print('\t\t\t%s[i] = %s(%s[i]);' % (lastParamName, hard_funcs[func_name], lastParamName))
+ else:
+ print('\t\t\t((GLuint *) %s)[i] = %s(%s[i]);' % (lastParamName, hard_funcs[func_name], lastParamName))
+ print('\t\t}')
+ print('\t}')
+ print('}\n')
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_getshaders.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_getshaders.c
new file mode 100644
index 00000000..97150222
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_getshaders.c
@@ -0,0 +1,214 @@
+/* $Id: packspu_getshaders.c $ */
+
+/** @file
+ * VBox OpenGL GLSL related functions
+ */
+
+/*
+ * Copyright (C) 2009-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include "packspu.h"
+#include "cr_packfunctions.h"
+#include "cr_net.h"
+#include "packspu_proto.h"
+#include "cr_mem.h"
+#include <iprt/assert.h>
+
+/** @todo combine with the one from server_getshaders.c*/
+typedef struct _crGetActive_t
+{
+ GLsizei length;
+ GLint size;
+ GLenum type;
+} crGetActive_t;
+
+void PACKSPU_APIENTRY packspu_GetActiveAttrib(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, char * name)
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ crGetActive_t *pLocal;
+
+ if (!size || !type || !name) return;
+
+ pLocal = (crGetActive_t*) crAlloc(bufSize+sizeof(crGetActive_t));
+ if (!pLocal) return;
+
+ crPackGetActiveAttrib(program, index, bufSize, (GLsizei*)pLocal, NULL, NULL, NULL, &writeback);
+
+ packspuFlush((void *) thread);
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ if (length) *length = pLocal->length;
+ *size = pLocal->size;
+ *type = pLocal->type;
+ crMemcpy(name, (char*)&pLocal[1], pLocal->length+1);
+ crFree(pLocal);
+}
+
+void PACKSPU_APIENTRY packspu_GetActiveUniform(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, char * name)
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ crGetActive_t *pLocal;
+
+ if (!size || !type || !name) return;
+
+ pLocal = (crGetActive_t*) crAlloc(bufSize+sizeof(crGetActive_t));
+ if (!pLocal) return;
+
+ crPackGetActiveUniform(program, index, bufSize, (GLsizei*)pLocal, NULL, NULL, NULL, &writeback);
+
+ packspuFlush((void *) thread);
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ if (length) *length = pLocal->length;
+ *size = pLocal->size;
+ *type = pLocal->type;
+ crMemcpy(name, &pLocal[1], pLocal->length+1);
+ crFree(pLocal);
+}
+
+void PACKSPU_APIENTRY packspu_GetAttachedShaders(GLuint program, GLsizei maxCount, GLsizei * count, GLuint * shaders)
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLsizei *pLocal;
+
+ if (!shaders) return;
+
+ pLocal = (GLsizei*) crAlloc(maxCount*sizeof(GLuint)+sizeof(GLsizei));
+ if (!pLocal) return;
+
+ crPackGetAttachedShaders(program, maxCount, pLocal, NULL, &writeback);
+
+ packspuFlush((void *) thread);
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ if (count) *count=*pLocal;
+ crMemcpy(shaders, &pLocal[1], *pLocal*sizeof(GLuint));
+ crFree(pLocal);
+}
+
+void PACKSPU_APIENTRY packspu_GetAttachedObjectsARB(VBoxGLhandleARB containerObj, GLsizei maxCount, GLsizei * count, VBoxGLhandleARB * obj)
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLsizei *pLocal;
+
+ if (!obj) return;
+
+ pLocal = (GLsizei*) crAlloc(maxCount*sizeof(VBoxGLhandleARB)+sizeof(GLsizei));
+ if (!pLocal) return;
+
+ crPackGetAttachedObjectsARB(containerObj, maxCount, pLocal, NULL, &writeback);
+
+ packspuFlush((void *) thread);
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ if (count) *count=*pLocal;
+ crMemcpy(obj, &pLocal[1], *pLocal*sizeof(VBoxGLhandleARB));
+ crFree(pLocal);
+}
+
+AssertCompile(sizeof(GLsizei) == 4);
+
+void PACKSPU_APIENTRY packspu_GetInfoLogARB(VBoxGLhandleARB obj, GLsizei maxLength, GLsizei * length, GLcharARB * infoLog)
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLsizei *pLocal;
+
+ if (!infoLog) return;
+
+ pLocal = (GLsizei*) crAlloc(maxLength+sizeof(GLsizei));
+ if (!pLocal) return;
+
+ crPackGetInfoLogARB(obj, maxLength, pLocal, NULL, &writeback);
+
+ packspuFlush((void *) thread);
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ CRASSERT((pLocal[0]) <= maxLength);
+
+ if (length) *length=*pLocal;
+ crMemcpy(infoLog, &pLocal[1], (maxLength >= (pLocal[0])) ? pLocal[0] : maxLength);
+ crFree(pLocal);
+}
+
+void PACKSPU_APIENTRY packspu_GetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei * length, char * infoLog)
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLsizei *pLocal;
+
+ if (!infoLog) return;
+
+ pLocal = (GLsizei*) crAlloc(bufSize+sizeof(GLsizei));
+ if (!pLocal) return;
+
+ crPackGetProgramInfoLog(program, bufSize, pLocal, NULL, &writeback);
+
+ packspuFlush((void *) thread);
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ if (length) *length=*pLocal;
+ crMemcpy(infoLog, &pLocal[1], (bufSize >= pLocal[0]) ? pLocal[0] : bufSize);
+ crFree(pLocal);
+}
+
+void PACKSPU_APIENTRY packspu_GetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei * length, char * infoLog)
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLsizei *pLocal;
+
+ if (!infoLog) return;
+
+ pLocal = (GLsizei*) crAlloc(bufSize+sizeof(GLsizei));
+ if (!pLocal) return;
+
+ crPackGetShaderInfoLog(shader, bufSize, pLocal, NULL, &writeback);
+
+ packspuFlush((void *) thread);
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ if (length) *length=*pLocal;
+ crMemcpy(infoLog, &pLocal[1], (bufSize >= pLocal[0]) ? pLocal[0] : bufSize);
+ crFree(pLocal);
+}
+
+void PACKSPU_APIENTRY packspu_GetShaderSource(GLuint shader, GLsizei bufSize, GLsizei * length, char * source)
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLsizei *pLocal;
+
+ if (!source) return;
+
+ pLocal = (GLsizei*) crAlloc(bufSize+sizeof(GLsizei));
+ if (!pLocal) return;
+
+ crPackGetShaderSource(shader, bufSize, pLocal, NULL, &writeback);
+
+ packspuFlush((void *) thread);
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ if (length) *length=*pLocal;
+ crMemcpy(source, &pLocal[1], (bufSize >= pLocal[0]) ? pLocal[0] : bufSize);
+
+ if (bufSize > pLocal[0])
+ {
+ source[pLocal[0]] = 0;
+ }
+
+ crFree(pLocal);
+}
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_getstring.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_getstring.c
new file mode 100644
index 00000000..c5890bfe
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_getstring.c
@@ -0,0 +1,211 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include "packspu.h"
+#include "cr_packfunctions.h"
+#include "state/cr_statefuncs.h"
+#include "cr_string.h"
+#include "packspu_proto.h"
+#include "cr_mem.h"
+#include <locale.h>
+
+static GLubyte gpszExtensions[10000];
+#ifdef CR_OPENGL_VERSION_2_0
+static GLubyte gpszShadingVersion[255]="";
+#endif
+
+static void GetString(GLenum name, GLubyte *pszStr)
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+
+ if (pack_spu.swap)
+ crPackGetStringSWAP(name, pszStr, &writeback);
+ else
+ crPackGetString(name, pszStr, &writeback);
+ packspuFlush( (void *) thread );
+
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+}
+
+static GLfloat
+GetVersionString(void)
+{
+ static GLboolean fInitialized = GL_FALSE;
+ static GLfloat version = 0.;
+
+ if (!fInitialized)
+ {
+ GLubyte return_value[100];
+
+ GetString(GL_VERSION, return_value);
+ CRASSERT(crStrlen((char *)return_value) < 100);
+
+ version = crStrToFloat((char *) return_value);
+ version = crStateComputeVersion(version);
+
+ fInitialized = GL_TRUE;
+ }
+
+ return version;
+}
+
+static const GLubyte *
+GetExtensions(void)
+{
+ static GLboolean fInitialized = GL_FALSE;
+ if (!fInitialized)
+ {
+ GLubyte return_value[10*1000];
+ const GLubyte *extensions, *ext;
+ GET_THREAD(thread);
+ int writeback = 1;
+
+ if (pack_spu.swap)
+ {
+ crPackGetStringSWAP( GL_EXTENSIONS, return_value, &writeback );
+ }
+ else
+ {
+ crPackGetString( GL_EXTENSIONS, return_value, &writeback );
+ }
+ packspuFlush( (void *) thread );
+
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ CRASSERT(crStrlen((char *)return_value) < 10*1000);
+
+ /* OK, we got the result from the server. Now we have to
+ * intersect is with the set of extensions that Chromium understands
+ * and tack on the Chromium-specific extensions.
+ */
+ extensions = return_value;
+ ext = crStateMergeExtensions(1, &extensions);
+
+#ifdef Linux
+ /** @todo
+ *That's a hack to allow running Unity, it uses libnux which is calling extension functions
+ *without checking if it's being supported/exported.
+ *glActiveStencilFaceEXT seems to be actually supported but the extension string isn't exported (for ex. on ATI HD4870),
+ *which leads to libglew setting function pointer to NULL and crashing Unity.
+ */
+ sprintf((char*)gpszExtensions, "%s GL_EXT_stencil_two_side", ext);
+#else
+ sprintf((char*)gpszExtensions, "%s", ext);
+#endif
+ fInitialized = GL_TRUE;
+ }
+
+ return gpszExtensions;
+}
+
+#ifdef WINDOWS
+static bool packspuRunningUnderWine(void)
+{
+ return NULL != GetModuleHandle("wined3d.dll") || NULL != GetModuleHandle("wined3dwddm.dll") || NULL != GetModuleHandle("wined3dwddm-x86.dll");
+}
+#endif
+
+const GLubyte * PACKSPU_APIENTRY packspu_GetString( GLenum name )
+{
+ GET_CONTEXT(ctx);
+
+ switch(name)
+ {
+ case GL_EXTENSIONS:
+ return GetExtensions();
+ case GL_VERSION:
+#if 0 && defined(WINDOWS)
+ if (packspuRunningUnderWine())
+ {
+ GetString(GL_REAL_VERSION, ctx->pszRealVersion);
+ return ctx->pszRealVersion;
+ }
+ else
+#endif
+ {
+ char *oldlocale;
+ float version;
+
+ oldlocale = setlocale(LC_NUMERIC, NULL);
+ oldlocale = crStrdup(oldlocale);
+ setlocale(LC_NUMERIC, "C");
+
+ version = GetVersionString();
+ sprintf((char*)ctx->glVersion, "%.1f Chromium %s", version, CR_VERSION_STRING);
+
+ if (oldlocale)
+ {
+ setlocale(LC_NUMERIC, oldlocale);
+ crFree(oldlocale);
+ }
+
+ return ctx->glVersion;
+ }
+ case GL_VENDOR:
+#ifdef WINDOWS
+ if (packspuRunningUnderWine())
+ {
+ GetString(GL_REAL_VENDOR, ctx->pszRealVendor);
+ return ctx->pszRealVendor;
+ }
+ else
+#endif
+ {
+ return crStateGetString(name);
+ }
+ case GL_RENDERER:
+#ifdef WINDOWS
+ if (packspuRunningUnderWine())
+ {
+ GetString(GL_REAL_RENDERER, ctx->pszRealRenderer);
+ return ctx->pszRealRenderer;
+ }
+ else
+#endif
+ {
+ return crStateGetString(name);
+ }
+
+#ifdef CR_OPENGL_VERSION_2_0
+ case GL_SHADING_LANGUAGE_VERSION:
+ {
+ static GLboolean fInitialized = GL_FALSE;
+ if (!fInitialized)
+ {
+ GetString(GL_SHADING_LANGUAGE_VERSION, gpszShadingVersion);
+ fInitialized = GL_TRUE;
+ }
+ return gpszShadingVersion;
+ }
+#endif
+#ifdef GL_CR_real_vendor_strings
+ case GL_REAL_VENDOR:
+ GetString(GL_REAL_VENDOR, ctx->pszRealVendor);
+ return ctx->pszRealVendor;
+ case GL_REAL_VERSION:
+ GetString(GL_REAL_VERSION, ctx->pszRealVersion);
+ return ctx->pszRealVersion;
+ case GL_REAL_RENDERER:
+ GetString(GL_REAL_RENDERER, ctx->pszRealRenderer);
+ return ctx->pszRealRenderer;
+#endif
+ default:
+ return crStateGetString(name);
+ }
+}
+
+void packspuInitStrings()
+{
+ static GLboolean fInitialized = GL_FALSE;
+
+ if (!fInitialized)
+ {
+ packspu_GetString(GL_EXTENSIONS);
+ packspu_GetString(GL_VERSION);
+ fInitialized = GL_TRUE;
+ }
+}
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_glsl.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_glsl.c
new file mode 100644
index 00000000..1116b7d5
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_glsl.c
@@ -0,0 +1,275 @@
+/* $Id: packspu_glsl.c $ */
+
+/** @file
+ * VBox OpenGL GLSL related functions
+ */
+
+/*
+ * Copyright (C) 2009-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include "packspu.h"
+#include "cr_packfunctions.h"
+#include "cr_net.h"
+#include "packspu_proto.h"
+#include "cr_mem.h"
+
+
+GLuint PACKSPU_APIENTRY packspu_CreateProgram(void)
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLuint return_val = (GLuint) 0;
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI() && !(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))
+ {
+ crError("packspu_CreateProgram doesn't work when there's no actual network involved!\nTry using the simplequery SPU in your chain!");
+ }
+ if (pack_spu.swap)
+ {
+ crPackCreateProgramSWAP(&return_val, &writeback);
+ }
+ else
+ {
+ crPackCreateProgram(&return_val, &writeback);
+ }
+ packspuFlush((void *) thread);
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ if (pack_spu.swap)
+ {
+ return_val = (GLuint) SWAP32(return_val);
+ }
+
+ crStateCreateProgram(return_val);
+
+ return return_val;
+}
+
+static GLint packspu_GetUniformLocationUncached(GLuint program, const char * name)
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLint return_val = (GLint) 0;
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI() && !(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))
+ {
+ crError("packspu_GetUniformLocation doesn't work when there's no actual network involved!\nTry using the simplequery SPU in your chain!");
+ }
+ if (pack_spu.swap)
+ {
+ crPackGetUniformLocationSWAP(program, name, &return_val, &writeback);
+ }
+ else
+ {
+ crPackGetUniformLocation(program, name, &return_val, &writeback);
+ }
+ packspuFlush((void *) thread);
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ if (pack_spu.swap)
+ {
+ return_val = (GLint) SWAP32(return_val);
+ }
+ return return_val;
+}
+
+GLint PACKSPU_APIENTRY packspu_GetUniformLocation(GLuint program, const char * name)
+{
+ if (!crStateIsProgramUniformsCached(program))
+ {
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLsizei maxcbData;
+ GLsizei *pData;
+ GLint mu;
+
+ packspu_GetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &mu);
+ maxcbData = 16*mu*sizeof(char);
+
+ pData = (GLsizei *) crAlloc(maxcbData+sizeof(GLsizei));
+ if (!pData)
+ {
+ crWarning("packspu_GetUniformLocation: not enough memory, fallback to single query");
+ return packspu_GetUniformLocationUncached(program, name);
+ }
+
+ crPackGetUniformsLocations(program, maxcbData, pData, NULL, &writeback);
+
+ packspuFlush((void *) thread);
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ crStateGLSLProgramCacheUniforms(program, pData[0], &pData[1]);
+
+ CRASSERT(crStateIsProgramUniformsCached(program));
+
+ crFree(pData);
+ }
+
+ /*crDebug("packspu_GetUniformLocation(%d, %s)=%i", program, name, crStateGetUniformLocation(program, name));*/
+ return crStateGetUniformLocation(program, name);
+}
+
+static GLint PACKSPU_APIENTRY packspu_GetAttribLocationUnchached( GLuint program, const char * name )
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLint return_val = (GLint) 0;
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI() && !(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))
+ {
+ crError( "packspu_GetAttribLocation doesn't work when there's no actual network involved!\nTry using the simplequery SPU in your chain!" );
+ }
+ if (pack_spu.swap)
+ {
+ crPackGetAttribLocationSWAP( program, name, &return_val, &writeback );
+ }
+ else
+ {
+ crPackGetAttribLocation( program, name, &return_val, &writeback );
+ }
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ if (pack_spu.swap)
+ {
+ return_val = (GLint) SWAP32(return_val);
+ }
+ return return_val;
+}
+
+GLint PACKSPU_APIENTRY packspu_GetAttribLocation(GLuint program, const char * name)
+{
+ if (!(CR_VBOX_CAP_GETATTRIBSLOCATIONS & g_u32VBoxHostCaps))
+ return packspu_GetAttribLocationUnchached(program, name);
+
+ if (!crStateIsProgramAttribsCached(program))
+ {
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLsizei maxcbData;
+ GLsizei *pData;
+ GLint mu;
+
+ packspu_GetIntegerv(GL_MAX_VERTEX_ATTRIBS, &mu);
+ maxcbData = 4*32*mu*sizeof(char);
+
+ pData = (GLsizei *) crAlloc(maxcbData+sizeof(GLsizei));
+ if (!pData)
+ {
+ crWarning("packspu_GetAttribLocation: not enough memory, fallback to single query");
+ return packspu_GetAttribLocationUnchached(program, name);
+ }
+
+ crPackGetAttribsLocations(program, maxcbData, pData, NULL, &writeback);
+
+ packspuFlush((void *) thread);
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ crStateGLSLProgramCacheAttribs(program, pData[0], &pData[1]);
+
+ CRASSERT(crStateIsProgramAttribsCached(program));
+
+ crFree(pData);
+ }
+
+ /*crDebug("packspu_GetAttribLocation(%d, %s)=%i", program, name, crStateGetAttribLocation(program, name));*/
+ return crStateGetAttribLocation(program, name);
+}
+
+void PACKSPU_APIENTRY packspu_GetUniformsLocations(GLuint program, GLsizei maxcbData, GLsizei * cbData, GLvoid * pData)
+{
+ (void) program;
+ (void) maxcbData;
+ (void) cbData;
+ (void) pData;
+ WARN(("packspu_GetUniformsLocations shouldn't be called directly"));
+}
+
+void PACKSPU_APIENTRY packspu_GetAttribsLocations(GLuint program, GLsizei maxcbData, GLsizei * cbData, GLvoid * pData)
+{
+ (void) program;
+ (void) maxcbData;
+ (void) cbData;
+ (void) pData;
+ WARN(("packspu_GetAttribsLocations shouldn't be called directly"));
+}
+
+void PACKSPU_APIENTRY packspu_DeleteProgram(GLuint program)
+{
+ crStateDeleteProgram(program);
+ crPackDeleteProgram(program);
+}
+
+void PACK_APIENTRY packspu_DeleteObjectARB(VBoxGLhandleARB obj)
+{
+ GLuint hwid = crStateGetProgramHWID(obj);
+
+ CRASSERT(obj);
+
+ /* we do not track shader creation inside guest since it is not needed currently.
+ * this is why we only care about programs here */
+ if (hwid)
+ {
+ crStateDeleteProgram(obj);
+ }
+
+ crPackDeleteObjectARB(obj);
+}
+
+#ifdef VBOX_WITH_CRPACKSPU_DUMPER
+static void packspu_RecCheckInitRec()
+{
+ if (pack_spu.Recorder.pDumper)
+ return;
+
+ crDmpDbgPrintInit(&pack_spu.Dumper);
+
+ crRecInit(&pack_spu.Recorder, NULL /*pBlitter: we do not support blitter operations here*/, &pack_spu.self, &pack_spu.Dumper.Base);
+}
+#endif
+
+void PACKSPU_APIENTRY packspu_LinkProgram(GLuint program)
+{
+#ifdef VBOX_WITH_CRPACKSPU_DUMPER
+ GLint linkStatus = 0;
+#endif
+
+ crStateLinkProgram(program);
+ crPackLinkProgram(program);
+
+#ifdef VBOX_WITH_CRPACKSPU_DUMPER
+ pack_spu.self.GetObjectParameterivARB(program, GL_OBJECT_LINK_STATUS_ARB, &linkStatus);
+ Assert(linkStatus);
+ if (!linkStatus)
+ {
+ CRContext *ctx = crStateGetCurrent();
+ packspu_RecCheckInitRec();
+ crRecDumpProgram(&pack_spu.Recorder, ctx, program, program);
+ }
+#endif
+}
+
+void PACKSPU_APIENTRY packspu_CompileShader(GLuint shader)
+{
+#ifdef VBOX_WITH_CRPACKSPU_DUMPER
+ GLint compileStatus = 0;
+#endif
+
+// crStateCompileShader(shader);
+ crPackCompileShader(shader);
+
+#ifdef VBOX_WITH_CRPACKSPU_DUMPER
+ pack_spu.self.GetObjectParameterivARB(shader, GL_OBJECT_COMPILE_STATUS_ARB, &compileStatus);
+ Assert(compileStatus);
+ if (!compileStatus)
+ {
+ CRContext *ctx = crStateGetCurrent();
+ packspu_RecCheckInitRec();
+ crRecDumpShader(&pack_spu.Recorder, ctx, shader, shader);
+ }
+#endif
+}
+
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_init.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_init.c
new file mode 100644
index 00000000..d5219950
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_init.c
@@ -0,0 +1,152 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include "cr_mem.h"
+#include "cr_spu.h"
+#include "cr_glstate.h"
+#include "packspu.h"
+#include "cr_packfunctions.h"
+#include <stdio.h>
+
+extern SPUNamedFunctionTable _cr_pack_table[];
+
+SPUFunctions pack_functions = {
+ NULL, /* CHILD COPY */
+ NULL, /* DATA */
+ _cr_pack_table /* THE ACTUAL FUNCTIONS */
+};
+
+PackSPU pack_spu;
+
+#ifdef CHROMIUM_THREADSAFE
+CRtsd _PackTSD;
+CRmutex _PackMutex;
+#endif
+
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+# include <VBoxCrHgsmi.h>
+# include <VBoxUhgsmi.h>
+#endif
+
+#if defined(RT_OS_WINDOWS) && defined(VBOX_WITH_WDDM)
+static bool isVBoxWDDMCrHgsmi(void)
+{
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ PVBOXUHGSMI pHgsmi = VBoxCrHgsmiCreate();
+ if (pHgsmi)
+ {
+ VBoxCrHgsmiDestroy(pHgsmi);
+ return true;
+ }
+#endif
+ return false;
+}
+#endif /* RT_OS_WINDOWS && VBOX_WITH_WDDM */
+
+static SPUFunctions *
+packSPUInit( int id, SPU *child, SPU *self,
+ unsigned int context_id,
+ unsigned int num_contexts )
+{
+ ThreadInfo *thread;
+
+ (void) context_id;
+ (void) num_contexts;
+ (void) child;
+ (void) self;
+
+#if defined(CHROMIUM_THREADSAFE) && !defined(WINDOWS)
+ crInitMutex(&_PackMutex);
+#endif
+
+#ifdef CHROMIUM_THREADSAFE
+ crInitTSD(&_PackerTSD);
+ crInitTSD(&_PackTSD);
+#endif
+
+ pack_spu.id = id;
+
+ packspuSetVBoxConfiguration( child );
+
+#if defined(WINDOWS) && defined(VBOX_WITH_WDDM)
+ pack_spu.bIsWDDMCrHgsmi = isVBoxWDDMCrHgsmi();
+#endif
+
+#ifdef VBOX_WITH_CRPACKSPU_DUMPER
+ memset(&pack_spu.Dumper, 0, sizeof (pack_spu.Dumper));
+#endif
+
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ /* This connects to the server, sets up the packer, etc. */
+ thread = packspuNewThread(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ NULL
+#endif
+ );
+
+ if (!thread) {
+ return NULL;
+ }
+ CRASSERT( thread == &(pack_spu.thread[0]) );
+ pack_spu.idxThreadInUse = 0;
+ }
+
+ packspuCreateFunctions();
+ crStateInit();
+
+ return &pack_functions;
+}
+
+static void
+packSPUSelfDispatch(SPUDispatchTable *self)
+{
+ crSPUInitDispatchTable( &(pack_spu.self) );
+ crSPUCopyDispatchTable( &(pack_spu.self), self );
+}
+
+static int
+packSPUCleanup(void)
+{
+ int i;
+#ifdef CHROMIUM_THREADSAFE
+ crLockMutex(&_PackMutex);
+#endif
+ for (i=0; i<MAX_THREADS; ++i)
+ {
+ if (pack_spu.thread[i].inUse && pack_spu.thread[i].packer)
+ {
+ crPackDeleteContext(pack_spu.thread[i].packer);
+ }
+ }
+
+#ifdef CHROMIUM_THREADSAFE
+ crFreeTSD(&_PackerTSD);
+ crFreeTSD(&_PackTSD);
+ crUnlockMutex(&_PackMutex);
+# ifndef WINDOWS
+ crFreeMutex(&_PackMutex);
+# endif
+#endif /* CHROMIUM_THREADSAFE */
+ return 1;
+}
+
+extern SPUOptions packSPUOptions[];
+
+int SPULoad( char **name, char **super, SPUInitFuncPtr *init,
+ SPUSelfDispatchFuncPtr *self, SPUCleanupFuncPtr *cleanup,
+ SPUOptionsPtr *options, int *flags )
+{
+ *name = "pack";
+ *super = NULL;
+ *init = packSPUInit;
+ *self = packSPUSelfDispatch;
+ *cleanup = packSPUCleanup;
+ *options = packSPUOptions;
+ *flags = (SPU_HAS_PACKER|SPU_IS_TERMINAL|SPU_MAX_SERVERS_ONE);
+
+ return 1;
+}
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_misc.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_misc.c
new file mode 100644
index 00000000..0b65be90
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_misc.c
@@ -0,0 +1,856 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include "cr_packfunctions.h"
+#include "packspu.h"
+#include "packspu_proto.h"
+#include "cr_mem.h"
+
+void PACKSPU_APIENTRY packspu_ChromiumParametervCR(GLenum target, GLenum type, GLsizei count, const GLvoid *values)
+{
+
+ CRMessage msg;
+ int len;
+ GLint ai32ServerValues[2];
+ GLboolean fFlush = GL_FALSE;
+ GET_THREAD(thread);
+
+
+ switch(target)
+ {
+ case GL_GATHER_PACK_CR:
+ /* flush the current pack buffer */
+ packspuFlush( (void *) thread );
+
+ /* the connection is thread->server.conn */
+ msg.header.type = CR_MESSAGE_GATHER;
+ msg.gather.offset = 69;
+ len = sizeof(CRMessageGather);
+ crNetSend(thread->netServer.conn, NULL, &msg, len);
+ return;
+
+ case GL_SHARE_LISTS_CR:
+ {
+ ContextInfo *pCtx[2];
+ GLint *ai32Values;
+ int i;
+ if (count != 2)
+ {
+ WARN(("GL_SHARE_LISTS_CR invalid cound %d", count));
+ return;
+ }
+
+ if (type != GL_UNSIGNED_INT && type != GL_INT)
+ {
+ WARN(("GL_SHARE_LISTS_CR invalid type %d", type));
+ return;
+ }
+
+ ai32Values = (GLint*)values;
+
+ for (i = 0; i < 2; ++i)
+ {
+ const int slot = ai32Values[i] - MAGIC_OFFSET;
+
+ if (slot < 0 || slot >= pack_spu.numContexts)
+ {
+ WARN(("GL_SHARE_LISTS_CR invalid value[%d] %d", i, ai32Values[i]));
+ return;
+ }
+
+ pCtx[i] = &pack_spu.context[slot];
+ if (!pCtx[i]->clientState)
+ {
+ WARN(("GL_SHARE_LISTS_CR invalid pCtx1 for value[%d] %d", i, ai32Values[i]));
+ return;
+ }
+
+ ai32ServerValues[i] = pCtx[i]->serverCtx;
+ }
+
+ crStateShareLists(pCtx[0]->clientState, pCtx[1]->clientState);
+
+ values = ai32ServerValues;
+
+ fFlush = GL_TRUE;
+
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ if (pack_spu.swap)
+ crPackChromiumParametervCRSWAP(target, type, count, values);
+ else
+ crPackChromiumParametervCR(target, type, count, values);
+
+ if (fFlush)
+ packspuFlush( (void *) thread );
+}
+
+GLboolean packspuSyncOnFlushes(void)
+{
+#if 1 /*Seems to still cause issues, always sync for now*/
+ return 1;
+#else
+ GLint buffer;
+
+ crStateGetIntegerv(GL_DRAW_BUFFER, &buffer);
+ /*Usually buffer==GL_BACK, so put this extra check to simplify boolean eval on runtime*/
+ return (buffer != GL_BACK)
+ && (buffer == GL_FRONT_LEFT
+ || buffer == GL_FRONT_RIGHT
+ || buffer == GL_FRONT
+ || buffer == GL_FRONT_AND_BACK
+ || buffer == GL_LEFT
+ || buffer == GL_RIGHT);
+#endif
+}
+
+void PACKSPU_APIENTRY packspu_DrawBuffer(GLenum mode)
+{
+ GLboolean hadtoflush;
+
+ hadtoflush = packspuSyncOnFlushes();
+
+ crStateDrawBuffer(mode);
+ crPackDrawBuffer(mode);
+
+ if (hadtoflush && !packspuSyncOnFlushes())
+ packspu_Flush();
+}
+
+void PACKSPU_APIENTRY packspu_Finish( void )
+{
+ GET_THREAD(thread);
+ GLint writeback = CRPACKSPU_IS_WDDM_CRHGSMI() ? 1 : pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network;
+
+ if (pack_spu.swap)
+ {
+ crPackFinishSWAP();
+ }
+ else
+ {
+ crPackFinish();
+ }
+
+ if (packspuSyncOnFlushes())
+ {
+ if (writeback)
+ {
+ if (pack_spu.swap)
+ crPackWritebackSWAP(&writeback);
+ else
+ crPackWriteback(&writeback);
+
+ packspuFlush( (void *) thread );
+
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ }
+ }
+}
+
+void PACKSPU_APIENTRY packspu_Flush( void )
+{
+ GET_THREAD(thread);
+ int writeback=1;
+ int found=0;
+
+ if (!thread->bInjectThread)
+ {
+ crPackFlush();
+ if (packspuSyncOnFlushes())
+ {
+ crPackWriteback(&writeback);
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ }
+ }
+ else
+ {
+ int i;
+
+ crLockMutex(&_PackMutex);
+
+ /*Make sure we process commands in order they should appear, so flush other threads first*/
+ for (i=0; i<MAX_THREADS; ++i)
+ {
+ if (pack_spu.thread[i].inUse
+ && (thread != &pack_spu.thread[i]) && pack_spu.thread[i].netServer.conn
+ && pack_spu.thread[i].packer && pack_spu.thread[i].packer->currentBuffer)
+ {
+ packspuFlush((void *) &pack_spu.thread[i]);
+
+ if (pack_spu.thread[i].netServer.conn->u32ClientID == thread->netServer.conn->u32InjectClientID)
+ {
+ found=1;
+ }
+
+ }
+ }
+
+ if (!found)
+ {
+ /*Thread we're supposed to inject commands for has been detached,
+ so there's nothing to sync with and we should just pass commands through our own connection.
+ */
+ thread->netServer.conn->u32InjectClientID=0;
+ }
+
+ packspuFlush((void *) thread);
+
+ crUnlockMutex(&_PackMutex);
+ }
+}
+
+void PACKSPU_APIENTRY packspu_NewList(GLuint list, GLenum mode)
+{
+ crStateNewList(list, mode);
+ crPackNewList(list, mode);
+}
+
+void PACKSPU_APIENTRY packspu_EndList()
+{
+ crStateEndList();
+ crPackEndList();
+}
+
+void PACKSPU_APIENTRY packspu_VBoxWindowDestroy( GLint con, GLint window )
+{
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ GET_THREAD(thread);
+ if (con)
+ {
+ CRPackContext * curPacker = crPackGetContext();
+ CRASSERT(!thread || !thread->bInjectThread);
+ thread = GET_THREAD_VAL_ID(con);
+ crPackSetContext(thread->packer);
+ crPackWindowDestroy(window);
+ if (curPacker != thread->packer)
+ crPackSetContext(curPacker);
+ return;
+ }
+ CRASSERT(thread);
+ CRASSERT(thread->bInjectThread);
+ }
+ crPackWindowDestroy(window);
+}
+
+GLint PACKSPU_APIENTRY packspu_VBoxWindowCreate( GLint con, const char *dpyName, GLint visBits )
+{
+ GET_THREAD(thread);
+ static int num_calls = 0;
+ int writeback = CRPACKSPU_IS_WDDM_CRHGSMI() ? 1 : pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network;
+ GLint return_val = (GLint) 0;
+ ThreadInfo *curThread = thread;
+ GLint retVal;
+
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ if (!con)
+ {
+ crError("connection expected!");
+ return 0;
+ }
+ thread = GET_THREAD_VAL_ID(con);
+ }
+ else
+ {
+ CRASSERT(!con);
+ if (!thread) {
+ thread = packspuNewThread(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ NULL
+#endif
+ );
+ }
+ }
+ CRASSERT(thread);
+ CRASSERT(thread->packer);
+ CRASSERT(crPackGetContext() == (curThread ? curThread->packer : NULL));
+
+ crPackSetContext(thread->packer);
+
+ if (pack_spu.swap)
+ {
+ crPackWindowCreateSWAP( dpyName, visBits, &return_val, &writeback );
+ }
+ else
+ {
+ crPackWindowCreate( dpyName, visBits, &return_val, &writeback );
+ }
+ packspuFlush(thread);
+ if (!(thread->netServer.conn->actual_network))
+ {
+ retVal = num_calls++;
+ }
+ else
+ {
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ if (pack_spu.swap)
+ {
+ return_val = (GLint) SWAP32(return_val);
+ }
+ retVal = return_val;
+ }
+
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ if (thread != curThread)
+ {
+ if (curThread)
+ crPackSetContext(curThread->packer);
+ else
+ crPackSetContext(NULL);
+ }
+ }
+
+ return retVal;
+}
+
+GLint PACKSPU_APIENTRY packspu_WindowCreate( const char *dpyName, GLint visBits )
+{
+ return packspu_VBoxWindowCreate( 0, dpyName, visBits );
+}
+
+GLboolean PACKSPU_APIENTRY
+packspu_AreTexturesResident( GLsizei n, const GLuint * textures,
+ GLboolean * residences )
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLboolean return_val = GL_TRUE;
+ GLsizei i;
+
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI() && !(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))
+ {
+ crError( "packspu_AreTexturesResident doesn't work when there's no actual network involved!\nTry using the simplequery SPU in your chain!" );
+ }
+
+ if (pack_spu.swap)
+ {
+ crPackAreTexturesResidentSWAP( n, textures, residences, &return_val, &writeback );
+ }
+ else
+ {
+ crPackAreTexturesResident( n, textures, residences, &return_val, &writeback );
+ }
+ packspuFlush( (void *) thread );
+
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ /* Since the Chromium packer/unpacker can't return both 'residences'
+ * and the function's return value, compute the return value here.
+ */
+ for (i = 0; i < n; i++) {
+ if (!residences[i]) {
+ return_val = GL_FALSE;
+ break;
+ }
+ }
+
+ return return_val;
+}
+
+
+GLboolean PACKSPU_APIENTRY
+packspu_AreProgramsResidentNV( GLsizei n, const GLuint * ids,
+ GLboolean * residences )
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLboolean return_val = GL_TRUE;
+ GLsizei i;
+
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI() && !(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))
+ {
+ crError( "packspu_AreProgramsResidentNV doesn't work when there's no actual network involved!\nTry using the simplequery SPU in your chain!" );
+ }
+ if (pack_spu.swap)
+ {
+ crPackAreProgramsResidentNVSWAP( n, ids, residences, &return_val, &writeback );
+ }
+ else
+ {
+ crPackAreProgramsResidentNV( n, ids, residences, &return_val, &writeback );
+ }
+ packspuFlush( (void *) thread );
+
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ /* Since the Chromium packer/unpacker can't return both 'residences'
+ * and the function's return value, compute the return value here.
+ */
+ for (i = 0; i < n; i++) {
+ if (!residences[i]) {
+ return_val = GL_FALSE;
+ break;
+ }
+ }
+
+ return return_val;
+}
+
+void PACKSPU_APIENTRY packspu_GetPolygonStipple( GLubyte * mask )
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+
+ if (pack_spu.swap)
+ {
+ crPackGetPolygonStippleSWAP( mask, &writeback );
+ }
+ else
+ {
+ crPackGetPolygonStipple( mask, &writeback );
+ }
+
+#ifdef CR_ARB_pixel_buffer_object
+ if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
+#endif
+ {
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ }
+}
+
+void PACKSPU_APIENTRY packspu_GetPixelMapfv( GLenum map, GLfloat * values )
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+
+ if (pack_spu.swap)
+ {
+ crPackGetPixelMapfvSWAP( map, values, &writeback );
+ }
+ else
+ {
+ crPackGetPixelMapfv( map, values, &writeback );
+ }
+
+#ifdef CR_ARB_pixel_buffer_object
+ if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
+#endif
+ {
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ }
+}
+
+void PACKSPU_APIENTRY packspu_GetPixelMapuiv( GLenum map, GLuint * values )
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+
+ if (pack_spu.swap)
+ {
+ crPackGetPixelMapuivSWAP( map, values, &writeback );
+ }
+ else
+ {
+ crPackGetPixelMapuiv( map, values, &writeback );
+ }
+
+#ifdef CR_ARB_pixel_buffer_object
+ if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
+#endif
+ {
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ }
+}
+
+void PACKSPU_APIENTRY packspu_GetPixelMapusv( GLenum map, GLushort * values )
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+
+ if (pack_spu.swap)
+ {
+ crPackGetPixelMapusvSWAP( map, values, &writeback );
+ }
+ else
+ {
+ crPackGetPixelMapusv( map, values, &writeback );
+ }
+
+#ifdef CR_ARB_pixel_buffer_object
+ if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
+#endif
+ {
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ }
+}
+
+static void packspuFluchOnThreadSwitch(GLboolean fEnable)
+{
+ GET_THREAD(thread);
+ if (thread->currentContext->fAutoFlush == fEnable)
+ return;
+
+ thread->currentContext->fAutoFlush = fEnable;
+ thread->currentContext->currentThread = fEnable ? thread : NULL;
+}
+
+static void packspuCheckZerroVertAttr(GLboolean fEnable)
+{
+ GET_THREAD(thread);
+
+ thread->currentContext->fCheckZerroVertAttr = fEnable;
+}
+
+void PACKSPU_APIENTRY packspu_ChromiumParameteriCR(GLenum target, GLint value)
+{
+ switch (target)
+ {
+ case GL_FLUSH_ON_THREAD_SWITCH_CR:
+ /* this is a pure packspu state, don't propagate it any further */
+ packspuFluchOnThreadSwitch(value);
+ return;
+ case GL_CHECK_ZERO_VERT_ARRT:
+ packspuCheckZerroVertAttr(value);
+ return;
+ case GL_SHARE_CONTEXT_RESOURCES_CR:
+ crStateShareContext(value);
+ break;
+ case GL_RCUSAGE_TEXTURE_SET_CR:
+ {
+ Assert(value);
+ crStateSetTextureUsed(value, GL_TRUE);
+ break;
+ }
+ case GL_RCUSAGE_TEXTURE_CLEAR_CR:
+ {
+ Assert(value);
+#ifdef DEBUG
+ {
+ CRContext *pCurState = crStateGetCurrent();
+ CRTextureObj *tobj = (CRTextureObj*)crHashtableSearch(pCurState->shared->textureTable, value);
+ Assert(tobj);
+ }
+#endif
+ crStateSetTextureUsed(value, GL_FALSE);
+ break;
+ }
+ default:
+ break;
+ }
+ crPackChromiumParameteriCR(target, value);
+}
+
+GLenum PACKSPU_APIENTRY packspu_GetError( void )
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLenum return_val = (GLenum) 0;
+ CRContext *pCurState = crStateGetCurrent();
+ NOREF(pCurState); /* it's unused, but I don't know about side effects.. */
+
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI() && !(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))
+ {
+ crError( "packspu_GetError doesn't work when there's no actual network involved!\nTry using the simplequery SPU in your chain!" );
+ }
+ if (pack_spu.swap)
+ {
+ crPackGetErrorSWAP( &return_val, &writeback );
+ }
+ else
+ {
+ crPackGetError( &return_val, &writeback );
+ }
+
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ if (pack_spu.swap)
+ {
+ return_val = (GLenum) SWAP32(return_val);
+ }
+
+ return return_val;
+}
+
+#ifdef CHROMIUM_THREADSAFE
+GLint PACKSPU_APIENTRY packspu_VBoxPackSetInjectThread(struct VBOXUHGSMI *pHgsmi)
+{
+ GLint con = 0;
+ int i;
+ GET_THREAD(thread);
+ CRASSERT(!thread);
+ RT_NOREF(pHgsmi);
+ crLockMutex(&_PackMutex);
+ {
+ CRASSERT(CRPACKSPU_IS_WDDM_CRHGSMI() || (pack_spu.numThreads>0));
+ CRASSERT(pack_spu.numThreads<MAX_THREADS);
+ for (i=0; i<MAX_THREADS; ++i)
+ {
+ if (!pack_spu.thread[i].inUse)
+ {
+ thread = &pack_spu.thread[i];
+ break;
+ }
+ }
+ CRASSERT(thread);
+
+ thread->inUse = GL_TRUE;
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI())
+ thread->id = crThreadID();
+ else
+ thread->id = THREAD_OFFSET_MAGIC + i;
+ thread->currentContext = NULL;
+ thread->bInjectThread = GL_TRUE;
+
+ thread->netServer.name = crStrdup(pack_spu.name);
+ thread->netServer.buffer_size = 64 * 1024;
+
+ packspuConnectToServer(&(thread->netServer)
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ , pHgsmi
+#endif
+ );
+ CRASSERT(thread->netServer.conn);
+
+ CRASSERT(thread->packer == NULL);
+ thread->packer = crPackNewContext( pack_spu.swap );
+ CRASSERT(thread->packer);
+ crPackInitBuffer(&(thread->buffer), crNetAlloc(thread->netServer.conn),
+ thread->netServer.conn->buffer_size, thread->netServer.conn->mtu);
+ thread->buffer.canBarf = thread->netServer.conn->Barf ? GL_TRUE : GL_FALSE;
+
+ crPackSetBuffer( thread->packer, &thread->buffer );
+ crPackFlushFunc( thread->packer, packspuFlush );
+ crPackFlushArg( thread->packer, (void *) thread );
+ crPackSendHugeFunc( thread->packer, packspuHuge );
+ crPackSetContext( thread->packer );
+
+ crSetTSD(&_PackTSD, thread);
+
+ pack_spu.numThreads++;
+ }
+ crUnlockMutex(&_PackMutex);
+
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ CRASSERT(thread->id - THREAD_OFFSET_MAGIC < RT_ELEMENTS(pack_spu.thread)
+ && GET_THREAD_VAL_ID(thread->id) == thread);
+ con = thread->id;
+ }
+ return con;
+}
+
+GLuint PACKSPU_APIENTRY packspu_VBoxPackGetInjectID(GLint con)
+{
+ GLuint ret;
+
+ crLockMutex(&_PackMutex);
+ {
+ ThreadInfo *thread = NULL;
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ if (!con)
+ {
+ crError("connection expected!");
+ return 0;
+ }
+ thread = GET_THREAD_VAL_ID(con);
+ }
+ else
+ {
+ CRASSERT(!con);
+ thread = GET_THREAD_VAL();
+ }
+ CRASSERT(thread && thread->netServer.conn && thread->netServer.conn->type==CR_VBOXHGCM);
+ ret = thread->netServer.conn->u32ClientID;
+ }
+ crUnlockMutex(&_PackMutex);
+
+ return ret;
+}
+
+void PACKSPU_APIENTRY packspu_VBoxPackSetInjectID(GLuint id)
+{
+ crLockMutex(&_PackMutex);
+ {
+ GET_THREAD(thread);
+
+ CRASSERT(thread && thread->netServer.conn && thread->netServer.conn->type==CR_VBOXHGCM && thread->bInjectThread);
+ thread->netServer.conn->u32InjectClientID = id;
+ }
+ crUnlockMutex(&_PackMutex);
+}
+
+void PACKSPU_APIENTRY packspu_VBoxAttachThread()
+{
+#if 0
+ int i;
+ GET_THREAD(thread);
+
+ for (i=0; i<MAX_THREADS; ++i)
+ {
+ if (pack_spu.thread[i].inUse && thread==&pack_spu.thread[i] && thread->id==crThreadID())
+ {
+ crError("2nd attach to same thread");
+ }
+ }
+#endif
+
+ crSetTSD(&_PackTSD, NULL);
+
+ crStateVBoxAttachThread();
+}
+
+void PACKSPU_APIENTRY packspu_VBoxDetachThread()
+{
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ crPackSetContext(NULL);
+ crSetTSD(&_PackTSD, NULL);
+ }
+ else
+ {
+ int i;
+ GET_THREAD(thread);
+ if (thread)
+ {
+ crLockMutex(&_PackMutex);
+
+ for (i=0; i<MAX_THREADS; ++i)
+ {
+ if (pack_spu.thread[i].inUse && thread==&pack_spu.thread[i]
+ && thread->id==crThreadID() && thread->netServer.conn)
+ {
+ CRASSERT(pack_spu.numThreads>0);
+
+ packspuFlush((void *) thread);
+
+ if (pack_spu.thread[i].packer)
+ {
+ CR_LOCK_PACKER_CONTEXT(thread->packer);
+ crPackSetContext(NULL);
+ CR_UNLOCK_PACKER_CONTEXT(thread->packer);
+ crPackDeleteContext(pack_spu.thread[i].packer);
+
+ if (pack_spu.thread[i].buffer.pack)
+ {
+ crNetFree(pack_spu.thread[i].netServer.conn, pack_spu.thread[i].buffer.pack);
+ pack_spu.thread[i].buffer.pack = NULL;
+ }
+ }
+ crNetFreeConnection(pack_spu.thread[i].netServer.conn);
+
+ if (pack_spu.thread[i].netServer.name)
+ crFree(pack_spu.thread[i].netServer.name);
+
+ pack_spu.numThreads--;
+ /*note can't shift the array here, because other threads have TLS references to array elements*/
+ crMemZero(&pack_spu.thread[i], sizeof(ThreadInfo));
+
+ crSetTSD(&_PackTSD, NULL);
+
+ if (i==pack_spu.idxThreadInUse)
+ {
+ for (i=0; i<MAX_THREADS; ++i)
+ {
+ if (pack_spu.thread[i].inUse)
+ {
+ pack_spu.idxThreadInUse=i;
+ break;
+ }
+ }
+ }
+
+ break;
+ }
+ }
+
+ for (i=0; i<CR_MAX_CONTEXTS; ++i)
+ {
+ ContextInfo *ctx = &pack_spu.context[i];
+ if (ctx->currentThread == thread)
+ {
+ CRASSERT(ctx->fAutoFlush);
+ ctx->currentThread = NULL;
+ }
+ }
+
+ crUnlockMutex(&_PackMutex);
+ }
+ }
+
+ crStateVBoxDetachThread();
+}
+
+#ifdef WINDOWS
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+BOOL WINAPI DllMain(HINSTANCE hDLLInst, DWORD fdwReason, LPVOID lpvReserved)
+{
+ (void) lpvReserved;
+
+ switch (fdwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ {
+ crInitMutex(&_PackMutex);
+ break;
+ }
+
+ case DLL_PROCESS_DETACH:
+ {
+ crFreeMutex(&_PackMutex);
+ crNetTearDown();
+ break;
+ }
+
+ case DLL_THREAD_ATTACH:
+ case DLL_THREAD_DETACH:
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+#endif
+
+#else /*ifdef CHROMIUM_THREADSAFE*/
+GLint PACKSPU_APIENTRY packspu_VBoxPackSetInjectThread(struct VBOXUHGSMI *pHgsmi)
+{
+}
+
+GLuint PACKSPU_APIENTRY packspu_VBoxPackGetInjectID(GLint con)
+{
+ return 0;
+}
+
+void PACKSPU_APIENTRY packspu_VBoxPackSetInjectID(GLuint id)
+{
+ (void) id;
+}
+
+void PACKSPU_APIENTRY packspu_VBoxPackAttachThread()
+{
+}
+
+void PACKSPU_APIENTRY packspu_VBoxPackDetachThread()
+{
+}
+#endif /*CHROMIUM_THREADSAFE*/
+
+void PACKSPU_APIENTRY packspu_VBoxPresentComposition(GLint win, const struct VBOXVR_SCR_COMPOSITOR * pCompositor,
+ const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry)
+{
+ RT_NOREF(win, pCompositor, pChangedEntry);
+}
+
+void PACKSPU_APIENTRY packspu_StringMarkerGREMEDY(GLsizei len, const GLvoid *string)
+{
+ RT_NOREF(len, string);
+}
+
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_net.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_net.c
new file mode 100644
index 00000000..6d5d41d6
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_net.c
@@ -0,0 +1,284 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include "cr_pack.h"
+#include "cr_mem.h"
+#include "cr_net.h"
+#include "cr_pixeldata.h"
+#include "cr_protocol.h"
+#include "cr_error.h"
+#include "packspu.h"
+#include "packspu_proto.h"
+
+uint32_t g_u32VBoxHostCaps = 0;
+
+static void
+packspuWriteback( const CRMessageWriteback *wb )
+{
+ int *writeback;
+ crMemcpy( &writeback, &(wb->writeback_ptr), sizeof( writeback ) );
+ *writeback = 0;
+}
+
+/**
+ * XXX Note that this routine is identical to crNetRecvReadback except
+ * we set *writeback=0 instead of decrementing it. Hmmm.
+ */
+static void
+packspuReadback( const CRMessageReadback *rb, unsigned int len )
+{
+ /* minus the header, the destination pointer,
+ * *and* the implicit writeback pointer at the head. */
+
+ int payload_len = len - sizeof( *rb );
+ int *writeback;
+ void *dest_ptr;
+ crMemcpy( &writeback, &(rb->writeback_ptr), sizeof( writeback ) );
+ crMemcpy( &dest_ptr, &(rb->readback_ptr), sizeof( dest_ptr ) );
+
+ *writeback = 0;
+ crMemcpy( dest_ptr, ((char *)rb) + sizeof(*rb), payload_len );
+}
+
+static void
+packspuReadPixels( const CRMessageReadPixels *rp, unsigned int len )
+{
+ crNetRecvReadPixels( rp, len );
+ --pack_spu.ReadPixels;
+}
+
+static int
+packspuReceiveData( CRConnection *conn, CRMessage *msg, unsigned int len )
+{
+ RT_NOREF(conn);
+ if (msg->header.type == CR_MESSAGE_REDIR_PTR)
+ msg = (CRMessage*) msg->redirptr.pMessage;
+
+ switch( msg->header.type )
+ {
+ case CR_MESSAGE_READ_PIXELS:
+ packspuReadPixels( &(msg->readPixels), len );
+ break;
+ case CR_MESSAGE_WRITEBACK:
+ packspuWriteback( &(msg->writeback) );
+ break;
+ case CR_MESSAGE_READBACK:
+ packspuReadback( &(msg->readback), len );
+ break;
+ default:
+ /*crWarning( "Why is the pack SPU getting a message of type 0x%x?", msg->type ); */
+ return 0; /* NOT HANDLED */
+ }
+ return 1; /* HANDLED */
+}
+
+static CRMessageOpcodes *
+__prependHeader( CRPackBuffer *buf, unsigned int *len, unsigned int senderID )
+{
+ int num_opcodes;
+ CRMessageOpcodes *hdr;
+ RT_NOREF(senderID);
+
+ CRASSERT( buf );
+ CRASSERT( buf->opcode_current < buf->opcode_start );
+ CRASSERT( buf->opcode_current >= buf->opcode_end );
+ CRASSERT( buf->data_current > buf->data_start );
+ CRASSERT( buf->data_current <= buf->data_end );
+
+ num_opcodes = buf->opcode_start - buf->opcode_current;
+ hdr = (CRMessageOpcodes *)
+ ( buf->data_start - ( ( num_opcodes + 3 ) & ~0x3 ) - sizeof(*hdr) );
+
+ CRASSERT( (void *) hdr >= buf->pack );
+
+ if (pack_spu.swap)
+ {
+ hdr->header.type = (CRMessageType) SWAP32(CR_MESSAGE_OPCODES);
+ hdr->numOpcodes = SWAP32(num_opcodes);
+ }
+ else
+ {
+ hdr->header.type = CR_MESSAGE_OPCODES;
+ hdr->numOpcodes = num_opcodes;
+ }
+
+ *len = buf->data_current - (unsigned char *) hdr;
+
+ return hdr;
+}
+
+
+/*
+ * This is called from either the Pack SPU and the packer library whenever
+ * we need to send a data buffer to the server.
+ */
+void packspuFlush(void *arg )
+{
+ ThreadInfo *thread = (ThreadInfo *) arg;
+ ContextInfo *ctx;
+ unsigned int len;
+ CRMessageOpcodes *hdr;
+ CRPackBuffer *buf;
+
+ /* we should _always_ pass a valid <arg> value */
+ CRASSERT(thread && thread->inUse);
+#ifdef CHROMIUM_THREADSAFE
+ CR_LOCK_PACKER_CONTEXT(thread->packer);
+#endif
+ ctx = thread->currentContext;
+ buf = &(thread->buffer);
+ CRASSERT(buf);
+
+ if (ctx && ctx->fCheckZerroVertAttr)
+ crStateCurrentRecoverNew(ctx->clientState, &thread->packer->current);
+
+ /* We're done packing into the current buffer, unbind it */
+ crPackReleaseBuffer( thread->packer );
+
+ /*
+ printf("%s thread=%p thread->id = %d thread->pc=%p t2->id=%d t2->pc=%p packbuf=%p packbuf=%p\n",
+ __FUNCTION__, (void*) thread, (int) thread->id, thread->packer,
+ (int) t2->id, t2->packer,
+ buf->pack, thread->packer->buffer.pack);
+ */
+
+ if ( buf->opcode_current == buf->opcode_start ) {
+ /*
+ printf("%s early return\n", __FUNCTION__);
+ */
+ /* XXX these calls seem to help, but might be appropriate */
+ crPackSetBuffer( thread->packer, buf );
+ crPackResetPointers(thread->packer);
+#ifdef CHROMIUM_THREADSAFE
+ CR_UNLOCK_PACKER_CONTEXT(thread->packer);
+#endif
+ return;
+ }
+
+ hdr = __prependHeader( buf, &len, 0 );
+
+ CRASSERT( thread->netServer.conn );
+
+ if ( buf->holds_BeginEnd )
+ {
+ /*crDebug("crNetBarf %d, (%d)", len, buf->size);*/
+ crNetBarf( thread->netServer.conn, &(buf->pack), hdr, len );
+ }
+ else
+ {
+ /*crDebug("crNetSend %d, (%d)", len, buf->size);*/
+ crNetSend( thread->netServer.conn, &(buf->pack), hdr, len );
+ }
+
+ buf->pack = crNetAlloc( thread->netServer.conn );
+
+ /* The network may have found a new mtu */
+ buf->mtu = thread->netServer.conn->mtu;
+
+ crPackSetBuffer( thread->packer, buf );
+
+ crPackResetPointers(thread->packer);
+
+#ifdef CHROMIUM_THREADSAFE
+ CR_UNLOCK_PACKER_CONTEXT(thread->packer);
+#endif
+}
+
+
+/**
+ * XXX NOTE: there's a lot of duplicate code here common to the
+ * pack, tilesort and replicate SPUs. Try to simplify someday!
+ */
+void packspuHuge( CROpcode opcode, void *buf )
+{
+ GET_THREAD(thread);
+ unsigned int len;
+ unsigned char *src;
+ CRMessageOpcodes *msg;
+
+ CRASSERT(thread);
+
+ /* packet length is indicated by the variable length field, and
+ includes an additional word for the opcode (with alignment) and
+ a header */
+ len = ((unsigned int *) buf)[-1];
+ if (pack_spu.swap)
+ {
+ /* It's already been swapped, swap it back. */
+ len = SWAP32(len);
+ }
+ len += 4 + sizeof(CRMessageOpcodes);
+
+ /* write the opcode in just before the length */
+ ((unsigned char *) buf)[-5] = (unsigned char) opcode;
+
+ /* fix up the pointer to the packet to include the length & opcode
+ & header */
+ src = (unsigned char *) buf - 8 - sizeof(CRMessageOpcodes);
+
+ msg = (CRMessageOpcodes *) src;
+
+ if (pack_spu.swap)
+ {
+ msg->header.type = (CRMessageType) SWAP32(CR_MESSAGE_OPCODES);
+ msg->numOpcodes = SWAP32(1);
+ }
+ else
+ {
+ msg->header.type = CR_MESSAGE_OPCODES;
+ msg->numOpcodes = 1;
+ }
+
+ CRASSERT( thread->netServer.conn );
+ crNetSend( thread->netServer.conn, NULL, src, len );
+}
+
+static void packspuFirstConnectToServer( CRNetServer *server
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ , struct VBOXUHGSMI *pHgsmi
+#endif
+ )
+{
+ crNetInit( packspuReceiveData, NULL );
+ crNetServerConnect( server
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ , pHgsmi
+#endif
+ );
+ if (server->conn)
+ {
+ g_u32VBoxHostCaps = crNetHostCapsGet();
+ crPackCapsSet(g_u32VBoxHostCaps);
+ }
+}
+
+void packspuConnectToServer( CRNetServer *server
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ , struct VBOXUHGSMI *pHgsmi
+#endif
+ )
+{
+ if (pack_spu.numThreads == 0) {
+ packspuFirstConnectToServer( server
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ , pHgsmi
+#endif
+ );
+ if (!server->conn) {
+ crError("packspuConnectToServer: no connection on first create!");
+ return;
+ }
+ pack_spu.swap = server->conn->swap;
+ }
+ else {
+ /* a new pthread */
+ crNetNewClient(server
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ , pHgsmi
+#endif
+ );
+ }
+}
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_pixel.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_pixel.c
new file mode 100644
index 00000000..06734b1e
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_pixel.c
@@ -0,0 +1,727 @@
+/* Copyright (c) 2001, Stanford University
+ All rights reserved.
+
+ See the file LICENSE.txt for information on redistributing this software. */
+
+#include "cr_packfunctions.h"
+#include "cr_glstate.h"
+#include "cr_pixeldata.h"
+#include "cr_version.h"
+#include "packspu.h"
+#include "packspu_proto.h"
+
+static GLboolean packspu_CheckTexImageFormat(GLenum format)
+{
+ if (format!=GL_COLOR_INDEX
+ && format!=GL_RED
+ && format!=GL_GREEN
+ && format!=GL_BLUE
+ && format!=GL_ALPHA
+ && format!=GL_RGB
+ && format!=GL_BGR
+ && format!=GL_RGBA
+ && format!=GL_BGRA
+ && format!=GL_LUMINANCE
+ && format!=GL_LUMINANCE_ALPHA
+ && format!=GL_DEPTH_COMPONENT
+ && format!=GL_DEPTH_STENCIL)
+ {
+ /*crWarning("crPackCheckTexImageFormat FAILED format 0x%x isn't valid", format);*/
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+static GLboolean packspu_CheckTexImageType(GLenum type)
+{
+ if (type!=GL_UNSIGNED_BYTE
+ && type!=GL_BYTE
+ && type!=GL_BITMAP
+ && type!=GL_UNSIGNED_SHORT
+ && type!=GL_SHORT
+ && type!=GL_UNSIGNED_INT
+ && type!=GL_INT
+ && type!=GL_FLOAT
+ && type!=GL_UNSIGNED_BYTE_3_3_2
+ && type!=GL_UNSIGNED_BYTE_2_3_3_REV
+ && type!=GL_UNSIGNED_SHORT_5_6_5
+ && type!=GL_UNSIGNED_SHORT_5_6_5_REV
+ && type!=GL_UNSIGNED_SHORT_4_4_4_4
+ && type!=GL_UNSIGNED_SHORT_4_4_4_4_REV
+ && type!=GL_UNSIGNED_SHORT_5_5_5_1
+ && type!=GL_UNSIGNED_SHORT_1_5_5_5_REV
+ && type!=GL_UNSIGNED_INT_8_8_8_8
+ && type!=GL_UNSIGNED_INT_8_8_8_8_REV
+ && type!=GL_UNSIGNED_INT_10_10_10_2
+ && type!=GL_UNSIGNED_INT_2_10_10_10_REV
+ && type!=GL_UNSIGNED_INT_24_8)
+ {
+ /*crWarning("crPackCheckTexImageType FAILED type 0x%x isn't valid", type);*/
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+static GLboolean packspu_CheckTexImageInternalFormat(GLint internalformat)
+{
+ if (internalformat!=1
+ && internalformat!=2
+ && internalformat!=3
+ && internalformat!=4
+ && internalformat!=GL_ALPHA
+ && internalformat!=GL_ALPHA4
+ && internalformat!=GL_ALPHA8
+ && internalformat!=GL_ALPHA12
+ && internalformat!=GL_ALPHA16
+ && internalformat!=GL_COMPRESSED_ALPHA
+ && internalformat!=GL_COMPRESSED_LUMINANCE
+ && internalformat!=GL_COMPRESSED_LUMINANCE_ALPHA
+ && internalformat!=GL_COMPRESSED_INTENSITY
+ && internalformat!=GL_COMPRESSED_RGB
+ && internalformat!=GL_COMPRESSED_RGBA
+ && internalformat!=GL_DEPTH_COMPONENT
+ && internalformat!=GL_DEPTH_COMPONENT16
+ && internalformat!=GL_DEPTH_COMPONENT24
+ && internalformat!=GL_DEPTH_COMPONENT32
+ && internalformat!=GL_DEPTH24_STENCIL8
+ && internalformat!=GL_LUMINANCE
+ && internalformat!=GL_LUMINANCE4
+ && internalformat!=GL_LUMINANCE8
+ && internalformat!=GL_LUMINANCE12
+ && internalformat!=GL_LUMINANCE16
+ && internalformat!=GL_LUMINANCE_ALPHA
+ && internalformat!=GL_LUMINANCE4_ALPHA4
+ && internalformat!=GL_LUMINANCE6_ALPHA2
+ && internalformat!=GL_LUMINANCE8_ALPHA8
+ && internalformat!=GL_LUMINANCE12_ALPHA4
+ && internalformat!=GL_LUMINANCE12_ALPHA12
+ && internalformat!=GL_LUMINANCE16_ALPHA16
+ && internalformat!=GL_INTENSITY
+ && internalformat!=GL_INTENSITY4
+ && internalformat!=GL_INTENSITY8
+ && internalformat!=GL_INTENSITY12
+ && internalformat!=GL_INTENSITY16
+ && internalformat!=GL_R3_G3_B2
+ && internalformat!=GL_RGB
+ && internalformat!=GL_RGB4
+ && internalformat!=GL_RGB5
+ && internalformat!=GL_RGB8
+ && internalformat!=GL_RGB10
+ && internalformat!=GL_RGB12
+ && internalformat!=GL_RGB16
+ && internalformat!=GL_RGBA
+ && internalformat!=GL_RGBA2
+ && internalformat!=GL_RGBA4
+ && internalformat!=GL_RGB5_A1
+ && internalformat!=GL_RGBA8
+ && internalformat!=GL_RGB10_A2
+ && internalformat!=GL_RGBA12
+ && internalformat!=GL_RGBA16
+ && internalformat!=GL_SLUMINANCE
+ && internalformat!=GL_SLUMINANCE8
+ && internalformat!=GL_SLUMINANCE_ALPHA
+ && internalformat!=GL_SLUMINANCE8_ALPHA8
+ && internalformat!=GL_SRGB
+ && internalformat!=GL_SRGB8
+ && internalformat!=GL_SRGB_ALPHA
+ && internalformat!=GL_SRGB8_ALPHA8
+#ifdef CR_EXT_texture_compression_s3tc
+ && internalformat!=GL_COMPRESSED_RGB_S3TC_DXT1_EXT
+ && internalformat!=GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
+ && internalformat!=GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
+ && internalformat!=GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
+# ifdef CR_EXT_texture_sRGB
+ && internalformat!=GL_COMPRESSED_SRGB_S3TC_DXT1_EXT
+ && internalformat!=GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT
+ && internalformat!=GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT
+ && internalformat!=GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT
+# endif
+#endif
+ /** @todo ARB_texture_float*/
+ && internalformat!=GL_RGBA32F_ARB
+ && internalformat!=GL_RGB32F_ARB
+ && internalformat!=GL_ALPHA32F_ARB
+ && internalformat!=GL_INTENSITY32F_ARB
+ && internalformat!=GL_LUMINANCE32F_ARB
+ && internalformat!=GL_LUMINANCE_ALPHA32F_ARB
+ && internalformat!=GL_RGBA16F_ARB
+ && internalformat!=GL_RGB16F_ARB
+ && internalformat!=GL_ALPHA16F_ARB
+ && internalformat!=GL_INTENSITY16F_ARB
+ && internalformat!=GL_LUMINANCE16F_ARB
+ && internalformat!=GL_LUMINANCE_ALPHA16F_ARB
+ )
+ {
+ /*crWarning("crPackCheckTexImageInternalFormat FAILED internalformat 0x%x isn't valid", internalformat);*/
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+static GLboolean packspu_CheckTexImageParams(GLint internalformat, GLenum format, GLenum type)
+{
+ return packspu_CheckTexImageFormat(format)
+ && packspu_CheckTexImageType(type)
+ && packspu_CheckTexImageInternalFormat(internalformat);
+}
+
+static GLboolean packspu_CheckTexImageFormatType(GLenum format, GLenum type)
+{
+ return packspu_CheckTexImageFormat(format)
+ && packspu_CheckTexImageType(type);
+}
+
+static const CRPixelPackState _defaultPacking = {
+ 0, /* rowLength */
+ 0, /* skipRows */
+ 0, /* skipPixels */
+ 1, /* alignment */
+ 0, /* imageHeight */
+ 0, /* skipImages */
+ GL_FALSE, /* swapBytes */
+ GL_FALSE, /* psLSBFirst */
+};
+
+#define APPLY_IF_NEQ(state, field, enum) \
+ if (state.field != _defaultPacking.field) \
+ { \
+ crPackPixelStorei(enum, state.field); \
+ }
+
+#define RESTORE_IF_NEQ(state, field, enum) \
+ if (state.field != _defaultPacking.field) \
+ { \
+ crPackPixelStorei(enum, _defaultPacking.field); \
+ }
+
+static void packspu_ApplyUnpackState(void)
+{
+ GET_THREAD(thread);
+ ContextInfo *ctx = thread->currentContext;
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ APPLY_IF_NEQ(clientState->unpack, rowLength, GL_UNPACK_ROW_LENGTH);
+ APPLY_IF_NEQ(clientState->unpack, skipRows, GL_UNPACK_SKIP_ROWS);
+ APPLY_IF_NEQ(clientState->unpack, skipPixels, GL_UNPACK_SKIP_PIXELS);
+ APPLY_IF_NEQ(clientState->unpack, alignment, GL_UNPACK_ALIGNMENT);
+ APPLY_IF_NEQ(clientState->unpack, imageHeight, GL_UNPACK_IMAGE_HEIGHT);
+ APPLY_IF_NEQ(clientState->unpack, skipImages, GL_UNPACK_SKIP_IMAGES);
+ APPLY_IF_NEQ(clientState->unpack, swapBytes, GL_UNPACK_SWAP_BYTES);
+ APPLY_IF_NEQ(clientState->unpack, psLSBFirst, GL_UNPACK_LSB_FIRST);
+}
+
+static void packspu_RestoreUnpackState(void)
+{
+ GET_THREAD(thread);
+ ContextInfo *ctx = thread->currentContext;
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ RESTORE_IF_NEQ(clientState->unpack, rowLength, GL_UNPACK_ROW_LENGTH);
+ RESTORE_IF_NEQ(clientState->unpack, skipRows, GL_UNPACK_SKIP_ROWS);
+ RESTORE_IF_NEQ(clientState->unpack, skipPixels, GL_UNPACK_SKIP_PIXELS);
+ RESTORE_IF_NEQ(clientState->unpack, alignment, GL_UNPACK_ALIGNMENT);
+ RESTORE_IF_NEQ(clientState->unpack, imageHeight, GL_UNPACK_IMAGE_HEIGHT);
+ RESTORE_IF_NEQ(clientState->unpack, skipImages, GL_UNPACK_SKIP_IMAGES);
+ RESTORE_IF_NEQ(clientState->unpack, swapBytes, GL_UNPACK_SWAP_BYTES);
+ RESTORE_IF_NEQ(clientState->unpack, psLSBFirst, GL_UNPACK_LSB_FIRST);
+}
+
+static void packspu_ApplyPackState(void)
+{
+ GET_THREAD(thread);
+ ContextInfo *ctx = thread->currentContext;
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ APPLY_IF_NEQ(clientState->pack, rowLength, GL_PACK_ROW_LENGTH);
+ APPLY_IF_NEQ(clientState->pack, skipRows, GL_PACK_SKIP_ROWS);
+ APPLY_IF_NEQ(clientState->pack, skipPixels, GL_PACK_SKIP_PIXELS);
+ APPLY_IF_NEQ(clientState->pack, alignment, GL_PACK_ALIGNMENT);
+ APPLY_IF_NEQ(clientState->pack, imageHeight, GL_PACK_IMAGE_HEIGHT);
+ APPLY_IF_NEQ(clientState->pack, skipImages, GL_PACK_SKIP_IMAGES);
+ APPLY_IF_NEQ(clientState->pack, swapBytes, GL_PACK_SWAP_BYTES);
+ APPLY_IF_NEQ(clientState->pack, psLSBFirst, GL_PACK_LSB_FIRST);
+}
+
+static void packspu_RestorePackState(void)
+{
+ GET_THREAD(thread);
+ ContextInfo *ctx = thread->currentContext;
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ RESTORE_IF_NEQ(clientState->pack, rowLength, GL_PACK_ROW_LENGTH);
+ RESTORE_IF_NEQ(clientState->pack, skipRows, GL_PACK_SKIP_ROWS);
+ RESTORE_IF_NEQ(clientState->pack, skipPixels, GL_PACK_SKIP_PIXELS);
+ RESTORE_IF_NEQ(clientState->pack, alignment, GL_PACK_ALIGNMENT);
+ RESTORE_IF_NEQ(clientState->pack, imageHeight, GL_PACK_IMAGE_HEIGHT);
+ RESTORE_IF_NEQ(clientState->pack, skipImages, GL_PACK_SKIP_IMAGES);
+ RESTORE_IF_NEQ(clientState->pack, swapBytes, GL_PACK_SWAP_BYTES);
+ RESTORE_IF_NEQ(clientState->pack, psLSBFirst, GL_PACK_LSB_FIRST);
+}
+
+void PACKSPU_APIENTRY packspu_PixelStoref( GLenum pname, GLfloat param )
+{
+ /* NOTE: we do not send pixel store parameters to the server!
+ * When we pack a glDrawPixels or glTexImage2D image we interpret
+ * the user's pixel store parameters at that time and pack the
+ * image in a canonical layout (see util/pixel.c).
+ */
+ crStatePixelStoref( pname, param );
+}
+
+void PACKSPU_APIENTRY packspu_PixelStorei( GLenum pname, GLint param )
+{
+ crStatePixelStorei( pname, param );
+}
+
+void PACKSPU_APIENTRY packspu_DrawPixels( GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels )
+{
+ GET_THREAD(thread);
+ ContextInfo *ctx = thread->currentContext;
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_ApplyUnpackState();
+ }
+
+ crPackDrawPixels( width, height, format, type, pixels, &(clientState->unpack) );
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_RestoreUnpackState();
+ }
+}
+
+void PACKSPU_APIENTRY packspu_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels )
+{
+ GET_THREAD(thread);
+ ContextInfo *ctx = thread->currentContext;
+ CRClientState *clientState = &(ctx->clientState->client);
+ int writeback;
+
+ if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
+ {
+ packspu_ApplyPackState();
+ }
+
+ crPackReadPixels(x, y, width, height, format, type, pixels, &(clientState->pack), &writeback);
+
+ if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
+ {
+ packspu_RestorePackState();
+ }
+
+#ifdef CR_ARB_pixel_buffer_object
+ if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
+#endif
+ {
+ pack_spu.ReadPixels++;
+
+ packspuFlush((void *) thread);
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ }
+}
+
+/** @todo check with pbo's*/
+void PACKSPU_APIENTRY packspu_CopyPixels( GLint x, GLint y, GLsizei width, GLsizei height, GLenum type )
+{
+ GET_THREAD(thread);
+ if (pack_spu.swap)
+ crPackCopyPixelsSWAP( x, y, width, height, type );
+ else
+ crPackCopyPixels( x, y, width, height, type );
+ /* XXX why flush here? */
+ packspuFlush( (void *) thread );
+}
+
+void PACKSPU_APIENTRY packspu_Bitmap( GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap )
+{
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_ApplyUnpackState();
+ }
+
+ crPackBitmap(width, height, xorig, yorig, xmove, ymove, bitmap, &(clientState->unpack));
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_RestoreUnpackState();
+ }
+}
+
+void PACKSPU_APIENTRY packspu_TexImage1D( GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels )
+{
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ if (!packspu_CheckTexImageParams(internalformat, format, type))
+ {
+ if (pixels || crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ crWarning("packspu_TexImage1D invalid internalFormat(%x)/format(%x)/type(%x)", internalformat, format, type);
+ return;
+ }
+ internalformat = packspu_CheckTexImageInternalFormat(internalformat) ? internalformat:GL_RGBA;
+ format = packspu_CheckTexImageFormat(format) ? format:GL_RGBA;
+ type = packspu_CheckTexImageType(type) ? type:GL_UNSIGNED_BYTE;
+ }
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_ApplyUnpackState();
+ }
+
+ if (pack_spu.swap)
+ crPackTexImage1DSWAP( target, level, internalformat, width, border, format, type, pixels, &(clientState->unpack) );
+ else
+ crPackTexImage1D( target, level, internalformat, width, border, format, type, pixels, &(clientState->unpack) );
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_RestoreUnpackState();
+ }
+}
+
+void PACKSPU_APIENTRY packspu_TexImage2D( GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels )
+{
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ if (!packspu_CheckTexImageParams(internalformat, format, type))
+ {
+ if (pixels || crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ crWarning("packspu_TexImage2D invalid internalFormat(%x)/format(%x)/type(%x)", internalformat, format, type);
+ return;
+ }
+ internalformat = packspu_CheckTexImageInternalFormat(internalformat) ? internalformat:GL_RGBA;
+ format = packspu_CheckTexImageFormat(format) ? format:GL_RGBA;
+ type = packspu_CheckTexImageType(type) ? type:GL_UNSIGNED_BYTE;
+ }
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_ApplyUnpackState();
+ }
+
+ if (pack_spu.swap)
+ crPackTexImage2DSWAP( target, level, internalformat, width, height, border, format, type, pixels, &(clientState->unpack) );
+ else
+ crPackTexImage2D( target, level, internalformat, width, height, border, format, type, pixels, &(clientState->unpack) );
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_RestoreUnpackState();
+ }
+}
+
+#ifdef GL_EXT_texture3D
+void PACKSPU_APIENTRY packspu_TexImage3DEXT( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels )
+{
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_ApplyUnpackState();
+ }
+
+ if (pack_spu.swap)
+ crPackTexImage3DEXTSWAP( target, level, internalformat, width, height, depth, border, format, type, pixels, &(clientState->unpack) );
+ else
+ crPackTexImage3DEXT( target, level, internalformat, width, height, depth, border, format, type, pixels, &(clientState->unpack) );
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_RestoreUnpackState();
+ }
+}
+#endif
+
+#ifdef CR_OPENGL_VERSION_1_2
+void PACKSPU_APIENTRY packspu_TexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels )
+{
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_ApplyUnpackState();
+ }
+
+ if (pack_spu.swap)
+ crPackTexImage3DSWAP( target, level, internalformat, width, height, depth, border, format, type, pixels, &(clientState->unpack) );
+ else
+ crPackTexImage3D( target, level, internalformat, width, height, depth, border, format, type, pixels, &(clientState->unpack) );
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_RestoreUnpackState();
+ }
+}
+#endif /* CR_OPENGL_VERSION_1_2 */
+
+void PACKSPU_APIENTRY packspu_TexSubImage1D( GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels )
+{
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ if (!packspu_CheckTexImageFormatType(format, type))
+ {
+ crWarning("packspu_TexSubImage1D invalid format(%x)/type(%x)", format, type);
+ return;
+ }
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_ApplyUnpackState();
+ }
+
+ if (pack_spu.swap)
+ crPackTexSubImage1DSWAP( target, level, xoffset, width, format, type, pixels, &(clientState->unpack) );
+ else
+ crPackTexSubImage1D( target, level, xoffset, width, format, type, pixels, &(clientState->unpack) );
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_RestoreUnpackState();
+ }
+}
+
+void PACKSPU_APIENTRY packspu_TexSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels )
+{
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ if (!packspu_CheckTexImageFormatType(format, type))
+ {
+ crWarning("packspu_TexSubImage2D invalid format(%x)/type(%x)", format, type);
+ return;
+ }
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_ApplyUnpackState();
+ }
+
+ if (pack_spu.swap)
+ crPackTexSubImage2DSWAP( target, level, xoffset, yoffset, width, height, format, type, pixels, &(clientState->unpack) );
+ else
+ crPackTexSubImage2D( target, level, xoffset, yoffset, width, height, format, type, pixels, &(clientState->unpack) );
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_RestoreUnpackState();
+ }
+}
+
+#ifdef CR_OPENGL_VERSION_1_2
+void PACKSPU_APIENTRY packspu_TexSubImage3D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels )
+{
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_ApplyUnpackState();
+ }
+
+ if (pack_spu.swap)
+ crPackTexSubImage3DSWAP( target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels, &(clientState->unpack) );
+ else
+ crPackTexSubImage3D( target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels, &(clientState->unpack) );
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_RestoreUnpackState();
+ }
+}
+#endif /* CR_OPENGL_VERSION_1_2 */
+
+void PACKSPU_APIENTRY packspu_ZPixCR( GLsizei width, GLsizei height, GLenum format, GLenum type, GLenum ztype, GLint zparm, GLint length, const GLvoid *pixels )
+{
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+ if (pack_spu.swap)
+ crPackZPixCRSWAP( width, height, format, type, ztype, zparm, length, pixels, &(clientState->unpack) );
+ else
+ crPackZPixCR( width, height, format, type, ztype, zparm, length, pixels, &(clientState->unpack) );
+}
+
+void PACKSPU_APIENTRY packspu_GetTexImage (GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels)
+{
+ GET_THREAD(thread);
+ ContextInfo *ctx = thread->currentContext;
+ CRClientState *clientState = &(ctx->clientState->client);
+ int writeback = 1;
+
+ /* XXX note: we're not observing the pixel pack parameters here unless PACK PBO is bound
+ * To do so, we'd have to allocate a temporary image buffer (how large???)
+ * and copy the image to the user's buffer using the pixel pack params.
+ */
+
+ if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
+ {
+ packspu_ApplyPackState();
+ }
+
+ if (pack_spu.swap)
+ crPackGetTexImageSWAP( target, level, format, type, pixels, &(clientState->pack), &writeback );
+ else
+ crPackGetTexImage( target, level, format, type, pixels, &(clientState->pack), &writeback );
+
+ if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
+ {
+ packspu_RestorePackState();
+ }
+
+#ifdef CR_ARB_pixel_buffer_object
+ if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
+#endif
+ {
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ }
+}
+
+void PACKSPU_APIENTRY packspu_GetCompressedTexImageARB( GLenum target, GLint level, GLvoid * img )
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+
+ if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
+ {
+ packspu_ApplyPackState();
+ }
+
+ if (pack_spu.swap)
+ {
+ crPackGetCompressedTexImageARBSWAP( target, level, img, &writeback );
+ }
+ else
+ {
+ crPackGetCompressedTexImageARB( target, level, img, &writeback );
+ }
+
+ if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
+ {
+ packspu_RestorePackState();
+ }
+
+#ifdef CR_ARB_pixel_buffer_object
+ if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
+#endif
+ {
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ }
+}
+
+void PACKSPU_APIENTRY
+packspu_CompressedTexImage1DARB(GLenum target, GLint level, GLenum internalformat, GLsizei width,
+ GLint border, GLsizei imagesize, const GLvoid *data)
+{
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_ApplyUnpackState();
+ }
+
+ crPackCompressedTexImage1DARB(target, level, internalformat, width, border, imagesize, data);
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_RestoreUnpackState();
+ }
+}
+
+void PACKSPU_APIENTRY
+packspu_CompressedTexImage2DARB(GLenum target, GLint level, GLenum internalformat, GLsizei width,
+ GLsizei height, GLint border, GLsizei imagesize, const GLvoid *data)
+{
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_ApplyUnpackState();
+ }
+
+ crPackCompressedTexImage2DARB(target, level, internalformat, width, height, border, imagesize, data);
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_RestoreUnpackState();
+ }
+}
+
+void PACKSPU_APIENTRY
+packspu_CompressedTexImage3DARB(GLenum target, GLint level, GLenum internalformat, GLsizei width,
+ GLsizei height, GLsizei depth, GLint border, GLsizei imagesize, const GLvoid *data)
+{
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_ApplyUnpackState();
+ }
+
+ crPackCompressedTexImage3DARB(target, level, internalformat, width, height, depth, border, imagesize, data);
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_RestoreUnpackState();
+ }
+}
+
+void PACKSPU_APIENTRY
+packspu_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, GLsizei width,
+ GLenum format, GLsizei imagesize, const GLvoid *data)
+{
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_ApplyUnpackState();
+ }
+
+ crPackCompressedTexSubImage1DARB(target, level, xoffset, width, format, imagesize, data);
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_RestoreUnpackState();
+ }
+}
+
+void PACKSPU_APIENTRY
+packspu_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height, GLenum format, GLsizei imagesize, const GLvoid *data)
+{
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_ApplyUnpackState();
+ }
+
+ crPackCompressedTexSubImage2DARB(target, level, xoffset, yoffset, width, height, format, imagesize, data);
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_RestoreUnpackState();
+ }
+}
+
+void PACKSPU_APIENTRY
+packspu_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format,
+ GLsizei imagesize, const GLvoid *data)
+{
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_ApplyUnpackState();
+ }
+
+ crPackCompressedTexSubImage3DARB(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imagesize, data);
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_RestoreUnpackState();
+ }
+}
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_proto.py b/src/VBox/Additions/common/crOpenGL/pack/packspu_proto.py
new file mode 100755
index 00000000..5feed9a9
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_proto.py
@@ -0,0 +1,50 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+from __future__ import print_function
+import sys
+
+import apiutil
+
+apiutil.CopyrightC()
+
+print("""
+/* DO NOT EDIT - THIS FILE AUTOMATICALLY GENERATED BY packspu_proto.py SCRIPT */
+
+#ifndef PACKSPU_FUNCTIONS_H
+#define PACKSPU_FUNCTIONS_H 1
+
+#include <stdio.h>
+#include "cr_string.h"
+#include "cr_spu.h"
+#include "packspu.h"
+#include "cr_packfunctions.h"
+""")
+
+
+pack_specials = []
+
+keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
+
+# make list of special functions
+for func_name in keys:
+ if ("get" in apiutil.Properties(func_name) or
+ apiutil.FindSpecial( "packspu", func_name ) or
+ apiutil.FindSpecial( "packspu_flush", func_name ) or
+ apiutil.FindSpecial( "packspu_vertex", func_name )):
+ pack_specials.append( func_name )
+
+for func_name in keys:
+ if apiutil.FindSpecial( "packspu_unimplemented", func_name ):
+ continue
+ if func_name in pack_specials:
+ return_type = apiutil.ReturnType(func_name)
+ params = apiutil.Parameters(func_name)
+ print('extern %s PACKSPU_APIENTRY packspu_%s(%s);' % ( return_type, func_name, apiutil.MakeDeclarationString(params) ))
+
+
+print("""
+#endif
+""")
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_special b/src/VBox/Additions/common/crOpenGL/pack/packspu_special
new file mode 100644
index 00000000..13c3e0a2
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_special
@@ -0,0 +1,138 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+AreTexturesResident
+AreProgramsResidentNV
+GetString
+GetTexImage
+EnableClientState
+DisableClientState
+Enable
+Disable
+ClientActiveTextureARB
+ColorPointer
+FogCoordPointerEXT
+SecondaryColorPointerEXT
+VertexAttribPointerARB
+VertexAttribPointerNV
+GetPointerv
+VertexPointer
+NormalPointer
+TexCoordPointer
+EdgeFlagPointer
+IndexPointer
+ArrayElement
+DrawArrays
+DrawElements
+DrawRangeElements
+InterleavedArrays
+ReadPixels
+DrawPixels
+CopyPixels
+Bitmap
+SwapBuffers
+Flush
+Finish
+PixelStorei
+PixelStoref
+PushClientAttrib
+PopClientAttrib
+CreateContext
+WindowCreate
+MakeCurrent
+DestroyContext
+Begin
+End
+TexImage1D
+TexSubImage1D
+TexImage2D
+TexSubImage2D
+TexImage3D
+TexImage3DEXT
+TexSubImage3D
+ChromiumParametervCR
+MultiDrawArraysEXT
+MultiDrawElementsEXT
+GetBufferPointervARB
+GetBufferParameterivARB
+MapBufferARB
+UnmapBufferARB
+BindBufferARB
+BufferDataARB
+ZPixCR
+ActiveTextureARB
+DrawBuffer
+Flush
+GetActiveAttrib
+GetActiveUniform
+GetAttachedShaders
+GetShaderInfoLog
+GetProgramInfoLog
+GetShaderSource
+GetAttachedObjectsARB
+GetInfoLogARB
+BufferSubDataARB
+EnableVertexAttribArrayARB
+DisableVertexAttribArrayARB
+GetBufferSubDataARB
+IsEnabled
+LockArraysEXT
+UnlockArraysEXT
+CreateProgram
+LinkProgram
+DeleteProgram
+GetUniformLocation
+GetAttribLocation
+GetUniformsLocations
+GetAttribsLocations
+BindFramebufferEXT
+DeleteObjectARB
+BindFramebufferEXT
+DeleteFramebuffersEXT
+FramebufferTexture1DEXT
+FramebufferTexture2DEXT
+FramebufferTexture3DEXT
+FramebufferRenderbufferEXT
+CheckFramebufferStatusEXT
+BindTexture
+DeleteTextures
+GetPolygonStipple
+GetPixelMapfv
+GetPixelMapuiv
+GetPixelMapusv
+GetCompressedTexImageARB
+BindRenderbufferEXT
+VBoxPackSetInjectThread
+VBoxPackGetInjectID
+VBoxPackSetInjectID
+VBoxAttachThread
+VBoxDetachThread
+VBoxCreateContext
+VBoxConChromiumParameteriCR
+VBoxConChromiumParametervCR
+VBoxWindowCreate
+VBoxWindowDestroy
+VBoxConCreate
+VBoxConDestroy
+VBoxConFlush
+VBoxPresentComposition
+ChromiumParameteriCR
+CompressedTexImage1DARB
+CompressedTexImage2DARB
+CompressedTexImage3DARB
+CompressedTexSubImage1DARB
+CompressedTexSubImage2DARB
+CompressedTexSubImage3DARB
+GenFramebuffersEXT
+GenRenderbuffersEXT
+DeleteFramebuffersEXT
+DeleteRenderbuffersEXT
+GenBuffersARB
+DeleteBuffersARB
+StringMarkerGREMEDY
+GenTextures
+CompileShader
+NewList
+EndList
+GetError
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_swapbuf.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_swapbuf.c
new file mode 100644
index 00000000..bc1895fe
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_swapbuf.c
@@ -0,0 +1,102 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include "cr_packfunctions.h"
+#include "cr_error.h"
+#include "cr_net.h"
+#include "packspu.h"
+#include "packspu_proto.h"
+
+#if 0
+
+void PACKSPU_APIENTRY packspu_SwapBuffers( GLint window, GLint flags )
+{
+ GET_THREAD(thread);
+ if (pack_spu.swap)
+ {
+ crPackSwapBuffersSWAP( window, flags );
+ }
+ else
+ {
+ crPackSwapBuffers( window, flags );
+ }
+ packspuFlush( (void *) thread );
+}
+
+
+#else
+
+void PACKSPU_APIENTRY packspu_SwapBuffers( GLint window, GLint flags )
+{
+ GET_THREAD(thread);
+
+ if (pack_spu.swap)
+ {
+ crPackSwapBuffersSWAP( window, flags );
+ }
+ else
+ {
+ crPackSwapBuffers( window, flags );
+ }
+ packspuFlush( (void *) thread );
+
+ if (!(thread->netServer.conn->actual_network))
+ {
+ /* no synchronization needed */
+ return;
+ }
+
+ if (pack_spu.swapbuffer_sync) {
+ /* This won't block unless there has been more than 1 frame
+ * since we received a writeback acknowledgement. In the
+ * normal case there's no performance penalty for doing this
+ * (beyond the cost of packing the writeback request into the
+ * stream and receiving the reply), but it eliminates the
+ * problem of runaway rendering that can occur, eg when
+ * rendering frames consisting of a single large display list
+ * in a tight loop.
+ *
+ * Note that this is *not* the same as doing a sync after each
+ * swapbuffers, which would force a round-trip 'bubble' into
+ * the network stream under normal conditions.
+ *
+ * This is complicated because writeback in the pack spu is
+ * overridden to always set the value to zero when the
+ * reply is received, rather than decrementing it:
+ */
+ switch( thread->writeback ) {
+ case 0:
+ /* Request writeback.
+ */
+ thread->writeback = 1;
+ if (pack_spu.swap)
+ {
+ crPackWritebackSWAP( (GLint *) &thread->writeback );
+ }
+ else
+ {
+ crPackWriteback( (GLint *) &thread->writeback );
+ }
+ break;
+ case 1:
+ /* Make sure writeback from previous frame has been received.
+ */
+ CRPACKSPU_WRITEBACK_WAIT(thread, thread->writeback);
+ break;
+ }
+ }
+
+ /* want to emit a parameter here */
+ if (pack_spu.emit_GATHER_POST_SWAPBUFFERS)
+ {
+ if (pack_spu.swap)
+ crPackChromiumParameteriCRSWAP(GL_GATHER_POST_SWAPBUFFERS_CR, 1);
+ else
+ crPackChromiumParameteriCR(GL_GATHER_POST_SWAPBUFFERS_CR, 1);
+ }
+}
+
+#endif
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_texture.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_texture.c
new file mode 100644
index 00000000..5057bcb3
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_texture.c
@@ -0,0 +1,70 @@
+/* $Id: packspu_texture.c $ */
+
+/** @file
+ * VBox OpenGL DRI driver functions
+ */
+
+/*
+ * Copyright (C) 2009-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include "packspu.h"
+#include "cr_packfunctions.h"
+#include "cr_glstate.h"
+#include "packspu_proto.h"
+
+void PACKSPU_APIENTRY packspu_ActiveTextureARB(GLenum texture)
+{
+ crStateActiveTextureARB(texture);
+ crPackActiveTextureARB(texture);
+}
+
+void PACKSPU_APIENTRY packspu_BindTexture(GLenum target, GLuint texture)
+{
+ crStateBindTexture(target, texture);
+ crPackBindTexture(target, texture);
+}
+
+void PACKSPU_APIENTRY packspu_DeleteTextures(GLsizei n, const GLuint * textures)
+{
+ crStateDeleteTextures(n, textures);
+ crPackDeleteTextures(n, textures);
+}
+
+void PACKSPU_APIENTRY packspu_GenTextures( GLsizei n, GLuint * textures )
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ unsigned int i;
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI() && !(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))
+ {
+ crError( "packspu_GenTextures doesn't work when there's no actual network involved!\nTry using the simplequery SPU in your chain!" );
+ }
+ if (pack_spu.swap)
+ {
+ crPackGenTexturesSWAP( n, textures, &writeback );
+ }
+ else
+ {
+ crPackGenTextures( n, textures, &writeback );
+ }
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ if (pack_spu.swap)
+ {
+ for (i = 0 ; i < (unsigned int) n ; i++)
+ {
+ textures[i] = SWAP32(textures[i]);
+ }
+ }
+
+ crStateRegTextures(n, textures);
+}
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_unimplemented_special b/src/VBox/Additions/common/crOpenGL/pack/packspu_unimplemented_special
new file mode 100644
index 00000000..f71300c9
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_unimplemented_special
@@ -0,0 +1,4 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_vertex_special b/src/VBox/Additions/common/crOpenGL/pack/packspu_vertex_special
new file mode 100644
index 00000000..bbbc13d0
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_vertex_special
@@ -0,0 +1,28 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+Vertex2d
+Vertex2dv
+Vertex2f
+Vertex2fv
+Vertex2i
+Vertex2iv
+Vertex2s
+Vertex2sv
+Vertex3d
+Vertex3dv
+Vertex3f
+Vertex3fv
+Vertex3i
+Vertex3iv
+Vertex3s
+Vertex3sv
+Vertex4d
+Vertex4dv
+Vertex4f
+Vertex4fv
+Vertex4i
+Vertex4iv
+Vertex4s
+Vertex4sv