VirtualBox

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

Last change on this file since 45616 was 45577, checked in by vboxsync, 12 years ago

crOpenGL: fix window mgmt

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 42.6 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 cr_server.head_spu->dispatch_table.GetChromiumParametervCR( target, index, type, count, local_storage );
53
54 crServerReturnValue( local_storage, bytes );
55}
56
57void SERVER_DISPATCH_APIENTRY crServerDispatchChromiumParametervCR(GLenum target, GLenum type, GLsizei count, const GLvoid *values)
58{
59 CRMuralInfo *mural = cr_server.curClient->currentMural;
60 static int gather_connect_count = 0;
61
62 switch (target) {
63 case GL_SET_MAX_VIEWPORT_CR:
64 {
65 GLint *maxDims = (GLint *)values;
66 cr_server.limits.maxViewportDims[0] = maxDims[0];
67 cr_server.limits.maxViewportDims[1] = maxDims[1];
68 }
69 break;
70
71 case GL_TILE_INFO_CR:
72 /* message from tilesort SPU to set new tile bounds */
73 {
74 GLint numTiles, muralWidth, muralHeight, server, tiles;
75 GLint *tileBounds;
76 CRASSERT(count >= 4);
77 CRASSERT((count - 4) % 4 == 0); /* must be multiple of four */
78 CRASSERT(type == GL_INT);
79 numTiles = (count - 4) / 4;
80 tileBounds = (GLint *) values;
81 server = tileBounds[0];
82 muralWidth = tileBounds[1];
83 muralHeight = tileBounds[2];
84 tiles = tileBounds[3];
85 CRASSERT(tiles == numTiles);
86 tileBounds += 4; /* skip over header values */
87 /*crServerNewMuralTiling(mural, muralWidth, muralHeight, numTiles, tileBounds);
88 mural->viewportValidated = GL_FALSE;*/
89 }
90 break;
91
92 case GL_GATHER_DRAWPIXELS_CR:
93 if (cr_server.only_swap_once && cr_server.curClient != cr_server.clients[0])
94 break;
95 cr_server.head_spu->dispatch_table.ChromiumParametervCR( target, type, count, values );
96 break;
97
98 case GL_GATHER_CONNECT_CR:
99 /*
100 * We want the last connect to go through,
101 * otherwise we might deadlock in CheckWindowSize()
102 * in the readback spu
103 */
104 gather_connect_count++;
105 if (cr_server.only_swap_once && (gather_connect_count != cr_server.numClients))
106 {
107 break;
108 }
109 cr_server.head_spu->dispatch_table.ChromiumParametervCR( target, type, count, values );
110 gather_connect_count = 0;
111 break;
112
113 case GL_SERVER_VIEW_MATRIX_CR:
114 /* Set this server's view matrix which will get premultiplied onto the
115 * modelview matrix. For non-planar tilesort and stereo.
116 */
117 CRASSERT(count == 18);
118 CRASSERT(type == GL_FLOAT);
119 /* values[0] is the server index. Ignored here but used in tilesort SPU */
120 /* values[1] is the left/right eye index (0 or 1) */
121 {
122 const GLfloat *v = (const GLfloat *) values;
123 const int eye = v[1] == 0.0 ? 0 : 1;
124 crMatrixInitFromFloats(&cr_server.viewMatrix[eye], v + 2);
125
126 crDebug("Got GL_SERVER_VIEW_MATRIX_CR:\n"
127 " %f %f %f %f\n"
128 " %f %f %f %f\n"
129 " %f %f %f %f\n"
130 " %f %f %f %f",
131 cr_server.viewMatrix[eye].m00,
132 cr_server.viewMatrix[eye].m10,
133 cr_server.viewMatrix[eye].m20,
134 cr_server.viewMatrix[eye].m30,
135 cr_server.viewMatrix[eye].m01,
136 cr_server.viewMatrix[eye].m11,
137 cr_server.viewMatrix[eye].m21,
138 cr_server.viewMatrix[eye].m31,
139 cr_server.viewMatrix[eye].m02,
140 cr_server.viewMatrix[eye].m12,
141 cr_server.viewMatrix[eye].m22,
142 cr_server.viewMatrix[eye].m32,
143 cr_server.viewMatrix[eye].m03,
144 cr_server.viewMatrix[eye].m13,
145 cr_server.viewMatrix[eye].m23,
146 cr_server.viewMatrix[eye].m33);
147 }
148 cr_server.viewOverride = GL_TRUE;
149 break;
150
151 case GL_SERVER_PROJECTION_MATRIX_CR:
152 /* Set this server's projection matrix which will get replace the user's
153 * projection matrix. For non-planar tilesort and stereo.
154 */
155 CRASSERT(count == 18);
156 CRASSERT(type == GL_FLOAT);
157 /* values[0] is the server index. Ignored here but used in tilesort SPU */
158 /* values[1] is the left/right eye index (0 or 1) */
159 {
160 const GLfloat *v = (const GLfloat *) values;
161 const int eye = v[1] == 0.0 ? 0 : 1;
162 crMatrixInitFromFloats(&cr_server.projectionMatrix[eye], v + 2);
163
164 crDebug("Got GL_SERVER_PROJECTION_MATRIX_CR:\n"
165 " %f %f %f %f\n"
166 " %f %f %f %f\n"
167 " %f %f %f %f\n"
168 " %f %f %f %f",
169 cr_server.projectionMatrix[eye].m00,
170 cr_server.projectionMatrix[eye].m10,
171 cr_server.projectionMatrix[eye].m20,
172 cr_server.projectionMatrix[eye].m30,
173 cr_server.projectionMatrix[eye].m01,
174 cr_server.projectionMatrix[eye].m11,
175 cr_server.projectionMatrix[eye].m21,
176 cr_server.projectionMatrix[eye].m31,
177 cr_server.projectionMatrix[eye].m02,
178 cr_server.projectionMatrix[eye].m12,
179 cr_server.projectionMatrix[eye].m22,
180 cr_server.projectionMatrix[eye].m32,
181 cr_server.projectionMatrix[eye].m03,
182 cr_server.projectionMatrix[eye].m13,
183 cr_server.projectionMatrix[eye].m23,
184 cr_server.projectionMatrix[eye].m33);
185
186 if (cr_server.projectionMatrix[eye].m33 == 0.0f) {
187 float x = cr_server.projectionMatrix[eye].m00;
188 float y = cr_server.projectionMatrix[eye].m11;
189 float a = cr_server.projectionMatrix[eye].m20;
190 float b = cr_server.projectionMatrix[eye].m21;
191 float c = cr_server.projectionMatrix[eye].m22;
192 float d = cr_server.projectionMatrix[eye].m32;
193 float znear = -d / (1.0f - c);
194 float zfar = (c - 1.0f) * znear / (c + 1.0f);
195 float left = znear * (a - 1.0f) / x;
196 float right = 2.0f * znear / x + left;
197 float bottom = znear * (b - 1.0f) / y;
198 float top = 2.0f * znear / y + bottom;
199 crDebug("Frustum: left, right, bottom, top, near, far: %f, %f, %f, %f, %f, %f", left, right, bottom, top, znear, zfar);
200 }
201 else {
202 /* Todo: Add debug output for orthographic projection*/
203 }
204
205 }
206 cr_server.projectionOverride = GL_TRUE;
207 break;
208
209 default:
210 /* Pass the parameter info to the head SPU */
211 cr_server.head_spu->dispatch_table.ChromiumParametervCR( target, type, count, values );
212 break;
213 }
214}
215
216
217void SERVER_DISPATCH_APIENTRY crServerDispatchChromiumParameteriCR(GLenum target, GLint value)
218{
219 switch (target) {
220 case GL_SHARE_CONTEXT_RESOURCES_CR:
221 crStateShareContext(value);
222 break;
223 case GL_RCUSAGE_TEXTURE_SET_CR:
224 crStateSetTextureUsed(value, GL_TRUE);
225 break;
226 case GL_RCUSAGE_TEXTURE_CLEAR_CR:
227 crStateSetTextureUsed(value, GL_FALSE);
228 break;
229 case GL_SHARED_DISPLAY_LISTS_CR:
230 cr_server.sharedDisplayLists = value;
231 break;
232 case GL_SHARED_TEXTURE_OBJECTS_CR:
233 cr_server.sharedTextureObjects = value;
234 break;
235 case GL_SHARED_PROGRAMS_CR:
236 cr_server.sharedPrograms = value;
237 break;
238 case GL_SERVER_CURRENT_EYE_CR:
239 cr_server.currentEye = value ? 1 : 0;
240 break;
241 case GL_HOST_WND_CREATED_HIDDEN:
242 cr_server.bWindowsInitiallyHidden = value ? 1 : 0;
243 break;
244 default:
245 /* Pass the parameter info to the head SPU */
246 cr_server.head_spu->dispatch_table.ChromiumParameteriCR( target, value );
247 }
248}
249
250
251void SERVER_DISPATCH_APIENTRY crServerDispatchChromiumParameterfCR(GLenum target, GLfloat value)
252{
253 switch (target) {
254 case GL_SHARED_DISPLAY_LISTS_CR:
255 cr_server.sharedDisplayLists = (int) value;
256 break;
257 case GL_SHARED_TEXTURE_OBJECTS_CR:
258 cr_server.sharedTextureObjects = (int) value;
259 break;
260 case GL_SHARED_PROGRAMS_CR:
261 cr_server.sharedPrograms = (int) value;
262 break;
263 default:
264 /* Pass the parameter info to the head SPU */
265 cr_server.head_spu->dispatch_table.ChromiumParameterfCR( target, value );
266 }
267}
268
269GLint crServerGenerateID(GLint *pCounter)
270{
271 return (*pCounter)++;
272}
273
274/*#define CR_DUMP_BLITS*/
275
276#ifdef CR_DUMP_BLITS
277static int blitnum=0;
278static int copynum=0;
279#endif
280
281# ifdef DEBUG_misha
282//# define CR_CHECK_BLITS
283# include <iprt/assert.h>
284# undef CRASSERT /* iprt assert's int3 are inlined that is why are more convenient to use since they can be easily disabled individually */
285# define CRASSERT Assert
286# endif
287
288
289void SERVER_DISPATCH_APIENTRY
290crServerDispatchCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
291{
292 /*@todo pbo/fbo disabled for now as it's slower, check on other gpus*/
293 static int siHavePBO = 0;
294 static int siHaveFBO = 0;
295
296 if ((target!=GL_TEXTURE_2D) || (height>=0))
297 {
298 cr_server.head_spu->dispatch_table.CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
299
300#ifdef CR_DUMP_BLITS
301 {
302 SPUDispatchTable *gl = &cr_server.head_spu->dispatch_table;
303 void *img;
304 GLint w, h;
305 char fname[200];
306
307 copynum++;
308
309 gl->GetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
310 gl->GetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
311
312 img = crAlloc(w*h*4);
313 CRASSERT(img);
314
315 gl->GetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, img);
316 sprintf(fname, "copy_blit%i_copy_%i.tga", blitnum, copynum);
317 crDumpNamedTGA(fname, w, h, img);
318 crFree(img);
319 }
320#endif
321 }
322 else /* negative height, means we have to Yinvert the source pixels while copying */
323 {
324 SPUDispatchTable *gl = &cr_server.head_spu->dispatch_table;
325
326 if (siHavePBO<0)
327 {
328 const char *ext = (const char*)gl->GetString(GL_EXTENSIONS);
329 siHavePBO = crStrstr(ext, "GL_ARB_pixel_buffer_object") ? 1:0;
330 }
331
332 if (siHaveFBO<0)
333 {
334 const char *ext = (const char*)gl->GetString(GL_EXTENSIONS);
335 siHaveFBO = crStrstr(ext, "GL_EXT_framebuffer_object") ? 1:0;
336 }
337
338 if (siHavePBO==0 && siHaveFBO==0)
339 {
340#if 1
341 GLint dRow, sRow;
342 for (dRow=yoffset, sRow=y-height-1; dRow<yoffset-height; dRow++, sRow--)
343 {
344 gl->CopyTexSubImage2D(target, level, xoffset, dRow, x, sRow, width, 1);
345 }
346#else
347 {
348 GLint w, h, i;
349 char *img1, *img2, *sPtr, *dPtr;
350 CRContext *ctx = crStateGetCurrent();
351
352 w = ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->level[0][level].width;
353 h = ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->level[0][level].height;
354
355 img1 = crAlloc(4*w*h);
356 img2 = crAlloc(4*width*(-height));
357 CRASSERT(img1 && img2);
358
359 gl->CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, -height);
360 gl->GetTexImage(target, level, GL_RGBA, GL_UNSIGNED_BYTE, img1);
361
362 sPtr=img1+4*xoffset+4*w*yoffset;
363 dPtr=img2+4*width*(-height-1);
364
365 for (i=0; i<-height; ++i)
366 {
367 crMemcpy(dPtr, sPtr, 4*width);
368 sPtr += 4*w;
369 dPtr -= 4*width;
370 }
371
372 gl->TexSubImage2D(target, level, xoffset, yoffset, width, -height, GL_RGBA, GL_UNSIGNED_BYTE, img2);
373
374 crFree(img1);
375 crFree(img2);
376 }
377#endif
378 }
379 else if (siHaveFBO==1) /*@todo more states to set and restore here*/
380 {
381 GLuint tID, fboID;
382 GLenum status;
383 CRContext *ctx = crStateGetCurrent();
384
385 gl->GenTextures(1, &tID);
386 gl->BindTexture(target, tID);
387 gl->CopyTexImage2D(target, level, GL_RGBA, x, y, width, -height, 0);
388 gl->GenFramebuffersEXT(1, &fboID);
389 gl->BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboID);
390 gl->FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target,
391 ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->hwid, level);
392 status = gl->CheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
393 if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
394 {
395 crWarning("Framebuffer status 0x%x", status);
396 }
397
398 gl->Enable(target);
399 gl->PushAttrib(GL_VIEWPORT_BIT);
400 gl->Viewport(xoffset, yoffset, width, -height);
401 gl->MatrixMode(GL_PROJECTION);
402 gl->PushMatrix();
403 gl->LoadIdentity();
404 gl->MatrixMode(GL_MODELVIEW);
405 gl->PushMatrix();
406 gl->LoadIdentity();
407
408 gl->Disable(GL_DEPTH_TEST);
409 gl->Disable(GL_CULL_FACE);
410 gl->Disable(GL_STENCIL_TEST);
411 gl->Disable(GL_SCISSOR_TEST);
412
413 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
414 gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
415 gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
416 gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
417 gl->TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
418
419 gl->Begin(GL_QUADS);
420 gl->TexCoord2f(0.0f, 1.0f);
421 gl->Vertex2f(-1.0, -1.0);
422
423 gl->TexCoord2f(0.0f, 0.0f);
424 gl->Vertex2f(-1.0f, 1.0f);
425
426 gl->TexCoord2f(1.0f, 0.0f);
427 gl->Vertex2f(1.0f, 1.0f);
428
429 gl->TexCoord2f(1.0f, 1.0f);
430 gl->Vertex2f(1.0f, -1.0f);
431 gl->End();
432
433 gl->PopMatrix();
434 gl->MatrixMode(GL_PROJECTION);
435 gl->PopMatrix();
436 gl->PopAttrib();
437
438 gl->FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target, 0, level);
439 gl->BindFramebufferEXT(GL_FRAMEBUFFER_EXT, ctx->framebufferobject.drawFB ? ctx->framebufferobject.drawFB->hwid:0);
440 gl->BindTexture(target, ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->hwid);
441 gl->DeleteFramebuffersEXT(1, &fboID);
442 gl->DeleteTextures(1, &tID);
443
444#if 0
445 {
446 GLint dRow, sRow, w, h;
447 void *img1, *img2;
448
449 w = ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->level[0][level].width;
450 h = ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->level[0][level].height;
451
452 img1 = crAlloc(4*w*h);
453 img2 = crAlloc(4*w*h);
454 CRASSERT(img1 && img2);
455
456 gl->GetTexImage(target, level, GL_BGRA, GL_UNSIGNED_BYTE, img1);
457
458
459 for (dRow=yoffset, sRow=y-height-1; dRow<yoffset-height; dRow++, sRow--)
460 {
461 gl->CopyTexSubImage2D(target, level, xoffset, dRow, x, sRow, width, 1);
462 }
463
464 gl->GetTexImage(target, level, GL_BGRA, GL_UNSIGNED_BYTE, img2);
465
466 if (crMemcmp(img1, img2, 4*w*h))
467 {
468 crDebug("MISMATCH! (%x, %i, ->%i,%i <-%i, %i [%ix%i])", target, level, xoffset, yoffset, x, y, width, height);
469 crDumpTGA(w, h, img1);
470 crDumpTGA(w, h, img2);
471 DebugBreak();
472 }
473 crFree(img1);
474 crFree(img2);
475 }
476#endif
477 }
478 else
479 {
480 GLuint pboId, dRow, sRow;
481 CRContext *ctx = crStateGetCurrent();
482
483 gl->GenBuffersARB(1, &pboId);
484 gl->BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboId);
485 gl->BufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, -width*height*4, 0, GL_STATIC_COPY_ARB);
486
487#if 1
488 gl->ReadPixels(x, y, width, -height, GL_RGBA, GL_UNSIGNED_BYTE, 0);
489 gl->BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, ctx->bufferobject.packBuffer->hwid);
490
491 gl->BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pboId);
492 for (dRow=yoffset, sRow=-height-1; dRow<yoffset-height; dRow++, sRow--)
493 {
494 gl->TexSubImage2D(target, level, xoffset, dRow, width, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)((uintptr_t)sRow*width*4));
495 }
496#else /*few times slower again*/
497 for (dRow=0, sRow=y-height-1; dRow<-height; dRow++, sRow--)
498 {
499 gl->ReadPixels(x, sRow, width, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)((uintptr_t)dRow*width*4));
500 }
501 gl->BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, ctx->bufferobject.packBuffer->hwid);
502
503 gl->BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pboId);
504 gl->TexSubImage2D(target, level, xoffset, yoffset, width, -height, GL_RGBA, GL_UNSIGNED_BYTE, 0);
505#endif
506
507 gl->BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, ctx->bufferobject.unpackBuffer->hwid);
508 gl->DeleteBuffersARB(1, &pboId);
509 }
510 }
511}
512
513#ifdef CR_CHECK_BLITS
514void crDbgFree(void *pvData)
515{
516 crFree(pvData);
517}
518
519void crDbgGetTexImage2D(GLint texTarget, GLint texName, GLvoid **ppvImage, GLint *pw, GLint *ph)
520{
521 SPUDispatchTable *gl = &cr_server.head_spu->dispatch_table;
522 GLint ppb, pub, dstw, dsth, otex;
523 GLint pa, pr, psp, psr, ua, ur, usp, usr;
524 GLvoid *pvImage;
525 GLint rfb, dfb, rb, db;
526
527 gl->GetIntegerv(GL_READ_FRAMEBUFFER_BINDING_EXT, &rfb);
528 gl->GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING_EXT, &dfb);
529 gl->GetIntegerv(GL_READ_BUFFER, &rb);
530 gl->GetIntegerv(GL_DRAW_BUFFER, &db);
531
532 gl->BindFramebufferEXT(GL_READ_FRAMEBUFFER_BINDING_EXT, 0);
533 gl->BindFramebufferEXT(GL_DRAW_FRAMEBUFFER_BINDING_EXT, 0);
534 gl->ReadBuffer(GL_BACK);
535 gl->DrawBuffer(GL_BACK);
536
537 gl->GetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, &ppb);
538 gl->GetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &pub);
539 gl->GetIntegerv(GL_TEXTURE_BINDING_2D, &otex);
540
541 gl->GetIntegerv(GL_PACK_ROW_LENGTH, &pr);
542 gl->GetIntegerv(GL_PACK_ALIGNMENT, &pa);
543 gl->GetIntegerv(GL_PACK_SKIP_PIXELS, &psp);
544 gl->GetIntegerv(GL_PACK_SKIP_ROWS, &psr);
545
546 gl->GetIntegerv(GL_UNPACK_ROW_LENGTH, &ur);
547 gl->GetIntegerv(GL_UNPACK_ALIGNMENT, &ua);
548 gl->GetIntegerv(GL_UNPACK_SKIP_PIXELS, &usp);
549 gl->GetIntegerv(GL_UNPACK_SKIP_ROWS, &usr);
550
551 gl->BindTexture(texTarget, texName);
552 gl->GetTexLevelParameteriv(texTarget, 0, GL_TEXTURE_WIDTH, &dstw);
553 gl->GetTexLevelParameteriv(texTarget, 0, GL_TEXTURE_HEIGHT, &dsth);
554
555 gl->PixelStorei(GL_PACK_ROW_LENGTH, 0);
556 gl->PixelStorei(GL_PACK_ALIGNMENT, 1);
557 gl->PixelStorei(GL_PACK_SKIP_PIXELS, 0);
558 gl->PixelStorei(GL_PACK_SKIP_ROWS, 0);
559
560 gl->PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
561 gl->PixelStorei(GL_UNPACK_ALIGNMENT, 1);
562 gl->PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
563 gl->PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
564
565 gl->BindBufferARB(GL_PIXEL_PACK_BUFFER, 0);
566 gl->BindBufferARB(GL_PIXEL_UNPACK_BUFFER, 0);
567
568 pvImage = crAlloc(4*dstw*dsth);
569 gl->GetTexImage(texTarget, 0, GL_BGRA, GL_UNSIGNED_BYTE, pvImage);
570
571 gl->BindTexture(texTarget, otex);
572
573 gl->PixelStorei(GL_PACK_ROW_LENGTH, pr);
574 gl->PixelStorei(GL_PACK_ALIGNMENT, pa);
575 gl->PixelStorei(GL_PACK_SKIP_PIXELS, psp);
576 gl->PixelStorei(GL_PACK_SKIP_ROWS, psr);
577
578 gl->PixelStorei(GL_UNPACK_ROW_LENGTH, ur);
579 gl->PixelStorei(GL_UNPACK_ALIGNMENT, ua);
580 gl->PixelStorei(GL_UNPACK_SKIP_PIXELS, usp);
581 gl->PixelStorei(GL_UNPACK_SKIP_ROWS, usr);
582
583 gl->BindBufferARB(GL_PIXEL_PACK_BUFFER, ppb);
584 gl->BindBufferARB(GL_PIXEL_UNPACK_BUFFER, pub);
585
586 gl->BindFramebufferEXT(GL_READ_FRAMEBUFFER_BINDING_EXT, rfb);
587 gl->BindFramebufferEXT(GL_DRAW_FRAMEBUFFER_BINDING_EXT, dfb);
588 gl->ReadBuffer(rb);
589 gl->DrawBuffer(db);
590
591 *ppvImage = pvImage;
592 *pw = dstw;
593 *ph = dsth;
594}
595
596DECLEXPORT(void) crDbgPrint(const char *format, ... )
597{
598 va_list args;
599 static char txt[8092];
600
601 va_start( args, format );
602 vsprintf( txt, format, args );
603
604 OutputDebugString(txt);
605}
606
607void crDbgDumpImage2D(const char* pszDesc, const void *pvData, uint32_t width, uint32_t height, uint32_t bpp, uint32_t pitch)
608{
609 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",
610 pvData, width, height, bpp, pitch,
611 pszDesc,
612 pvData, width, height, bpp, pitch);
613}
614
615void crDbgDumpTexImage2D(const char* pszDesc, GLint texTarget, GLint texName, GLboolean fBreak)
616{
617 GLvoid *pvImage;
618 GLint w, h;
619 crDbgGetTexImage2D(texTarget, texName, &pvImage, &w, &h);
620 crDbgPrint("%s target(%d), name(%d), width(%d), height(%d)", pszDesc, texTarget, texName, w, h);
621 crDbgDumpImage2D("texture data", pvImage, w, h, 32, (32 * w)/8);
622 if (fBreak)
623 {
624 CRASSERT(0);
625 }
626 crDbgFree(pvImage);
627}
628#endif
629
630PCR_BLITTER crServerVBoxBlitterGet()
631{
632 if (!CrBltIsInitialized(&cr_server.Blitter))
633 {
634 CR_BLITTER_CONTEXT Ctx;
635 int rc;
636 CRASSERT(cr_server.MainContextInfo.SpuContext);
637 Ctx.Base.id = cr_server.MainContextInfo.SpuContext;
638 Ctx.Base.visualBits = cr_server.MainContextInfo.CreateInfo.visualBits;
639 rc = CrBltInit(&cr_server.Blitter, &Ctx, true, true, &cr_server.head_spu->dispatch_table);
640 if (RT_SUCCESS(rc))
641 {
642 CRASSERT(CrBltIsInitialized(&cr_server.Blitter));
643 }
644 else
645 {
646 crWarning("CrBltInit failed, rc %d", rc);
647 CRASSERT(!CrBltIsInitialized(&cr_server.Blitter));
648 return NULL;
649 }
650 }
651 return &cr_server.Blitter;
652}
653
654int crServerVBoxBlitterTexInit(CRContext *ctx, CRMuralInfo *mural, PVBOXVR_TEXTURE pTex, GLboolean fDraw)
655{
656 CRTextureObj *tobj;
657 CRFramebufferObjectState *pBuf = &ctx->framebufferobject;
658 GLenum enmBuf;
659 CRFBOAttachmentPoint *pAp;
660 GLuint idx;
661 CRTextureLevel *tl;
662 CRFramebufferObject *pFBO = fDraw ? pBuf->drawFB : pBuf->readFB;
663
664 if (!pFBO)
665 {
666 GLuint hwid;
667
668 if (!(mural->fPresentMode & CR_SERVER_REDIR_F_FBO))
669 return VERR_NOT_IMPLEMENTED;
670
671 enmBuf = fDraw ? ctx->buffer.drawBuffer : ctx->buffer.readBuffer;
672 switch (enmBuf)
673 {
674 case GL_BACK:
675 case GL_BACK_RIGHT:
676 case GL_BACK_LEFT:
677 hwid = mural->aidColorTexs[CR_SERVER_FBO_BB_IDX(mural)];
678 break;
679 case GL_FRONT:
680 case GL_FRONT_RIGHT:
681 case GL_FRONT_LEFT:
682 hwid = mural->aidColorTexs[CR_SERVER_FBO_FB_IDX(mural)];
683 break;
684 default:
685 crWarning("unsupported enum buf");
686 return VERR_NOT_IMPLEMENTED;
687 break;
688 }
689
690 if (!hwid)
691 {
692 crWarning("offscreen render tex hwid is null");
693 return VERR_INVALID_STATE;
694 }
695
696 pTex->width = mural->width;
697 pTex->height = mural->height;
698 pTex->target = GL_TEXTURE_2D;
699 pTex->hwid = hwid;
700 return VINF_SUCCESS;
701 }
702
703 enmBuf = fDraw ? pFBO->drawbuffer[0] : pFBO->readbuffer;
704 idx = enmBuf - GL_COLOR_ATTACHMENT0_EXT;
705 if (idx >= CR_MAX_COLOR_ATTACHMENTS)
706 {
707 crWarning("idx is invalid %d, using 0", idx);
708 }
709
710 pAp = &pFBO->color[idx];
711
712 if (!pAp->name)
713 {
714 crWarning("no collor draw attachment");
715 return VERR_INVALID_STATE;
716 }
717
718 if (pAp->level)
719 {
720 crWarning("non-zero level not implemented");
721 return VERR_NOT_IMPLEMENTED;
722 }
723
724 tobj = (CRTextureObj*)crHashtableSearch(ctx->shared->textureTable, pAp->name);
725 if (!tobj)
726 {
727 crWarning("no texture object found for name %d", pAp->name);
728 return VERR_INVALID_STATE;
729 }
730
731 if (tobj->target != GL_TEXTURE_2D && tobj->target != GL_TEXTURE_RECTANGLE_NV)
732 {
733 crWarning("non-texture[rect|2d] not implemented");
734 return VERR_NOT_IMPLEMENTED;
735 }
736
737 CRASSERT(tobj->hwid);
738
739 tl = tobj->level[0];
740 pTex->width = tl->width;
741 pTex->height = tl->height;
742 pTex->target = tobj->target;
743 pTex->hwid = tobj->hwid;
744
745 return VINF_SUCCESS;
746}
747
748int crServerVBoxBlitterBlitCurrentCtx(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
749 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
750 GLbitfield mask, GLenum filter)
751{
752 PCR_BLITTER pBlitter;
753 CR_BLITTER_CONTEXT Ctx;
754 CRMuralInfo *mural;
755 CRContext *ctx = crStateGetCurrent();
756 PVBOXVR_TEXTURE pDrawTex, pReadTex;
757 VBOXVR_TEXTURE DrawTex, ReadTex;
758 int rc;
759 GLuint idDrawFBO, idReadFBO;
760 CR_BLITTER_WINDOW BltInfo;
761
762 if (mask != GL_COLOR_BUFFER_BIT)
763 {
764 crWarning("not supported blit mask %d", mask);
765 return VERR_NOT_IMPLEMENTED;
766 }
767
768 if (!cr_server.curClient)
769 {
770 crWarning("no current client");
771 return VERR_INVALID_STATE;
772 }
773 mural = cr_server.curClient->currentMural;
774 if (!mural)
775 {
776 crWarning("no current mural");
777 return VERR_INVALID_STATE;
778 }
779
780 rc = crServerVBoxBlitterTexInit(ctx, mural, &DrawTex, GL_TRUE);
781 if (RT_SUCCESS(rc))
782 {
783 pDrawTex = &DrawTex;
784 }
785 else
786 {
787 crWarning("crServerVBoxBlitterTexInit failed for draw");
788 return rc;
789 }
790
791 rc = crServerVBoxBlitterTexInit(ctx, mural, &ReadTex, GL_FALSE);
792 if (RT_SUCCESS(rc))
793 {
794 pReadTex = &ReadTex;
795 }
796 else
797 {
798// crWarning("crServerVBoxBlitterTexInit failed for read");
799 return rc;
800 }
801
802 pBlitter = crServerVBoxBlitterGet();
803 if (!pBlitter)
804 {
805 crWarning("crServerVBoxBlitterGet failed");
806 return VERR_GENERAL_FAILURE;
807 }
808
809 crServerVBoxBlitterWinInit(&BltInfo, mural);
810
811 crServerVBoxBlitterCtxInit(&Ctx, cr_server.curClient->currentCtxInfo);
812
813 CrBltMuralSetCurrent(pBlitter, &BltInfo);
814
815 idDrawFBO = mural->aidFBOs[mural->iCurDrawBuffer];
816 idReadFBO = mural->aidFBOs[mural->iCurReadBuffer];
817
818 crStateSwitchPrepare(NULL, ctx, idDrawFBO, idReadFBO);
819
820 rc = CrBltEnter(pBlitter, &Ctx, &BltInfo);
821 if (RT_SUCCESS(rc))
822 {
823 RTRECT ReadRect, DrawRect;
824 ReadRect.xLeft = srcX0;
825 ReadRect.yTop = srcY0;
826 ReadRect.xRight = srcX1;
827 ReadRect.yBottom = srcY1;
828 DrawRect.xLeft = dstX0;
829 DrawRect.yTop = dstY0;
830 DrawRect.xRight = dstX1;
831 DrawRect.yBottom = dstY1;
832 CrBltBlitTexTex(pBlitter, pReadTex, &ReadRect, pDrawTex, &DrawRect, 1, CRBLT_FLAGS_FROM_FILTER(filter));
833 CrBltLeave(pBlitter);
834 }
835 else
836 {
837 crWarning("CrBltEnter failed rc %d", rc);
838 }
839
840 crStateSwitchPostprocess(ctx, NULL, idDrawFBO, idReadFBO);
841
842 return rc;
843}
844
845void SERVER_DISPATCH_APIENTRY
846crServerDispatchBlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
847 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
848 GLbitfield mask, GLenum filter)
849{
850 CRContext *ctx = crStateGetCurrent();
851 bool fTryBlitter = false;
852#ifdef CR_CHECK_BLITS
853// {
854 SPUDispatchTable *gl = &cr_server.head_spu->dispatch_table;
855 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;
856 GLint sdtex=0, srtex=0;
857 GLenum dStatus, rStatus;
858
859 CRTextureObj *tobj = 0;
860 CRTextureLevel *tl = 0;
861 GLint id, tuId, pbufId, pbufIdHw, ubufId, ubufIdHw, width, height, depth;
862
863 crDebug("===StateTracker===");
864 crDebug("Current TU: %i", ctx->texture.curTextureUnit);
865
866 tobj = ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D;
867 CRASSERT(tobj);
868 tl = &tobj->level[0][0];
869 crDebug("Texture %i(hw %i), w=%i, h=%i", tobj->id, tobj->hwid, tl->width, tl->height, tl->depth);
870
871 if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
872 {
873 pbufId = ctx->bufferobject.packBuffer->hwid;
874 }
875 else
876 {
877 pbufId = 0;
878 }
879 crDebug("Pack BufferId %i", pbufId);
880
881 if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
882 {
883 ubufId = ctx->bufferobject.unpackBuffer->hwid;
884 }
885 else
886 {
887 ubufId = 0;
888 }
889 crDebug("Unpack BufferId %i", ubufId);
890
891 crDebug("===GPU===");
892 cr_server.head_spu->dispatch_table.GetIntegerv(GL_ACTIVE_TEXTURE, &tuId);
893 crDebug("Current TU: %i", tuId - GL_TEXTURE0_ARB);
894 CRASSERT(tuId - GL_TEXTURE0_ARB == ctx->texture.curTextureUnit);
895
896 cr_server.head_spu->dispatch_table.GetIntegerv(GL_TEXTURE_BINDING_2D, &id);
897 cr_server.head_spu->dispatch_table.GetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
898 cr_server.head_spu->dispatch_table.GetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
899 cr_server.head_spu->dispatch_table.GetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_DEPTH, &depth);
900 crDebug("Texture: %i, w=%i, h=%i, d=%i", id, width, height, depth);
901 CRASSERT(id == tobj->hwid);
902 CRASSERT(width == tl->width);
903 CRASSERT(height == tl->height);
904 CRASSERT(depth == tl->depth);
905
906 cr_server.head_spu->dispatch_table.GetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, &pbufIdHw);
907 crDebug("Hw Pack BufferId %i", pbufIdHw);
908 CRASSERT(pbufIdHw == pbufId);
909
910 cr_server.head_spu->dispatch_table.GetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &ubufIdHw);
911 crDebug("Hw Unpack BufferId %i", ubufIdHw);
912 CRASSERT(ubufIdHw == ubufId);
913
914 gl->GetIntegerv(GL_READ_FRAMEBUFFER_BINDING_EXT, &rfb);
915 gl->GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING_EXT, &dfb);
916 gl->GetIntegerv(GL_READ_BUFFER, &rb);
917 gl->GetIntegerv(GL_DRAW_BUFFER, &db);
918
919 gl->GetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, &ppb);
920 gl->GetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &pub);
921
922 gl->GetIntegerv(GL_VIEWPORT, &vp[0]);
923
924 gl->GetIntegerv(GL_TEXTURE_BINDING_2D, &otex);
925
926 gl->GetFramebufferAttachmentParameterivEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT, &dtex);
927 gl->GetFramebufferAttachmentParameterivEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT, &dlev);
928 dStatus = gl->CheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT);
929
930 gl->GetFramebufferAttachmentParameterivEXT(GL_READ_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT, &rtex);
931 gl->GetFramebufferAttachmentParameterivEXT(GL_READ_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT, &rlev);
932 rStatus = gl->CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER_EXT);
933
934 if (dtex)
935 {
936 CRASSERT(!dlev);
937 }
938
939 if (rtex)
940 {
941 CRASSERT(!rlev);
942 }
943
944 if (ctx->framebufferobject.drawFB)
945 {
946 CRASSERT(dfb);
947 CRASSERT(ctx->framebufferobject.drawFB->hwid == dfb);
948 CRASSERT(ctx->framebufferobject.drawFB->drawbuffer[0] == db);
949
950 CRASSERT(dStatus==GL_FRAMEBUFFER_COMPLETE_EXT);
951 CRASSERT(db==GL_COLOR_ATTACHMENT0_EXT);
952
953 CRASSERT(ctx->framebufferobject.drawFB->color[0].type == GL_TEXTURE);
954 CRASSERT(ctx->framebufferobject.drawFB->color[0].level == 0);
955 sdtex = ctx->framebufferobject.drawFB->color[0].name;
956 sdtex = crStateGetTextureHWID(sdtex);
957
958 CRASSERT(sdtex);
959 }
960 else
961 {
962 CRASSERT(!dfb);
963 }
964
965 if (ctx->framebufferobject.readFB)
966 {
967 CRASSERT(rfb);
968 CRASSERT(ctx->framebufferobject.readFB->hwid == rfb);
969
970 CRASSERT(rStatus==GL_FRAMEBUFFER_COMPLETE_EXT);
971
972 CRASSERT(ctx->framebufferobject.readFB->color[0].type == GL_TEXTURE);
973 CRASSERT(ctx->framebufferobject.readFB->color[0].level == 0);
974 srtex = ctx->framebufferobject.readFB->color[0].name;
975 srtex = crStateGetTextureHWID(srtex);
976
977 CRASSERT(srtex);
978 }
979 else
980 {
981 CRASSERT(!rfb);
982 }
983
984 CRASSERT(sdtex == dtex);
985 CRASSERT(srtex == rtex);
986
987// crDbgDumpTexImage2D("==> src tex:", GL_TEXTURE_2D, rtex, true);
988// crDbgDumpTexImage2D("==> dst tex:", GL_TEXTURE_2D, dtex, true);
989
990// }
991#endif
992#ifdef CR_DUMP_BLITS
993 SPUDispatchTable *gl = &cr_server.head_spu->dispatch_table;
994 GLint rfb=0, dfb=0, dtex=0, dlev=-1, rb=0, db=0, ppb=0, pub=0, vp[4], otex, dstw, dsth;
995 GLenum status;
996 char fname[200];
997 void *img;
998
999 blitnum++;
1000
1001 crDebug("[%i]BlitFramebufferEXT(%i, %i, %i, %i, %i, %i, %i, %i, %x, %x)", blitnum, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
1002 crDebug("%i, %i <-> %i, %i", srcX1-srcX0, srcY1-srcY0, dstX1-dstX0, dstY1-dstY0);
1003
1004 gl->GetIntegerv(GL_READ_FRAMEBUFFER_BINDING_EXT, &rfb);
1005 gl->GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING_EXT, &dfb);
1006 gl->GetIntegerv(GL_READ_BUFFER, &rb);
1007 gl->GetIntegerv(GL_DRAW_BUFFER, &db);
1008
1009 gl->GetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, &ppb);
1010 gl->GetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &pub);
1011
1012 gl->GetIntegerv(GL_VIEWPORT, &vp[0]);
1013
1014 gl->GetIntegerv(GL_TEXTURE_BINDING_2D, &otex);
1015
1016 CRASSERT(!rfb && dfb);
1017 gl->GetFramebufferAttachmentParameterivEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT, &dtex);
1018 gl->GetFramebufferAttachmentParameterivEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT, &dlev);
1019 status = gl->CheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT);
1020
1021 CRASSERT(status==GL_FRAMEBUFFER_COMPLETE_EXT
1022 && db==GL_COLOR_ATTACHMENT0_EXT
1023 && (rb==GL_FRONT || rb==GL_BACK)
1024 && !rfb && dfb && dtex && !dlev
1025 && !ppb && !pub);
1026
1027 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);
1028 crDebug("Viewport [%i, %i, %i, %i]", vp[0], vp[1], vp[2], vp[3]);
1029
1030 gl->PixelStorei(GL_PACK_ROW_LENGTH, 0);
1031 gl->PixelStorei(GL_PACK_ALIGNMENT, 1);
1032 gl->PixelStorei(GL_PACK_SKIP_PIXELS, 0);
1033 gl->PixelStorei(GL_PACK_SKIP_ROWS, 0);
1034
1035 gl->PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
1036 gl->PixelStorei(GL_UNPACK_ALIGNMENT, 1);
1037 gl->PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
1038 gl->PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
1039
1040 gl->BindTexture(GL_TEXTURE_2D, dtex);
1041 gl->GetTexLevelParameteriv(GL_TEXTURE_2D, dlev, GL_TEXTURE_WIDTH, &dstw);
1042 gl->GetTexLevelParameteriv(GL_TEXTURE_2D, dlev, GL_TEXTURE_HEIGHT, &dsth);
1043 gl->BindTexture(GL_TEXTURE_2D, otex);
1044 crDebug("Dst is %i, %i", dstw, dsth);
1045
1046 CRASSERT(vp[2]>=dstw && vp[3]>=dsth);
1047 img = crAlloc(vp[2]*vp[3]*4);
1048 CRASSERT(img);
1049
1050 gl->ReadPixels(0, 0, vp[2], vp[3], GL_BGRA, GL_UNSIGNED_BYTE, img);
1051 sprintf(fname, "blit%iA_src.tga", blitnum);
1052 crDumpNamedTGA(fname, vp[2], vp[3], img);
1053
1054 gl->BindTexture(GL_TEXTURE_2D, dtex);
1055 gl->GetTexImage(GL_TEXTURE_2D, dlev, GL_BGRA, GL_UNSIGNED_BYTE, img);
1056 sprintf(fname, "blit%iB_dst.tga", blitnum);
1057 crDumpNamedTGA(fname, dstw, dsth, img);
1058 gl->BindTexture(GL_TEXTURE_2D, otex);
1059#endif
1060
1061 if (srcY0 > srcY1)
1062 {
1063 /* work around Intel driver bug on Linux host */
1064 if (1 || dstY0 > dstY1)
1065 {
1066 /* use srcY1 < srcY2 && dstY1 < dstY2 whenever possible to avoid GPU driver bugs */
1067 int32_t tmp = srcY0;
1068 srcY0 = srcY1;
1069 srcY1 = tmp;
1070 tmp = dstY0;
1071 dstY0 = dstY1;
1072 dstY1 = tmp;
1073 }
1074 }
1075
1076 if (srcX0 > srcX1)
1077 {
1078 if (dstX0 > dstX1)
1079 {
1080 /* use srcX1 < srcX2 && dstX1 < dstX2 whenever possible to avoid GPU driver bugs */
1081 int32_t tmp = srcX0;
1082 srcX0 = srcX1;
1083 srcX1 = tmp;
1084 tmp = dstX0;
1085 dstX0 = dstX1;
1086 dstX1 = tmp;
1087 }
1088 }
1089
1090 if (cr_server.fBlitterMode)
1091 {
1092 fTryBlitter = true;
1093 }
1094
1095 if (fTryBlitter)
1096 {
1097 int rc = crServerVBoxBlitterBlitCurrentCtx(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
1098 if (RT_SUCCESS(rc))
1099 goto my_exit;
1100 }
1101
1102 if (ctx->viewport.scissorTest)
1103 cr_server.head_spu->dispatch_table.Disable(GL_SCISSOR_TEST);
1104
1105 cr_server.head_spu->dispatch_table.BlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1,
1106 dstX0, dstY0, dstX1, dstY1,
1107 mask, filter);
1108
1109 if (ctx->viewport.scissorTest)
1110 cr_server.head_spu->dispatch_table.Enable(GL_SCISSOR_TEST);
1111
1112
1113my_exit:
1114
1115//#ifdef CR_CHECK_BLITS
1116// crDbgDumpTexImage2D("<== src tex:", GL_TEXTURE_2D, rtex, true);
1117// crDbgDumpTexImage2D("<== dst tex:", GL_TEXTURE_2D, dtex, true);
1118//#endif
1119#ifdef CR_DUMP_BLITS
1120 gl->BindTexture(GL_TEXTURE_2D, dtex);
1121 gl->GetTexImage(GL_TEXTURE_2D, dlev, GL_BGRA, GL_UNSIGNED_BYTE, img);
1122 sprintf(fname, "blit%iC_res.tga", blitnum);
1123 crDumpNamedTGA(fname, dstw, dsth, img);
1124 gl->BindTexture(GL_TEXTURE_2D, otex);
1125 crFree(img);
1126#endif
1127 return;
1128}
1129
1130void SERVER_DISPATCH_APIENTRY crServerDispatchDrawBuffer( GLenum mode )
1131{
1132 crStateDrawBuffer( mode );
1133
1134 if (!crStateGetCurrent()->framebufferobject.drawFB)
1135 {
1136 if (mode == GL_FRONT || mode == GL_FRONT_LEFT || mode == GL_FRONT_RIGHT)
1137 cr_server.curClient->currentMural->bFbDraw = GL_TRUE;
1138
1139 if (crServerIsRedirectedToFBO()
1140 && cr_server.curClient->currentMural->aidFBOs[0])
1141 {
1142 GLuint iBufferNeeded;
1143 switch (mode)
1144 {
1145 case GL_BACK:
1146 case GL_BACK_LEFT:
1147 case GL_BACK_RIGHT:
1148 mode = GL_COLOR_ATTACHMENT0;
1149 iBufferNeeded = CR_SERVER_FBO_BB_IDX(cr_server.curClient->currentMural);
1150 break;
1151 case GL_FRONT:
1152 case GL_FRONT_LEFT:
1153 case GL_FRONT_RIGHT:
1154 mode = GL_COLOR_ATTACHMENT0;
1155 iBufferNeeded = CR_SERVER_FBO_FB_IDX(cr_server.curClient->currentMural);
1156 break;
1157 default:
1158 crWarning("unexpected mode! 0x%x", mode);
1159 iBufferNeeded = CR_SERVER_FBO_BB_IDX(cr_server.curClient->currentMural);
1160 break;
1161 }
1162
1163 Assert(cr_server.curClient->currentMural->aidFBOs[cr_server.curClient->currentMural->iCurDrawBuffer]);
1164 if (iBufferNeeded != cr_server.curClient->currentMural->iCurDrawBuffer)
1165 {
1166 cr_server.curClient->currentMural->iCurDrawBuffer = iBufferNeeded;
1167 cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER,
1168 cr_server.curClient->currentMural->aidFBOs[iBufferNeeded]);
1169 }
1170 }
1171 }
1172
1173 cr_server.head_spu->dispatch_table.DrawBuffer( mode );
1174}
1175
1176void SERVER_DISPATCH_APIENTRY crServerDispatchReadBuffer( GLenum mode )
1177{
1178 crStateReadBuffer( mode );
1179
1180 if (crServerIsRedirectedToFBO()
1181 && cr_server.curClient->currentMural->aidFBOs[0]
1182 && !crStateGetCurrent()->framebufferobject.readFB)
1183 {
1184 GLuint iBufferNeeded;
1185 switch (mode)
1186 {
1187 case GL_BACK:
1188 case GL_BACK_LEFT:
1189 case GL_BACK_RIGHT:
1190 mode = GL_COLOR_ATTACHMENT0;
1191 iBufferNeeded = CR_SERVER_FBO_BB_IDX(cr_server.curClient->currentMural);
1192 break;
1193 case GL_FRONT:
1194 case GL_FRONT_LEFT:
1195 case GL_FRONT_RIGHT:
1196 mode = GL_COLOR_ATTACHMENT0;
1197 iBufferNeeded = CR_SERVER_FBO_FB_IDX(cr_server.curClient->currentMural);
1198 break;
1199 default:
1200 crWarning("unexpected mode! 0x%x", mode);
1201 iBufferNeeded = CR_SERVER_FBO_BB_IDX(cr_server.curClient->currentMural);
1202 break;
1203 }
1204
1205 Assert(cr_server.curClient->currentMural->aidFBOs[cr_server.curClient->currentMural->iCurReadBuffer]);
1206 if (iBufferNeeded != cr_server.curClient->currentMural->iCurReadBuffer)
1207 {
1208 cr_server.curClient->currentMural->iCurReadBuffer = iBufferNeeded;
1209 cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_READ_FRAMEBUFFER,
1210 cr_server.curClient->currentMural->aidFBOs[iBufferNeeded]);
1211 }
1212 }
1213 cr_server.head_spu->dispatch_table.ReadBuffer( mode );
1214}
1215
1216GLenum SERVER_DISPATCH_APIENTRY crServerDispatchGetError( void )
1217{
1218 GLenum retval, err;
1219 CRContext *ctx = crStateGetCurrent();
1220 retval = ctx->error;
1221
1222 err = cr_server.head_spu->dispatch_table.GetError();
1223 if (retval == GL_NO_ERROR)
1224 retval = err;
1225 else
1226 ctx->error = GL_NO_ERROR;
1227
1228 /* our impl has a single error flag, so we just loop here to reset all error flags to no_error */
1229 while (err != GL_NO_ERROR)
1230 err = cr_server.head_spu->dispatch_table.GetError();
1231
1232 crServerReturnValue( &retval, sizeof(retval) );
1233 return retval; /* WILL PROBABLY BE IGNORED */
1234}
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