VirtualBox

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

最後變更 在這個檔案從52095是 51559,由 vboxsync 提交於 10 年 前

crOpenGL: wglShareLists support

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

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