VirtualBox

source: vbox/trunk/src/VBox/Additions/common/crOpenGL/pack/packspu_client.c@ 34805

Last change on this file since 34805 was 33549, checked in by vboxsync, 15 years ago

crOpenGL/wddm: avoid unrolling drawprimitive calls when possible

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 17.6 KB
Line 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#include "packspu.h"
8#include "cr_packfunctions.h"
9#include "cr_glstate.h"
10#include "packspu_proto.h"
11
12void PACKSPU_APIENTRY packspu_FogCoordPointerEXT( GLenum type, GLsizei stride, const GLvoid *pointer )
13{
14#if CR_ARB_vertex_buffer_object
15 GET_CONTEXT(ctx);
16 if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
17 if (pack_spu.swap)
18 crPackFogCoordPointerEXTSWAP( type, stride, pointer );
19 else
20 crPackFogCoordPointerEXT( type, stride, pointer );
21 }
22#endif
23 crStateFogCoordPointerEXT( type, stride, pointer );
24}
25
26void PACKSPU_APIENTRY packspu_ColorPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer )
27{
28#if CR_ARB_vertex_buffer_object
29 GET_CONTEXT(ctx);
30 if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
31 if (pack_spu.swap)
32 crPackColorPointerSWAP( size, type, stride, pointer );
33 else
34 crPackColorPointer( size, type, stride, pointer );
35 }
36#endif
37 crStateColorPointer( size, type, stride, pointer );
38}
39
40void PACKSPU_APIENTRY packspu_SecondaryColorPointerEXT( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer )
41{
42#if CR_ARB_vertex_buffer_object
43 GET_CONTEXT(ctx);
44 if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
45 if (pack_spu.swap)
46 crPackSecondaryColorPointerEXTSWAP( size, type, stride, pointer );
47 else
48 crPackSecondaryColorPointerEXT( size, type, stride, pointer );
49 }
50#endif
51 crStateSecondaryColorPointerEXT( size, type, stride, pointer );
52}
53
54void PACKSPU_APIENTRY packspu_VertexPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer )
55{
56#if CR_ARB_vertex_buffer_object
57 GET_CONTEXT(ctx);
58 CRASSERT(ctx->clientState->extensions.ARB_vertex_buffer_object);
59 if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
60 if (pack_spu.swap)
61 crPackVertexPointerSWAP( size, type, stride, pointer );
62 else
63 crPackVertexPointer( size, type, stride, pointer );
64 }
65#endif
66 crStateVertexPointer( size, type, stride, pointer );
67}
68
69void PACKSPU_APIENTRY packspu_TexCoordPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer )
70{
71#if CR_ARB_vertex_buffer_object
72 GET_CONTEXT(ctx);
73 if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
74 if (pack_spu.swap)
75 crPackTexCoordPointerSWAP( size, type, stride, pointer );
76 else
77 crPackTexCoordPointer( size, type, stride, pointer );
78 }
79#endif
80 crStateTexCoordPointer( size, type, stride, pointer );
81}
82
83void PACKSPU_APIENTRY packspu_NormalPointer( GLenum type, GLsizei stride, const GLvoid *pointer )
84{
85#if CR_ARB_vertex_buffer_object
86 GET_CONTEXT(ctx);
87 if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
88 if (pack_spu.swap)
89 crPackNormalPointerSWAP( type, stride, pointer );
90 else
91 crPackNormalPointer( type, stride, pointer );
92 }
93#endif
94 crStateNormalPointer( type, stride, pointer );
95}
96
97void PACKSPU_APIENTRY packspu_EdgeFlagPointer( GLsizei stride, const GLvoid *pointer )
98{
99#if CR_ARB_vertex_buffer_object
100 GET_CONTEXT(ctx);
101 if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
102 if (pack_spu.swap)
103 crPackEdgeFlagPointerSWAP( stride, pointer );
104 else
105 crPackEdgeFlagPointer( stride, pointer );
106 }
107#endif
108 crStateEdgeFlagPointer( stride, pointer );
109}
110
111void PACKSPU_APIENTRY packspu_VertexAttribPointerARB( GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer )
112{
113#if CR_ARB_vertex_buffer_object
114 GET_CONTEXT(ctx);
115 if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
116 if (pack_spu.swap)
117 crPackVertexAttribPointerARBSWAP( index, size, type, normalized, stride, pointer );
118 else
119 crPackVertexAttribPointerARB( index, size, type, normalized, stride, pointer );
120 }
121#endif
122 crStateVertexAttribPointerARB( index, size, type, normalized, stride, pointer );
123}
124
125void PACKSPU_APIENTRY packspu_VertexAttribPointerNV( GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer )
126{
127#if CR_ARB_vertex_buffer_object
128 GET_CONTEXT(ctx);
129 if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
130 if (pack_spu.swap)
131 crPackVertexAttribPointerNVSWAP( index, size, type, stride, pointer );
132 else
133 crPackVertexAttribPointerNV( index, size, type, stride, pointer );
134 }
135#endif
136 crStateVertexAttribPointerNV( index, size, type, stride, pointer );
137}
138
139void PACKSPU_APIENTRY packspu_IndexPointer( GLenum type, GLsizei stride, const GLvoid *pointer )
140{
141#if CR_ARB_vertex_buffer_object
142 GET_CONTEXT(ctx);
143 if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
144 if (pack_spu.swap)
145 crPackIndexPointerSWAP( type, stride, pointer );
146 else
147 crPackIndexPointer( type, stride, pointer );
148 }
149#endif
150 crStateIndexPointer(type, stride, pointer);
151}
152
153void PACKSPU_APIENTRY packspu_GetPointerv( GLenum pname, GLvoid **params )
154{
155 crStateGetPointerv( pname, params );
156}
157
158void PACKSPU_APIENTRY packspu_InterleavedArrays( GLenum format, GLsizei stride, const GLvoid *pointer )
159{
160#if CR_ARB_vertex_buffer_object
161 GET_CONTEXT(ctx);
162 if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
163 if (pack_spu.swap)
164 crPackInterleavedArraysSWAP( format, stride, pointer );
165 else
166 crPackInterleavedArrays( format, stride, pointer );
167 }
168#endif
169
170 /*crDebug("packspu_InterleavedArrays");*/
171
172 crStateInterleavedArrays( format, stride, pointer );
173}
174
175
176void PACKSPU_APIENTRY
177packspu_ArrayElement( GLint index )
178{
179/*@todo cash guest/host pointers calculation and use appropriate path here without crStateUseServerArrays call*/
180#if 1
181 GLboolean serverArrays = GL_FALSE;
182
183#if CR_ARB_vertex_buffer_object
184 GET_CONTEXT(ctx);
185 /*crDebug("packspu_ArrayElement index:%i", index);*/
186 if (ctx->clientState->extensions.ARB_vertex_buffer_object)
187 serverArrays = crStateUseServerArrays();
188#endif
189
190 if (serverArrays) {
191 GET_CONTEXT(ctx);
192 CRClientState *clientState = &(ctx->clientState->client);
193
194 /* LockArraysEXT can not be executed between glBegin/glEnd pair, it also
195 * leads to vertexpointers being adjusted on the host side between glBegin/glEnd calls which
196 * produces unpredictable results. Locking is done before the glBegin call instead.
197 */
198 CRASSERT(!clientState->array.locked || clientState->array.synced);
199
200 /* Send the DrawArrays command over the wire */
201 if (pack_spu.swap)
202 crPackArrayElementSWAP( index );
203 else
204 crPackArrayElement( index );
205 }
206 else {
207 /* evaluate locally */
208 GET_CONTEXT(ctx);
209 CRClientState *clientState = &(ctx->clientState->client);
210 if (pack_spu.swap)
211 crPackExpandArrayElementSWAP( index, clientState );
212 else
213 crPackExpandArrayElement( index, clientState );
214 }
215#else
216 GET_CONTEXT(ctx);
217 CRClientState *clientState = &(ctx->clientState->client);
218 crPackExpandArrayElement(index, clientState);
219#endif
220}
221
222
223void PACKSPU_APIENTRY
224packspu_DrawElements( GLenum mode, GLsizei count, GLenum type, const GLvoid *indices )
225{
226 GLboolean serverArrays = GL_FALSE;
227
228#if CR_ARB_vertex_buffer_object
229 GET_CONTEXT(ctx);
230 GLboolean lockedArrays = GL_FALSE;
231 CRBufferObject *elementsBuffer = crStateGetCurrent()->bufferobject.elementsBuffer;
232 /*crDebug("DrawElements count=%d, indices=%p", count, indices);*/
233 if (ctx->clientState->extensions.ARB_vertex_buffer_object)
234 serverArrays = crStateUseServerArrays();
235
236 if (!serverArrays && !ctx->clientState->client.array.locked && (count>3)
237 && (!elementsBuffer || !elementsBuffer->id))
238 {
239 GLuint min, max;
240 GLsizei i;
241
242 switch (type)
243 {
244 case GL_UNSIGNED_BYTE:
245 {
246 GLubyte *pIdx = (GLubyte *)indices;
247 min = max = pIdx[0];
248 for (i=0; i<count; ++i)
249 {
250 if (pIdx[i]<min) min = pIdx[i];
251 else if (pIdx[i]>max) max = pIdx[i];
252 }
253 break;
254 }
255 case GL_UNSIGNED_SHORT:
256 {
257 GLushort *pIdx = (GLushort *)indices;
258 min = max = pIdx[0];
259 for (i=0; i<count; ++i)
260 {
261 if (pIdx[i]<min) min = pIdx[i];
262 else if (pIdx[i]>max) max = pIdx[i];
263 }
264 break;
265 }
266 case GL_UNSIGNED_INT:
267 {
268 GLuint *pIdx = (GLuint *)indices;
269 min = max = pIdx[0];
270 for (i=0; i<count; ++i)
271 {
272 if (pIdx[i]<min) min = pIdx[i];
273 else if (pIdx[i]>max) max = pIdx[i];
274 }
275 break;
276 }
277 default: crError("Unknown type 0x%x", type);
278 }
279
280 if ((max-min)<(GLuint)(2*count))
281 {
282 crStateLockArraysEXT(min, max-min+1);
283
284 serverArrays = crStateUseServerArrays();
285 if (serverArrays)
286 {
287 lockedArrays = GL_TRUE;
288 }
289 else
290 {
291 crStateUnlockArraysEXT();
292 }
293 }
294 }
295#endif
296
297 if (serverArrays) {
298 GET_CONTEXT(ctx);
299 CRClientState *clientState = &(ctx->clientState->client);
300
301 /*Note the comment in packspu_LockArraysEXT*/
302 if (clientState->array.locked && !clientState->array.synced)
303 {
304 crPackLockArraysEXT(clientState->array.lockFirst, clientState->array.lockCount);
305 clientState->array.synced = GL_TRUE;
306 }
307 /* Send the DrawArrays command over the wire */
308 if (pack_spu.swap)
309 crPackDrawElementsSWAP( mode, count, type, indices );
310 else
311 crPackDrawElements( mode, count, type, indices );
312 }
313 else {
314 /* evaluate locally */
315 GET_CONTEXT(ctx);
316 CRClientState *clientState = &(ctx->clientState->client);
317 if (pack_spu.swap)
318 crPackExpandDrawElementsSWAP( mode, count, type, indices, clientState );
319 else
320 {
321 //packspu_Begin(mode);
322 crPackExpandDrawElements( mode, count, type, indices, clientState );
323 //packspu_End();
324 }
325 }
326
327#if CR_ARB_vertex_buffer_object
328 if (lockedArrays)
329 {
330 packspu_UnlockArraysEXT();
331 }
332#endif
333}
334
335
336void PACKSPU_APIENTRY
337packspu_DrawRangeElements( GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices )
338{
339 GLboolean serverArrays = GL_FALSE;
340
341#if CR_ARB_vertex_buffer_object
342 GET_CONTEXT(ctx);
343 /*crDebug("DrawRangeElements count=%d", count);*/
344 if (ctx->clientState->extensions.ARB_vertex_buffer_object)
345 serverArrays = crStateUseServerArrays();
346#endif
347
348 if (serverArrays) {
349 GET_CONTEXT(ctx);
350 CRClientState *clientState = &(ctx->clientState->client);
351
352 /*Note the comment in packspu_LockArraysEXT*/
353 if (clientState->array.locked && !clientState->array.synced)
354 {
355 crPackLockArraysEXT(clientState->array.lockFirst, clientState->array.lockCount);
356 clientState->array.synced = GL_TRUE;
357 }
358
359 /* Send the DrawRangeElements command over the wire */
360 if (pack_spu.swap)
361 crPackDrawRangeElementsSWAP( mode, start, end, count, type, indices );
362 else
363 crPackDrawRangeElements( mode, start, end, count, type, indices );
364 }
365 else {
366 /* evaluate locally */
367 GET_CONTEXT(ctx);
368 CRClientState *clientState = &(ctx->clientState->client);
369 if (pack_spu.swap)
370 crPackExpandDrawRangeElementsSWAP( mode, start, end, count, type, indices, clientState );
371 else
372 {
373 crPackExpandDrawRangeElements( mode, start, end, count, type, indices, clientState );
374 }
375 }
376}
377
378
379void PACKSPU_APIENTRY
380packspu_DrawArrays( GLenum mode, GLint first, GLsizei count )
381{
382 GLboolean serverArrays = GL_FALSE;
383
384#if CR_ARB_vertex_buffer_object
385 GET_CONTEXT(ctx);
386 GLboolean lockedArrays = GL_FALSE;
387 /*crDebug("DrawArrays count=%d", count);*/
388 if (ctx->clientState->extensions.ARB_vertex_buffer_object)
389 serverArrays = crStateUseServerArrays();
390
391 if (!serverArrays && !ctx->clientState->client.array.locked && (count>3))
392 {
393 crStateLockArraysEXT(first, count);
394 serverArrays = crStateUseServerArrays();
395 if (serverArrays)
396 {
397 lockedArrays = GL_TRUE;
398 }
399 else
400 {
401 crStateUnlockArraysEXT();
402 }
403 }
404#endif
405
406 if (serverArrays)
407 {
408 GET_CONTEXT(ctx);
409 CRClientState *clientState = &(ctx->clientState->client);
410
411 /*Note the comment in packspu_LockArraysEXT*/
412 if (clientState->array.locked && !clientState->array.synced)
413 {
414 crPackLockArraysEXT(clientState->array.lockFirst, clientState->array.lockCount);
415 clientState->array.synced = GL_TRUE;
416 }
417
418 /* Send the DrawArrays command over the wire */
419 if (pack_spu.swap)
420 crPackDrawArraysSWAP( mode, first, count );
421 else
422 crPackDrawArrays( mode, first, count );
423 }
424 else
425 {
426 /* evaluate locally */
427 GET_CONTEXT(ctx);
428 CRClientState *clientState = &(ctx->clientState->client);
429 if (pack_spu.swap)
430 crPackExpandDrawArraysSWAP( mode, first, count, clientState );
431 else
432 crPackExpandDrawArrays( mode, first, count, clientState );
433 }
434
435#if CR_ARB_vertex_buffer_object
436 if (lockedArrays)
437 {
438 packspu_UnlockArraysEXT();
439 }
440#endif
441}
442
443
444#ifdef CR_EXT_multi_draw_arrays
445void PACKSPU_APIENTRY packspu_MultiDrawArraysEXT( GLenum mode, GLint *first, GLsizei *count, GLsizei primcount )
446{
447 GLint i;
448 for (i = 0; i < primcount; i++) {
449 if (count[i] > 0) {
450 packspu_DrawArrays(mode, first[i], count[i]);
451 }
452 }
453}
454
455void PACKSPU_APIENTRY packspu_MultiDrawElementsEXT( GLenum mode, const GLsizei *count, GLenum type, const GLvoid **indices, GLsizei primcount )
456{
457 GLint i;
458 for (i = 0; i < primcount; i++) {
459 if (count[i] > 0) {
460 packspu_DrawElements(mode, count[i], type, indices[i]);
461 }
462 }
463}
464#endif
465
466
467void PACKSPU_APIENTRY packspu_EnableClientState( GLenum array )
468{
469 crStateEnableClientState(array);
470 crPackEnableClientState(array);
471}
472
473void PACKSPU_APIENTRY packspu_DisableClientState( GLenum array )
474{
475 crStateDisableClientState(array);
476 crPackDisableClientState(array);
477}
478
479void PACKSPU_APIENTRY packspu_ClientActiveTextureARB( GLenum texUnit )
480{
481 crStateClientActiveTextureARB(texUnit);
482 crPackClientActiveTextureARB(texUnit);
483}
484
485void PACKSPU_APIENTRY packspu_EnableVertexAttribArrayARB(GLuint index)
486{
487 crStateEnableVertexAttribArrayARB(index);
488 crPackEnableVertexAttribArrayARB(index);
489}
490
491
492void PACKSPU_APIENTRY packspu_DisableVertexAttribArrayARB(GLuint index)
493{
494 crStateDisableVertexAttribArrayARB(index);
495 crPackDisableVertexAttribArrayARB(index);
496}
497
498void PACKSPU_APIENTRY packspu_Enable( GLenum cap )
499{
500 if (cap!=GL_LIGHT_MODEL_TWO_SIDE)
501 {
502 crStateEnable(cap);
503
504 if (pack_spu.swap)
505 crPackEnableSWAP(cap);
506 else
507 crPackEnable(cap);
508 }
509 else
510 {
511 static int g_glmts1_warn=0;
512 if (!g_glmts1_warn)
513 {
514 crWarning("glEnable(GL_LIGHT_MODEL_TWO_SIDE) converted to valid glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,1)");
515 g_glmts1_warn=1;
516 }
517 crStateLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
518 crPackLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
519 }
520}
521
522
523void PACKSPU_APIENTRY packspu_Disable( GLenum cap )
524{
525 if (cap!=GL_LIGHT_MODEL_TWO_SIDE)
526 {
527 crStateDisable(cap);
528
529 if (pack_spu.swap)
530 crPackDisableSWAP(cap);
531 else
532 crPackDisable(cap);
533 }
534 else
535 {
536 static int g_glmts0_warn=0;
537 if (!g_glmts0_warn)
538 {
539 crWarning("glDisable(GL_LIGHT_MODEL_TWO_SIDE) converted to valid glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,0)");
540 g_glmts0_warn=1;
541 }
542 crStateLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
543 crPackLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
544 }
545}
546
547GLboolean PACKSPU_APIENTRY packspu_IsEnabled(GLenum cap)
548{
549 GLboolean res = crStateIsEnabled(cap);
550#ifdef DEBUG
551 {
552 GET_THREAD(thread);
553 int writeback = 1;
554 GLboolean return_val = (GLboolean) 0;
555 crPackIsEnabled(cap, &return_val, &writeback);
556 packspuFlush( (void *) thread );
557 while (writeback)
558 crNetRecv();
559 CRASSERT(return_val==res);
560 }
561#endif
562
563 return res;
564}
565
566void PACKSPU_APIENTRY packspu_PushClientAttrib( GLbitfield mask )
567{
568 crStatePushClientAttrib(mask);
569 crPackPushClientAttrib(mask);
570}
571
572void PACKSPU_APIENTRY packspu_PopClientAttrib( void )
573{
574 crStatePopClientAttrib();
575 crPackPopClientAttrib();
576}
577
578void PACKSPU_APIENTRY packspu_LockArraysEXT(GLint first, GLint count)
579{
580 if (first>=0 && count>0)
581 {
582 crStateLockArraysEXT(first, count);
583 /*Note: this is a workaround for quake3 based apps.
584 It's modifying vertex data between glLockArraysEXT and glDrawElements calls,
585 so we'd pass data to host right before the glDrawSomething or glBegin call.
586 */
587 /*crPackLockArraysEXT(first, count);*/
588 }
589 else crDebug("Ignoring packspu_LockArraysEXT: first:%i, count:%i", first, count);
590}
591
592void PACKSPU_APIENTRY packspu_UnlockArraysEXT()
593{
594 crStateUnlockArraysEXT();
595 crPackUnlockArraysEXT();
596}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette