VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_misc.c@ 76690

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

3D: Memory allocations fixed, bugref:9251. Merged changes r125768, r125779, r125780, r125812.

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