VirtualBox

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

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

DevVGA/crOpenGL: bugfixes, logging

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

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