From f8fe689a81f906d1b91bb3220acde2a4ecb14c5b Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 6 May 2024 05:01:46 +0200 Subject: Adding upstream version 6.0.4-dfsg. Signed-off-by: Daniel Baumann --- .../Additions/common/crOpenGL/pack/Makefile.kup | 0 src/VBox/Additions/common/crOpenGL/pack/pack.def | 6 + src/VBox/Additions/common/crOpenGL/pack/pack.py | 57 ++ src/VBox/Additions/common/crOpenGL/pack/packspu.h | 185 +++++ src/VBox/Additions/common/crOpenGL/pack/packspu.rc | 69 ++ .../common/crOpenGL/pack/packspu_beginend.py | 177 ++++ .../common/crOpenGL/pack/packspu_bufferobject.c | 160 ++++ .../common/crOpenGL/pack/packspu_client.c | 910 +++++++++++++++++++++ .../common/crOpenGL/pack/packspu_config.c | 60 ++ .../common/crOpenGL/pack/packspu_context.c | 617 ++++++++++++++ .../common/crOpenGL/pack/packspu_flush.py | 42 + .../common/crOpenGL/pack/packspu_flush_special | 9 + .../common/crOpenGL/pack/packspu_framebuffer.c | 143 ++++ .../Additions/common/crOpenGL/pack/packspu_get.py | 250 ++++++ .../common/crOpenGL/pack/packspu_getshaders.c | 214 +++++ .../common/crOpenGL/pack/packspu_getstring.c | 211 +++++ .../Additions/common/crOpenGL/pack/packspu_glsl.c | 275 +++++++ .../Additions/common/crOpenGL/pack/packspu_init.c | 152 ++++ .../Additions/common/crOpenGL/pack/packspu_misc.c | 856 +++++++++++++++++++ .../Additions/common/crOpenGL/pack/packspu_net.c | 284 +++++++ .../Additions/common/crOpenGL/pack/packspu_pixel.c | 727 ++++++++++++++++ .../common/crOpenGL/pack/packspu_proto.py | 50 ++ .../Additions/common/crOpenGL/pack/packspu_special | 138 ++++ .../common/crOpenGL/pack/packspu_swapbuf.c | 102 +++ .../common/crOpenGL/pack/packspu_texture.c | 70 ++ .../crOpenGL/pack/packspu_unimplemented_special | 4 + .../common/crOpenGL/pack/packspu_vertex_special | 28 + 27 files changed, 5796 insertions(+) create mode 100644 src/VBox/Additions/common/crOpenGL/pack/Makefile.kup create mode 100644 src/VBox/Additions/common/crOpenGL/pack/pack.def create mode 100755 src/VBox/Additions/common/crOpenGL/pack/pack.py create mode 100644 src/VBox/Additions/common/crOpenGL/pack/packspu.h create mode 100644 src/VBox/Additions/common/crOpenGL/pack/packspu.rc create mode 100755 src/VBox/Additions/common/crOpenGL/pack/packspu_beginend.py create mode 100644 src/VBox/Additions/common/crOpenGL/pack/packspu_bufferobject.c create mode 100644 src/VBox/Additions/common/crOpenGL/pack/packspu_client.c create mode 100644 src/VBox/Additions/common/crOpenGL/pack/packspu_config.c create mode 100644 src/VBox/Additions/common/crOpenGL/pack/packspu_context.c create mode 100755 src/VBox/Additions/common/crOpenGL/pack/packspu_flush.py create mode 100644 src/VBox/Additions/common/crOpenGL/pack/packspu_flush_special create mode 100644 src/VBox/Additions/common/crOpenGL/pack/packspu_framebuffer.c create mode 100755 src/VBox/Additions/common/crOpenGL/pack/packspu_get.py create mode 100644 src/VBox/Additions/common/crOpenGL/pack/packspu_getshaders.c create mode 100644 src/VBox/Additions/common/crOpenGL/pack/packspu_getstring.c create mode 100644 src/VBox/Additions/common/crOpenGL/pack/packspu_glsl.c create mode 100644 src/VBox/Additions/common/crOpenGL/pack/packspu_init.c create mode 100644 src/VBox/Additions/common/crOpenGL/pack/packspu_misc.c create mode 100644 src/VBox/Additions/common/crOpenGL/pack/packspu_net.c create mode 100644 src/VBox/Additions/common/crOpenGL/pack/packspu_pixel.c create mode 100755 src/VBox/Additions/common/crOpenGL/pack/packspu_proto.py create mode 100644 src/VBox/Additions/common/crOpenGL/pack/packspu_special create mode 100644 src/VBox/Additions/common/crOpenGL/pack/packspu_swapbuf.c create mode 100644 src/VBox/Additions/common/crOpenGL/pack/packspu_texture.c create mode 100644 src/VBox/Additions/common/crOpenGL/pack/packspu_unimplemented_special create mode 100644 src/VBox/Additions/common/crOpenGL/pack/packspu_vertex_special (limited to 'src/VBox/Additions/common/crOpenGL/pack') 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 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 +#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 +#include + +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; imax) max = pIdx[i]; + } + break; + } + case GL_UNSIGNED_SHORT: + { + GLushort *pIdx = (GLushort *)indices; + min = max = pIdx[0]; + for (i=0; imax) max = pIdx[i]; + } + break; + } + case GL_UNSIGNED_INT: + { + GLuint *pIdx = (GLuint *)indices; + min = max = pIdx[0]; + for (i=0; imax) 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 + +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; iinUse = 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; ipacker == 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 -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 + +/** @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 + +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 + +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 +# include +#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; iserver.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; icurrentBuffer) + { + 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.numThreadsinUse = 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; iid==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; iid==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; icurrentThread == thread) + { + CRASSERT(ctx->fAutoFlush); + ctx->currentThread = NULL; + } + } + + crUnlockMutex(&_PackMutex); + } + } + + crStateVBoxDetachThread(); +} + +#ifdef WINDOWS +#define WIN32_LEAN_AND_MEAN +#include +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 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 +#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 -- cgit v1.2.3