server_misc.c revision ce2cc4412def73d9a9c4663225431dd415b208e8
/* Copyright (c) 2001, Stanford University
* All rights reserved
*
* See the file LICENSE.txt for information on redistributing this software.
*/
#include "server_dispatch.h"
#include "server.h"
#include "cr_error.h"
#include "cr_mem.h"
#include "cr_string.h"
#include "cr_pixeldata.h"
{
(void) size;
(void) buffer;
crError( "Unsupported network glSelectBuffer call." );
}
void SERVER_DISPATCH_APIENTRY crServerDispatchGetChromiumParametervCR(GLenum target, GLuint index, GLenum type, GLsizei count, GLvoid *values)
{
switch (type) {
case GL_BYTE:
case GL_UNSIGNED_BYTE:
break;
case GL_SHORT:
case GL_UNSIGNED_SHORT:
break;
case GL_INT:
case GL_UNSIGNED_INT:
break;
case GL_FLOAT:
break;
case GL_DOUBLE:
break;
default:
crError("Bad type in crServerDispatchGetChromiumParametervCR");
}
switch (target)
{
case GL_DBG_CHECK_BREAK_CR:
{
if (bytes > 0)
{
int rc;
if (cr_server.RcToGuestOnce)
{
cr_server.RcToGuestOnce = 0;
}
else
{
}
if (puRc)
else
}
else
{
crWarning("zero bytes for GL_DBG_CHECK_BREAK_CR");
}
break;
}
default:
cr_server.head_spu->dispatch_table.GetChromiumParametervCR( target, index, type, count, local_storage );
break;
}
}
void SERVER_DISPATCH_APIENTRY crServerDispatchChromiumParametervCR(GLenum target, GLenum type, GLsizei count, const GLvoid *values)
{
static int gather_connect_count = 0;
switch (target) {
case GL_SET_MAX_VIEWPORT_CR:
{
}
break;
case GL_TILE_INFO_CR:
/* message from tilesort SPU to set new tile bounds */
{
server = tileBounds[0];
/*crServerNewMuralTiling(mural, muralWidth, muralHeight, numTiles, tileBounds);
mural->viewportValidated = GL_FALSE;*/
}
break;
case GL_GATHER_DRAWPIXELS_CR:
break;
break;
case GL_GATHER_CONNECT_CR:
/*
* We want the last connect to go through,
* otherwise we might deadlock in CheckWindowSize()
* in the readback spu
*/
{
break;
}
gather_connect_count = 0;
break;
case GL_SERVER_VIEW_MATRIX_CR:
/* Set this server's view matrix which will get premultiplied onto the
* modelview matrix. For non-planar tilesort and stereo.
*/
/* values[0] is the server index. Ignored here but used in tilesort SPU */
{
crDebug("Got GL_SERVER_VIEW_MATRIX_CR:\n"
" %f %f %f %f\n"
" %f %f %f %f\n"
" %f %f %f %f\n"
" %f %f %f %f",
}
break;
/* Set this server's projection matrix which will get replace the user's
* projection matrix. For non-planar tilesort and stereo.
*/
/* values[0] is the server index. Ignored here but used in tilesort SPU */
{
crDebug("Got GL_SERVER_PROJECTION_MATRIX_CR:\n"
" %f %f %f %f\n"
" %f %f %f %f\n"
" %f %f %f %f\n"
" %f %f %f %f",
float znear = -d / (1.0f - c);
crDebug("Frustum: left, right, bottom, top, near, far: %f, %f, %f, %f, %f, %f", left, right, bottom, top, znear, zfar);
}
else {
/* Todo: Add debug output for orthographic projection*/
}
}
break;
default:
/* Pass the parameter info to the head SPU */
break;
}
}
{
switch (target) {
break;
break;
break;
break;
break;
case GL_SHARED_PROGRAMS_CR:
break;
case GL_SERVER_CURRENT_EYE_CR:
break;
break;
default:
/* Pass the parameter info to the head SPU */
}
}
{
switch (target) {
break;
break;
case GL_SHARED_PROGRAMS_CR:
break;
default:
/* Pass the parameter info to the head SPU */
}
}
{
return (*pCounter)++;
}
/*#define CR_DUMP_BLITS*/
#ifdef CR_DUMP_BLITS
static int blitnum=0;
static int copynum=0;
#endif
# ifdef DEBUG_misha
//# define CR_CHECK_BLITS
# undef CRASSERT /* iprt assert's int3 are inlined that is why are more convenient to use since they can be easily disabled individually */
# endif
crServerDispatchCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
{
static int siHavePBO = 0;
static int siHaveFBO = 0;
{
cr_server.head_spu->dispatch_table.CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
#ifdef CR_DUMP_BLITS
{
void *img;
GLint w, h;
char fname[200];
copynum++;
}
#endif
}
else /* negative height, means we have to Yinvert the source pixels while copying */
{
if (siHavePBO<0)
{
}
if (siHaveFBO<0)
{
}
{
#if 1
{
}
#else
{
GLint w, h, i;
for (i=0; i<-height; ++i)
{
sPtr += 4*w;
}
gl->TexSubImage2D(target, level, xoffset, yoffset, width, -height, GL_RGBA, GL_UNSIGNED_BYTE, img2);
}
#endif
}
{
if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
{
}
gl->PushMatrix();
gl->LoadIdentity();
gl->PushMatrix();
gl->LoadIdentity();
gl->BindFramebufferEXT(GL_FRAMEBUFFER_EXT, ctx->framebufferobject.drawFB ? ctx->framebufferobject.drawFB->hwid:0);
#if 0
{
{
}
{
crDebug("MISMATCH! (%x, %i, ->%i,%i <-%i, %i [%ix%i])", target, level, xoffset, yoffset, x, y, width, height);
DebugBreak();
}
}
#endif
}
else
{
#if 1
{
gl->TexSubImage2D(target, level, xoffset, dRow, width, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)((uintptr_t)sRow*width*4));
}
#else /*few times slower again*/
{
}
#endif
}
}
}
#ifdef CR_CHECK_BLITS
{
}
{
}
{
static char txt[8092];
}
void crDbgDumpImage2D(const char* pszDesc, const void *pvData, uint32_t width, uint32_t height, uint32_t bpp, uint32_t pitch)
{
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",
}
{
GLint w, h;
if (fBreak)
{
CRASSERT(0);
}
}
#endif
{
{
int rc;
if (RT_SUCCESS(rc))
{
}
else
{
return NULL;
}
}
}
int crServerVBoxBlitterTexInit(CRContext *ctx, CRMuralInfo *mural, PVBOXVR_TEXTURE pTex, GLboolean fDraw)
{
if (!pFBO)
{
return VERR_NOT_IMPLEMENTED;
switch (enmBuf)
{
case GL_BACK:
case GL_BACK_RIGHT:
case GL_BACK_LEFT:
break;
case GL_FRONT:
case GL_FRONT_RIGHT:
case GL_FRONT_LEFT:
break;
default:
crWarning("unsupported enum buf");
return VERR_NOT_IMPLEMENTED;
break;
}
if (!hwid)
{
crWarning("offscreen render tex hwid is null");
return VERR_INVALID_STATE;
}
return VINF_SUCCESS;
}
if (idx >= CR_MAX_COLOR_ATTACHMENTS)
{
}
{
crWarning("no collor draw attachment");
return VERR_INVALID_STATE;
}
{
crWarning("non-zero level not implemented");
return VERR_NOT_IMPLEMENTED;
}
if (!tobj)
{
return VERR_INVALID_STATE;
}
{
crWarning("non-texture[rect|2d] not implemented");
return VERR_NOT_IMPLEMENTED;
}
return VINF_SUCCESS;
}
{
int rc;
if (mask != GL_COLOR_BUFFER_BIT)
{
return VERR_NOT_IMPLEMENTED;
}
{
crWarning("no current client");
return VERR_INVALID_STATE;
}
if (!mural)
{
crWarning("no current mural");
return VERR_INVALID_STATE;
}
if (RT_SUCCESS(rc))
{
}
else
{
crWarning("crServerVBoxBlitterTexInit failed for draw");
return rc;
}
if (RT_SUCCESS(rc))
{
}
else
{
// crWarning("crServerVBoxBlitterTexInit failed for read");
return rc;
}
if (!pBlitter)
{
crWarning("crServerVBoxBlitterGet failed");
return VERR_GENERAL_FAILURE;
}
if (RT_SUCCESS(rc))
{
CrBltBlitTexTex(pBlitter, pReadTex, &ReadRect, pDrawTex, &DrawRect, 1, CRBLT_FLAGS_FROM_FILTER(filter));
}
else
{
}
return rc;
}
{
bool fTryBlitter = false;
#ifdef CR_CHECK_BLITS
// {
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;
CRTextureObj *tobj = 0;
CRTextureLevel *tl = 0;
crDebug("===StateTracker===");
{
}
else
{
pbufId = 0;
}
{
}
else
{
ubufId = 0;
}
crDebug("===GPU===");
cr_server.head_spu->dispatch_table.GetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
cr_server.head_spu->dispatch_table.GetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
cr_server.head_spu->dispatch_table.GetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_DEPTH, &depth);
gl->GetFramebufferAttachmentParameterivEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT, &dtex);
gl->GetFramebufferAttachmentParameterivEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT, &dlev);
gl->GetFramebufferAttachmentParameterivEXT(GL_READ_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT, &rtex);
gl->GetFramebufferAttachmentParameterivEXT(GL_READ_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT, &rlev);
if (dtex)
{
}
if (rtex)
{
}
{
}
else
{
}
{
}
else
{
}
// crDbgDumpTexImage2D("==> src tex:", GL_TEXTURE_2D, rtex, true);
// crDbgDumpTexImage2D("==> dst tex:", GL_TEXTURE_2D, dtex, true);
// }
#endif
#ifdef CR_DUMP_BLITS
char fname[200];
void *img;
blitnum++;
crDebug("[%i]BlitFramebufferEXT(%i, %i, %i, %i, %i, %i, %i, %i, %x, %x)", blitnum, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
gl->GetFramebufferAttachmentParameterivEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT, &dtex);
gl->GetFramebufferAttachmentParameterivEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT, &dlev);
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);
#endif
{
/* work around Intel driver bug on Linux host */
{
/* use srcY1 < srcY2 && dstY1 < dstY2 whenever possible to avoid GPU driver bugs */
}
}
{
{
/* use srcX1 < srcX2 && dstX1 < dstX2 whenever possible to avoid GPU driver bugs */
}
}
if (cr_server.fBlitterMode)
{
fTryBlitter = true;
}
if (fTryBlitter)
{
int rc = crServerVBoxBlitterBlitCurrentCtx(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
if (RT_SUCCESS(rc))
goto my_exit;
}
//#ifdef CR_CHECK_BLITS
// crDbgDumpTexImage2D("<== src tex:", GL_TEXTURE_2D, rtex, true);
// crDbgDumpTexImage2D("<== dst tex:", GL_TEXTURE_2D, dtex, true);
//#endif
#ifdef CR_DUMP_BLITS
#endif
return;
}
{
{
{
switch (mode)
{
case GL_BACK:
case GL_BACK_LEFT:
case GL_BACK_RIGHT:
break;
case GL_FRONT:
case GL_FRONT_LEFT:
case GL_FRONT_RIGHT:
break;
case GL_NONE:
crDebug("DrawBuffer: GL_NONE");
break;
case GL_AUX0:
crDebug("DrawBuffer: GL_AUX0");
break;
case GL_AUX1:
crDebug("DrawBuffer: GL_AUX1");
break;
case GL_AUX2:
crDebug("DrawBuffer: GL_AUX2");
break;
case GL_AUX3:
crDebug("DrawBuffer: GL_AUX3");
break;
case GL_LEFT:
crWarning("DrawBuffer: GL_LEFT not supported properly");
break;
case GL_RIGHT:
crWarning("DrawBuffer: GL_RIGHT not supported properly");
break;
case GL_FRONT_AND_BACK:
crWarning("DrawBuffer: GL_FRONT_AND_BACK not supported properly");
break;
default:
break;
}
{
cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_DRAW_FRAMEBUFFER, CR_SERVER_FBO_FOR_IDX(mural, iBufferNeeded));
}
}
}
}
{
{
switch (mode)
{
case GL_BACK:
case GL_BACK_LEFT:
case GL_BACK_RIGHT:
break;
case GL_FRONT:
case GL_FRONT_LEFT:
case GL_FRONT_RIGHT:
break;
case GL_NONE:
crDebug("ReadBuffer: GL_NONE");
break;
case GL_AUX0:
crDebug("ReadBuffer: GL_AUX0");
break;
case GL_AUX1:
crDebug("ReadBuffer: GL_AUX1");
break;
case GL_AUX2:
crDebug("ReadBuffer: GL_AUX2");
break;
case GL_AUX3:
crDebug("ReadBuffer: GL_AUX3");
break;
case GL_LEFT:
crWarning("ReadBuffer: GL_LEFT not supported properly");
break;
case GL_RIGHT:
crWarning("ReadBuffer: GL_RIGHT not supported properly");
break;
case GL_FRONT_AND_BACK:
crWarning("ReadBuffer: GL_FRONT_AND_BACK not supported properly");
break;
default:
break;
}
{
cr_server.head_spu->dispatch_table.BindFramebufferEXT(GL_READ_FRAMEBUFFER, CR_SERVER_FBO_FOR_IDX(mural, iBufferNeeded));
}
}
}
{
if (retval == GL_NO_ERROR)
else
/* our impl has a single error flag, so we just loop here to reset all error flags to no_error */
while (err != GL_NO_ERROR)
return retval; /* WILL PROBABLY BE IGNORED */
}
{
int fDoPrePostProcess = 0;
if (pCtx)
{
GLint curSrvSpuCtx = cr_server.currentCtxInfo && cr_server.currentCtxInfo->SpuContext > 0 ? cr_server.currentCtxInfo->SpuContext : cr_server.MainContextInfo.SpuContext;
if (pCurrentMural)
{
}
else
{
idDrawFBO = 0;
idReadFBO = 0;
}
}
else
{
/* this is a GUI thread, so no need to do anything here */
}
if (fDoPrePostProcess > 0)
if (fDoPrePostProcess < 0)
}
void crServerInitTmpCtxDispatch()
{
}
/* dump stuff */
#ifdef VBOX_WITH_CRSERVER_DUMPER
/* first four bits are buffer dump config
* second four bits are texture dump config
* config flags:
* 1 - blit on enter
* 2 - blit on exit
*
*
* Example:
*
* 0x03 - dump buffer on enter and exit
* 0x22 - dump texture and buffer on exit */
unsigned long g_CrDbgDumpEnabled = 1;
unsigned long g_CrDbgDumpDraw = CR_SERVER_DUMP_F_COMPILE_SHADER
; //CR_SERVER_DUMP_F_DRAW_BUFF_ENTER | CR_SERVER_DUMP_F_DRAW_BUFF_LEAVE;
unsigned long g_CrDbgDumpDrawFramesSettings = CR_SERVER_DUMP_F_DRAW_BUFF_ENTER
unsigned long g_CrDbgDumpDrawFramesAppliedSettings = 0;
unsigned long g_CrDbgDumpDrawFramesSavedInitSettings = 0;
unsigned long g_CrDbgDumpDrawFramesCount = 0;
void crServerDumpCheckTerm()
{
return;
}
int crServerDumpCheckInit()
{
int rc;
return VINF_SUCCESS;
if (!pBlitterMural)
{
crWarning("crServerGetDummyMural failed");
return VERR_GENERAL_FAILURE;
}
if (!RT_SUCCESS(rc))
{
return rc;
}
if (!RT_SUCCESS(rc))
{
return rc;
}
#if 0
#else
#endif
crRecInit(&cr_server.Recorder, &cr_server.RecorderBlitter, &cr_server.TmpCtxDispatch, cr_server.pDumper);
return VINF_SUCCESS;
}
{
}
{
}
void crServerDumpCurrentProgram()
{
}
{
}
void crServerDumpState()
{
}
void crServerDumpDrawel(const char*pszFormat, ...)
{
}
void crServerDumpDrawelv(GLuint idx, const char*pszElFormat, uint32_t cbEl, const void *pvVal, uint32_t cVal)
{
}
void crServerDumpBuffer(int idx)
{
int rc = crServerDumpCheckInit();
idx = idx >= 0 ? idx : crServerMuralFBOIdxFromBufferName(cr_server.currentMural, pCtxInfo->pContext->buffer.drawBuffer);
if (!RT_SUCCESS(rc))
{
return;
}
if (idx < 0)
{
crWarning("neg idx, unsupported");
return;
}
}
void crServerDumpTextures()
{
int rc = crServerDumpCheckInit();
if (!RT_SUCCESS(rc))
{
return;
}
}
{
return CR_SERVER_DUMP_DEFAULT_FILTER_OP(event);
}
{
return CR_SERVER_DUMP_DEFAULT_FILTER_DMP(event);
}
void crServerDumpFramesCheck()
{
return;
{
{
crWarning("g_CrDbgDumpDrawFramesSettings is NULL, bump will not be started");
return;
}
crDmpStrF(cr_server.Recorder.pDumper, "***Starting draw dump for %d frames, settings(0x%x)", g_CrDbgDumpDrawFramesCount, g_CrDbgDumpDraw);
return;
}
{
}
}
#endif
/* */