VirtualBox

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

Last change on this file since 50436 was 50277, checked in by vboxsync, 11 years ago

crOpenGL: correct way of dealing with CreateInfo

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