VirtualBox

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

最後變更 在這個檔案從41380是 41380,由 vboxsync 提交於 13 年 前

VRDP+3D: 3D rendering speedup: avoid unnecessary host GPU->guest VRAM->VRDP data transfers

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id
檔案大小: 34.4 KB
 
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
266void crServerCreateInfoDeleteCB(void *data)
267{
268 CRCreateInfo_t *pCreateInfo = (CRCreateInfo_t *) data;
269 if (pCreateInfo->pszDpyName)
270 crFree(pCreateInfo->pszDpyName);
271 crFree(pCreateInfo);
272}
273
274GLint crServerGenerateID(GLint *pCounter)
275{
276 return (*pCounter)++;
277}
278
279/*#define CR_DUMP_BLITS*/
280
281#ifdef CR_DUMP_BLITS
282static int blitnum=0;
283static int copynum=0;
284#endif
285
286# ifdef DEBUG_misha
287# define CR_CHECK_BLITS
288# include <iprt/assert.h>
289# undef CRASSERT /* iprt assert's int3 are inlined that is why are more convenient to use since they can be easily disabled individually */
290# define CRASSERT Assert
291# endif
292
293
294void SERVER_DISPATCH_APIENTRY
295crServerDispatchCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
296{
297 /*@todo pbo/fbo disabled for now as it's slower, check on other gpus*/
298 static int siHavePBO = 0;
299 static int siHaveFBO = 0;
300
301 if ((target!=GL_TEXTURE_2D) || (height>=0))
302 {
303 cr_server.head_spu->dispatch_table.CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
304
305#ifdef CR_DUMP_BLITS
306 {
307 SPUDispatchTable *gl = &cr_server.head_spu->dispatch_table;
308 void *img;
309 GLint w, h;
310 char fname[200];
311
312 copynum++;
313
314 gl->GetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
315 gl->GetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
316
317 img = crAlloc(w*h*4);
318 CRASSERT(img);
319
320 gl->GetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, img);
321 sprintf(fname, "copy_blit%i_copy_%i.tga", blitnum, copynum);
322 crDumpNamedTGA(fname, w, h, img);
323 crFree(img);
324 }
325#endif
326 }
327 else /* negative height, means we have to Yinvert the source pixels while copying */
328 {
329 SPUDispatchTable *gl = &cr_server.head_spu->dispatch_table;
330
331 if (siHavePBO<0)
332 {
333 const char *ext = (const char*)gl->GetString(GL_EXTENSIONS);
334 siHavePBO = crStrstr(ext, "GL_ARB_pixel_buffer_object") ? 1:0;
335 }
336
337 if (siHaveFBO<0)
338 {
339 const char *ext = (const char*)gl->GetString(GL_EXTENSIONS);
340 siHaveFBO = crStrstr(ext, "GL_EXT_framebuffer_object") ? 1:0;
341 }
342
343 if (siHavePBO==0 && siHaveFBO==0)
344 {
345#if 1
346 GLint dRow, sRow;
347 for (dRow=yoffset, sRow=y-height-1; dRow<yoffset-height; dRow++, sRow--)
348 {
349 gl->CopyTexSubImage2D(target, level, xoffset, dRow, x, sRow, width, 1);
350 }
351#else
352 {
353 GLint w, h, i;
354 char *img1, *img2, *sPtr, *dPtr;
355 CRContext *ctx = crStateGetCurrent();
356
357 w = ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->level[0][level].width;
358 h = ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->level[0][level].height;
359
360 img1 = crAlloc(4*w*h);
361 img2 = crAlloc(4*width*(-height));
362 CRASSERT(img1 && img2);
363
364 gl->CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, -height);
365 gl->GetTexImage(target, level, GL_RGBA, GL_UNSIGNED_BYTE, img1);
366
367 sPtr=img1+4*xoffset+4*w*yoffset;
368 dPtr=img2+4*width*(-height-1);
369
370 for (i=0; i<-height; ++i)
371 {
372 crMemcpy(dPtr, sPtr, 4*width);
373 sPtr += 4*w;
374 dPtr -= 4*width;
375 }
376
377 gl->TexSubImage2D(target, level, xoffset, yoffset, width, -height, GL_RGBA, GL_UNSIGNED_BYTE, img2);
378
379 crFree(img1);
380 crFree(img2);
381 }
382#endif
383 }
384 else if (siHaveFBO==1) /*@todo more states to set and restore here*/
385 {
386 GLuint tID, fboID;
387 GLenum status;
388 CRContext *ctx = crStateGetCurrent();
389
390 gl->GenTextures(1, &tID);
391 gl->BindTexture(target, tID);
392 gl->CopyTexImage2D(target, level, GL_RGBA, x, y, width, -height, 0);
393 gl->GenFramebuffersEXT(1, &fboID);
394 gl->BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboID);
395 gl->FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target,
396 ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->hwid, level);
397 status = gl->CheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
398 if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
399 {
400 crWarning("Framebuffer status 0x%x", status);
401 }
402
403 gl->Enable(target);
404 gl->PushAttrib(GL_VIEWPORT_BIT);
405 gl->Viewport(xoffset, yoffset, width, -height);
406 gl->MatrixMode(GL_PROJECTION);
407 gl->PushMatrix();
408 gl->LoadIdentity();
409 gl->MatrixMode(GL_MODELVIEW);
410 gl->PushMatrix();
411 gl->LoadIdentity();
412
413 gl->Disable(GL_DEPTH_TEST);
414 gl->Disable(GL_CULL_FACE);
415 gl->Disable(GL_STENCIL_TEST);
416 gl->Disable(GL_SCISSOR_TEST);
417
418 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
419 gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
420 gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
421 gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
422 gl->TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
423
424 gl->Begin(GL_QUADS);
425 gl->TexCoord2f(0.0f, 1.0f);
426 gl->Vertex2f(-1.0, -1.0);
427
428 gl->TexCoord2f(0.0f, 0.0f);
429 gl->Vertex2f(-1.0f, 1.0f);
430
431 gl->TexCoord2f(1.0f, 0.0f);
432 gl->Vertex2f(1.0f, 1.0f);
433
434 gl->TexCoord2f(1.0f, 1.0f);
435 gl->Vertex2f(1.0f, -1.0f);
436 gl->End();
437
438 gl->PopMatrix();
439 gl->MatrixMode(GL_PROJECTION);
440 gl->PopMatrix();
441 gl->PopAttrib();
442
443 gl->FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target, 0, level);
444 gl->BindFramebufferEXT(GL_FRAMEBUFFER_EXT, ctx->framebufferobject.drawFB ? ctx->framebufferobject.drawFB->hwid:0);
445 gl->BindTexture(target, ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->hwid);
446 gl->DeleteFramebuffersEXT(1, &fboID);
447 gl->DeleteTextures(1, &tID);
448
449#if 0
450 {
451 GLint dRow, sRow, w, h;
452 void *img1, *img2;
453
454 w = ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->level[0][level].width;
455 h = ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D->level[0][level].height;
456
457 img1 = crAlloc(4*w*h);
458 img2 = crAlloc(4*w*h);
459 CRASSERT(img1 && img2);
460
461 gl->GetTexImage(target, level, GL_BGRA, GL_UNSIGNED_BYTE, img1);
462
463
464 for (dRow=yoffset, sRow=y-height-1; dRow<yoffset-height; dRow++, sRow--)
465 {
466 gl->CopyTexSubImage2D(target, level, xoffset, dRow, x, sRow, width, 1);
467 }
468
469 gl->GetTexImage(target, level, GL_BGRA, GL_UNSIGNED_BYTE, img2);
470
471 if (crMemcmp(img1, img2, 4*w*h))
472 {
473 crDebug("MISMATCH! (%x, %i, ->%i,%i <-%i, %i [%ix%i])", target, level, xoffset, yoffset, x, y, width, height);
474 crDumpTGA(w, h, img1);
475 crDumpTGA(w, h, img2);
476 DebugBreak();
477 }
478 crFree(img1);
479 crFree(img2);
480 }
481#endif
482 }
483 else
484 {
485 GLuint pboId, dRow, sRow;
486 CRContext *ctx = crStateGetCurrent();
487
488 gl->GenBuffersARB(1, &pboId);
489 gl->BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboId);
490 gl->BufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, -width*height*4, 0, GL_STATIC_COPY_ARB);
491
492#if 1
493 gl->ReadPixels(x, y, width, -height, GL_RGBA, GL_UNSIGNED_BYTE, 0);
494 gl->BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, ctx->bufferobject.packBuffer->hwid);
495
496 gl->BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pboId);
497 for (dRow=yoffset, sRow=-height-1; dRow<yoffset-height; dRow++, sRow--)
498 {
499 gl->TexSubImage2D(target, level, xoffset, dRow, width, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)((uintptr_t)sRow*width*4));
500 }
501#else /*few times slower again*/
502 for (dRow=0, sRow=y-height-1; dRow<-height; dRow++, sRow--)
503 {
504 gl->ReadPixels(x, sRow, width, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)((uintptr_t)dRow*width*4));
505 }
506 gl->BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, ctx->bufferobject.packBuffer->hwid);
507
508 gl->BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pboId);
509 gl->TexSubImage2D(target, level, xoffset, yoffset, width, -height, GL_RGBA, GL_UNSIGNED_BYTE, 0);
510#endif
511
512 gl->BindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, ctx->bufferobject.unpackBuffer->hwid);
513 gl->DeleteBuffersARB(1, &pboId);
514 }
515 }
516}
517
518#ifdef CR_CHECK_BLITS
519void crDbgFree(void *pvData)
520{
521 crFree(pvData);
522}
523
524void crDbgGetTexImage2D(GLint texTarget, GLint texName, GLvoid **ppvImage, GLint *pw, GLint *ph)
525{
526 SPUDispatchTable *gl = &cr_server.head_spu->dispatch_table;
527 GLint ppb, pub, dstw, dsth, otex;
528 GLint pa, pr, psp, psr, ua, ur, usp, usr;
529 GLvoid *pvImage;
530 GLint rfb, dfb, rb, db;
531
532 gl->GetIntegerv(GL_READ_FRAMEBUFFER_BINDING_EXT, &rfb);
533 gl->GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING_EXT, &dfb);
534 gl->GetIntegerv(GL_READ_BUFFER, &rb);
535 gl->GetIntegerv(GL_DRAW_BUFFER, &db);
536
537 gl->BindFramebufferEXT(GL_READ_FRAMEBUFFER_BINDING_EXT, 0);
538 gl->BindFramebufferEXT(GL_DRAW_FRAMEBUFFER_BINDING_EXT, 0);
539 gl->ReadBuffer(GL_BACK);
540 gl->DrawBuffer(GL_BACK);
541
542 gl->GetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, &ppb);
543 gl->GetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &pub);
544 gl->GetIntegerv(GL_TEXTURE_BINDING_2D, &otex);
545
546 gl->GetIntegerv(GL_PACK_ROW_LENGTH, &pr);
547 gl->GetIntegerv(GL_PACK_ALIGNMENT, &pa);
548 gl->GetIntegerv(GL_PACK_SKIP_PIXELS, &psp);
549 gl->GetIntegerv(GL_PACK_SKIP_ROWS, &psr);
550
551 gl->GetIntegerv(GL_UNPACK_ROW_LENGTH, &ur);
552 gl->GetIntegerv(GL_UNPACK_ALIGNMENT, &ua);
553 gl->GetIntegerv(GL_UNPACK_SKIP_PIXELS, &usp);
554 gl->GetIntegerv(GL_UNPACK_SKIP_ROWS, &usr);
555
556 gl->BindTexture(texTarget, texName);
557 gl->GetTexLevelParameteriv(texTarget, 0, GL_TEXTURE_WIDTH, &dstw);
558 gl->GetTexLevelParameteriv(texTarget, 0, GL_TEXTURE_HEIGHT, &dsth);
559
560 gl->PixelStorei(GL_PACK_ROW_LENGTH, 0);
561 gl->PixelStorei(GL_PACK_ALIGNMENT, 1);
562 gl->PixelStorei(GL_PACK_SKIP_PIXELS, 0);
563 gl->PixelStorei(GL_PACK_SKIP_ROWS, 0);
564
565 gl->PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
566 gl->PixelStorei(GL_UNPACK_ALIGNMENT, 1);
567 gl->PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
568 gl->PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
569
570 gl->BindBufferARB(GL_PIXEL_PACK_BUFFER, 0);
571 gl->BindBufferARB(GL_PIXEL_UNPACK_BUFFER, 0);
572
573 pvImage = crAlloc(4*dstw*dsth);
574 gl->GetTexImage(texTarget, 0, GL_BGRA, GL_UNSIGNED_BYTE, pvImage);
575
576 gl->BindTexture(texTarget, otex);
577
578 gl->PixelStorei(GL_PACK_ROW_LENGTH, pr);
579 gl->PixelStorei(GL_PACK_ALIGNMENT, pa);
580 gl->PixelStorei(GL_PACK_SKIP_PIXELS, psp);
581 gl->PixelStorei(GL_PACK_SKIP_ROWS, psr);
582
583 gl->PixelStorei(GL_UNPACK_ROW_LENGTH, ur);
584 gl->PixelStorei(GL_UNPACK_ALIGNMENT, ua);
585 gl->PixelStorei(GL_UNPACK_SKIP_PIXELS, usp);
586 gl->PixelStorei(GL_UNPACK_SKIP_ROWS, usr);
587
588 gl->BindBufferARB(GL_PIXEL_PACK_BUFFER, ppb);
589 gl->BindBufferARB(GL_PIXEL_UNPACK_BUFFER, pub);
590
591 gl->BindFramebufferEXT(GL_READ_FRAMEBUFFER_BINDING_EXT, rfb);
592 gl->BindFramebufferEXT(GL_DRAW_FRAMEBUFFER_BINDING_EXT, dfb);
593 gl->ReadBuffer(rb);
594 gl->DrawBuffer(db);
595
596 *ppvImage = pvImage;
597 *pw = dstw;
598 *ph = dsth;
599}
600
601DECLEXPORT(void) crDbgPrint(const char *format, ... )
602{
603 va_list args;
604 static char txt[8092];
605
606 va_start( args, format );
607 vsprintf( txt, format, args );
608
609 OutputDebugString(txt);
610}
611
612void crDbgDumpImage2D(const char* pszDesc, const void *pvData, uint32_t width, uint32_t height, uint32_t bpp, uint32_t pitch)
613{
614 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",
615 pvData, width, height, bpp, pitch,
616 pszDesc,
617 pvData, width, height, bpp, pitch);
618}
619
620void crDbgDumpTexImage2D(const char* pszDesc, GLint texTarget, GLint texName, GLboolean fBreak)
621{
622 GLvoid *pvImage;
623 GLint w, h;
624 crDbgGetTexImage2D(texTarget, texName, &pvImage, &w, &h);
625 crDbgPrint("%s target(%d), name(%d), width(%d), height(%d)", pszDesc, texTarget, texName, w, h);
626 crDbgDumpImage2D("texture data", pvImage, w, h, 32, (32 * w)/8);
627 if (fBreak)
628 {
629 CRASSERT(0);
630 }
631 crDbgFree(pvImage);
632}
633#endif
634
635void SERVER_DISPATCH_APIENTRY
636crServerDispatchBlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
637 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
638 GLbitfield mask, GLenum filter)
639{
640#ifdef CR_CHECK_BLITS
641// {
642 SPUDispatchTable *gl = &cr_server.head_spu->dispatch_table;
643 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;
644 GLint sdtex=0, srtex=0;
645 GLenum dStatus, rStatus;
646 CRContext *ctx = crStateGetCurrent();
647
648 CRTextureObj *tobj = 0;
649 CRTextureLevel *tl = 0;
650 GLint id, tuId, pbufId, pbufIdHw, ubufId, ubufIdHw, width, height, depth;
651
652 crDebug("===StateTracker===");
653 crDebug("Current TU: %i", ctx->texture.curTextureUnit);
654
655 tobj = ctx->texture.unit[ctx->texture.curTextureUnit].currentTexture2D;
656 CRASSERT(tobj);
657 tl = &tobj->level[0][0];
658 crDebug("Texture %i(hw %i), w=%i, h=%i", tobj->id, tobj->hwid, tl->width, tl->height, tl->depth);
659
660 if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
661 {
662 pbufId = ctx->bufferobject.packBuffer->hwid;
663 }
664 else
665 {
666 pbufId = 0;
667 }
668 crDebug("Pack BufferId %i", pbufId);
669
670 if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
671 {
672 ubufId = ctx->bufferobject.unpackBuffer->hwid;
673 }
674 else
675 {
676 ubufId = 0;
677 }
678 crDebug("Unpack BufferId %i", ubufId);
679
680 crDebug("===GPU===");
681 cr_server.head_spu->dispatch_table.GetIntegerv(GL_ACTIVE_TEXTURE, &tuId);
682 crDebug("Current TU: %i", tuId - GL_TEXTURE0_ARB);
683 CRASSERT(tuId - GL_TEXTURE0_ARB == ctx->texture.curTextureUnit);
684
685 cr_server.head_spu->dispatch_table.GetIntegerv(GL_TEXTURE_BINDING_2D, &id);
686 cr_server.head_spu->dispatch_table.GetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
687 cr_server.head_spu->dispatch_table.GetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
688 cr_server.head_spu->dispatch_table.GetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_DEPTH, &depth);
689 crDebug("Texture: %i, w=%i, h=%i, d=%i", id, width, height, depth);
690 CRASSERT(id == tobj->hwid);
691 CRASSERT(width == tl->width);
692 CRASSERT(height == tl->height);
693 CRASSERT(depth == tl->depth);
694
695 cr_server.head_spu->dispatch_table.GetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, &pbufIdHw);
696 crDebug("Hw Pack BufferId %i", pbufIdHw);
697 CRASSERT(pbufIdHw == pbufId);
698
699 cr_server.head_spu->dispatch_table.GetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &ubufIdHw);
700 crDebug("Hw Unpack BufferId %i", ubufIdHw);
701 CRASSERT(ubufIdHw == ubufId);
702
703 gl->GetIntegerv(GL_READ_FRAMEBUFFER_BINDING_EXT, &rfb);
704 gl->GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING_EXT, &dfb);
705 gl->GetIntegerv(GL_READ_BUFFER, &rb);
706 gl->GetIntegerv(GL_DRAW_BUFFER, &db);
707
708 gl->GetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, &ppb);
709 gl->GetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &pub);
710
711 gl->GetIntegerv(GL_VIEWPORT, &vp[0]);
712
713 gl->GetIntegerv(GL_TEXTURE_BINDING_2D, &otex);
714
715 gl->GetFramebufferAttachmentParameterivEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT, &dtex);
716 gl->GetFramebufferAttachmentParameterivEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT, &dlev);
717 dStatus = gl->CheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT);
718
719 gl->GetFramebufferAttachmentParameterivEXT(GL_READ_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT, &rtex);
720 gl->GetFramebufferAttachmentParameterivEXT(GL_READ_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT, &rlev);
721 rStatus = gl->CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER_EXT);
722
723 if (dtex)
724 {
725 CRASSERT(!dlev);
726 }
727
728 if (rtex)
729 {
730 CRASSERT(!rlev);
731 }
732
733 if (ctx->framebufferobject.drawFB)
734 {
735 CRASSERT(dfb);
736 CRASSERT(ctx->framebufferobject.drawFB->hwid == dfb);
737 CRASSERT(ctx->framebufferobject.drawFB->drawbuffer[0] == db);
738
739 CRASSERT(dStatus==GL_FRAMEBUFFER_COMPLETE_EXT);
740 CRASSERT(db==GL_COLOR_ATTACHMENT0_EXT);
741
742 CRASSERT(ctx->framebufferobject.drawFB->color[0].type == GL_TEXTURE);
743 CRASSERT(ctx->framebufferobject.drawFB->color[0].level == 0);
744 sdtex = ctx->framebufferobject.drawFB->color[0].name;
745 sdtex = crStateGetTextureHWID(sdtex);
746
747 CRASSERT(sdtex);
748 }
749 else
750 {
751 CRASSERT(!dfb);
752 }
753
754 if (ctx->framebufferobject.readFB)
755 {
756 CRASSERT(rfb);
757 CRASSERT(ctx->framebufferobject.readFB->hwid == rfb);
758 CRASSERT(ctx->framebufferobject.readFB->readbuffer == rb);
759
760 CRASSERT(rStatus==GL_FRAMEBUFFER_COMPLETE_EXT);
761 CRASSERT(rb==GL_COLOR_ATTACHMENT0_EXT);
762
763 CRASSERT(ctx->framebufferobject.readFB->color[0].type == GL_TEXTURE);
764 CRASSERT(ctx->framebufferobject.readFB->color[0].level == 0);
765 srtex = ctx->framebufferobject.readFB->color[0].name;
766 srtex = crStateGetTextureHWID(srtex);
767
768 CRASSERT(srtex);
769 }
770 else
771 {
772 CRASSERT(!rfb);
773 }
774
775 CRASSERT(sdtex == dtex);
776 CRASSERT(srtex == rtex);
777
778// crDbgDumpTexImage2D("==> src tex:", GL_TEXTURE_2D, rtex, true);
779// crDbgDumpTexImage2D("==> dst tex:", GL_TEXTURE_2D, dtex, true);
780
781// }
782#endif
783#ifdef CR_DUMP_BLITS
784 SPUDispatchTable *gl = &cr_server.head_spu->dispatch_table;
785 GLint rfb=0, dfb=0, dtex=0, dlev=-1, rb=0, db=0, ppb=0, pub=0, vp[4], otex, dstw, dsth;
786 GLenum status;
787 char fname[200];
788 void *img;
789
790 blitnum++;
791
792 crDebug("[%i]BlitFramebufferEXT(%i, %i, %i, %i, %i, %i, %i, %i, %x, %x)", blitnum, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
793 crDebug("%i, %i <-> %i, %i", srcX1-srcX0, srcY1-srcY0, dstX1-dstX0, dstY1-dstY0);
794
795 gl->GetIntegerv(GL_READ_FRAMEBUFFER_BINDING_EXT, &rfb);
796 gl->GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING_EXT, &dfb);
797 gl->GetIntegerv(GL_READ_BUFFER, &rb);
798 gl->GetIntegerv(GL_DRAW_BUFFER, &db);
799
800 gl->GetIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, &ppb);
801 gl->GetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &pub);
802
803 gl->GetIntegerv(GL_VIEWPORT, &vp[0]);
804
805 gl->GetIntegerv(GL_TEXTURE_BINDING_2D, &otex);
806
807 CRASSERT(!rfb && dfb);
808 gl->GetFramebufferAttachmentParameterivEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT, &dtex);
809 gl->GetFramebufferAttachmentParameterivEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT, &dlev);
810 status = gl->CheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT);
811
812 CRASSERT(status==GL_FRAMEBUFFER_COMPLETE_EXT
813 && db==GL_COLOR_ATTACHMENT0_EXT
814 && (rb==GL_FRONT || rb==GL_BACK)
815 && !rfb && dfb && dtex && !dlev
816 && !ppb && !pub);
817
818 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);
819 crDebug("Viewport [%i, %i, %i, %i]", vp[0], vp[1], vp[2], vp[3]);
820
821 gl->PixelStorei(GL_PACK_ROW_LENGTH, 0);
822 gl->PixelStorei(GL_PACK_ALIGNMENT, 1);
823 gl->PixelStorei(GL_PACK_SKIP_PIXELS, 0);
824 gl->PixelStorei(GL_PACK_SKIP_ROWS, 0);
825
826 gl->PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
827 gl->PixelStorei(GL_UNPACK_ALIGNMENT, 1);
828 gl->PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
829 gl->PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
830
831 gl->BindTexture(GL_TEXTURE_2D, dtex);
832 gl->GetTexLevelParameteriv(GL_TEXTURE_2D, dlev, GL_TEXTURE_WIDTH, &dstw);
833 gl->GetTexLevelParameteriv(GL_TEXTURE_2D, dlev, GL_TEXTURE_HEIGHT, &dsth);
834 gl->BindTexture(GL_TEXTURE_2D, otex);
835 crDebug("Dst is %i, %i", dstw, dsth);
836
837 CRASSERT(vp[2]>=dstw && vp[3]>=dsth);
838 img = crAlloc(vp[2]*vp[3]*4);
839 CRASSERT(img);
840
841 gl->ReadPixels(0, 0, vp[2], vp[3], GL_BGRA, GL_UNSIGNED_BYTE, img);
842 sprintf(fname, "blit%iA_src.tga", blitnum);
843 crDumpNamedTGA(fname, vp[2], vp[3], img);
844
845 gl->BindTexture(GL_TEXTURE_2D, dtex);
846 gl->GetTexImage(GL_TEXTURE_2D, dlev, GL_BGRA, GL_UNSIGNED_BYTE, img);
847 sprintf(fname, "blit%iB_dst.tga", blitnum);
848 crDumpNamedTGA(fname, dstw, dsth, img);
849 gl->BindTexture(GL_TEXTURE_2D, otex);
850#endif
851
852 cr_server.head_spu->dispatch_table.BlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1,
853 dstX0, dstY0, dstX1, dstY1,
854 mask, filter);
855
856//#ifdef CR_CHECK_BLITS
857// crDbgDumpTexImage2D("<== src tex:", GL_TEXTURE_2D, rtex, true);
858// crDbgDumpTexImage2D("<== dst tex:", GL_TEXTURE_2D, dtex, true);
859//#endif
860#ifdef CR_DUMP_BLITS
861 gl->BindTexture(GL_TEXTURE_2D, dtex);
862 gl->GetTexImage(GL_TEXTURE_2D, dlev, GL_BGRA, GL_UNSIGNED_BYTE, img);
863 sprintf(fname, "blit%iC_res.tga", blitnum);
864 crDumpNamedTGA(fname, dstw, dsth, img);
865 gl->BindTexture(GL_TEXTURE_2D, otex);
866 crFree(img);
867#endif
868}
869
870void SERVER_DISPATCH_APIENTRY crServerDispatchDrawBuffer( GLenum mode )
871{
872 crStateDrawBuffer( mode );
873
874 if (!crStateGetCurrent()->framebufferobject.drawFB)
875 {
876 if (mode == GL_FRONT || mode == GL_FRONT_LEFT)
877 cr_server.curClient->currentMural->bFbDraw = GL_TRUE;
878
879 if (cr_server.curClient->currentMural->bUseFBO && crServerIsRedirectedToFBO()
880 && cr_server.curClient->currentMural->idFBO)
881 {
882 switch (mode)
883 {
884 case GL_BACK:
885 case GL_BACK_LEFT:
886 mode = GL_COLOR_ATTACHMENT0;
887 break;
888 case GL_FRONT:
889 case GL_FRONT_LEFT:
890 crDebug("Setting GL_FRONT with FBO mode! (0x%x)", mode);
891 mode = GL_COLOR_ATTACHMENT0;
892 break;
893 default:
894 crWarning("unexpected mode! 0x%x", mode);
895 break;
896 }
897 }
898 }
899
900#ifdef DEBUG_misha
901 cr_server.head_spu->dispatch_table.GetError();
902#endif
903 cr_server.head_spu->dispatch_table.DrawBuffer( mode );
904#ifdef DEBUG_misha
905 {
906 GLint db = 0;
907 GLenum err = cr_server.head_spu->dispatch_table.GetError();
908 cr_server.head_spu->dispatch_table.GetIntegerv(GL_DRAW_BUFFER, &db);
909 Assert(db == mode);
910 }
911#endif
912}
913
914void SERVER_DISPATCH_APIENTRY crServerDispatchReadBuffer( GLenum mode )
915{
916 crStateReadBuffer( mode );
917
918 if (cr_server.curClient->currentMural->bUseFBO && crServerIsRedirectedToFBO()
919 && cr_server.curClient->currentMural->idFBO
920 && !crStateGetCurrent()->framebufferobject.readFB)
921 {
922 switch (mode)
923 {
924 case GL_BACK:
925 case GL_BACK_LEFT:
926 mode = GL_COLOR_ATTACHMENT0;
927 break;
928 case GL_FRONT:
929 case GL_FRONT_LEFT:
930 crWarning("GL_FRONT not supported for FBO mode!");
931 mode = GL_COLOR_ATTACHMENT0;
932 break;
933 default:
934 crWarning("unexpected mode! 0x%x", mode);
935 break;
936 }
937 }
938#ifdef DEBUG_misha
939 cr_server.head_spu->dispatch_table.GetError();
940#endif
941 cr_server.head_spu->dispatch_table.ReadBuffer( mode );
942#ifdef DEBUG_misha
943 {
944 GLint rb = 0;
945 GLenum err = cr_server.head_spu->dispatch_table.GetError();
946 cr_server.head_spu->dispatch_table.GetIntegerv(GL_READ_BUFFER, &rb);
947 Assert(rb == mode);
948 }
949#endif
950}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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