VirtualBox

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

Last change on this file since 50098 was 50095, checked in by vboxsync, 11 years ago

crOpenGL: presentation infrastructure rework (still work in progress)

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