/* Copyright (c) 2001, Stanford University * All rights reserved. * * See the file LICENSE.txt for information on redistributing this software. */ #ifndef CR_PROTOCOL_H #define CR_PROTOCOL_H #include #include #ifdef DEBUG_misha #include "cr_error.h" #endif #ifdef __cplusplus extern "C" { #endif #define CR_CMDVBVA_VERSION 1 #pragma pack(1) typedef struct CR_CAPS_INFO { uint32_t u32Caps; uint32_t u32CmdVbvaVersion; } CR_CAPS_INFO; #pragma pack() /*For now guest is allowed to connect host opengl service if protocol version matches exactly*/ /*Note: that after any change to this file, or glapi_parser\apispec.txt version should be changed*/ #define CR_PROTOCOL_VERSION_MAJOR 9 #define CR_PROTOCOL_VERSION_MINOR 1 /* new TexPresent mechanism is available */ #define CR_VBOX_CAP_TEX_PRESENT 0x00000001 /* vbva command submission mechanism supported */ #define CR_VBOX_CAP_CMDVBVA 0x00000002 /* host supports Command Blocks, i.e. CR_CMDBLOCKBEGIN_OPCODE and CR_CMDBLOCKEND_OPCODE opcodes. * Command Block can be used by guest to prevent clients from blocking each other. * The Command Block allows multiple command buffers to be processed with one run. * Command Block commands have to obey to the following rules: * CR_CMDBLOCKBEGIN_OPCODE - must be the first command in the command buffer, specifying the command block start * CR_CMDBLOCKEND_OPCODE - must be the last command in the command buffer, specifying the command block end * If not placed accordingly, CR_CMDBLOCK** commands are ignored. * Server copies the command block buffer commands to its internal storage * and processes them with one run when the command block end is signalled */ #define CR_VBOX_CAP_CMDBLOCKS 0x00000004 /* GetAttribsLocations support */ #define CR_VBOX_CAP_GETATTRIBSLOCATIONS 0x00000008 /* flush command blocks for execution */ #define CR_VBOX_CAP_CMDBLOCKS_FLUSH 0x00000010 /* Notify guest if host reports minimal OpenGL capabilities. */ #define CR_VBOX_CAP_HOST_CAPS_NOT_SUFFICIENT 0x00000020 #define CR_VBOX_CAPS_ALL 0x0000003f #define CR_PRESENT_SCREEN_MASK 0xffff #define CR_PRESENT_FLAGS_OFFSET 16 #define CR_PRESENT_FLAGS_MASK 0xffff0000 #define CR_PRESENT_DEFINE_FLAG(_f) (1 << (CR_PRESENT_FLAGS_OFFSET + _f)) #define CR_PRESENT_FLAG_CLEAR_RECTS CR_PRESENT_DEFINE_FLAG(0) #define CR_PRESENT_FLAG_TEX_NONINVERT_YCOORD CR_PRESENT_DEFINE_FLAG(1) #define CR_PRESENT_GET_SCREEN(_cfg) ((_cfg) & CR_PRESENT_SCREEN_MASK) #define CR_PRESENT_GET_FLAGS(_cfg) ((_cfg) & CR_PRESENT_FLAGS_MASK) typedef enum { /* first message types is 'wGL\001', so we can immediately recognize bad message types */ CR_MESSAGE_OPCODES = 0x77474c01, CR_MESSAGE_WRITEBACK, CR_MESSAGE_READBACK, CR_MESSAGE_READ_PIXELS, CR_MESSAGE_MULTI_BODY, CR_MESSAGE_MULTI_TAIL, CR_MESSAGE_FLOW_CONTROL, CR_MESSAGE_OOB, CR_MESSAGE_NEWCLIENT, CR_MESSAGE_GATHER, CR_MESSAGE_ERROR, CR_MESSAGE_CRUT, CR_MESSAGE_REDIR_PTR } CRMessageType; typedef union { /* pointers are usually 4 bytes, but on 64-bit machines (Alpha, * SGI-n64, etc.) they are 8 bytes. Pass network pointers around * as an opaque array of bytes, since the interpretation & size of * the pointer only matter to the machine which emitted the * pointer (and will eventually receive the pointer back again) */ unsigned int ptrAlign[2]; unsigned char ptrSize[8]; /* hack to make this packet big */ /* unsigned int junk[512]; */ } CRNetworkPointer; #if 0 /*def DEBUG_misha*/ #define CRDBGPTR_SETZ(_p) crMemset((_p), 0, sizeof (CRNetworkPointer)) #define CRDBGPTR_CHECKZ(_p) do { \ CRNetworkPointer _ptr = {0}; \ CRASSERT(!crMemcmp((_p), &_ptr, sizeof (CRNetworkPointer))); \ } while (0) #define CRDBGPTR_CHECKNZ(_p) do { \ CRNetworkPointer _ptr = {0}; \ CRASSERT(crMemcmp((_p), &_ptr, sizeof (CRNetworkPointer))); \ } while (0) # if 0 # define _CRDBGPTR_PRINT(_tStr, _id, _p) do { \ crDebug(_tStr "%d:0x%08x%08x", (_id), (_p)->ptrAlign[1], (_p)->ptrAlign[0]); \ } while (0) # else # define _CRDBGPTR_PRINT(_tStr, _id, _p) do { } while (0) # endif #define CRDBGPTR_PRINTWB(_id, _p) _CRDBGPTR_PRINT("wbptr:", _id, _p) #define CRDBGPTR_PRINTRB(_id, _p) _CRDBGPTR_PRINT("rbptr:", _id, _p) #else #define CRDBGPTR_SETZ(_p) do { } while (0) #define CRDBGPTR_CHECKZ(_p) do { } while (0) #define CRDBGPTR_CHECKNZ(_p) do { } while (0) #define CRDBGPTR_PRINTWB(_id, _p) do { } while (0) #define CRDBGPTR_PRINTRB(_id, _p) do { } while (0) #endif #ifdef VBOX_WITH_CRHGSMI typedef struct CRVBOXHGSMI_CMDDATA { union { struct VBOXVDMACMD_CHROMIUM_CMD *pHgsmiCmd; struct VBOXCMDVBVA_CRCMD_CMD *pVbvaCmd; const void *pvCmd; }; int *pCmdRc; char *pWriteback; unsigned int *pcbWriteback; unsigned int cbWriteback; bool fHgsmiCmd; } CRVBOXHGSMI_CMDDATA, *PCRVBOXHGSMI_CMDDATA; #ifdef DEBUG # define CRVBOXHGSMI_CMDDATA_ASSERT_CONSISTENT(_pData) do { \ CRASSERT(!(_pData)->pvCmd == !(_pData)->pCmdRc); \ CRASSERT(!(_pData)->pWriteback == !(_pData)->pcbWriteback); \ CRASSERT(!(_pData)->pWriteback == !(_pData)->cbWriteback); \ if ((_pData)->pWriteback) \ { \ CRASSERT((_pData)->pvCmd); \ } \ } while (0) # define CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(_pData) do { \ CRASSERT(!(_pData)->pvCmd); \ CRASSERT(!(_pData)->pCmdRc); \ CRASSERT(!(_pData)->pWriteback); \ CRASSERT(!(_pData)->pcbWriteback); \ CRASSERT(!(_pData)->cbWriteback); \ } while (0) # define CRVBOXHGSMI_CMDDATA_ASSERT_ISSET(_pData) do { \ CRVBOXHGSMI_CMDDATA_ASSERT_CONSISTENT(_pData); \ CRASSERT(CRVBOXHGSMI_CMDDATA_IS_SET(_pData)); \ } while (0) # define CRVBOXHGSMI_CMDDATA_ASSERT_ISSETWB(_pData) do { \ CRVBOXHGSMI_CMDDATA_ASSERT_CONSISTENT(_pData); \ CRASSERT(CRVBOXHGSMI_CMDDATA_IS_SETWB(_pData)); \ } while (0) #else # define CRVBOXHGSMI_CMDDATA_ASSERT_CONSISTENT(_pData) do { } while (0) # define CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(_pData) do { } while (0) # define CRVBOXHGSMI_CMDDATA_ASSERT_ISSET(_pData) do { } while (0) # define CRVBOXHGSMI_CMDDATA_ASSERT_ISSETWB(_pData) do { } while (0) #endif #define CRVBOXHGSMI_CMDDATA_IS_HGSMICMD(_pData) (!!(_pData)->fHgsmiCmd) #define CRVBOXHGSMI_CMDDATA_IS_SET(_pData) (!!(_pData)->pvCmd) #define CRVBOXHGSMI_CMDDATA_IS_SETWB(_pData) (!!(_pData)->pWriteback) #define CRVBOXHGSMI_CMDDATA_CLEANUP(_pData) do { \ crMemset(_pData, 0, sizeof (CRVBOXHGSMI_CMDDATA)); \ CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(_pData); \ CRVBOXHGSMI_CMDDATA_ASSERT_CONSISTENT(_pData); \ } while (0) #define CRVBOXHGSMI_CMDDATA_SET(_pData, _pCmd, _pHdr, _fHgsmiCmd) do { \ CRVBOXHGSMI_CMDDATA_ASSERT_CLEANED(_pData); \ (_pData)->pvCmd = (_pCmd); \ (_pData)->pCmdRc = &(_pHdr)->result; \ (_pData)->fHgsmiCmd = (_fHgsmiCmd); \ CRVBOXHGSMI_CMDDATA_ASSERT_CONSISTENT(_pData); \ } while (0) #define CRVBOXHGSMI_CMDDATA_SETWB(_pData, _pCmd, _pHdr, _pWb, _cbWb, _pcbWb, _fHgsmiCmd) do { \ CRVBOXHGSMI_CMDDATA_SET(_pData, _pCmd, _pHdr, _fHgsmiCmd); \ (_pData)->pWriteback = (_pWb); \ (_pData)->pcbWriteback = (_pcbWb); \ (_pData)->cbWriteback = (_cbWb); \ CRVBOXHGSMI_CMDDATA_ASSERT_CONSISTENT(_pData); \ } while (0) #define CRVBOXHGSMI_CMDDATA_RC(_pData, _rc) do { \ *(_pData)->pCmdRc = (_rc); \ } while (0) #endif typedef struct { CRMessageType type; unsigned int conn_id; } CRMessageHeader; typedef struct CRMessageOpcodes { CRMessageHeader header; unsigned int numOpcodes; } CRMessageOpcodes; typedef struct CRMessageRedirPtr { CRMessageHeader header; CRMessageHeader* pMessage; #ifdef VBOX_WITH_CRHGSMI CRVBOXHGSMI_CMDDATA CmdData; #endif } CRMessageRedirPtr; typedef struct CRMessageWriteback { CRMessageHeader header; CRNetworkPointer writeback_ptr; } CRMessageWriteback; typedef struct CRMessageReadback { CRMessageHeader header; CRNetworkPointer writeback_ptr; CRNetworkPointer readback_ptr; } CRMessageReadback; typedef struct CRMessageMulti { CRMessageHeader header; } CRMessageMulti; typedef struct CRMessageFlowControl { CRMessageHeader header; unsigned int credits; } CRMessageFlowControl; typedef struct CRMessageReadPixels { CRMessageHeader header; int width, height; unsigned int bytes_per_row; unsigned int stride; int alignment; int skipRows; int skipPixels; int rowLength; int format; int type; CRNetworkPointer pixels; } CRMessageReadPixels; typedef struct CRMessageNewClient { CRMessageHeader header; } CRMessageNewClient; typedef struct CRMessageGather { CRMessageHeader header; unsigned long offset; unsigned long len; } CRMessageGather; typedef union { CRMessageHeader header; CRMessageOpcodes opcodes; CRMessageRedirPtr redirptr; CRMessageWriteback writeback; CRMessageReadback readback; CRMessageReadPixels readPixels; CRMessageMulti multi; CRMessageFlowControl flowControl; CRMessageNewClient newclient; CRMessageGather gather; } CRMessage; DECLEXPORT(void) crNetworkPointerWrite( CRNetworkPointer *dst, void *src ); #ifdef __cplusplus } #endif #endif /* CR_PROTOCOL_H */