VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_misc.cpp@ 78375

Last change on this file since 78375 was 78375, checked in by vboxsync, 6 years ago

Additions/common/crOpengl,GuestHost/OpenGL,HostServices/SharedOpenGL: Eliminate all global variables from the state tracker library (state_tracker) in preparation of the SPU DLL merging, bugref:9435

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 66.8 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 "server_dispatch.h"
8#include "server.h"
9#include "cr_error.h"
10#include "cr_mem.h"
11#include "cr_string.h"
12#include "cr_pixeldata.h"
13#ifdef VBOX_WITH_CRDUMPER
14# include "cr_dump.h"
15#endif
16
17void SERVER_DISPATCH_APIENTRY crServerDispatchSelectBuffer( GLsizei size, GLuint *buffer )
18{
19 (void) size;
20 (void) buffer;
21 crError( "Unsupported network glSelectBuffer call." );
22}
23
24void SERVER_DISPATCH_APIENTRY crServerDispatchGetChromiumParametervCR(GLenum target, GLuint index, GLenum type, GLsizei count, GLvoid *values)
25{
26 RT_NOREF(values);
27
28 GLubyte local_storage[4096];
29 GLint bytes = 0;
30 GLint cbType = 1; /* One byte by default. */
31
32 memset(local_storage, 0, sizeof(local_storage));
33
34 switch (type) {
35 case GL_BYTE:
36 case GL_UNSIGNED_BYTE:
37 cbType = sizeof(GLbyte);
38 break;
39 case GL_SHORT:
40 case GL_UNSIGNED_SHORT:
41 cbType = sizeof(GLshort);
42 break;
43 case GL_INT:
44 case GL_UNSIGNED_INT:
45 cbType = sizeof(GLint);
46 break;
47 case GL_FLOAT:
48 cbType = sizeof(GLfloat);
49 break;
50 case GL_DOUBLE:
51 cbType = sizeof(GLdouble);
52 break;
53 default:
54 crError("Bad type in crServerDispatchGetChromiumParametervCR");
55 }
56
57 if (count < 0) /* 'GLsizei' is usually an 'int'. */
58 count = 0;
59 else if ((size_t)count > sizeof(local_storage) / cbType)
60 count = sizeof(local_storage) / cbType;
61
62 bytes = count * cbType;
63
64 CRASSERT(bytes >= 0);
65 CRASSERT(bytes < 4096);
66
67 switch (target)
68 {
69 case GL_DBG_CHECK_BREAK_CR:
70 {
71 if (bytes > 0)
72 {
73 GLubyte *pbRc = local_storage;
74 GLuint *puRc = (GLuint *)(bytes >=4 ? local_storage : NULL);
75 int rc;
76 memset(local_storage, 0, bytes);
77 if (cr_server.RcToGuestOnce)
78 {
79 rc = cr_server.RcToGuestOnce;
80 cr_server.RcToGuestOnce = 0;
81 }
82 else
83 {
84 rc = cr_server.RcToGuest;
85 }
86 if (puRc)
87 *puRc = rc;
88 else
89 *pbRc = !!rc;
90 }
91 else
92 {
93 crWarning("zero bytes for GL_DBG_CHECK_BREAK_CR");
94 }
95 break;
96 }
97 case GL_HH_SET_DEFAULT_SHARED_CTX:
98 WARN(("Recieved GL_HH_SET_DEFAULT_SHARED_CTX from guest, ignoring"));
99 break;
100 case GL_HH_SET_CLIENT_CALLOUT:
101 WARN(("Recieved GL_HH_SET_CLIENT_CALLOUT from guest, ignoring"));
102 break;
103 default:
104 cr_server.head_spu->dispatch_table.GetChromiumParametervCR( target, index, type, count, local_storage );
105 break;
106 }
107
108 crServerReturnValue( local_storage, bytes );
109}
110
111void SERVER_DISPATCH_APIENTRY crServerDispatchChromiumParametervCR(GLenum target, GLenum type, GLsizei count, const GLvoid *values)
112{
113 static int gather_connect_count = 0;
114
115 switch (target) {
116 case GL_SHARE_LISTS_CR:
117 {
118 CRContextInfo *pCtx[2];
119 GLint *ai32Values;
120 int i;
121 if (count != 2)
122 {
123 WARN(("GL_SHARE_LISTS_CR invalid cound %d", count));
124 return;
125 }
126
127 if (type != GL_UNSIGNED_INT && type != GL_INT)
128 {
129 WARN(("GL_SHARE_LISTS_CR invalid type %d", type));
130 return;
131 }
132
133 ai32Values = (GLint*)values;
134
135 for (i = 0; i < 2; ++i)
136 {
137 const int32_t val = ai32Values[i];
138
139 if (val == 0)
140 {
141 WARN(("GL_SHARE_LISTS_CR invalid value[%d] %d", i, val));
142 return;
143 }
144
145 pCtx[i] = (CRContextInfo *) crHashtableSearch(cr_server.contextTable, val);
146 if (!pCtx[i])
147 {
148 WARN(("GL_SHARE_LISTS_CR invalid pCtx1 for value[%d] %d", i, val));
149 return;
150 }
151
152 if (!pCtx[i]->pContext)
153 {
154 WARN(("GL_SHARE_LISTS_CR invalid pCtx1 pContext for value[%d] %d", i, val));
155 return;
156 }
157 }
158
159 crStateShareLists(pCtx[0]->pContext, pCtx[1]->pContext);
160
161 break;
162 }
163
164 case GL_SET_MAX_VIEWPORT_CR:
165 {
166 GLint *maxDims = (GLint *)values;
167 cr_server.limits.maxViewportDims[0] = maxDims[0];
168 cr_server.limits.maxViewportDims[1] = maxDims[1];
169 }
170 break;
171
172 case GL_TILE_INFO_CR:
173 /* message from tilesort SPU to set new tile bounds */
174 {
175 GLint numTiles, muralWidth, muralHeight, server, tiles;
176 GLint *tileBounds;
177 CRASSERT(count >= 4);
178 CRASSERT((count - 4) % 4 == 0); /* must be multiple of four */
179 CRASSERT(type == GL_INT);
180 numTiles = (count - 4) / 4;
181 tileBounds = (GLint *) values;
182 server = tileBounds[0];
183 muralWidth = tileBounds[1];
184 muralHeight = tileBounds[2];
185 tiles = tileBounds[3];
186 CRASSERT(tiles == numTiles);
187 tileBounds += 4; /* skip over header values */
188 /*crServerNewMuralTiling(mural, muralWidth, muralHeight, numTiles, tileBounds);
189 mural->viewportValidated = GL_FALSE;*/
190 }
191 break;
192
193 case GL_GATHER_DRAWPIXELS_CR:
194 if (cr_server.only_swap_once && cr_server.curClient != cr_server.clients[0])
195 break;
196 cr_server.head_spu->dispatch_table.ChromiumParametervCR( target, type, count, values );
197 break;
198
199 case GL_GATHER_CONNECT_CR:
200 /*
201 * We want the last connect to go through,
202 * otherwise we might deadlock in CheckWindowSize()
203 * in the readback spu
204 */
205 gather_connect_count++;
206 if (cr_server.only_swap_once && (gather_connect_count != cr_server.numClients))
207 {
208 break;
209 }
210 cr_server.head_spu->dispatch_table.ChromiumParametervCR( target, type, count, values );
211 gather_connect_count = 0;
212 break;
213
214 case GL_SERVER_VIEW_MATRIX_CR:
215 /* Set this server's view matrix which will get premultiplied onto the
216 * modelview matrix. For non-planar tilesort and stereo.
217 */
218 CRASSERT(count == 18);
219 CRASSERT(type == GL_FLOAT);
220 /* values[0] is the server index. Ignored here but used in tilesort SPU */
221 /* values[1] is the left/right eye index (0 or 1) */
222 {
223 const GLfloat *v = (const GLfloat *) values;
224 const int eye = v[1] == 0.0 ? 0 : 1;
225 crMatrixInitFromFloats(&cr_server.viewMatrix[eye], v + 2);
226
227 crDebug("Got GL_SERVER_VIEW_MATRIX_CR:\n"
228 " %f %f %f %f\n"
229 " %f %f %f %f\n"
230 " %f %f %f %f\n"
231 " %f %f %f %f",
232 cr_server.viewMatrix[eye].m00,
233 cr_server.viewMatrix[eye].m10,
234 cr_server.viewMatrix[eye].m20,
235 cr_server.viewMatrix[eye].m30,
236 cr_server.viewMatrix[eye].m01,
237 cr_server.viewMatrix[eye].m11,
238 cr_server.viewMatrix[eye].m21,
239 cr_server.viewMatrix[eye].m31,
240 cr_server.viewMatrix[eye].m02,
241 cr_server.viewMatrix[eye].m12,
242 cr_server.viewMatrix[eye].m22,
243 cr_server.viewMatrix[eye].m32,
244 cr_server.viewMatrix[eye].m03,
245 cr_server.viewMatrix[eye].m13,
246 cr_server.viewMatrix[eye].m23,
247 cr_server.viewMatrix[eye].m33);
248 }
249 cr_server.viewOverride = GL_TRUE;
250 break;
251
252 case GL_SERVER_PROJECTION_MATRIX_CR:
253 /* Set this server's projection matrix which will get replace the user's
254 * projection matrix. For non-planar tilesort and stereo.
255 */
256 CRASSERT(count == 18);
257 CRASSERT(type == GL_FLOAT);
258 /* values[0] is the server index. Ignored here but used in tilesort SPU */
259 /* values[1] is the left/right eye index (0 or 1) */
260 {
261 const GLfloat *v = (const GLfloat *) values;
262 const int eye = v[1] == 0.0 ? 0 : 1;
263 crMatrixInitFromFloats(&cr_server.projectionMatrix[eye], v + 2);
264
265 crDebug("Got GL_SERVER_PROJECTION_MATRIX_CR:\n"
266 " %f %f %f %f\n"
267 " %f %f %f %f\n"
268 " %f %f %f %f\n"
269 " %f %f %f %f",
270 cr_server.projectionMatrix[eye].m00,
271 cr_server.projectionMatrix[eye].m10,
272 cr_server.projectionMatrix[eye].m20,
273 cr_server.projectionMatrix[eye].m30,
274 cr_server.projectionMatrix[eye].m01,
275 cr_server.projectionMatrix[eye].m11,
276 cr_server.projectionMatrix[eye].m21,
277 cr_server.projectionMatrix[eye].m31,
278 cr_server.projectionMatrix[eye].m02,
279 cr_server.projectionMatrix[eye].m12,
280 cr_server.projectionMatrix[eye].m22,
281 cr_server.projectionMatrix[eye].m32,
282 cr_server.projectionMatrix[eye].m03,
283 cr_server.projectionMatrix[eye].m13,
284 cr_server.projectionMatrix[eye].m23,
285 cr_server.projectionMatrix[eye].m33);
286
287 if (cr_server.projectionMatrix[eye].m33 == 0.0f) {
288 float x = cr_server.projectionMatrix[eye].m00;
289 float y = cr_server.projectionMatrix[eye].m11;
290 float a = cr_server.projectionMatrix[eye].m20;
291 float b = cr_server.projectionMatrix[eye].m21;
292 float c = cr_server.projectionMatrix[eye].m22;
293 float d = cr_server.projectionMatrix[eye].m32;
294 float znear = -d / (1.0f - c);
295 float zfar = (c - 1.0f) * znear / (c + 1.0f);
296 float left = znear * (a - 1.0f) / x;
297 float right = 2.0f * znear / x + left;
298 float bottom = znear * (b - 1.0f) / y;
299 float top = 2.0f * znear / y + bottom;
300 crDebug("Frustum: left, right, bottom, top, near, far: %f, %f, %f, %f, %f, %f", left, right, bottom, top, znear, zfar);
301 }
302 else {
303 /** @todo Add debug output for orthographic projection*/
304 }
305
306 }
307 cr_server.projectionOverride = GL_TRUE;
308 break;
309
310 case GL_HH_SET_TMPCTX_MAKE_CURRENT:
311 /*we should not receive it from the guest! */
312 break;
313
314 case GL_HH_SET_CLIENT_CALLOUT:
315 WARN(("Recieved GL_HH_SET_CLIENT_CALLOUT from guest, ignoring"));
316 break;
317
318 default:
319 /* Pass the parameter info to the head SPU */
320 cr_server.head_spu->dispatch_table.ChromiumParametervCR( target, type, count, values );
321 break;
322 }
323}
324
325
326void SERVER_DISPATCH_APIENTRY crServerDispatchChromiumParameteriCR(GLenum target, GLint value)
327{
328 switch (target) {
329 case GL_SHARE_CONTEXT_RESOURCES_CR:
330 crStateShareContext(&cr_server.StateTracker, value);
331 break;
332 case GL_RCUSAGE_TEXTURE_SET_CR:
333 crStateSetTextureUsed(&cr_server.StateTracker, value, GL_TRUE);
334 break;
335 case GL_RCUSAGE_TEXTURE_CLEAR_CR:
336 crStateSetTextureUsed(&cr_server.StateTracker, value, GL_FALSE);
337 break;
338 case GL_PIN_TEXTURE_SET_CR:
339 crStatePinTexture(&cr_server.StateTracker, value, GL_TRUE);
340 break;
341 case GL_PIN_TEXTURE_CLEAR_CR:
342 crStatePinTexture(&cr_server.StateTracker, value, GL_FALSE);
343 break;
344 case GL_SHARED_DISPLAY_LISTS_CR:
345 cr_server.sharedDisplayLists = value;
346 break;
347 case GL_SHARED_TEXTURE_OBJECTS_CR:
348 cr_server.sharedTextureObjects = value;
349 break;
350 case GL_SHARED_PROGRAMS_CR:
351 cr_server.sharedPrograms = value;
352 break;
353 case GL_SERVER_CURRENT_EYE_CR:
354 cr_server.currentEye = value ? 1 : 0;
355 break;
356 case GL_HOST_WND_CREATED_HIDDEN_CR:
357 cr_server.bWindowsInitiallyHidden = value ? 1 : 0;
358 break;
359 case GL_HH_SET_DEFAULT_SHARED_CTX:
360 WARN(("Recieved GL_HH_SET_DEFAULT_SHARED_CTX from guest, ignoring"));
361 break;
362 case GL_HH_RENDERTHREAD_INFORM:
363 WARN(("Recieved GL_HH_RENDERTHREAD_INFORM from guest, ignoring"));
364 break;
365 default:
366 /* Pass the parameter info to the head SPU */
367 cr_server.head_spu->dispatch_table.ChromiumParameteriCR( target, value );
368 }
369}
370
371
372void SERVER_DISPATCH_APIENTRY crServerDispatchChromiumParameterfCR(GLenum target, GLfloat value)
373{
374 switch (target) {
375 case GL_SHARED_DISPLAY_LISTS_CR:
376 cr_server.sharedDisplayLists = (int) value;
377 break;
378 case GL_SHARED_TEXTURE_OBJECTS_CR:
379 cr_server.sharedTextureObjects = (int) value;
380 break;
381 case GL_SHARED_PROGRAMS_CR:
382 cr_server.sharedPrograms = (int) value;
383 break;
384 default:
385 /* Pass the parameter info to the head SPU */
386 cr_server.head_spu->dispatch_table.ChromiumParameterfCR( target, value );
387 }
388}
389
390GLint crServerGenerateID(GLint *pCounter)
391{
392 return (*pCounter)++;
393}
394
395/*#define CR_DUMP_BLITS*/
396
397#ifdef CR_DUMP_BLITS
398static int blitnum=0;
399static int copynum=0;
400#endif
401
402# ifdef DEBUG_misha
403//# define CR_CHECK_BLITS
404# include <iprt/assert.h>
405# undef CRASSERT /* iprt assert's int3 are inlined that is why are more convenient to use since they can be easily disabled individually */
406# define CRASSERT Assert
407# endif
408
409
410void SERVER_DISPATCH_APIENTRY
411crServerDispatchCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
412{
413 /** @todo pbo/fbo disabled for now as it's slower, check on other gpus*/
414 static int siHavePBO = 0;
415 static int siHaveFBO = 0;
416
417 if ((target!=GL_TEXTURE_2D) || (height>=0))
418 {
419 cr_server.head_spu->dispatch_table.CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
420
421#ifdef CR_DUMP_BLITS
422 {
423 SPUDispatchTable *gl = &cr_server.head_spu->dispatch_table;
424 void *img;
425 GLint w, h;
426 char fname[200];
427
428 copynum++;
429
430 gl->GetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
431 gl->GetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
432
433 img = crAlloc(w*h*4);
434 CRASSERT(img);
435
436 gl->GetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, img);
437 sprintf(fname, "copy_blit%i_copy_%i.tga", blitnum, copynum);
438 crDumpNamedTGA(fname, w, h, img);
439 crFree(img);
440 }
441#endif
442 }
443 else /* negative height, means we have to Yinvert the source pixels while copying */
444 {
445 SPUDispatchTable *gl = &cr_server.head_spu->dispatch_table;
446
447 if (siHavePBO<0)
448 {
449 const char *ext = (const char*)gl->GetString(GL_EXTENSIONS);
450 siHavePBO = crStrstr(ext, "GL_ARB_pixel_buffer_object") ? 1:0;
451 }
452
453 if (siHaveFBO<0)
454 {
455 const char *ext = (const char*)gl->GetString(GL_EXTENSIONS);
456 siHaveFBO = crStrstr(ext, "GL_EXT_framebuffer_object") ? 1:0;
457 }
458
459 if (siHavePBO==0 && siHaveFBO==0)
460 {
461#if 1
462 GLint dRow, sRow;
463 for (dRow=yoffset, sRow=y-height-1; dRow<yoffset-height; dRow++, sRow--)
464 {
465 gl->CopyTexSubImage2D(target, level, xoffset, dRow, x, sRow, width, 1);
466 }
467#else
468 {
469 GLint w, h, i;
470 char *img1, *img2, *sPtr, *dPtr;
471 CRContext *ctx = crStateGetCurrent();
472
473 w = ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->level[0][level].width;
474 h = ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->level[0][level].height;
475
476 img1 = crAlloc(4*w*h);
477 img2 = crAlloc(4*width*(-height));
478 CRASSERT(img1 && img2);
479
480 gl->CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, -height);
481 gl->GetTexImage(target, level, GL_RGBA, GL_UNSIGNED_BYTE, img1);
482
483 sPtr=img1+4*xoffset+4*w*yoffset;
484 dPtr=img2+4*width*(-height-1);
485
486 for (i=0; i<-height; ++i)
487 {
488 crMemcpy(dPtr, sPtr, 4*width);
489 sPtr += 4*w;
490 dPtr -= 4*width;
491 }
492
493 gl->TexSubImage2D(target, level, xoffset, yoffset, width, -height, GL_RGBA, GL_UNSIGNED_BYTE, img2);
494
495 crFree(img1);
496 crFree(img2);
497 }
498#endif
499 }
500 else if (siHaveFBO==1) /** @todo more states to set and restore here*/
501 {
502 GLuint tID, fboID;
503 GLenum status;
504 CRContext *ctx = crStateGetCurrent(&cr_server.StateTracker);
505
506 gl->GenTextures(1, &tID);
507 gl->BindTexture(target, tID);
508 gl->CopyTexImage2D(target, level, GL_RGBA, x, y, width, -height, 0);
509 gl->GenFramebuffersEXT(1, &fboID);
510 gl->BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboID);
511 gl->FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target,
512 ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->hwid, level);
513 status = gl->CheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
514 if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
515 {
516 crWarning("Framebuffer status 0x%x", status);
517 }
518
519 gl->Enable(target);
520 gl->PushAttrib(GL_VIEWPORT_BIT);
521 gl->Viewport(xoffset, yoffset, width, -height);
522 gl->MatrixMode(GL_PROJECTION);
523 gl->PushMatrix();
524 gl->LoadIdentity();
525 gl->MatrixMode(GL_MODELVIEW);
526 gl->PushMatrix();
527 gl->LoadIdentity();
528
529 gl->Disable(GL_DEPTH_TEST);
530 gl->Disable(GL_CULL_FACE);
531 gl->Disable(GL_STENCIL_TEST);
532 gl->Disable(GL_SCISSOR_TEST);
533
534 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
535 gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
536 gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
537 gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
538 gl->TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
539
540 gl->Begin(GL_QUADS);
541 gl->TexCoord2f(0.0f, 1.0f);
542 gl->Vertex2f(-1.0, -1.0);
543
544 gl->TexCoord2f(0.0f, 0.0f);
545 gl->Vertex2f(-1.0f, 1.0f);
546
547 gl->TexCoord2f(1.0f, 0.0f);
548 gl->Vertex2f(1.0f, 1.0f);
549
550 gl->TexCoord2f(1.0f, 1.0f);
551 gl->Vertex2f(1.0f, -1.0f);
552 gl->End();
553
554 gl->PopMatrix();
555 gl->MatrixMode(GL_PROJECTION);
556 gl->PopMatrix();
557 gl->PopAttrib();
558
559 gl->FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target, 0, level);
560 gl->BindFramebufferEXT(GL_FRAMEBUFFER_EXT, ctx->framebufferobject.drawFB ? ctx->framebufferobject.drawFB->hwid:0);
561 gl->BindTexture(target, ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->hwid);
562 gl->DeleteFramebuffersEXT(1, &fboID);
563 gl->DeleteTextures(1, &tID);
564
565#if 0
566 {
567 GLint dRow, sRow, w, h;
568 void *img1, *img2;
569
570 w = ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->level[0][level].width;
571 h = ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->level[0][level].height;
572
573 img1 = crAlloc(4*w*h);
574 img2 = crAlloc(4*w*h);
575 CRASSERT(img1 && img2);
576
577 gl->GetTexImage(target, level, GL_BGRA, GL_UNSIGNED_BYTE, img1);
578
579
580 for (dRow=yoffset, sRow=y-height-1; dRow<yoffset-height; dRow++, sRow--)
581 {
582 gl->CopyTexSubImage2D(target, level, xoffset, dRow, x, sRow, width, 1);
583 }
584
585 gl->GetTexImage(target, level, GL_BGRA, GL_UNSIGNED_BYTE, img2);
586
587 if (crMemcmp(img1, img2, 4*w*h))
588 {
589 crDebug("MISMATCH! (%x, %i, ->%i,%i <-%i, %i [%ix%i])", target, level, xoffset, yoffset, x, y, width, height);
590 crDumpTGA(w, h, img1);
591 crDumpTGA(w, h, img2);
592 DebugBreak();
593 }
594 crFree(img1);
595 crFree(img2);
596 }
597#endif
598 }
599 else
600 {
601 GLint dRow;
602 GLuint pboId, sRow;
603 CRContext *ctx = crStateGetCurrent(&cr_server.StateTracker);
604
605 gl->GenBuffersARB(1, &pboId);
606 gl->BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboId);
607 gl->BufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, -width*height*4, 0, GL_STATIC_COPY_ARB);
608
609#if 1
610 gl->ReadPixels(x, y, width, -height, GL_RGBA, GL_UNSIGNED_BYTE, 0);
611 gl->BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, ctx->bufferobject.packBuffer->hwid);
612
613 gl->BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pboId);
614 for (dRow=yoffset, sRow=-height-1; dRow<yoffset-height; dRow++, sRow--)
615 {
616 gl->TexSubImage2D(target, level, xoffset, dRow, width, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)((uintptr_t)sRow*width*4));
617 }
618#else /*few times slower again*/
619 for (dRow=0, sRow=y-height-1; dRow<-height; dRow++, sRow--)
620 {
621 gl->ReadPixels(x, sRow, width, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)((uintptr_t)dRow*width*4));
622 }
623 gl->BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, ctx->bufferobject.packBuffer->hwid);
624
625 gl->BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pboId);
626 gl->TexSubImage2D(target, level, xoffset, yoffset, width, -height, GL_RGBA, GL_UNSIGNED_BYTE, 0);
627#endif
628
629 gl->BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, ctx->bufferobject.unpackBuffer->hwid);
630 gl->DeleteBuffersARB(1, &pboId);
631 }
632 }
633}
634
635#ifdef CR_CHECK_BLITS
636void crDbgFree(void *pvData)
637{
638 crFree(pvData);
639}
640
641void crDbgGetTexImage2D(GLint texTarget, GLint texName, GLvoid **ppvImage, GLint *pw, GLint *ph)
642{
643 SPUDispatchTable *gl = &cr_server.head_spu->dispatch_table;
644 GLint ppb, pub, dstw, dsth, otex;
645 GLint pa, pr, psp, psr, ua, ur, usp, usr;
646 GLvoid *pvImage;
647 GLint rfb, dfb, rb, db;
648
649 gl->GetIntegerv(GL_READ_FRAMEBUFFER_BINDING_EXT, &rfb);
650 gl->GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING_EXT, &dfb);
651 gl->GetIntegerv(GL_READ_BUFFER, &rb);
652 gl->GetIntegerv(GL_DRAW_BUFFER, &db);
653
654 gl->BindFramebufferEXT(GL_READ_FRAMEBUFFER_BINDING_EXT, 0);
655 gl->BindFramebufferEXT(GL_DRAW_FRAMEBUFFER_BINDING_EXT, 0);
656 gl->ReadBuffer(GL_BACK);
657 gl->DrawBuffer(GL_BACK);
658
659 gl->GetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, &ppb);
660 gl->GetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &pub);
661 gl->GetIntegerv(GL_TEXTURE_BINDING_2D, &otex);
662
663 gl->GetIntegerv(GL_PACK_ROW_LENGTH, &pr);
664 gl->GetIntegerv(GL_PACK_ALIGNMENT, &pa);
665 gl->GetIntegerv(GL_PACK_SKIP_PIXELS, &psp);
666 gl->GetIntegerv(GL_PACK_SKIP_ROWS, &psr);
667
668 gl->GetIntegerv(GL_UNPACK_ROW_LENGTH, &ur);
669 gl->GetIntegerv(GL_UNPACK_ALIGNMENT, &ua);
670 gl->GetIntegerv(GL_UNPACK_SKIP_PIXELS, &usp);
671 gl->GetIntegerv(GL_UNPACK_SKIP_ROWS, &usr);
672
673 gl->BindTexture(texTarget, texName);
674 gl->GetTexLevelParameteriv(texTarget, 0, GL_TEXTURE_WIDTH, &dstw);
675 gl->GetTexLevelParameteriv(texTarget, 0, GL_TEXTURE_HEIGHT, &dsth);
676
677 gl->PixelStorei(GL_PACK_ROW_LENGTH, 0);
678 gl->PixelStorei(GL_PACK_ALIGNMENT, 1);
679 gl->PixelStorei(GL_PACK_SKIP_PIXELS, 0);
680 gl->PixelStorei(GL_PACK_SKIP_ROWS, 0);
681
682 gl->PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
683 gl->PixelStorei(GL_UNPACK_ALIGNMENT, 1);
684 gl->PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
685 gl->PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
686
687 gl->BindBufferARB(GL_PIXEL_PACK_BUFFER, 0);
688 gl->BindBufferARB(GL_PIXEL_UNPACK_BUFFER, 0);
689
690 pvImage = crAlloc(4*dstw*dsth);
691 gl->GetTexImage(texTarget, 0, GL_BGRA, GL_UNSIGNED_BYTE, pvImage);
692
693 gl->BindTexture(texTarget, otex);
694
695 gl->PixelStorei(GL_PACK_ROW_LENGTH, pr);
696 gl->PixelStorei(GL_PACK_ALIGNMENT, pa);
697 gl->PixelStorei(GL_PACK_SKIP_PIXELS, psp);
698 gl->PixelStorei(GL_PACK_SKIP_ROWS, psr);
699
700 gl->PixelStorei(GL_UNPACK_ROW_LENGTH, ur);
701 gl->PixelStorei(GL_UNPACK_ALIGNMENT, ua);
702 gl->PixelStorei(GL_UNPACK_SKIP_PIXELS, usp);
703 gl->PixelStorei(GL_UNPACK_SKIP_ROWS, usr);
704
705 gl->BindBufferARB(GL_PIXEL_PACK_BUFFER, ppb);
706 gl->BindBufferARB(GL_PIXEL_UNPACK_BUFFER, pub);
707
708 gl->BindFramebufferEXT(GL_READ_FRAMEBUFFER_BINDING_EXT, rfb);
709 gl->BindFramebufferEXT(GL_DRAW_FRAMEBUFFER_BINDING_EXT, dfb);
710 gl->ReadBuffer(rb);
711 gl->DrawBuffer(db);
712
713 *ppvImage = pvImage;
714 *pw = dstw;
715 *ph = dsth;
716}
717
718DECLEXPORT(void) crDbgPrint(const char *format, ... )
719{
720 va_list args;
721 static char txt[8092];
722
723 va_start(args, format);
724 vsprintf(txt, format, args);
725 va_end(args);
726
727 OutputDebugString(txt);
728}
729
730void crDbgDumpImage2D(const char* pszDesc, const void *pvData, uint32_t width, uint32_t height, uint32_t bpp, uint32_t pitch)
731{
732 crDbgPrint("<?dml?><exec cmd=\"!vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d\">%s</exec>, ( !vbvdbg.ms 0x%p 0n%d 0n%d 0n%d 0n%d )\n",
733 pvData, width, height, bpp, pitch,
734 pszDesc,
735 pvData, width, height, bpp, pitch);
736}
737
738void crDbgDumpTexImage2D(const char* pszDesc, GLint texTarget, GLint texName, GLboolean fBreak)
739{
740 GLvoid *pvImage;
741 GLint w, h;
742 crDbgGetTexImage2D(texTarget, texName, &pvImage, &w, &h);
743 crDbgPrint("%s target(%d), name(%d), width(%d), height(%d)", pszDesc, texTarget, texName, w, h);
744 crDbgDumpImage2D("texture data", pvImage, w, h, 32, (32 * w)/8);
745 if (fBreak)
746 {
747 CRASSERT(0);
748 }
749 crDbgFree(pvImage);
750}
751#endif
752
753PCR_BLITTER crServerVBoxBlitterGet()
754{
755 if (!CrBltIsInitialized(&cr_server.Blitter))
756 {
757 CR_BLITTER_CONTEXT Ctx;
758 int rc;
759 CRASSERT(cr_server.MainContextInfo.SpuContext);
760 Ctx.Base.id = cr_server.MainContextInfo.SpuContext;
761 Ctx.Base.visualBits = cr_server.MainContextInfo.CreateInfo.realVisualBits;
762 rc = CrBltInit(&cr_server.Blitter, &Ctx, true, true, NULL, &cr_server.TmpCtxDispatch);
763 if (RT_SUCCESS(rc))
764 {
765 CRASSERT(CrBltIsInitialized(&cr_server.Blitter));
766 }
767 else
768 {
769 crWarning("CrBltInit failed, rc %d", rc);
770 CRASSERT(!CrBltIsInitialized(&cr_server.Blitter));
771 return NULL;
772 }
773 }
774
775 if (!CrBltMuralGetCurrentInfo(&cr_server.Blitter)->Base.id)
776 {
777 CRMuralInfo *dummy = crServerGetDummyMural(cr_server.MainContextInfo.CreateInfo.realVisualBits);
778 CR_BLITTER_WINDOW DummyInfo;
779 CRASSERT(dummy);
780 crServerVBoxBlitterWinInit(&DummyInfo, dummy);
781 CrBltMuralSetCurrentInfo(&cr_server.Blitter, &DummyInfo);
782 }
783
784 return &cr_server.Blitter;
785}
786
787PCR_BLITTER crServerVBoxBlitterGetInitialized()
788{
789 if (CrBltIsInitialized(&cr_server.Blitter))
790 return &cr_server.Blitter;
791 return NULL;
792}
793
794
795int crServerVBoxBlitterTexInit(CRContext *ctx, CRMuralInfo *mural, PVBOXVR_TEXTURE pTex, GLboolean fDraw)
796{
797 CRTextureObj *tobj;
798 CRFramebufferObjectState *pBuf = &ctx->framebufferobject;
799 GLenum enmBuf;
800 CRFBOAttachmentPoint *pAp;
801 GLuint idx;
802 CRTextureLevel *tl;
803 CRFramebufferObject *pFBO = fDraw ? pBuf->drawFB : pBuf->readFB;
804
805 if (!pFBO)
806 {
807 GLuint hwid;
808
809 if (!mural->fRedirected)
810 {
811 WARN(("mural not redirected!"));
812 return VERR_NOT_IMPLEMENTED;
813 }
814
815 enmBuf = fDraw ? ctx->buffer.drawBuffer : ctx->buffer.readBuffer;
816 switch (enmBuf)
817 {
818 case GL_BACK:
819 case GL_BACK_RIGHT:
820 case GL_BACK_LEFT:
821 hwid = mural->aidColorTexs[CR_SERVER_FBO_BB_IDX(mural)];
822 break;
823 case GL_FRONT:
824 case GL_FRONT_RIGHT:
825 case GL_FRONT_LEFT:
826 hwid = mural->aidColorTexs[CR_SERVER_FBO_FB_IDX(mural)];
827 break;
828 default:
829 WARN(("unsupported enum buf %d", enmBuf));
830 return VERR_NOT_IMPLEMENTED;
831 break;
832 }
833
834 if (!hwid)
835 {
836 crWarning("offscreen render tex hwid is null");
837 return VERR_INVALID_STATE;
838 }
839
840 pTex->width = mural->width;
841 pTex->height = mural->height;
842 pTex->target = GL_TEXTURE_2D;
843 pTex->hwid = hwid;
844 return VINF_SUCCESS;
845 }
846
847 enmBuf = fDraw ? pFBO->drawbuffer[0] : pFBO->readbuffer;
848 idx = enmBuf - GL_COLOR_ATTACHMENT0_EXT;
849 if (idx >= CR_MAX_COLOR_ATTACHMENTS)
850 {
851 crWarning("idx is invalid %d, using 0", idx);
852 }
853
854 pAp = &pFBO->color[idx];
855
856 if (!pAp->name)
857 {
858 crWarning("no collor draw attachment");
859 return VERR_INVALID_STATE;
860 }
861
862 if (pAp->level)
863 {
864 WARN(("non-zero level not implemented"));
865 return VERR_NOT_IMPLEMENTED;
866 }
867
868 tobj = (CRTextureObj*)crHashtableSearch(ctx->shared->textureTable, pAp->name);
869 if (!tobj)
870 {
871 crWarning("no texture object found for name %d", pAp->name);
872 return VERR_INVALID_STATE;
873 }
874
875 if (tobj->target != GL_TEXTURE_2D && tobj->target != GL_TEXTURE_RECTANGLE_NV)
876 {
877 WARN(("non-texture[rect|2d] not implemented"));
878 return VERR_NOT_IMPLEMENTED;
879 }
880
881 CRASSERT(tobj->hwid);
882
883 tl = tobj->level[0];
884 pTex->width = tl->width;
885 pTex->height = tl->height;
886 pTex->target = tobj->target;
887 pTex->hwid = tobj->hwid;
888
889 return VINF_SUCCESS;
890}
891
892int crServerVBoxBlitterBlitCurrentCtx(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
893 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
894 GLbitfield mask, GLenum filter)
895{
896 PCR_BLITTER pBlitter;
897 CR_BLITTER_CONTEXT Ctx;
898 CRMuralInfo *mural;
899 CRContext *ctx = crStateGetCurrent(&cr_server.StateTracker);
900 PVBOXVR_TEXTURE pDrawTex, pReadTex;
901 VBOXVR_TEXTURE DrawTex, ReadTex;
902 int rc;
903 GLuint idDrawFBO, idReadFBO;
904 CR_BLITTER_WINDOW BltInfo;
905
906 if (mask != GL_COLOR_BUFFER_BIT)
907 {
908 WARN(("not supported blit mask %d", mask));
909 return VERR_NOT_IMPLEMENTED;
910 }
911
912 if (!cr_server.curClient)
913 {
914 crWarning("no current client");
915 return VERR_INVALID_STATE;
916 }
917 mural = cr_server.curClient->currentMural;
918 if (!mural)
919 {
920 crWarning("no current mural");
921 return VERR_INVALID_STATE;
922 }
923
924 rc = crServerVBoxBlitterTexInit(ctx, mural, &DrawTex, GL_TRUE);
925 if (RT_SUCCESS(rc))
926 {
927 pDrawTex = &DrawTex;
928 }
929 else
930 {
931 crWarning("crServerVBoxBlitterTexInit failed for draw");
932 return rc;
933 }
934
935 rc = crServerVBoxBlitterTexInit(ctx, mural, &ReadTex, GL_FALSE);
936 if (RT_SUCCESS(rc))
937 {
938 pReadTex = &ReadTex;
939 }
940 else
941 {
942// crWarning("crServerVBoxBlitterTexInit failed for read");
943 return rc;
944 }
945
946 pBlitter = crServerVBoxBlitterGet();
947 if (!pBlitter)
948 {
949 crWarning("crServerVBoxBlitterGet failed");
950 return VERR_GENERAL_FAILURE;
951 }
952
953 crServerVBoxBlitterWinInit(&BltInfo, mural);
954
955 crServerVBoxBlitterCtxInit(&Ctx, cr_server.curClient->currentCtxInfo);
956
957 CrBltMuralSetCurrentInfo(pBlitter, &BltInfo);
958
959 idDrawFBO = CR_SERVER_FBO_FOR_IDX(mural, mural->iCurDrawBuffer);
960 idReadFBO = CR_SERVER_FBO_FOR_IDX(mural, mural->iCurReadBuffer);
961
962 crStateSwitchPrepare(NULL, ctx, idDrawFBO, idReadFBO);
963
964 rc = CrBltEnter(pBlitter);
965 if (RT_SUCCESS(rc))
966 {
967 RTRECT ReadRect, DrawRect;
968 ReadRect.xLeft = srcX0;
969 ReadRect.yTop = srcY0;
970 ReadRect.xRight = srcX1;
971 ReadRect.yBottom = srcY1;
972 DrawRect.xLeft = dstX0;
973 DrawRect.yTop = dstY0;
974 DrawRect.xRight = dstX1;
975 DrawRect.yBottom = dstY1;
976 CrBltBlitTexTex(pBlitter, pReadTex, &ReadRect, pDrawTex, &DrawRect, 1, CRBLT_FLAGS_FROM_FILTER(filter));
977 CrBltLeave(pBlitter);
978 }
979 else
980 {
981 crWarning("CrBltEnter failed rc %d", rc);
982 }
983
984 crStateSwitchPostprocess(ctx, NULL, idDrawFBO, idReadFBO);
985
986 return rc;
987}
988
989void SERVER_DISPATCH_APIENTRY
990crServerDispatchBlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
991 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
992 GLbitfield mask, GLenum filter)
993{
994 CRContext *ctx = crStateGetCurrent(&cr_server.StateTracker);
995 bool fTryBlitter = false;
996#ifdef CR_CHECK_BLITS
997// {
998 SPUDispatchTable *gl = &cr_server.head_spu->dispatch_table;
999 GLint rfb=0, dfb=0, dtex=0, dlev=-1, rtex=0, rlev=-1, rb=0, db=0, ppb=0, pub=0, vp[4], otex, dstw, dsth;
1000 GLint sdtex=0, srtex=0;
1001 GLenum dStatus, rStatus;
1002
1003 CRTextureObj *tobj = 0;
1004 CRTextureLevel *tl = 0;
1005 GLint id, tuId, pbufId, pbufIdHw, ubufId, ubufIdHw, width, height, depth;
1006
1007 crDebug("===StateTracker===");
1008 crDebug("Current TU: %i", ctx->texture.curTextureUnit);
1009
1010 tobj = ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D;
1011 CRASSERT(tobj);
1012 tl = &tobj->level[0][0];
1013 crDebug("Texture %i(hw %i), w=%i, h=%i", tobj->id, tobj->hwid, tl->width, tl->height, tl->depth);
1014
1015 if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
1016 {
1017 pbufId = ctx->bufferobject.packBuffer->hwid;
1018 }
1019 else
1020 {
1021 pbufId = 0;
1022 }
1023 crDebug("Pack BufferId %i", pbufId);
1024
1025 if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
1026 {
1027 ubufId = ctx->bufferobject.unpackBuffer->hwid;
1028 }
1029 else
1030 {
1031 ubufId = 0;
1032 }
1033 crDebug("Unpack BufferId %i", ubufId);
1034
1035 crDebug("===GPU===");
1036 cr_server.head_spu->dispatch_table.GetIntegerv(GL_ACTIVE_TEXTURE, &tuId);
1037 crDebug("Current TU: %i", tuId - GL_TEXTURE0_ARB);
1038 CRASSERT(tuId - GL_TEXTURE0_ARB == ctx->texture.curTextureUnit);
1039
1040 cr_server.head_spu->dispatch_table.GetIntegerv(GL_TEXTURE_BINDING_2D, &id);
1041 cr_server.head_spu->dispatch_table.GetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
1042 cr_server.head_spu->dispatch_table.GetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
1043 cr_server.head_spu->dispatch_table.GetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_DEPTH, &depth);
1044 crDebug("Texture: %i, w=%i, h=%i, d=%i", id, width, height, depth);
1045 CRASSERT(id == tobj->hwid);
1046 CRASSERT(width == tl->width);
1047 CRASSERT(height == tl->height);
1048 CRASSERT(depth == tl->depth);
1049
1050 cr_server.head_spu->dispatch_table.GetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, &pbufIdHw);
1051 crDebug("Hw Pack BufferId %i", pbufIdHw);
1052 CRASSERT(pbufIdHw == pbufId);
1053
1054 cr_server.head_spu->dispatch_table.GetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &ubufIdHw);
1055 crDebug("Hw Unpack BufferId %i", ubufIdHw);
1056 CRASSERT(ubufIdHw == ubufId);
1057
1058 gl->GetIntegerv(GL_READ_FRAMEBUFFER_BINDING_EXT, &rfb);
1059 gl->GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING_EXT, &dfb);
1060 gl->GetIntegerv(GL_READ_BUFFER, &rb);
1061 gl->GetIntegerv(GL_DRAW_BUFFER, &db);
1062
1063 gl->GetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, &ppb);
1064 gl->GetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &pub);
1065
1066 gl->GetIntegerv(GL_VIEWPORT, &vp[0]);
1067
1068 gl->GetIntegerv(GL_TEXTURE_BINDING_2D, &otex);
1069
1070 gl->GetFramebufferAttachmentParameterivEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT, &dtex);
1071 gl->GetFramebufferAttachmentParameterivEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT, &dlev);
1072 dStatus = gl->CheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT);
1073
1074 gl->GetFramebufferAttachmentParameterivEXT(GL_READ_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT, &rtex);
1075 gl->GetFramebufferAttachmentParameterivEXT(GL_READ_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT, &rlev);
1076 rStatus = gl->CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER_EXT);
1077
1078 if (dtex)
1079 {
1080 CRASSERT(!dlev);
1081 }
1082
1083 if (rtex)
1084 {
1085 CRASSERT(!rlev);
1086 }
1087
1088 if (ctx->framebufferobject.drawFB)
1089 {
1090 CRASSERT(dfb);
1091 CRASSERT(ctx->framebufferobject.drawFB->hwid == dfb);
1092 CRASSERT(ctx->framebufferobject.drawFB->drawbuffer[0] == db);
1093
1094 CRASSERT(dStatus==GL_FRAMEBUFFER_COMPLETE_EXT);
1095 CRASSERT(db==GL_COLOR_ATTACHMENT0_EXT);
1096
1097 CRASSERT(ctx->framebufferobject.drawFB->color[0].type == GL_TEXTURE);
1098 CRASSERT(ctx->framebufferobject.drawFB->color[0].level == 0);
1099 sdtex = ctx->framebufferobject.drawFB->color[0].name;
1100 sdtex = crStateGetTextureHWID(sdtex);
1101
1102 CRASSERT(sdtex);
1103 }
1104 else
1105 {
1106 CRASSERT(!dfb);
1107 }
1108
1109 if (ctx->framebufferobject.readFB)
1110 {
1111 CRASSERT(rfb);
1112 CRASSERT(ctx->framebufferobject.readFB->hwid == rfb);
1113
1114 CRASSERT(rStatus==GL_FRAMEBUFFER_COMPLETE_EXT);
1115
1116 CRASSERT(ctx->framebufferobject.readFB->color[0].type == GL_TEXTURE);
1117 CRASSERT(ctx->framebufferobject.readFB->color[0].level == 0);
1118 srtex = ctx->framebufferobject.readFB->color[0].name;
1119 srtex = crStateGetTextureHWID(srtex);
1120
1121 CRASSERT(srtex);
1122 }
1123 else
1124 {
1125 CRASSERT(!rfb);
1126 }
1127
1128 CRASSERT(sdtex == dtex);
1129 CRASSERT(srtex == rtex);
1130
1131// crDbgDumpTexImage2D("==> src tex:", GL_TEXTURE_2D, rtex, true);
1132// crDbgDumpTexImage2D("==> dst tex:", GL_TEXTURE_2D, dtex, true);
1133
1134// }
1135#endif
1136#ifdef CR_DUMP_BLITS
1137 SPUDispatchTable *gl = &cr_server.head_spu->dispatch_table;
1138 GLint rfb=0, dfb=0, dtex=0, dlev=-1, rb=0, db=0, ppb=0, pub=0, vp[4], otex, dstw, dsth;
1139 GLenum status;
1140 char fname[200];
1141 void *img;
1142
1143 blitnum++;
1144
1145 crDebug("[%i]BlitFramebufferEXT(%i, %i, %i, %i, %i, %i, %i, %i, %x, %x)", blitnum, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
1146 crDebug("%i, %i <-> %i, %i", srcX1-srcX0, srcY1-srcY0, dstX1-dstX0, dstY1-dstY0);
1147
1148 gl->GetIntegerv(GL_READ_FRAMEBUFFER_BINDING_EXT, &rfb);
1149 gl->GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING_EXT, &dfb);
1150 gl->GetIntegerv(GL_READ_BUFFER, &rb);
1151 gl->GetIntegerv(GL_DRAW_BUFFER, &db);
1152
1153 gl->GetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, &ppb);
1154 gl->GetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &pub);
1155
1156 gl->GetIntegerv(GL_VIEWPORT, &vp[0]);
1157
1158 gl->GetIntegerv(GL_TEXTURE_BINDING_2D, &otex);
1159
1160 CRASSERT(!rfb && dfb);
1161 gl->GetFramebufferAttachmentParameterivEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT, &dtex);
1162 gl->GetFramebufferAttachmentParameterivEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT, &dlev);
1163 status = gl->CheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT);
1164
1165 CRASSERT(status==GL_FRAMEBUFFER_COMPLETE_EXT
1166 && db==GL_COLOR_ATTACHMENT0_EXT
1167 && (rb==GL_FRONT || rb==GL_BACK)
1168 && !rfb && dfb && dtex && !dlev
1169 && !ppb && !pub);
1170
1171 crDebug("Src[rb 0x%x, fbo %i] Dst[db 0x%x, fbo %i(0x%x), tex %i.%i]", rb, rfb, db, dfb, status, dtex, dlev);
1172 crDebug("Viewport [%i, %i, %i, %i]", vp[0], vp[1], vp[2], vp[3]);
1173
1174 gl->PixelStorei(GL_PACK_ROW_LENGTH, 0);
1175 gl->PixelStorei(GL_PACK_ALIGNMENT, 1);
1176 gl->PixelStorei(GL_PACK_SKIP_PIXELS, 0);
1177 gl->PixelStorei(GL_PACK_SKIP_ROWS, 0);
1178
1179 gl->PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
1180 gl->PixelStorei(GL_UNPACK_ALIGNMENT, 1);
1181 gl->PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
1182 gl->PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
1183
1184 gl->BindTexture(GL_TEXTURE_2D, dtex);
1185 gl->GetTexLevelParameteriv(GL_TEXTURE_2D, dlev, GL_TEXTURE_WIDTH, &dstw);
1186 gl->GetTexLevelParameteriv(GL_TEXTURE_2D, dlev, GL_TEXTURE_HEIGHT, &dsth);
1187 gl->BindTexture(GL_TEXTURE_2D, otex);
1188 crDebug("Dst is %i, %i", dstw, dsth);
1189
1190 CRASSERT(vp[2]>=dstw && vp[3]>=dsth);
1191 img = crAlloc(vp[2]*vp[3]*4);
1192 CRASSERT(img);
1193
1194 gl->ReadPixels(0, 0, vp[2], vp[3], GL_BGRA, GL_UNSIGNED_BYTE, img);
1195 sprintf(fname, "blit%iA_src.tga", blitnum);
1196 crDumpNamedTGA(fname, vp[2], vp[3], img);
1197
1198 gl->BindTexture(GL_TEXTURE_2D, dtex);
1199 gl->GetTexImage(GL_TEXTURE_2D, dlev, GL_BGRA, GL_UNSIGNED_BYTE, img);
1200 sprintf(fname, "blit%iB_dst.tga", blitnum);
1201 crDumpNamedTGA(fname, dstw, dsth, img);
1202 gl->BindTexture(GL_TEXTURE_2D, otex);
1203#endif
1204
1205 if (srcY0 > srcY1)
1206 {
1207 /* work around Intel driver bug on Linux host */
1208 if (1 || dstY0 > dstY1)
1209 {
1210 /* use srcY1 < srcY2 && dstY1 < dstY2 whenever possible to avoid GPU driver bugs */
1211 int32_t tmp = srcY0;
1212 srcY0 = srcY1;
1213 srcY1 = tmp;
1214 tmp = dstY0;
1215 dstY0 = dstY1;
1216 dstY1 = tmp;
1217 }
1218 }
1219
1220 if (srcX0 > srcX1)
1221 {
1222 if (dstX0 > dstX1)
1223 {
1224 /* use srcX1 < srcX2 && dstX1 < dstX2 whenever possible to avoid GPU driver bugs */
1225 int32_t tmp = srcX0;
1226 srcX0 = srcX1;
1227 srcX1 = tmp;
1228 tmp = dstX0;
1229 dstX0 = dstX1;
1230 dstX1 = tmp;
1231 }
1232 }
1233
1234 if (cr_server.fBlitterMode)
1235 {
1236 fTryBlitter = true;
1237 }
1238
1239 if (fTryBlitter)
1240 {
1241 int rc = crServerVBoxBlitterBlitCurrentCtx(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
1242 if (RT_SUCCESS(rc))
1243 goto my_exit;
1244 }
1245
1246 if (ctx->viewport.scissorTest)
1247 cr_server.head_spu->dispatch_table.Disable(GL_SCISSOR_TEST);
1248
1249 cr_server.head_spu->dispatch_table.BlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1,
1250 dstX0, dstY0, dstX1, dstY1,
1251 mask, filter);
1252
1253 if (ctx->viewport.scissorTest)
1254 cr_server.head_spu->dispatch_table.Enable(GL_SCISSOR_TEST);
1255
1256
1257my_exit:
1258
1259//#ifdef CR_CHECK_BLITS
1260// crDbgDumpTexImage2D("<== src tex:", GL_TEXTURE_2D, rtex, true);
1261// crDbgDumpTexImage2D("<== dst tex:", GL_TEXTURE_2D, dtex, true);
1262//#endif
1263#ifdef CR_DUMP_BLITS
1264 gl->BindTexture(GL_TEXTURE_2D, dtex);
1265 gl->GetTexImage(GL_TEXTURE_2D, dlev, GL_BGRA, GL_UNSIGNED_BYTE, img);
1266 sprintf(fname, "blit%iC_res.tga", blitnum);
1267 crDumpNamedTGA(fname, dstw, dsth, img);
1268 gl->BindTexture(GL_TEXTURE_2D, otex);
1269 crFree(img);
1270#endif
1271 return;
1272}
1273
1274void SERVER_DISPATCH_APIENTRY crServerDispatchDrawBuffer( GLenum mode )
1275{
1276 crStateDrawBuffer(&cr_server.StateTracker, mode );
1277
1278 if (!crStateGetCurrent(&cr_server.StateTracker)->framebufferobject.drawFB)
1279 {
1280 if (mode == GL_FRONT || mode == GL_FRONT_LEFT || mode == GL_FRONT_RIGHT)
1281 cr_server.curClient->currentMural->bFbDraw = GL_TRUE;
1282
1283 if (crServerIsRedirectedToFBO()
1284 && cr_server.curClient->currentMural->aidFBOs[0])
1285 {
1286 CRMuralInfo *mural = cr_server.curClient->currentMural;
1287 GLint iBufferNeeded = -1;
1288 switch (mode)
1289 {
1290 case GL_BACK:
1291 case GL_BACK_LEFT:
1292 case GL_BACK_RIGHT:
1293 mode = GL_COLOR_ATTACHMENT0;
1294 iBufferNeeded = CR_SERVER_FBO_BB_IDX(mural);
1295 break;
1296 case GL_FRONT:
1297 case GL_FRONT_LEFT:
1298 case GL_FRONT_RIGHT:
1299 mode = GL_COLOR_ATTACHMENT0;
1300 iBufferNeeded = CR_SERVER_FBO_FB_IDX(mural);
1301 break;
1302 case GL_NONE:
1303 crDebug("DrawBuffer: GL_NONE");
1304 break;
1305 case GL_AUX0:
1306 crDebug("DrawBuffer: GL_AUX0");
1307 break;
1308 case GL_AUX1:
1309 crDebug("DrawBuffer: GL_AUX1");
1310 break;
1311 case GL_AUX2:
1312 crDebug("DrawBuffer: GL_AUX2");
1313 break;
1314 case GL_AUX3:
1315 crDebug("DrawBuffer: GL_AUX3");
1316 break;
1317 case GL_LEFT:
1318 crWarning("DrawBuffer: GL_LEFT not supported properly");
1319 mode = GL_COLOR_ATTACHMENT0;
1320 iBufferNeeded = CR_SERVER_FBO_BB_IDX(mural);
1321 break;
1322 case GL_RIGHT:
1323 crWarning("DrawBuffer: GL_RIGHT not supported properly");
1324 mode = GL_COLOR_ATTACHMENT0;
1325 iBufferNeeded = CR_SERVER_FBO_BB_IDX(mural);
1326 break;
1327 case GL_FRONT_AND_BACK:
1328 crWarning("DrawBuffer: GL_FRONT_AND_BACK not supported properly");
1329 mode = GL_COLOR_ATTACHMENT0;
1330 iBufferNeeded = CR_SERVER_FBO_BB_IDX(mural);
1331 break;
1332 default:
1333 crWarning("DrawBuffer: unexpected mode! 0x%x", mode);
1334 iBufferNeeded = mural->iCurDrawBuffer;
1335 break;
1336 }
1337
1338 if (iBufferNeeded != mural->iCurDrawBuffer)
1339 {
1340 mural->iCurDrawBuffer = iBufferNeeded;
1341 cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, CR_SERVER_FBO_FOR_IDX(mural, iBufferNeeded));
1342 }
1343 }
1344 }
1345
1346 cr_server.head_spu->dispatch_table.DrawBuffer( mode );
1347}
1348
1349void SERVER_DISPATCH_APIENTRY crServerDispatchDrawBuffers( GLsizei n, const GLenum* bufs )
1350{
1351 if (n == 1)
1352 {
1353 crServerDispatchDrawBuffer( bufs[0] );
1354 }
1355 else
1356 {
1357 /** @todo State tracker. */
1358 cr_server.head_spu->dispatch_table.DrawBuffers( n, bufs );
1359 }
1360}
1361
1362void SERVER_DISPATCH_APIENTRY crServerDispatchReadBuffer( GLenum mode )
1363{
1364 crStateReadBuffer(&cr_server.StateTracker, mode );
1365
1366 if (crServerIsRedirectedToFBO()
1367 && cr_server.curClient->currentMural->aidFBOs[0]
1368 && !crStateGetCurrent(&cr_server.StateTracker)->framebufferobject.readFB)
1369 {
1370 CRMuralInfo *mural = cr_server.curClient->currentMural;
1371 GLint iBufferNeeded = -1;
1372 switch (mode)
1373 {
1374 case GL_BACK:
1375 case GL_BACK_LEFT:
1376 case GL_BACK_RIGHT:
1377 mode = GL_COLOR_ATTACHMENT0;
1378 iBufferNeeded = CR_SERVER_FBO_BB_IDX(mural);
1379 break;
1380 case GL_FRONT:
1381 case GL_FRONT_LEFT:
1382 case GL_FRONT_RIGHT:
1383 mode = GL_COLOR_ATTACHMENT0;
1384 iBufferNeeded = CR_SERVER_FBO_FB_IDX(mural);
1385 break;
1386 case GL_NONE:
1387 crDebug("ReadBuffer: GL_NONE");
1388 break;
1389 case GL_AUX0:
1390 crDebug("ReadBuffer: GL_AUX0");
1391 break;
1392 case GL_AUX1:
1393 crDebug("ReadBuffer: GL_AUX1");
1394 break;
1395 case GL_AUX2:
1396 crDebug("ReadBuffer: GL_AUX2");
1397 break;
1398 case GL_AUX3:
1399 crDebug("ReadBuffer: GL_AUX3");
1400 break;
1401 case GL_LEFT:
1402 crWarning("ReadBuffer: GL_LEFT not supported properly");
1403 mode = GL_COLOR_ATTACHMENT0;
1404 iBufferNeeded = CR_SERVER_FBO_BB_IDX(mural);
1405 break;
1406 case GL_RIGHT:
1407 crWarning("ReadBuffer: GL_RIGHT not supported properly");
1408 mode = GL_COLOR_ATTACHMENT0;
1409 iBufferNeeded = CR_SERVER_FBO_BB_IDX(mural);
1410 break;
1411 case GL_FRONT_AND_BACK:
1412 crWarning("ReadBuffer: GL_FRONT_AND_BACK not supported properly");
1413 mode = GL_COLOR_ATTACHMENT0;
1414 iBufferNeeded = CR_SERVER_FBO_BB_IDX(mural);
1415 break;
1416 default:
1417 crWarning("ReadBuffer: unexpected mode! 0x%x", mode);
1418 iBufferNeeded = mural->iCurDrawBuffer;
1419 break;
1420 }
1421
1422 Assert(CR_SERVER_FBO_FOR_IDX(mural, mural->iCurReadBuffer));
1423 if (iBufferNeeded != mural->iCurReadBuffer)
1424 {
1425 mural->iCurReadBuffer = iBufferNeeded;
1426 cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_READ_FRAMEBUFFER, CR_SERVER_FBO_FOR_IDX(mural, iBufferNeeded));
1427 }
1428 }
1429 cr_server.head_spu->dispatch_table.ReadBuffer( mode );
1430}
1431
1432GLenum SERVER_DISPATCH_APIENTRY crServerDispatchGetError( void )
1433{
1434 GLenum retval, err;
1435 CRContext *ctx = crStateGetCurrent(&cr_server.StateTracker);
1436 retval = ctx->error;
1437
1438 err = cr_server.head_spu->dispatch_table.GetError();
1439 if (retval == GL_NO_ERROR)
1440 retval = err;
1441 else
1442 ctx->error = GL_NO_ERROR;
1443
1444 /* our impl has a single error flag, so we just loop here to reset all error flags to no_error */
1445 while (err != GL_NO_ERROR)
1446 err = cr_server.head_spu->dispatch_table.GetError();
1447
1448 crServerReturnValue( &retval, sizeof(retval) );
1449 return retval; /* WILL PROBABLY BE IGNORED */
1450}
1451
1452void SERVER_DISPATCH_APIENTRY
1453crServerMakeTmpCtxCurrent( GLint window, GLint nativeWindow, GLint context )
1454{
1455 CRContext *pCtx = crStateGetCurrent(&cr_server.StateTracker);
1456 CRContext *pCurCtx = NULL;
1457 GLuint idDrawFBO = 0, idReadFBO = 0;
1458 int fDoPrePostProcess = 0;
1459
1460 if (pCtx)
1461 {
1462 CRMuralInfo *pCurrentMural = cr_server.currentMural;
1463
1464 pCurCtx = cr_server.currentCtxInfo ? cr_server.currentCtxInfo->pContext : cr_server.MainContextInfo.pContext;
1465 Assert(pCurCtx == pCtx);
1466
1467 if (!context)
1468 {
1469 if (pCurrentMural)
1470 {
1471 Assert(cr_server.currentCtxInfo);
1472 context = cr_server.currentCtxInfo->SpuContext > 0 ? cr_server.currentCtxInfo->SpuContext : cr_server.MainContextInfo.SpuContext;
1473 window = pCurrentMural->spuWindow;
1474 }
1475 else
1476 {
1477 CRMuralInfo * pDummy;
1478 Assert(!cr_server.currentCtxInfo);
1479 pDummy = crServerGetDummyMural(cr_server.MainContextInfo.CreateInfo.realVisualBits);
1480 context = cr_server.MainContextInfo.SpuContext;
1481 window = pDummy->spuWindow;
1482 }
1483
1484
1485 fDoPrePostProcess = -1;
1486 }
1487 else
1488 {
1489 fDoPrePostProcess = 1;
1490 }
1491
1492 if (pCurrentMural)
1493 {
1494 idDrawFBO = CR_SERVER_FBO_FOR_IDX(pCurrentMural, pCurrentMural->iCurDrawBuffer);
1495 idReadFBO = CR_SERVER_FBO_FOR_IDX(pCurrentMural, pCurrentMural->iCurReadBuffer);
1496 }
1497 else
1498 {
1499 idDrawFBO = 0;
1500 idReadFBO = 0;
1501 }
1502 }
1503 else
1504 {
1505 /* this is a GUI thread, so no need to do anything here */
1506 }
1507
1508 if (fDoPrePostProcess > 0)
1509 crStateSwitchPrepare(NULL, pCurCtx, idDrawFBO, idReadFBO);
1510
1511 cr_server.head_spu->dispatch_table.MakeCurrent( window, nativeWindow, context);
1512
1513 if (fDoPrePostProcess < 0)
1514 crStateSwitchPostprocess(pCurCtx, NULL, idDrawFBO, idReadFBO);
1515}
1516
1517void crServerInitTmpCtxDispatch()
1518{
1519 MakeCurrentFunc_t pfnMakeCurrent;
1520
1521 crSPUInitDispatchTable(&cr_server.TmpCtxDispatch);
1522 crSPUCopyDispatchTable(&cr_server.TmpCtxDispatch, &cr_server.head_spu->dispatch_table);
1523 cr_server.TmpCtxDispatch.MakeCurrent = crServerMakeTmpCtxCurrent;
1524
1525 pfnMakeCurrent = crServerMakeTmpCtxCurrent;
1526 cr_server.head_spu->dispatch_table.ChromiumParametervCR(GL_HH_SET_TMPCTX_MAKE_CURRENT, GL_BYTE, sizeof (void*), &pfnMakeCurrent);
1527
1528}
1529
1530/* dump stuff */
1531#ifdef VBOX_WITH_CRSERVER_DUMPER
1532
1533# ifndef VBOX_WITH_CRDUMPER
1534# error "VBOX_WITH_CRDUMPER undefined!"
1535# endif
1536
1537/* first four bits are buffer dump config
1538 * second four bits are texture dump config
1539 * config flags:
1540 * 1 - blit on enter
1541 * 2 - blit on exit
1542 *
1543 *
1544 * Example:
1545 *
1546 * 0x03 - dump buffer on enter and exit
1547 * 0x22 - dump texture and buffer on exit */
1548
1549int64_t g_CrDbgDumpPid = 0;
1550unsigned long g_CrDbgDumpEnabled = 0;
1551unsigned long g_CrDbgDumpDraw = 0
1552#if 0
1553 | CR_SERVER_DUMP_F_COMPILE_SHADER
1554 | CR_SERVER_DUMP_F_LINK_PROGRAM
1555#endif
1556 ;
1557#if 0
1558 | CR_SERVER_DUMP_F_DRAW_BUFF_ENTER
1559 | CR_SERVER_DUMP_F_DRAW_BUFF_LEAVE
1560 | CR_SERVER_DUMP_F_DRAW_PROGRAM_UNIFORMS_ENTER
1561 | CR_SERVER_DUMP_F_DRAW_PROGRAM_ATTRIBS_ENTER
1562 | CR_SERVER_DUMP_F_DRAW_TEX_ENTER
1563 | CR_SERVER_DUMP_F_DRAW_PROGRAM_ENTER
1564 | CR_SERVER_DUMP_F_DRAW_STATE_ENTER
1565 | CR_SERVER_DUMP_F_SWAPBUFFERS_ENTER
1566 | CR_SERVER_DUMP_F_DRAWEL
1567 | CR_SERVER_DUMP_F_SHADER_SOURCE
1568 ;
1569#endif
1570unsigned long g_CrDbgDumpDrawFramesSettings = CR_SERVER_DUMP_F_DRAW_BUFF_ENTER
1571 | CR_SERVER_DUMP_F_DRAW_BUFF_LEAVE
1572 | CR_SERVER_DUMP_F_DRAW_TEX_ENTER
1573 | CR_SERVER_DUMP_F_DRAW_PROGRAM_ENTER
1574 | CR_SERVER_DUMP_F_COMPILE_SHADER
1575 | CR_SERVER_DUMP_F_LINK_PROGRAM
1576 | CR_SERVER_DUMP_F_SWAPBUFFERS_ENTER;
1577unsigned long g_CrDbgDumpDrawFramesAppliedSettings = 0;
1578unsigned long g_CrDbgDumpDrawFramesSavedInitSettings = 0;
1579unsigned long g_CrDbgDumpDrawFramesCount = 0;
1580
1581uint32_t g_CrDbgDumpDrawCount = 0;
1582uint32_t g_CrDbgDumpDumpOnCount = 10;
1583uint32_t g_CrDbgDumpDumpOnCountEnabled = 0;
1584uint32_t g_CrDbgDumpDumpOnCountPerform = 0;
1585uint32_t g_CrDbgDumpDrawFlags = CR_SERVER_DUMP_F_COMPILE_SHADER
1586 | CR_SERVER_DUMP_F_SHADER_SOURCE
1587 | CR_SERVER_DUMP_F_COMPILE_SHADER
1588 | CR_SERVER_DUMP_F_LINK_PROGRAM
1589 | CR_SERVER_DUMP_F_DRAW_BUFF_ENTER
1590 | CR_SERVER_DUMP_F_DRAW_BUFF_LEAVE
1591 | CR_SERVER_DUMP_F_DRAW_TEX_ENTER
1592 | CR_SERVER_DUMP_F_DRAW_PROGRAM_UNIFORMS_ENTER
1593 | CR_SERVER_DUMP_F_DRAW_PROGRAM_ATTRIBS_ENTER
1594 | CR_SERVER_DUMP_F_DRAW_PROGRAM_ENTER
1595 | CR_SERVER_DUMP_F_DRAW_STATE_ENTER
1596 | CR_SERVER_DUMP_F_SWAPBUFFERS_ENTER
1597 | CR_SERVER_DUMP_F_DRAWEL
1598 | CR_SERVER_DUMP_F_TEXPRESENT;
1599
1600void crServerDumpCheckTerm()
1601{
1602 if (!CrBltIsInitialized(&cr_server.RecorderBlitter))
1603 return;
1604
1605 CrBltTerm(&cr_server.RecorderBlitter);
1606}
1607
1608int crServerDumpCheckInit()
1609{
1610 int rc;
1611 CR_BLITTER_WINDOW BltWin;
1612 CR_BLITTER_CONTEXT BltCtx;
1613 CRMuralInfo *pBlitterMural;
1614
1615 if (!CrBltIsInitialized(&cr_server.RecorderBlitter))
1616 {
1617 pBlitterMural = crServerGetDummyMural(cr_server.MainContextInfo.CreateInfo.realVisualBits);
1618 if (!pBlitterMural)
1619 {
1620 crWarning("crServerGetDummyMural failed");
1621 return VERR_GENERAL_FAILURE;
1622 }
1623
1624 crServerVBoxBlitterWinInit(&BltWin, pBlitterMural);
1625 crServerVBoxBlitterCtxInit(&BltCtx, &cr_server.MainContextInfo);
1626
1627 rc = CrBltInit(&cr_server.RecorderBlitter, &BltCtx, true, true, NULL, &cr_server.TmpCtxDispatch);
1628 if (!RT_SUCCESS(rc))
1629 {
1630 crWarning("CrBltInit failed rc %d", rc);
1631 return rc;
1632 }
1633
1634 rc = CrBltMuralSetCurrentInfo(&cr_server.RecorderBlitter, &BltWin);
1635 if (!RT_SUCCESS(rc))
1636 {
1637 crWarning("CrBltMuralSetCurrentInfo failed rc %d", rc);
1638 return rc;
1639 }
1640 }
1641
1642#if 0
1643 crDmpDbgPrintInit(&cr_server.DbgPrintDumper);
1644 cr_server.pDumper = &cr_server.DbgPrintDumper.Base;
1645#else
1646 if (!crDmpHtmlIsInited(&cr_server.HtmlDumper))
1647 {
1648 static int cCounter = 0;
1649// crDmpHtmlInit(&cr_server.HtmlDumper, "S:\\projects\\virtualbox\\3d\\dumps\\1", "index.html");
1650 crDmpHtmlInitF(&cr_server.HtmlDumper, "/Users/oracle-mac/vbox/dump/1", "index%d.html", cCounter);
1651 cr_server.pDumper = &cr_server.HtmlDumper.Base;
1652 ++cCounter;
1653 }
1654#endif
1655
1656 crRecInit(&cr_server.Recorder, &cr_server.RecorderBlitter, &cr_server.TmpCtxDispatch, cr_server.pDumper);
1657 return VINF_SUCCESS;
1658}
1659
1660void crServerDumpShader(GLint id)
1661{
1662 CRContext *ctx = crStateGetCurrent();
1663 crRecDumpShader(&cr_server.Recorder, ctx, id, 0);
1664}
1665
1666void crServerDumpProgram(GLint id)
1667{
1668 CRContext *ctx = crStateGetCurrent();
1669 crRecDumpProgram(&cr_server.Recorder, ctx, id, 0);
1670}
1671
1672void crServerDumpCurrentProgram()
1673{
1674 CRContext *ctx = crStateGetCurrent();
1675 crRecDumpCurrentProgram(&cr_server.Recorder, ctx);
1676}
1677
1678void crServerDumpRecompileDumpCurrentProgram()
1679{
1680 crDmpStrF(cr_server.Recorder.pDumper, "==Dump(1)==");
1681 crServerRecompileCurrentProgram();
1682 crServerDumpCurrentProgramUniforms();
1683 crServerDumpCurrentProgramAttribs();
1684 crDmpStrF(cr_server.Recorder.pDumper, "Done Dump(1)");
1685 crServerRecompileCurrentProgram();
1686 crDmpStrF(cr_server.Recorder.pDumper, "Dump(2)");
1687 crServerRecompileCurrentProgram();
1688 crServerDumpCurrentProgramUniforms();
1689 crServerDumpCurrentProgramAttribs();
1690 crDmpStrF(cr_server.Recorder.pDumper, "Done Dump(2)");
1691}
1692
1693void crServerRecompileCurrentProgram()
1694{
1695 CRContext *ctx = crStateGetCurrent();
1696 crRecRecompileCurrentProgram(&cr_server.Recorder, ctx);
1697}
1698
1699void crServerDumpCurrentProgramUniforms()
1700{
1701 CRContext *ctx = crStateGetCurrent();
1702 crDmpStrF(cr_server.Recorder.pDumper, "==Uniforms==");
1703 crRecDumpCurrentProgramUniforms(&cr_server.Recorder, ctx);
1704 crDmpStrF(cr_server.Recorder.pDumper, "==Done Uniforms==");
1705}
1706
1707void crServerDumpCurrentProgramAttribs()
1708{
1709 CRContext *ctx = crStateGetCurrent();
1710 crDmpStrF(cr_server.Recorder.pDumper, "==Attribs==");
1711 crRecDumpCurrentProgramAttribs(&cr_server.Recorder, ctx);
1712 crDmpStrF(cr_server.Recorder.pDumper, "==Done Attribs==");
1713}
1714
1715void crServerDumpState()
1716{
1717 CRContext *ctx = crStateGetCurrent();
1718 crRecDumpGlGetState(&cr_server.Recorder, ctx);
1719 crRecDumpGlEnableState(&cr_server.Recorder, ctx);
1720}
1721
1722void crServerDumpDrawel(const char*pszFormat, ...)
1723{
1724 CRContext *ctx = crStateGetCurrent();
1725 va_list pArgList;
1726 va_start(pArgList, pszFormat);
1727 crRecDumpVertAttrV(&cr_server.Recorder, ctx, pszFormat, pArgList);
1728 va_end(pArgList);
1729}
1730
1731void crServerDumpDrawelv(GLuint idx, const char*pszElFormat, uint32_t cbEl, const void *pvVal, uint32_t cVal)
1732{
1733 CRContext *ctx = crStateGetCurrent();
1734 crRecDumpVertAttrv(&cr_server.Recorder, ctx, idx, pszElFormat, cbEl, pvVal, cVal);
1735}
1736
1737void crServerDumpBuffer(int idx)
1738{
1739 CRContextInfo *pCtxInfo = cr_server.currentCtxInfo;
1740 CRContext *ctx = crStateGetCurrent();
1741 GLint idFBO;
1742 GLint idTex;
1743 VBOXVR_TEXTURE RedirTex;
1744 int rc = crServerDumpCheckInit();
1745 idx = idx >= 0 ? idx : crServerMuralFBOIdxFromBufferName(cr_server.currentMural, pCtxInfo->pContext->buffer.drawBuffer);
1746 if (!RT_SUCCESS(rc))
1747 {
1748 crWarning("crServerDumpCheckInit failed, rc %d", rc);
1749 return;
1750 }
1751
1752 if (idx < 0)
1753 {
1754 crWarning("neg idx, unsupported");
1755 return;
1756 }
1757
1758 idFBO = CR_SERVER_FBO_FOR_IDX(cr_server.currentMural, idx);
1759 idTex = CR_SERVER_FBO_TEX_FOR_IDX(cr_server.currentMural, idx);
1760
1761 RedirTex.width = cr_server.currentMural->fboWidth;
1762 RedirTex.height = cr_server.currentMural->fboHeight;
1763 RedirTex.target = GL_TEXTURE_2D;
1764 RedirTex.hwid = idTex;
1765
1766 crRecDumpBuffer(&cr_server.Recorder, ctx, idFBO, idTex ? &RedirTex : NULL);
1767}
1768
1769void crServerDumpTexture(const VBOXVR_TEXTURE *pTex)
1770{
1771 CRContextInfo *pCtxInfo = cr_server.currentCtxInfo;
1772 CR_BLITTER_WINDOW BltWin;
1773 CR_BLITTER_CONTEXT BltCtx;
1774 CRContext *ctx = crStateGetCurrent();
1775 int rc = crServerDumpCheckInit();
1776 if (!RT_SUCCESS(rc))
1777 {
1778 crWarning("crServerDumpCheckInit failed, rc %d", rc);
1779 return;
1780 }
1781
1782 crServerVBoxBlitterWinInit(&BltWin, cr_server.currentMural);
1783 crServerVBoxBlitterCtxInit(&BltCtx, pCtxInfo);
1784
1785 crRecDumpTextureF(&cr_server.Recorder, pTex, &BltCtx, &BltWin, "Tex (%d x %d), hwid (%d) target %#x", pTex->width, pTex->height, pTex->hwid, pTex->target);
1786}
1787
1788void crServerDumpTextures()
1789{
1790 CRContextInfo *pCtxInfo = cr_server.currentCtxInfo;
1791 CRContext *ctx = crStateGetCurrent();
1792 int rc = crServerDumpCheckInit();
1793 if (!RT_SUCCESS(rc))
1794 {
1795 crWarning("crServerDumpCheckInit failed, rc %d", rc);
1796 return;
1797 }
1798
1799 crRecDumpTextures(&cr_server.Recorder, ctx);
1800}
1801
1802void crServerDumpFilterOpLeave(unsigned long event, CR_DUMPER *pDumper)
1803{
1804 if (CR_SERVER_DUMP_F_DRAW_LEAVE_ALL & event)
1805 {
1806 g_CrDbgDumpDumpOnCountPerform = 0;
1807 }
1808}
1809
1810bool crServerDumpFilterOpEnter(unsigned long event, CR_DUMPER *pDumper)
1811{
1812 if ((CR_SERVER_DUMP_F_SWAPBUFFERS_ENTER & event)
1813 || (CR_SERVER_DUMP_F_TEXPRESENT & event))
1814 {
1815 if (g_CrDbgDumpDumpOnCountEnabled == 1)
1816 g_CrDbgDumpDumpOnCountEnabled = 2;
1817 else if (g_CrDbgDumpDumpOnCountEnabled)
1818 {
1819 g_CrDbgDumpDumpOnCountEnabled = 0;
1820 if (cr_server.pDumper == &cr_server.HtmlDumper.Base)
1821 {
1822 crDmpHtmlTerm(&cr_server.HtmlDumper);
1823 cr_server.pDumper = NULL;
1824 }
1825 }
1826
1827 g_CrDbgDumpDrawCount = 0;
1828 }
1829 else if (CR_SERVER_DUMP_F_DRAW_ENTER_ALL & event)
1830 {
1831 if (g_CrDbgDumpDumpOnCountEnabled == 2)
1832 {
1833 if (g_CrDbgDumpDumpOnCount == g_CrDbgDumpDrawCount)
1834 {
1835 g_CrDbgDumpDumpOnCountPerform = 1;
1836 }
1837 ++g_CrDbgDumpDrawCount;
1838 }
1839 }
1840 if (g_CrDbgDumpDumpOnCountPerform)
1841 {
1842 if (g_CrDbgDumpDrawFlags & event)
1843 return true;
1844 }
1845 return CR_SERVER_DUMP_DEFAULT_FILTER_OP(event);
1846}
1847
1848bool crServerDumpFilterDmp(unsigned long event, CR_DUMPER *pDumper)
1849{
1850 if (g_CrDbgDumpDumpOnCountPerform)
1851 {
1852 if (g_CrDbgDumpDrawFlags & event)
1853 return true;
1854 }
1855 return CR_SERVER_DUMP_DEFAULT_FILTER_DMP(event);
1856}
1857
1858void crServerDumpFramesCheck()
1859{
1860 if (!g_CrDbgDumpDrawFramesCount)
1861 return;
1862
1863 if (!g_CrDbgDumpDrawFramesAppliedSettings)
1864 {
1865 if (!g_CrDbgDumpDrawFramesSettings)
1866 {
1867 crWarning("g_CrDbgDumpDrawFramesSettings is NULL, bump will not be started");
1868 g_CrDbgDumpDrawFramesCount = 0;
1869 return;
1870 }
1871
1872 g_CrDbgDumpDrawFramesSavedInitSettings = g_CrDbgDumpDraw;
1873 g_CrDbgDumpDrawFramesAppliedSettings = g_CrDbgDumpDrawFramesSettings;
1874 g_CrDbgDumpDraw = g_CrDbgDumpDrawFramesSettings;
1875 crDmpStrF(cr_server.Recorder.pDumper, "***Starting draw dump for %d frames, settings(0x%x)", g_CrDbgDumpDrawFramesCount, g_CrDbgDumpDraw);
1876 return;
1877 }
1878
1879 --g_CrDbgDumpDrawFramesCount;
1880
1881 if (!g_CrDbgDumpDrawFramesCount)
1882 {
1883 crDmpStrF(cr_server.Recorder.pDumper, "***Stop draw dump");
1884 g_CrDbgDumpDraw = g_CrDbgDumpDrawFramesSavedInitSettings;
1885 g_CrDbgDumpDrawFramesAppliedSettings = 0;
1886 }
1887}
1888#endif
1889
1890GLvoid crServerSpriteCoordReplEnable(GLboolean fEnable)
1891{
1892 CRContext *g = crStateGetCurrent(&cr_server.StateTracker);
1893 CRTextureState *t = &(g->texture);
1894 GLuint curTextureUnit = t->curTextureUnit;
1895 GLuint curTextureUnitRestore = curTextureUnit;
1896 GLuint i;
1897
1898 for (i = 0; i < g->limits.maxTextureUnits; ++i)
1899 {
1900 if (g->point.coordReplacement[i])
1901 {
1902 if (i != curTextureUnit)
1903 {
1904 curTextureUnit = i;
1905 cr_server.head_spu->dispatch_table.ActiveTextureARB( i + GL_TEXTURE0_ARB );
1906 }
1907
1908 cr_server.head_spu->dispatch_table.TexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, (GLint)fEnable);
1909 }
1910 }
1911
1912 if (curTextureUnit != curTextureUnitRestore)
1913 {
1914 cr_server.head_spu->dispatch_table.ActiveTextureARB( curTextureUnitRestore + GL_TEXTURE0_ARB );
1915 }
1916}
1917
1918GLvoid SERVER_DISPATCH_APIENTRY crServerDispatchDrawArrays(GLenum mode, GLint first, GLsizei count)
1919{
1920#ifdef DEBUG
1921 GLenum status = cr_server.head_spu->dispatch_table.CheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT);
1922 Assert(GL_FRAMEBUFFER_COMPLETE == status);
1923#endif
1924 if (mode == GL_POINTS)
1925 crServerSpriteCoordReplEnable(GL_TRUE);
1926 CR_SERVER_DUMP_DRAW_ENTER();
1927 CR_GLERR_CHECK(cr_server.head_spu->dispatch_table.DrawArrays(mode, first, count););
1928 CR_SERVER_DUMP_DRAW_LEAVE();
1929 if (mode == GL_POINTS)
1930 crServerSpriteCoordReplEnable(GL_FALSE);
1931}
1932
1933GLvoid SERVER_DISPATCH_APIENTRY crServerDispatchDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid * indices)
1934{
1935#ifdef DEBUG
1936 GLenum status = cr_server.head_spu->dispatch_table.CheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT);
1937 Assert(GL_FRAMEBUFFER_COMPLETE == status);
1938#endif
1939 if (mode == GL_POINTS)
1940 crServerSpriteCoordReplEnable(GL_TRUE);
1941 CR_SERVER_DUMP_DRAW_ENTER();
1942 CR_GLERR_CHECK(cr_server.head_spu->dispatch_table.DrawElements(mode, count, type, indices););
1943 CR_SERVER_DUMP_DRAW_LEAVE();
1944 if (mode == GL_POINTS)
1945 crServerSpriteCoordReplEnable(GL_FALSE);
1946}
1947
1948void SERVER_DISPATCH_APIENTRY crServerDispatchEnd( void )
1949{
1950 CRContext *g = crStateGetCurrent(&cr_server.StateTracker);
1951 GLenum mode = g->current.mode;
1952
1953 crStateEnd(&cr_server.StateTracker);
1954 cr_server.head_spu->dispatch_table.End();
1955
1956 CR_SERVER_DUMP_DRAW_LEAVE();
1957
1958 if (mode == GL_POINTS)
1959 crServerSpriteCoordReplEnable(GL_FALSE);
1960}
1961
1962void SERVER_DISPATCH_APIENTRY crServerDispatchBegin(GLenum mode)
1963{
1964#ifdef DEBUG
1965 CRContext *ctx = crStateGetCurrent(&cr_server.StateTracker);
1966 SPUDispatchTable *gl = &cr_server.head_spu->dispatch_table;
1967
1968 if (ctx->program.vpProgramBinding)
1969 {
1970 AssertRelease(ctx->program.currentVertexProgram);
1971
1972 if (ctx->program.currentVertexProgram->isARBprogram)
1973 {
1974 GLint pid=-1;
1975 gl->GetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_BINDING_ARB, &pid);
1976
1977 if ((GLuint)pid != ctx->program.currentVertexProgram->id)
1978 {
1979 crWarning("pid(%d) != ctx->program.currentVertexProgram->id(%d)", pid, ctx->program.currentVertexProgram->id);
1980 }
1981 AssertRelease((GLuint)pid == ctx->program.currentVertexProgram->id);
1982 }
1983 else
1984 {
1985 GLint pid=-1;
1986
1987 gl->GetIntegerv(GL_VERTEX_PROGRAM_BINDING_NV, &pid);
1988 if ((GLuint)pid != ctx->program.currentVertexProgram->id)
1989 {
1990 crWarning("pid(%d) != ctx->program.currentVertexProgram->id(%d)", pid, ctx->program.currentVertexProgram->id);
1991 }
1992 AssertRelease((GLuint)pid == ctx->program.currentVertexProgram->id);
1993 }
1994 }
1995 else if (ctx->glsl.activeProgram)
1996 {
1997 GLint pid=-1;
1998
1999 gl->GetIntegerv(GL_CURRENT_PROGRAM, &pid);
2000 //crDebug("pid %i, state: id %i, hwid %i", pid, ctx->glsl.activeProgram->id, ctx->glsl.activeProgram->hwid);
2001 if ((GLuint)pid != ctx->glsl.activeProgram->hwid)
2002 {
2003 crWarning("pid(%d) != ctx->glsl.activeProgram->hwid(%d)", pid, ctx->glsl.activeProgram->hwid);
2004 }
2005 AssertRelease((GLuint)pid == ctx->glsl.activeProgram->hwid);
2006 }
2007#endif
2008
2009 if (mode == GL_POINTS)
2010 crServerSpriteCoordReplEnable(GL_TRUE);
2011
2012 CR_SERVER_DUMP_DRAW_ENTER();
2013
2014 crStateBegin(&cr_server.StateTracker, mode);
2015 cr_server.head_spu->dispatch_table.Begin(mode);
2016}
2017
Note: See TracBrowser for help on using the repository browser.

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