summaryrefslogtreecommitdiff
path: root/src/VBox/GuestHost/OpenGL/include/cr_protocol.h
blob: 1bf785ba3d250019013e77b463909f537104920f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
/* 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 <iprt/types.h>
#include <iprt/cdefs.h>
#ifdef DEBUG_misha
#include "cr_error.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif

/*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


#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;
        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 */