VirtualBox

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

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

crOpenGL: workaround BlitFramebuffer host driver issues

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