Changeset 57152 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Aug 2, 2015 8:31:46 PM (9 years ago)
- Location:
- trunk/src/VBox/Devices/Graphics
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-info.cpp
r57151 r57152 99 99 }; 100 100 VMSVGAINFOENUMMAP_MAKE(RT_NOTHING, g_SVGA3dSurfaceFormat2String, g_aSVGA3dSurfaceFormats, "SVGA3D_"); 101 102 103 /**104 * Worker for vmsvga3dUpdateHeapBuffersForSurfaces.105 *106 * This will allocate heap buffers if necessary, thus increasing the memory107 * usage of the process.108 *109 * @todo Would be interesting to share this code with the saved state code.110 *111 * @returns VBox status code.112 * @param pState The 3D state structure.113 * @param pSurface The surface to refresh the heap buffers for.114 */115 static int vmsvga3dSurfaceUpdateHeapBuffers(PVMSVGA3DSTATE pState, PVMSVGA3DSURFACE pSurface)116 {117 /*118 * Currently we've got trouble retreving bit for DEPTHSTENCIL119 * surfaces both for OpenGL and D3D, so skip these here (don't120 * wast memory on them).121 */122 uint32_t const fSwitchFlags = pSurface->flags123 & ( SVGA3D_SURFACE_HINT_INDEXBUFFER | SVGA3D_SURFACE_HINT_VERTEXBUFFER124 | SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET125 | SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_CUBEMAP);126 if ( fSwitchFlags != SVGA3D_SURFACE_HINT_DEPTHSTENCIL127 && fSwitchFlags != (SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_HINT_TEXTURE))128 {129 130 #ifdef VMSVGA3D_OPENGL131 /*132 * Change OpenGL context to the one the surface is associated with.133 */134 # ifdef VMSVGA3D_OGL_WITH_SHARED_CTX135 PVMSVGA3DCONTEXT pContext = &pState->SharedCtx;136 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);137 # else138 /** @todo stricter checks for associated context */139 uint32_t cid = pSurface->idAssociatedContext;140 if ( cid >= pState->cContexts141 || pState->papContexts[cid]->id != cid)142 {143 Log(("vmsvga3dSurfaceUpdateHeapBuffers: invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id));144 AssertFailedReturn(VERR_INVALID_PARAMETER);145 }146 PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];147 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);148 # endif149 #endif150 151 /*152 * Work thru each mipmap level for each face.153 */154 for (uint32_t iFace = 0; iFace < pSurface->cFaces; iFace++)155 {156 Assert(pSurface->faces[iFace].numMipLevels <= pSurface->faces[0].numMipLevels);157 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->pMipmapLevels[iFace * pSurface->faces[0].numMipLevels];158 for (uint32_t i = 0; i < pSurface->faces[iFace].numMipLevels; i++, pMipmapLevel++)159 {160 #ifdef VMSVGA3D_DIRECT3D161 if (pSurface->u.pSurface)162 #else163 if (pSurface->oglId.texture != OPENGL_INVALID_ID)164 #endif165 {166 Assert(pMipmapLevel->cbSurface);167 Assert(pMipmapLevel->cbSurface == pMipmapLevel->cbSurfacePitch * pMipmapLevel->size.height); /* correct for depth stuff? */168 169 /*170 * Make sure we've got surface memory buffer.171 */172 uint8_t *pbDst = (uint8_t *)pMipmapLevel->pSurfaceData;173 if (!pbDst)174 {175 pMipmapLevel->pSurfaceData = pbDst = (uint8_t *)RTMemAllocZ(pMipmapLevel->cbSurface);176 AssertReturn(pbDst, VERR_NO_MEMORY);177 }178 179 #ifdef VMSVGA3D_DIRECT3D180 /*181 * D3D specifics.182 */183 HRESULT hr;184 switch (fSwitchFlags)185 {186 case SVGA3D_SURFACE_HINT_TEXTURE:187 case SVGA3D_SURFACE_HINT_RENDERTARGET:188 case SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET:189 {190 /*191 * Lock the buffer and make it accessible to memcpy.192 */193 D3DLOCKED_RECT LockedRect;194 if (fSwitchFlags & SVGA3D_SURFACE_HINT_TEXTURE)195 {196 if (pSurface->bounce.pTexture)197 {198 if ( !pSurface->fDirty199 && fSwitchFlags == (SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET)200 && i == 0 /* only the first time */)201 {202 /** @todo stricter checks for associated context */203 uint32_t cid = pSurface->idAssociatedContext;204 if ( cid >= pState->cContexts205 || pState->papContexts[cid]->id != cid)206 {207 Log(("vmsvga3dSurfaceUpdateHeapBuffers: invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id));208 AssertFailedReturn(VERR_INVALID_PARAMETER);209 }210 PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];211 212 IDirect3DSurface9 *pDst = NULL;213 hr = pSurface->bounce.pTexture->GetSurfaceLevel(i, &pDst);214 AssertMsgReturn(hr == D3D_OK, ("GetSurfaceLevel failed with %#x\n", hr), VERR_INTERNAL_ERROR);215 216 IDirect3DSurface9 *pSrc = NULL;217 hr = pSurface->u.pTexture->GetSurfaceLevel(i, &pSrc);218 AssertMsgReturn(hr == D3D_OK, ("GetSurfaceLevel failed with %#x\n", hr), VERR_INTERNAL_ERROR);219 220 hr = pContext->pDevice->GetRenderTargetData(pSrc, pDst);221 AssertMsgReturn(hr == D3D_OK, ("GetRenderTargetData failed with %#x\n", hr), VERR_INTERNAL_ERROR);222 223 pSrc->Release();224 pDst->Release();225 }226 227 hr = pSurface->bounce.pTexture->LockRect(i, /* texture level */228 &LockedRect,229 NULL,230 D3DLOCK_READONLY);231 }232 else233 hr = pSurface->u.pTexture->LockRect(i, /* texture level */234 &LockedRect,235 NULL,236 D3DLOCK_READONLY);237 }238 else239 hr = pSurface->u.pSurface->LockRect(&LockedRect,240 NULL,241 D3DLOCK_READONLY);242 AssertMsgReturn(hr == D3D_OK, ("LockRect failed with %x\n", hr), VERR_INTERNAL_ERROR);243 244 /*245 * Copy the data. Take care in case the pitch differs.246 */247 if (pMipmapLevel->cbSurfacePitch == (uint32_t)LockedRect.Pitch)248 memcpy(pbDst, LockedRect.pBits, pMipmapLevel->cbSurface);249 else250 for (uint32_t j = 0; j < pMipmapLevel->size.height; j++)251 memcpy(pbDst + j * pMipmapLevel->cbSurfacePitch,252 (uint8_t *)LockedRect.pBits + j * LockedRect.Pitch,253 pMipmapLevel->cbSurfacePitch);254 255 /*256 * Release the buffer.257 */258 if (fSwitchFlags & SVGA3D_SURFACE_HINT_TEXTURE)259 {260 if (pSurface->bounce.pTexture)261 {262 hr = pSurface->bounce.pTexture->UnlockRect(i);263 AssertMsgReturn(hr == D3D_OK, ("UnlockRect failed with %#x\n", hr), VERR_INTERNAL_ERROR);264 }265 else266 hr = pSurface->u.pTexture->UnlockRect(i);267 }268 else269 hr = pSurface->u.pSurface->UnlockRect();270 AssertMsgReturn(hr == D3D_OK, ("UnlockRect failed with %#x\n", hr), VERR_INTERNAL_ERROR);271 break;272 }273 274 case SVGA3D_SURFACE_HINT_VERTEXBUFFER:275 {276 void *pvD3DData = NULL;277 hr = pSurface->u.pVertexBuffer->Lock(0, 0, &pvD3DData, D3DLOCK_READONLY);278 AssertMsgReturn(hr == D3D_OK, ("Lock vertex failed with %x\n", hr), VERR_INTERNAL_ERROR);279 280 memcpy(pbDst, pvD3DData, pMipmapLevel->cbSurface);281 282 hr = pSurface->u.pVertexBuffer->Unlock();283 AssertMsg(hr == D3D_OK, ("Unlock vertex failed with %x\n", hr));284 break;285 }286 287 case SVGA3D_SURFACE_HINT_INDEXBUFFER:288 {289 void *pvD3DData = NULL;290 hr = pSurface->u.pIndexBuffer->Lock(0, 0, &pvD3DData, D3DLOCK_READONLY);291 AssertMsgReturn(hr == D3D_OK, ("Lock index failed with %x\n", hr), VERR_INTERNAL_ERROR);292 293 memcpy(pbDst, pvD3DData, pMipmapLevel->cbSurface);294 295 hr = pSurface->u.pIndexBuffer->Unlock();296 AssertMsg(hr == D3D_OK, ("Unlock index failed with %x\n", hr));297 break;298 }299 300 default:301 AssertMsgFailed(("%#x\n", fSwitchFlags));302 }303 304 #elif defined(VMSVGA3D_OPENGL)305 /*306 * OpenGL specifics.307 */308 switch (fSwitchFlags)309 {310 case SVGA3D_SURFACE_HINT_TEXTURE:311 case SVGA3D_SURFACE_HINT_RENDERTARGET:312 case SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET:313 {314 GLint activeTexture;315 glGetIntegerv(GL_TEXTURE_BINDING_2D, &activeTexture);316 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);317 318 glBindTexture(GL_TEXTURE_2D, pSurface->oglId.texture);319 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);320 321 /* Set row length and alignment of the output data. */322 VMSVGAPACKPARAMS SavedParams;323 vmsvga3dOglSetPackParams(pState, pContext, pSurface, &SavedParams);324 325 glGetTexImage(GL_TEXTURE_2D,326 i,327 pSurface->formatGL,328 pSurface->typeGL,329 pbDst);330 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);331 332 vmsvga3dOglRestorePackParams(pState, pContext, pSurface, &SavedParams);333 334 /* Restore the old active texture. */335 glBindTexture(GL_TEXTURE_2D, activeTexture);336 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);337 break;338 }339 340 case SVGA3D_SURFACE_HINT_VERTEXBUFFER:341 case SVGA3D_SURFACE_HINT_INDEXBUFFER:342 {343 pState->ext.glBindBuffer(GL_ARRAY_BUFFER, pSurface->oglId.buffer);344 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);345 346 void *pvSrc = pState->ext.glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);347 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);348 if (RT_VALID_PTR(pvSrc))349 memcpy(pbDst, pvSrc, pMipmapLevel->cbSurface);350 else351 AssertPtr(pvSrc);352 353 pState->ext.glUnmapBuffer(GL_ARRAY_BUFFER);354 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);355 356 pState->ext.glBindBuffer(GL_ARRAY_BUFFER, 0);357 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);358 break;359 }360 361 default:362 AssertMsgFailed(("%#x\n", fSwitchFlags));363 }364 #else365 # error "misconfigured"366 #endif367 }368 /* else: There is no data in hardware yet, so whatever we got is already current. */369 }370 }371 }372 373 return VINF_SUCCESS;374 }375 376 377 /**378 * Updates the heap buffers for all surfaces or one specific one.379 *380 * @param pThis The VGA device instance data.381 * @param sid The surface ID, UINT32_MAX if all.382 * @thread VMSVGAFIFO383 */384 void vmsvga3dUpdateHeapBuffersForSurfaces(PVGASTATE pThis, uint32_t sid)385 {386 PVMSVGA3DSTATE pState = pThis->svga.p3dState;387 AssertReturnVoid(pState);388 389 if (sid == UINT32_MAX)390 {391 uint32_t cSurfaces = pState->cSurfaces;392 for (sid = 0; sid < cSurfaces; sid++)393 {394 PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];395 if (pSurface && pSurface->id == sid)396 vmsvga3dSurfaceUpdateHeapBuffers(pState, pSurface);397 }398 }399 else if (sid < pState->cSurfaces)400 {401 PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];402 if (pSurface && pSurface->id == sid)403 vmsvga3dSurfaceUpdateHeapBuffers(pState, pSurface);404 }405 }406 407 408 409 410 void vmsvga3dInfoU32Flags(PCDBGFINFOHLP pHlp, uint32_t fFlags, const char *pszPrefix, PCVMSVGAINFOFLAGS32 paFlags, uint32_t cFlags)411 {412 for (uint32_t i = 0; i < cFlags; i++)413 if ((paFlags[i].fFlags & fFlags) == paFlags[i].fFlags)414 {415 Assert(paFlags[i].fFlags);416 pHlp->pfnPrintf(pHlp, " %s%s", pszPrefix, paFlags[i].pszJohnny);417 fFlags &= ~paFlags[i].fFlags;418 if (!fFlags)419 return;420 }421 if (fFlags)422 pHlp->pfnPrintf(pHlp, " UNKNOWN_%#x", fFlags);423 }424 425 426 /**427 * Worker for vmsvgaR3Info that display details of a host window.428 *429 * @param pHlp The output methods.430 * @param idHostWindow The host window handle/id/whatever.431 */432 void vmsvga3dInfoHostWindow(PCDBGFINFOHLP pHlp, uint64_t idHostWindow)433 {434 #ifdef RT_OS_WINDOWS435 HWND hwnd = (HWND)(uintptr_t)idHostWindow;436 Assert((uintptr_t)hwnd == idHostWindow);437 if (hwnd != NULL)438 {439 WINDOWINFO Info;440 RT_ZERO(Info);441 Info.cbSize = sizeof(Info);442 if (GetWindowInfo(hwnd, &Info))443 {444 pHlp->pfnPrintf(pHlp, " Window rect: xLeft=%d, yTop=%d, xRight=%d, yBottom=%d (cx=%d, cy=%d)\n",445 Info.rcWindow.left, Info.rcWindow.top, Info.rcWindow.right, Info.rcWindow.bottom,446 Info.rcWindow.right - Info.rcWindow.left, Info.rcWindow.bottom - Info.rcWindow.top);447 pHlp->pfnPrintf(pHlp, " Client rect: xLeft=%d, yTop=%d, xRight=%d, yBottom=%d (cx=%d, cy=%d)\n",448 Info.rcClient.left, Info.rcClient.top, Info.rcClient.right, Info.rcClient.bottom,449 Info.rcClient.right - Info.rcClient.left, Info.rcClient.bottom - Info.rcClient.top);450 pHlp->pfnPrintf(pHlp, " Style: %#x", Info.dwStyle);451 static const VMSVGAINFOFLAGS32 g_aStyles[] =452 {453 { WS_POPUP , "POPUP" },454 { WS_CHILD , "CHILD" },455 { WS_MINIMIZE , "MINIMIZE" },456 { WS_VISIBLE , "VISIBLE" },457 { WS_DISABLED , "DISABLED" },458 { WS_CLIPSIBLINGS , "CLIPSIBLINGS" },459 { WS_CLIPCHILDREN , "CLIPCHILDREN" },460 { WS_MAXIMIZE , "MAXIMIZE" },461 { WS_BORDER , "BORDER" },462 { WS_DLGFRAME , "DLGFRAME" },463 { WS_VSCROLL , "VSCROLL" },464 { WS_HSCROLL , "HSCROLL" },465 { WS_SYSMENU , "SYSMENU" },466 { WS_THICKFRAME , "THICKFRAME" },467 { WS_GROUP , "GROUP" },468 { WS_TABSTOP , "TABSTOP" },469 };470 vmsvga3dInfoU32Flags(pHlp, Info.dwStyle, "", g_aStyles, RT_ELEMENTS(g_aStyles));471 pHlp->pfnPrintf(pHlp, "\n");472 473 pHlp->pfnPrintf(pHlp, " ExStyle: %#x", Info.dwExStyle);474 static const VMSVGAINFOFLAGS32 g_aExStyles[] =475 {476 { WS_EX_DLGMODALFRAME, "DLGMODALFRAME" },477 { 0x00000002, "DRAGDETECT" },478 { WS_EX_NOPARENTNOTIFY, "NOPARENTNOTIFY" },479 { WS_EX_TOPMOST, "TOPMOST" },480 { WS_EX_ACCEPTFILES, "ACCEPTFILES" },481 { WS_EX_TRANSPARENT, "TRANSPARENT" },482 { WS_EX_MDICHILD, "MDICHILD" },483 { WS_EX_TOOLWINDOW, "TOOLWINDOW" },484 { WS_EX_WINDOWEDGE, "WINDOWEDGE" },485 { WS_EX_CLIENTEDGE, "CLIENTEDGE" },486 { WS_EX_CONTEXTHELP, "CONTEXTHELP" },487 { WS_EX_RIGHT, "RIGHT" },488 /*{ WS_EX_LEFT, "LEFT" }, = 0 */489 { WS_EX_RTLREADING, "RTLREADING" },490 /*{ WS_EX_LTRREADING, "LTRREADING" }, = 0 */491 { WS_EX_LEFTSCROLLBAR, "LEFTSCROLLBAR" },492 /*{ WS_EX_RIGHTSCROLLBAR, "RIGHTSCROLLBAR" }, = 0 */493 { WS_EX_CONTROLPARENT, "CONTROLPARENT" },494 { WS_EX_STATICEDGE, "STATICEDGE" },495 { WS_EX_APPWINDOW, "APPWINDOW" },496 { WS_EX_LAYERED, "LAYERED" },497 { WS_EX_NOINHERITLAYOUT, "NOINHERITLAYOUT" },498 { WS_EX_LAYOUTRTL, "LAYOUTRTL" },499 { WS_EX_COMPOSITED, "COMPOSITED" },500 { WS_EX_NOACTIVATE, "NOACTIVATE" },501 };502 vmsvga3dInfoU32Flags(pHlp, Info.dwExStyle, "", g_aExStyles, RT_ELEMENTS(g_aExStyles));503 pHlp->pfnPrintf(pHlp, "\n");504 505 pHlp->pfnPrintf(pHlp, " Window Status: %#x\n", Info.dwWindowStatus);506 if (Info.cxWindowBorders || Info.cyWindowBorders)507 pHlp->pfnPrintf(pHlp, " Borders: cx=%u, cy=%u\n", Info.cxWindowBorders, Info.cyWindowBorders);508 pHlp->pfnPrintf(pHlp, " Window Type: %#x\n", Info.atomWindowType);509 pHlp->pfnPrintf(pHlp, " Creator Ver: %#x\n", Info.wCreatorVersion);510 }511 else512 pHlp->pfnPrintf(pHlp, " GetWindowInfo: last error %d\n", GetLastError());513 }514 #else515 pHlp->pfnPrintf(pHlp, " Windows info: Not implemented on this platform\n");516 #endif517 518 }519 520 521 /**522 * Looks up an enum value in a translation table.523 *524 * @returns The value name.525 * @param iValue The value to name.526 * @param pEnumMap Enum value to string mapping.527 */528 const char *vmsvgaLookupEnum(int32_t iValue, PCVMSVGAINFOENUMMAP pEnumMap)529 {530 PCVMSVGAINFOENUM paValues = pEnumMap->paValues;531 532 #ifdef VBOX_STRICT533 /*534 * Check that it's really sorted, or the binary lookup won't work right.535 */536 if (!*pEnumMap->pfAsserted)537 {538 *pEnumMap->pfAsserted = true;539 for (uint32_t i = 1; i < pEnumMap->cValues; i++)540 Assert(paValues[i - 1].iValue <= paValues[i].iValue);541 }542 #endif543 544 /*545 * Binary search546 */547 uint32_t iStart = 0;548 uint32_t iEnd = (uint32_t)pEnumMap->cValues;549 for (;;)550 {551 uint32_t i = iStart + (iEnd - iStart) / 2;552 if (iValue < paValues[i].iValue)553 {554 if (i > iStart)555 iEnd = i;556 else557 break;558 }559 else if (iValue > paValues[i].iValue)560 {561 i++;562 if (i < iEnd)563 iStart = i;564 else565 break;566 }567 else568 return paValues[i].pszName;569 }570 return NULL;571 }572 573 574 /**575 * Formats an enum value as a string, sparse mapping table.576 *577 * @returns pszBuffer.578 * @param pszBuffer The output buffer.579 * @param cbBuffer The size of the output buffer.580 * @param pszName The variable name, optional.581 * @param iValue The enum value.582 * @param fPrefix Whether to prepend the prefix or not.583 * @param pEnumMap Enum value to string mapping.584 */585 char *vmsvgaFormatEnumValueEx(char *pszBuffer, size_t cbBuffer, const char *pszName, int32_t iValue,586 bool fPrefix, PCVMSVGAINFOENUMMAP pEnumMap)587 {588 const char *pszValueName = vmsvgaLookupEnum(iValue, pEnumMap);589 const char *pszPrefix = fPrefix ? pEnumMap->pszPrefix : "";590 if (pszValueName)591 {592 if (pszName)593 RTStrPrintf(pszBuffer, cbBuffer, "%s = %s%s (%#x)", pszName, pszPrefix, pszValueName, iValue);594 else595 RTStrPrintf(pszBuffer, cbBuffer, "%s%s (%#x)", pszPrefix, pszValueName, iValue);596 return pszBuffer;597 }598 599 if (pszName)600 RTStrPrintf(pszBuffer, cbBuffer, "%s = %sUNKNOWN_%d (%#x)", pszName, pszPrefix, iValue, iValue);601 else602 RTStrPrintf(pszBuffer, cbBuffer, "%sUNKNOWN_%d (%#x)", pszPrefix, iValue, iValue);603 return pszBuffer;604 }605 606 607 /**608 * Formats an enum value as a string.609 *610 * @returns pszBuffer.611 * @param pszBuffer The output buffer.612 * @param cbBuffer The size of the output buffer.613 * @param pszName The variable name, optional.614 * @param uValue The enum value.615 * @param pszPrefix The prefix of the enum values. Empty string if616 * none. This helps reduce the memory footprint617 * as well as the source code size.618 * @param papszValues One to one string mapping of the enum values.619 * @param cValues The number of values in the mapping.620 */621 char *vmsvgaFormatEnumValue(char *pszBuffer, size_t cbBuffer, const char *pszName, uint32_t uValue,622 const char *pszPrefix, const char * const *papszValues, size_t cValues)623 {624 if (uValue < cValues)625 {626 if (pszName)627 RTStrPrintf(pszBuffer, cbBuffer, "%s = %s%s (%#x)", pszName, pszPrefix, papszValues[uValue], uValue);628 else629 RTStrPrintf(pszBuffer, cbBuffer, "%s%s (%#x)", pszPrefix, papszValues[uValue], uValue);630 }631 else632 {633 if (pszName)634 RTStrPrintf(pszBuffer, cbBuffer, "%s = %sUNKNOWN_%d (%#x)", pszName, pszPrefix, uValue, uValue);635 else636 RTStrPrintf(pszBuffer, cbBuffer, "%sUNKNOWN_%d (%#x)", pszPrefix, uValue, uValue);637 }638 return pszBuffer;639 }640 641 642 /**643 * DBGF info printer for vmsvga3dAsciiPrint.644 *645 * @param pszLine The line to print.646 * @param pvUser The debug info helpers.647 */648 DECLCALLBACK(void) vmsvga3dAsciiPrintlnInfo(const char *pszLine, void *pvUser)649 {650 PCDBGFINFOHLP pHlp = (PCDBGFINFOHLP)pvUser;651 pHlp->pfnPrintf(pHlp, ">%s<\n", pszLine);652 }653 654 655 /**656 * Log printer for vmsvga3dAsciiPrint.657 *658 * @param pszLine The line to print.659 * @param pvUser Ignored.660 */661 DECLCALLBACK(void) vmsvga3dAsciiPrintlnLog(const char *pszLine, void *pvUser)662 {663 size_t cch = strlen(pszLine);664 while (cch > 0 && pszLine[cch - 1] == ' ')665 cch--;666 RTLogPrintf("%.*s\n", cch, pszLine);667 NOREF(pvUser);668 }669 670 671 void vmsvga3dAsciiPrint(PFMVMSVGAASCIIPRINTLN pfnPrintLine, void *pvUser, void const *pvImage, size_t cbImage,672 uint32_t cx, uint32_t cy, uint32_t cbScanline, SVGA3dSurfaceFormat enmFormat, bool fInvY,673 uint32_t cchMaxX, uint32_t cchMaxY)674 {675 /*676 * Skip stuff we can't or won't need to handle.677 */678 if (!cx || !cy)679 return;680 switch (enmFormat)681 {682 /* Compressed. */683 case SVGA3D_DXT1:684 case SVGA3D_DXT2:685 case SVGA3D_DXT3:686 case SVGA3D_DXT4:687 case SVGA3D_DXT5:688 return;689 /* Generic. */690 case SVGA3D_BUFFER:691 return;692 default:693 break; /* ok */694 }695 696 /*697 * Figure the pixel conversion factors.698 */699 uint32_t cxPerChar = cx / cchMaxX + 1;700 uint32_t cyPerChar = cy / cchMaxY + 1;701 /** @todo try keep aspect... */702 uint32_t const cchLine = (cx + cxPerChar - 1) / cxPerChar;703 uint32_t const cbSrcPixel = vmsvga3dSurfaceFormatSize(enmFormat);704 705 /*706 * The very simple conversion we're doing in this function is based on707 * mapping a block of converted pixels to an ASCII character of similar708 * weigth. We do that by summing up all the 8-bit gray scale pixels in709 * that block, applying a conversion factor and getting an index into an710 * array of increasingly weighty characters.711 */712 static const char s_szPalette[] = " ..`',:;icodxkO08XNWM";713 static const uint32_t s_cchPalette = sizeof(s_szPalette) - 1;714 uint32_t const cPixelsWeightPerChar = cxPerChar * cyPerChar * 256;715 716 /*717 * Do the work718 */719 uint32_t *pauScanline = (uint32_t *)RTMemTmpAllocZ(sizeof(pauScanline[0]) * cchLine + cchLine + 1);720 if (!pauScanline)721 return;722 char *pszLine = (char *)&pauScanline[cchLine];723 RTCPTRUNION uSrc;724 uSrc.pv = pvImage;725 if (fInvY)726 uSrc.pu8 += (cy - 1) * cbScanline;727 uint32_t cyLeft = cy;728 uint32_t cyLeftInScanline = cyPerChar;729 bool fHitFormatAssert = false;730 for (;;)731 {732 /*733 * Process the scanline. This is tedious because of all the734 * different formats. We generally ignore alpha, unless it's735 * all we've got to work with.736 * Color to 8-bit grayscale conversion is done by averaging.737 */738 #define CONVERT_SCANLINE(a_RdExpr, a_AddExpr) \739 do { \740 for (uint32_t xSrc = 0, xDst = 0, cxLeftInChar = cxPerChar; xSrc < cx; xSrc++) \741 { \742 a_RdExpr; \743 pauScanline[xDst] += (a_AddExpr) & 0xff; \744 Assert(pauScanline[xDst] <= cPixelsWeightPerChar); \745 if (--cxLeftInChar == 0) \746 { \747 xDst++; \748 cxLeftInChar = cxPerChar; \749 } \750 } \751 } while (0)752 753 switch (enmFormat)754 {755 /* Unsigned RGB and super/subsets. */756 case SVGA3D_X8R8G8B8:757 case SVGA3D_A8R8G8B8:758 CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],759 ( ( u32Tmp & 0xff) /* B */760 + ((u32Tmp >> 8) & 0xff) /* G */761 + ((u32Tmp >> 16) & 0xff) /* R */) / 3);762 break;763 case SVGA3D_R5G6B5:764 CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],765 ( ( u16Tmp & 0x1f) * 8766 + ((u16Tmp >> 5) & 0x3f) * 4767 + ( u16Tmp >> 11) * 8 ) / 3 );768 break;769 case SVGA3D_X1R5G5B5:770 case SVGA3D_A1R5G5B5:771 CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],772 ( ( u16Tmp & 0x1f) * 8773 + ((u16Tmp >> 5) & 0x1f) * 8774 + ((u16Tmp >> 10) & 0x1f) * 8) / 3 );775 break;776 case SVGA3D_A4R4G4B4:777 CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],778 ( ( u16Tmp & 0xf) * 16779 + ((u16Tmp >> 4) & 0xf) * 16780 + ((u16Tmp >> 8) & 0xf) * 16) / 3 );781 break;782 case SVGA3D_A16B16G16R16:783 CONVERT_SCANLINE(uint64_t const u64Tmp = uSrc.pu64[xSrc],784 ( ((u64Tmp >> 8) & 0xff) /* R */785 + ((u64Tmp >> 24) & 0xff) /* G */786 + ((u64Tmp >> 40) & 0xff) /* B */ ) / 3);787 break;788 case SVGA3D_A2R10G10B10:789 CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],790 ( ( u32Tmp & 0x3ff) /* B */791 + ((u32Tmp >> 10) & 0x3ff) /* G */792 + ((u32Tmp >> 20) & 0x3ff) /* R */ ) / (3 * 4));793 break;794 case SVGA3D_G16R16:795 CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],796 ( (u32Tmp & 0xffff) /* R */797 + (u32Tmp >> 16 ) /* G */) / 0x200);798 break;799 800 /* Depth. */801 case SVGA3D_Z_D32:802 CONVERT_SCANLINE(uint32_t const u32Tmp = ~((uSrc.pu32[xSrc] >> 1) | uSrc.pu32[xSrc]) & UINT32_C(0x44444444),803 (( u32Tmp >> (2 - 0)) & RT_BIT_32(0))804 | ((u32Tmp >> ( 6 - 1)) & RT_BIT_32(1))805 | ((u32Tmp >> (10 - 2)) & RT_BIT_32(2))806 | ((u32Tmp >> (14 - 3)) & RT_BIT_32(3))807 | ((u32Tmp >> (18 - 4)) & RT_BIT_32(4))808 | ((u32Tmp >> (22 - 5)) & RT_BIT_32(5))809 | ((u32Tmp >> (26 - 6)) & RT_BIT_32(6))810 | ((u32Tmp >> (30 - 7)) & RT_BIT_32(7)) );811 break;812 case SVGA3D_Z_D16:813 CONVERT_SCANLINE(uint16_t const u16Tmp = ~uSrc.pu16[xSrc],814 ((u16Tmp >> ( 1 - 0)) & RT_BIT_32(0))815 | ((u16Tmp >> ( 3 - 1)) & RT_BIT_32(1))816 | ((u16Tmp >> ( 5 - 2)) & RT_BIT_32(2))817 | ((u16Tmp >> ( 7 - 3)) & RT_BIT_32(3))818 | ((u16Tmp >> ( 9 - 4)) & RT_BIT_32(4))819 | ((u16Tmp >> (11 - 5)) & RT_BIT_32(5))820 | ((u16Tmp >> (13 - 6)) & RT_BIT_32(6))821 | ((u16Tmp >> (15 - 7)) & RT_BIT_32(7)) );822 break;823 case SVGA3D_Z_D24S8:824 CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],825 ( u32Tmp & 0xff) /* stencile */826 | ((~u32Tmp >> 18) & 0x3f));827 break;828 case SVGA3D_Z_D15S1:829 CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],830 ( (u16Tmp & 0x01) << 7) /* stencile */831 | ((~u16Tmp >> 8) & 0x7f));832 break;833 834 /* Pure alpha. */835 case SVGA3D_ALPHA8:836 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc]);837 break;838 839 /* Luminance */840 case SVGA3D_LUMINANCE8:841 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc]);842 break;843 case SVGA3D_LUMINANCE4_ALPHA4:844 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc] & 0xf0);845 break;846 case SVGA3D_LUMINANCE16:847 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu16[xSrc] >> 8);848 break;849 case SVGA3D_LUMINANCE8_ALPHA8:850 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu16[xSrc] >> 8);851 break;852 853 /* Not supported. */854 case SVGA3D_DXT1:855 case SVGA3D_DXT2:856 case SVGA3D_DXT3:857 case SVGA3D_DXT4:858 case SVGA3D_DXT5:859 case SVGA3D_BUFFER:860 AssertFailedBreak();861 862 /* Not considered for implementation yet. */863 case SVGA3D_BUMPU8V8:864 case SVGA3D_BUMPL6V5U5:865 case SVGA3D_BUMPX8L8V8U8:866 case SVGA3D_BUMPL8V8U8:867 case SVGA3D_ARGB_S10E5:868 case SVGA3D_ARGB_S23E8:869 case SVGA3D_V8U8:870 case SVGA3D_Q8W8V8U8:871 case SVGA3D_CxV8U8:872 case SVGA3D_X8L8V8U8:873 case SVGA3D_A2W10V10U10:874 case SVGA3D_R_S10E5:875 case SVGA3D_R_S23E8:876 case SVGA3D_RG_S10E5:877 case SVGA3D_RG_S23E8:878 case SVGA3D_Z_D24X8:879 case SVGA3D_V16U16:880 case SVGA3D_UYVY:881 case SVGA3D_YUY2:882 case SVGA3D_NV12:883 case SVGA3D_AYUV:884 case SVGA3D_BC4_UNORM:885 case SVGA3D_BC5_UNORM:886 case SVGA3D_Z_DF16:887 case SVGA3D_Z_DF24:888 case SVGA3D_Z_D24S8_INT:889 if (!fHitFormatAssert)890 {891 AssertMsgFailed(("%s is not implemented\n", vmsvgaLookupEnum((int)enmFormat, &g_SVGA3dSurfaceFormat2String)));892 fHitFormatAssert = true;893 }894 /* fall thru */895 default:896 /* Lazy programmer fallbacks. */897 if (cbSrcPixel == 4)898 CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc],899 ( ( u32Tmp & 0xff)900 + ((u32Tmp >> 8) & 0xff)901 + ((u32Tmp >> 16) & 0xff)902 + ((u32Tmp >> 24) & 0xff) ) / 4);903 else if (cbSrcPixel == 3)904 CONVERT_SCANLINE(RT_NOTHING,905 ( (uint32_t)uSrc.pu8[xSrc * 4]906 + (uint32_t)uSrc.pu8[xSrc * 4 + 1]907 + (uint32_t)uSrc.pu8[xSrc * 4 + 2] ) / 3);908 else if (cbSrcPixel == 2)909 CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc],910 ( ( u16Tmp & 0xf)911 + ((u16Tmp >> 4) & 0xf)912 + ((u16Tmp >> 8) & 0xf)913 + ((u16Tmp >> 12) & 0xf) ) * 4 /* mul 16 div 4 */ );914 else if (cbSrcPixel == 1)915 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc]);916 else917 AssertFailed();918 break;919 920 }921 922 /*923 * Print we've reached the end of a block in y direction or if we're at924 * the end of the image.925 */926 cyLeft--;927 if (--cyLeftInScanline == 0 || cyLeft == 0)928 {929 for (uint32_t i = 0; i < cchLine; i++)930 {931 uint32_t off = pauScanline[i] * s_cchPalette / cPixelsWeightPerChar; Assert(off < s_cchPalette);932 pszLine[i] = s_szPalette[off < sizeof(s_szPalette) - 1 ? off : sizeof(s_szPalette) - 1];933 }934 pszLine[cchLine] = '\0';935 pfnPrintLine(pszLine, pvUser);936 937 if (!cyLeft)938 break;939 cyLeftInScanline = cyPerChar;940 RT_BZERO(pauScanline, sizeof(pauScanline[0]) * cchLine);941 }942 943 /*944 * Advance.945 */946 if (!fInvY)947 uSrc.pu8 += cbScanline;948 else949 uSrc.pu8 -= cbScanline;950 }951 }952 953 954 /**955 * List of render state names with type prefix.956 *957 * First char in the name is a type indicator:958 * - '*' = requires special handling.959 * - 'f' = SVGA3dbool960 * - 'd' = uint32_t961 * - 'r' = float962 * - 'b' = SVGA3dBlendOp963 * - 'c' = SVGA3dColor, SVGA3dColorMask964 * - 'e' = SVGA3dBlendEquation965 * - 'm' = SVGA3dColorMask966 * - 'p' = SVGA3dCmpFunc967 * - 's' = SVGA3dStencilOp968 * - 'v' = SVGA3dVertexMaterial969 * - 'w' = SVGA3dWrapFlags970 */971 static const char * const g_apszRenderStateNamesAndType[] =972 {973 "*" "INVALID", /* invalid */974 "f" "ZENABLE", /* SVGA3dBool */975 "f" "ZWRITEENABLE", /* SVGA3dBool */976 "f" "ALPHATESTENABLE", /* SVGA3dBool */977 "f" "DITHERENABLE", /* SVGA3dBool */978 "f" "BLENDENABLE", /* SVGA3dBool */979 "f" "FOGENABLE", /* SVGA3dBool */980 "f" "SPECULARENABLE", /* SVGA3dBool */981 "f" "STENCILENABLE", /* SVGA3dBool */982 "f" "LIGHTINGENABLE", /* SVGA3dBool */983 "f" "NORMALIZENORMALS", /* SVGA3dBool */984 "f" "POINTSPRITEENABLE", /* SVGA3dBool */985 "f" "POINTSCALEENABLE", /* SVGA3dBool */986 "x" "STENCILREF", /* uint32_t */987 "x" "STENCILMASK", /* uint32_t */988 "x" "STENCILWRITEMASK", /* uint32_t */989 "r" "FOGSTART", /* float */990 "r" "FOGEND", /* float */991 "r" "FOGDENSITY", /* float */992 "r" "POINTSIZE", /* float */993 "r" "POINTSIZEMIN", /* float */994 "r" "POINTSIZEMAX", /* float */995 "r" "POINTSCALE_A", /* float */996 "r" "POINTSCALE_B", /* float */997 "r" "POINTSCALE_C", /* float */998 "c" "FOGCOLOR", /* SVGA3dColor */999 "c" "AMBIENT", /* SVGA3dColor */1000 "*" "CLIPPLANEENABLE", /* SVGA3dClipPlanes */1001 "*" "FOGMODE", /* SVGA3dFogMode */1002 "*" "FILLMODE", /* SVGA3dFillMode */1003 "*" "SHADEMODE", /* SVGA3dShadeMode */1004 "*" "LINEPATTERN", /* SVGA3dLinePattern */1005 "b" "SRCBLEND", /* SVGA3dBlendOp */1006 "b" "DSTBLEND", /* SVGA3dBlendOp */1007 "e" "BLENDEQUATION", /* SVGA3dBlendEquation */1008 "*" "CULLMODE", /* SVGA3dFace */1009 "p" "ZFUNC", /* SVGA3dCmpFunc */1010 "p" "ALPHAFUNC", /* SVGA3dCmpFunc */1011 "p" "STENCILFUNC", /* SVGA3dCmpFunc */1012 "s" "STENCILFAIL", /* SVGA3dStencilOp */1013 "s" "STENCILZFAIL", /* SVGA3dStencilOp */1014 "s" "STENCILPASS", /* SVGA3dStencilOp */1015 "r" "ALPHAREF", /* float */1016 "*" "FRONTWINDING", /* SVGA3dFrontWinding */1017 "*" "COORDINATETYPE", /* SVGA3dCoordinateType */1018 "r" "ZBIAS", /* float */1019 "f" "RANGEFOGENABLE", /* SVGA3dBool */1020 "c" "COLORWRITEENABLE", /* SVGA3dColorMask */1021 "f" "VERTEXMATERIALENABLE", /* SVGA3dBool */1022 "v" "DIFFUSEMATERIALSOURCE", /* SVGA3dVertexMaterial */1023 "v" "SPECULARMATERIALSOURCE", /* SVGA3dVertexMaterial */1024 "v" "AMBIENTMATERIALSOURCE", /* SVGA3dVertexMaterial */1025 "v" "EMISSIVEMATERIALSOURCE", /* SVGA3dVertexMaterial */1026 "c" "TEXTUREFACTOR", /* SVGA3dColor */1027 "f" "LOCALVIEWER", /* SVGA3dBool */1028 "f" "SCISSORTESTENABLE", /* SVGA3dBool */1029 "c" "BLENDCOLOR", /* SVGA3dColor */1030 "f" "STENCILENABLE2SIDED", /* SVGA3dBool */1031 "p" "CCWSTENCILFUNC", /* SVGA3dCmpFunc */1032 "s" "CCWSTENCILFAIL", /* SVGA3dStencilOp */1033 "s" "CCWSTENCILZFAIL", /* SVGA3dStencilOp */1034 "s" "CCWSTENCILPASS", /* SVGA3dStencilOp */1035 "*" "VERTEXBLEND", /* SVGA3dVertexBlendFlags */1036 "r" "SLOPESCALEDEPTHBIAS", /* float */1037 "r" "DEPTHBIAS", /* float */1038 "r" "OUTPUTGAMMA", /* float */1039 "f" "ZVISIBLE", /* SVGA3dBool */1040 "f" "LASTPIXEL", /* SVGA3dBool */1041 "f" "CLIPPING", /* SVGA3dBool */1042 "w" "WRAP0", /* SVGA3dWrapFlags */1043 "w" "WRAP1", /* SVGA3dWrapFlags */1044 "w" "WRAP2", /* SVGA3dWrapFlags */1045 "w" "WRAP3", /* SVGA3dWrapFlags */1046 "w" "WRAP4", /* SVGA3dWrapFlags */1047 "w" "WRAP5", /* SVGA3dWrapFlags */1048 "w" "WRAP6", /* SVGA3dWrapFlags */1049 "w" "WRAP7", /* SVGA3dWrapFlags */1050 "w" "WRAP8", /* SVGA3dWrapFlags */1051 "w" "WRAP9", /* SVGA3dWrapFlags */1052 "w" "WRAP10", /* SVGA3dWrapFlags */1053 "w" "WRAP11", /* SVGA3dWrapFlags */1054 "w" "WRAP12", /* SVGA3dWrapFlags */1055 "w" "WRAP13", /* SVGA3dWrapFlags */1056 "w" "WRAP14", /* SVGA3dWrapFlags */1057 "w" "WRAP15", /* SVGA3dWrapFlags */1058 "f" "MULTISAMPLEANTIALIAS", /* SVGA3dBool */1059 "x" "MULTISAMPLEMASK", /* uint32_t */1060 "f" "INDEXEDVERTEXBLENDENABLE", /* SVGA3dBool */1061 "r" "TWEENFACTOR", /* float */1062 "f" "ANTIALIASEDLINEENABLE", /* SVGA3dBool */1063 "c" "COLORWRITEENABLE1", /* SVGA3dColorMask */1064 "c" "COLORWRITEENABLE2", /* SVGA3dColorMask */1065 "c" "COLORWRITEENABLE3", /* SVGA3dColorMask */1066 "f" "SEPARATEALPHABLENDENABLE", /* SVGA3dBool */1067 "b" "SRCBLENDALPHA", /* SVGA3dBlendOp */1068 "b" "DSTBLENDALPHA", /* SVGA3dBlendOp */1069 "e" "BLENDEQUATIONALPHA", /* SVGA3dBlendEquation */1070 "*" "TRANSPARENCYANTIALIAS", /* SVGA3dTransparencyAntialiasType */1071 "f" "LINEAA", /* SVGA3dBool */1072 "r" "LINEWIDTH", /* float */1073 };1074 1075 1076 /**1077 * Formats a SVGA3dRenderState structure as a string.1078 *1079 * @returns pszBuffer.1080 * @param pszBuffer Output string buffer.1081 * @param cbBuffer Size of output buffer.1082 * @param pRenderState The SVGA3d render state to format.1083 */1084 char *vmsvga3dFormatRenderState(char *pszBuffer, size_t cbBuffer, SVGA3dRenderState const *pRenderState)1085 {1086 uint32_t iState = pRenderState->state;1087 if (iState != SVGA3D_RS_INVALID)1088 {1089 if (iState < RT_ELEMENTS(g_apszRenderStateNamesAndType))1090 {1091 const char *pszName = g_apszRenderStateNamesAndType[iState];1092 char const chType = *pszName++;1093 1094 union1095 {1096 uint32_t u;1097 float r;1098 SVGA3dColorMask Color;1099 } uValue;1100 uValue.u = pRenderState->uintValue;1101 1102 switch (chType)1103 {1104 case 'f':1105 if (uValue.u == 0)1106 RTStrPrintf(pszBuffer, cbBuffer, "%s = false", pszName);1107 else if (uValue.u == 1)1108 RTStrPrintf(pszBuffer, cbBuffer, "%s = true", pszName);1109 else1110 RTStrPrintf(pszBuffer, cbBuffer, "%s = true (%#x)", pszName, uValue.u);1111 break;1112 case 'x':1113 RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x (%d)", pszName, uValue.u, uValue.u);1114 break;1115 case 'r':1116 RTStrPrintf(pszBuffer, cbBuffer, "%s = %d.%06u (%#x)",1117 pszName, (int)uValue.r, (unsigned)(uValue.r * 1000000) % 1000000U, uValue.u);1118 break;1119 case 'c': //SVGA3dColor, SVGA3dColorMask1120 RTStrPrintf(pszBuffer, cbBuffer, "%s = RGBA(%d,%d,%d,%d) (%#x)", pszName,1121 uValue.Color.s.red, uValue.Color.s.green, uValue.Color.s.blue, uValue.Color.s.alpha, uValue.u);1122 break;1123 case 'w': //SVGA3dWrapFlags1124 RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x%s", pszName, uValue.u,1125 uValue.u <= SVGA3D_WRAPCOORD_ALL ? " (out of bounds" : "");1126 break;1127 default:1128 AssertFailed();1129 case 'b': //SVGA3dBlendOp1130 case 'e': //SVGA3dBlendEquation1131 case 'p': //SVGA3dCmpFunc1132 case 's': //SVGA3dStencilOp1133 case 'v': //SVGA3dVertexMaterial1134 case '*':1135 RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x", pszName, uValue.u);1136 break;1137 }1138 }1139 else1140 RTStrPrintf(pszBuffer, cbBuffer, "UNKNOWN_%d_%#x = %#x", iState, iState, pRenderState->uintValue);1141 }1142 else1143 RTStrPrintf(pszBuffer, cbBuffer, "INVALID");1144 return pszBuffer;1145 }1146 1147 /**1148 * Texture state names with type prefix.1149 */1150 static const char * const g_apszTextureStateNamesAndType[] =1151 {1152 "*" "INVALID", /* invalid */1153 "x" "BIND_TEXTURE", /* SVGA3dSurfaceId */1154 "m" "COLOROP", /* SVGA3dTextureCombiner */1155 "a" "COLORARG1", /* SVGA3dTextureArgData */1156 "a" "COLORARG2", /* SVGA3dTextureArgData */1157 "m" "ALPHAOP", /* SVGA3dTextureCombiner */1158 "a" "ALPHAARG1", /* SVGA3dTextureArgData */1159 "a" "ALPHAARG2", /* SVGA3dTextureArgData */1160 "e" "ADDRESSU", /* SVGA3dTextureAddress */1161 "e" "ADDRESSV", /* SVGA3dTextureAddress */1162 "l" "MIPFILTER", /* SVGA3dTextureFilter */1163 "l" "MAGFILTER", /* SVGA3dTextureFilter */1164 "m" "MINFILTER", /* SVGA3dTextureFilter */1165 "c" "BORDERCOLOR", /* SVGA3dColor */1166 "r" "TEXCOORDINDEX", /* uint32_t */1167 "t" "TEXTURETRANSFORMFLAGS", /* SVGA3dTexTransformFlags */1168 "g" "TEXCOORDGEN", /* SVGA3dTextureCoordGen */1169 "r" "BUMPENVMAT00", /* float */1170 "r" "BUMPENVMAT01", /* float */1171 "r" "BUMPENVMAT10", /* float */1172 "r" "BUMPENVMAT11", /* float */1173 "x" "TEXTURE_MIPMAP_LEVEL", /* uint32_t */1174 "r" "TEXTURE_LOD_BIAS", /* float */1175 "x" "TEXTURE_ANISOTROPIC_LEVEL", /* uint32_t */1176 "e" "ADDRESSW", /* SVGA3dTextureAddress */1177 "r" "GAMMA", /* float */1178 "r" "BUMPENVLSCALE", /* float */1179 "r" "BUMPENVLOFFSET", /* float */1180 "a" "COLORARG0", /* SVGA3dTextureArgData */1181 "a" "ALPHAARG0" /* SVGA3dTextureArgData */1182 };1183 1184 /**1185 * Formats a SVGA3dTextureState structure as a string.1186 *1187 * @returns pszBuffer.1188 * @param pszBuffer Output string buffer.1189 * @param cbBuffer Size of output buffer.1190 * @param pTextureState The SVGA3d texture state to format.1191 */1192 char *vmsvga3dFormatTextureState(char *pszBuffer, size_t cbBuffer, SVGA3dTextureState const *pTextureState)1193 {1194 /*1195 * Format the stage first.1196 */1197 char *pszRet = pszBuffer;1198 size_t cchPrefix = RTStrPrintf(pszBuffer, cbBuffer, "[%u] ", pTextureState->stage);1199 if (cchPrefix < cbBuffer)1200 {1201 cbBuffer -= cchPrefix;1202 pszBuffer += cchPrefix;1203 }1204 else1205 cbBuffer = 0;1206 1207 /*1208 * Format the name and value.1209 */1210 uint32_t iName = pTextureState->name;1211 if (iName != SVGA3D_TS_INVALID)1212 {1213 if (iName < RT_ELEMENTS(g_apszTextureStateNamesAndType))1214 {1215 const char *pszName = g_apszTextureStateNamesAndType[iName];1216 char chType = *pszName++;1217 1218 union1219 {1220 uint32_t u;1221 float r;1222 SVGA3dColorMask Color;1223 } uValue;1224 uValue.u = pTextureState->value;1225 1226 switch (chType)1227 {1228 case 'x':1229 RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x (%d)", pszName, uValue.u, uValue.u);1230 break;1231 1232 case 'r':1233 RTStrPrintf(pszBuffer, cbBuffer, "%s = %d.%06u (%#x)",1234 pszName, (int)uValue.r, (unsigned)(uValue.r * 1000000) % 1000000U, uValue.u);1235 break;1236 1237 case 'a': //SVGA3dTextureArgData1238 {1239 static const char * const s_apszValues[] =1240 {1241 "INVALID", "CONSTANT", "PREVIOUS", "DIFFUSE", "TEXTURE", "SPECULAR"1242 };1243 vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,1244 "SVGA3D_TA_", s_apszValues, RT_ELEMENTS(s_apszValues));1245 break;1246 }1247 1248 case 'c': //SVGA3dColor, SVGA3dColorMask1249 RTStrPrintf(pszBuffer, cbBuffer, "%s = RGBA(%d,%d,%d,%d) (%#x)", pszName,1250 uValue.Color.s.red, uValue.Color.s.green, uValue.Color.s.blue, uValue.Color.s.alpha, uValue.u);1251 break;1252 1253 case 'e': //SVGA3dTextureAddress1254 {1255 static const char * const s_apszValues[] =1256 {1257 "INVALID", "WRAP", "MIRROR", "CLAMP", "BORDER", "MIRRORONCE", "EDGE",1258 };1259 vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,1260 "SVGA3D_TEX_ADDRESS_", s_apszValues, RT_ELEMENTS(s_apszValues));1261 break;1262 }1263 1264 case 'l': //SVGA3dTextureFilter1265 {1266 static const char * const s_apszValues[] =1267 {1268 "NONE", "NEAREST", "LINEAR", "ANISOTROPIC", "FLATCUBIC", "GAUSSIANCUBIC", "PYRAMIDALQUAD", "GAUSSIANQUAD",1269 };1270 vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,1271 "SVGA3D_TEX_FILTER_", s_apszValues, RT_ELEMENTS(s_apszValues));1272 break;1273 }1274 1275 case 'g': //SVGA3dTextureCoordGen1276 {1277 static const char * const s_apszValues[] =1278 {1279 "OFF", "EYE_POSITION", "EYE_NORMAL", "REFLECTIONVECTOR", "SPHERE",1280 };1281 vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,1282 "SVGA3D_TEXCOORD_GEN_", s_apszValues, RT_ELEMENTS(s_apszValues));1283 break;1284 }1285 1286 case 'm': //SVGA3dTextureCombiner1287 {1288 static const char * const s_apszValues[] =1289 {1290 "INVALID", "DISABLE", "SELECTARG1", "SELECTARG2", "MODULATE", "ADD", "ADDSIGNED", "SUBTRACT",1291 "BLENDTEXTUREALPHA", "BLENDDIFFUSEALPHA", "BLENDCURRENTALPHA", "BLENDFACTORALPHA", "MODULATE2X",1292 "MODULATE4X", "DSDT", "DOTPRODUCT3", "BLENDTEXTUREALPHAPM", "ADDSIGNED2X", "ADDSMOOTH", "PREMODULATE",1293 "MODULATEALPHA_ADDCOLOR", "MODULATECOLOR_ADDALPHA", "MODULATEINVALPHA_ADDCOLOR",1294 "MODULATEINVCOLOR_ADDALPHA", "BUMPENVMAPLUMINANCE", "MULTIPLYADD", "LERP",1295 };1296 vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u,1297 "SVGA3D_TC_", s_apszValues, RT_ELEMENTS(s_apszValues));1298 break;1299 }1300 1301 default:1302 AssertFailed();1303 RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x\n", pszName, uValue.u);1304 break;1305 }1306 }1307 else1308 RTStrPrintf(pszBuffer, cbBuffer, "UNKNOWN_%d_%#x = %#x\n", iName, iName, pTextureState->value);1309 }1310 else1311 RTStrPrintf(pszBuffer, cbBuffer, "INVALID");1312 return pszRet;1313 }1314 1315 1316 1317 static const char * const g_apszTransformTypes[] =1318 {1319 "SVGA3D_TRANSFORM_INVALID",1320 "SVGA3D_TRANSFORM_WORLD",1321 "SVGA3D_TRANSFORM_VIEW",1322 "SVGA3D_TRANSFORM_PROJECTION",1323 "SVGA3D_TRANSFORM_TEXTURE0",1324 "SVGA3D_TRANSFORM_TEXTURE1",1325 "SVGA3D_TRANSFORM_TEXTURE2",1326 "SVGA3D_TRANSFORM_TEXTURE3",1327 "SVGA3D_TRANSFORM_TEXTURE4",1328 "SVGA3D_TRANSFORM_TEXTURE5",1329 "SVGA3D_TRANSFORM_TEXTURE6",1330 "SVGA3D_TRANSFORM_TEXTURE7",1331 "SVGA3D_TRANSFORM_WORLD1",1332 "SVGA3D_TRANSFORM_WORLD2",1333 "SVGA3D_TRANSFORM_WORLD3",1334 };1335 1336 static const char * const g_apszFaces[] =1337 {1338 "SVGA3D_FACE_INVALID",1339 "SVGA3D_FACE_NONE",1340 "SVGA3D_FACE_FRONT",1341 "SVGA3D_FACE_BACK",1342 "SVGA3D_FACE_FRONT_BACK",1343 };1344 1345 static const char * const g_apszLightTypes[] =1346 {1347 "SVGA3D_LIGHTTYPE_INVALID",1348 "SVGA3D_LIGHTTYPE_POINT",1349 "SVGA3D_LIGHTTYPE_SPOT1",1350 "SVGA3D_LIGHTTYPE_SPOT2",1351 "SVGA3D_LIGHTTYPE_DIRECTIONAL",1352 };1353 1354 static const char * const g_apszRenderTargets[] =1355 {1356 "SVGA3D_RT_DEPTH",1357 "SVGA3D_RT_STENCIL",1358 "SVGA3D_RT_COLOR0",1359 "SVGA3D_RT_COLOR1",1360 "SVGA3D_RT_COLOR2",1361 "SVGA3D_RT_COLOR3",1362 "SVGA3D_RT_COLOR4",1363 "SVGA3D_RT_COLOR5",1364 "SVGA3D_RT_COLOR6",1365 "SVGA3D_RT_COLOR7",1366 };1367 1368 static void vmsvga3dInfoContextWorkerOne(PCDBGFINFOHLP pHlp, PVMSVGA3DCONTEXT pContext, bool fVerbose)1369 {1370 char szTmp[128];1371 1372 pHlp->pfnPrintf(pHlp, "*** VMSVGA 3d context %#x (%d) ***\n", pContext->id, pContext->id);1373 #ifdef RT_OS_WINDOWS1374 pHlp->pfnPrintf(pHlp, "hwnd: %p\n", pContext->hwnd);1375 if (fVerbose)1376 vmsvga3dInfoHostWindow(pHlp, (uintptr_t)pContext->hwnd);1377 # ifdef VMSVGA3D_DIRECT3D1378 pHlp->pfnPrintf(pHlp, "pDevice: %p\n", pContext->pDevice);1379 # else1380 pHlp->pfnPrintf(pHlp, "hdc: %p\n", pContext->hdc);1381 pHlp->pfnPrintf(pHlp, "hglrc: %p\n", pContext->hglrc);1382 # endif1383 #else1384 /** @todo Other hosts... */1385 #endif1386 pHlp->pfnPrintf(pHlp, "sidRenderTarget: %#x\n", pContext->sidRenderTarget);1387 1388 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->aSidActiveTexture); i++)1389 if (pContext->aSidActiveTexture[i] != SVGA3D_INVALID_ID)1390 pHlp->pfnPrintf(pHlp, "aSidActiveTexture[%u]: %#x\n", i, pContext->aSidActiveTexture[i]);1391 1392 pHlp->pfnPrintf(pHlp, "fUpdateFlags: %#x\n", pContext->state.u32UpdateFlags);1393 1394 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aRenderState); i++)1395 if (pContext->state.aRenderState[i].state != SVGA3D_RS_INVALID)1396 pHlp->pfnPrintf(pHlp, "aRenderState[%3d]: %s\n", i,1397 vmsvga3dFormatRenderState(szTmp, sizeof(szTmp), &pContext->state.aRenderState[i]));1398 1399 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aTextureState); i++)1400 for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aTextureState[i]); j++)1401 if (pContext->state.aTextureState[i][j].name != SVGA3D_TS_INVALID)1402 pHlp->pfnPrintf(pHlp, "aTextureState[%3d][%3d]: %s\n", i, j,1403 vmsvga3dFormatTextureState(szTmp, sizeof(szTmp), &pContext->state.aTextureState[i][j]));1404 1405 AssertCompile(RT_ELEMENTS(g_apszTransformTypes) == SVGA3D_TRANSFORM_MAX);1406 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aTransformState); i++)1407 if (pContext->state.aTransformState[i].fValid)1408 {1409 pHlp->pfnPrintf(pHlp, "aTransformState[%s(%u)]:\n", g_apszTransformTypes[i], i);1410 for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aTransformState[i].matrix); j++)1411 pHlp->pfnPrintf(pHlp,1412 (j % 4) == 0 ? " [ " FLOAT_FMT_STR : (j % 4) < 3 ? ", " FLOAT_FMT_STR : ", " FLOAT_FMT_STR "]\n",1413 FLOAT_FMT_ARGS(pContext->state.aTransformState[i].matrix[j]));1414 }1415 1416 AssertCompile(RT_ELEMENTS(g_apszFaces) == SVGA3D_FACE_MAX);1417 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aMaterial); i++)1418 if (pContext->state.aMaterial[i].fValid)1419 {1420 pHlp->pfnPrintf(pHlp, "aTransformState[%s(%u)]: shininess=" FLOAT_FMT_STR "\n",1421 g_apszFaces[i], i, FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.shininess));1422 pHlp->pfnPrintf(pHlp, " diffuse =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",1423 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[0]),1424 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[1]),1425 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[2]),1426 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[3]));1427 pHlp->pfnPrintf(pHlp, " ambient =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",1428 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[0]),1429 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[1]),1430 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[2]),1431 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[3]));1432 pHlp->pfnPrintf(pHlp, " specular=[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",1433 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[0]),1434 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[1]),1435 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[2]),1436 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[3]));1437 pHlp->pfnPrintf(pHlp, " emissive=[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",1438 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[0]),1439 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[1]),1440 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[2]),1441 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[3]));1442 }1443 1444 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aClipPlane); i++)1445 if (pContext->state.aClipPlane[i].fValid)1446 pHlp->pfnPrintf(pHlp, "aClipPlane[%#04x]: [ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",1447 FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[0]),1448 FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[1]),1449 FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[2]),1450 FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[3]));1451 1452 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aLightData); i++)1453 if (pContext->state.aLightData[i].fValidData)1454 {1455 pHlp->pfnPrintf(pHlp, "aLightData[%#04x]: enabled=%RTbool inWorldSpace=%RTbool type=%s(%u)\n",1456 i,1457 pContext->state.aLightData[i].fEnabled,1458 pContext->state.aLightData[i].data.inWorldSpace,1459 (uint32_t)pContext->state.aLightData[i].data.type < RT_ELEMENTS(g_apszLightTypes)1460 ? g_apszLightTypes[pContext->state.aLightData[i].data.type] : "UNKNOWN",1461 pContext->state.aLightData[i].data.type);1462 pHlp->pfnPrintf(pHlp, " diffuse =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",1463 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[0]),1464 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[1]),1465 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[2]),1466 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[3]));1467 pHlp->pfnPrintf(pHlp, " specular =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",1468 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[0]),1469 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[1]),1470 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[2]),1471 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[3]));1472 pHlp->pfnPrintf(pHlp, " ambient =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",1473 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[0]),1474 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[1]),1475 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[2]),1476 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[3]));1477 pHlp->pfnPrintf(pHlp, " position =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",1478 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[0]),1479 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[1]),1480 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[2]),1481 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[3]));1482 pHlp->pfnPrintf(pHlp, " direction=[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",1483 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[0]),1484 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[1]),1485 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[2]),1486 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[3]));1487 pHlp->pfnPrintf(pHlp, " range=" FLOAT_FMT_STR " falloff=" FLOAT_FMT_STR "\n",1488 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.range),1489 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.falloff));1490 pHlp->pfnPrintf(pHlp, " attenuation0=" FLOAT_FMT_STR " attenuation1=" FLOAT_FMT_STR " attenuation2=" FLOAT_FMT_STR "\n",1491 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.attenuation0),1492 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.attenuation1),1493 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.attenuation2));1494 pHlp->pfnPrintf(pHlp, " theta=" FLOAT_FMT_STR " phi=" FLOAT_FMT_STR "\n",1495 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.theta),1496 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.phi));1497 }1498 1499 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aRenderTargets); i++)1500 if (pContext->state.aRenderTargets[i] != SVGA3D_INVALID_ID)1501 pHlp->pfnPrintf(pHlp, "aRenderTargets[%s/%u] = %#x (%d)\n",1502 i < RT_ELEMENTS(g_apszRenderTargets) ? g_apszRenderTargets[i] : "UNKNOWN", i,1503 pContext->state.aRenderTargets[i], pContext->state.aRenderTargets[i]);1504 1505 pHlp->pfnPrintf(pHlp, "RectScissor: (x,y,cx,cy)=(%u,%u,%u,%u)\n",1506 pContext->state.RectViewPort.x, pContext->state.RectViewPort.y,1507 pContext->state.RectViewPort.w, pContext->state.RectViewPort.h);1508 pHlp->pfnPrintf(pHlp, "zRange: (min,max)=(" FLOAT_FMT_STR ", " FLOAT_FMT_STR ")\n",1509 FLOAT_FMT_ARGS(pContext->state.zRange.min),1510 FLOAT_FMT_ARGS(pContext->state.zRange.max));1511 pHlp->pfnPrintf(pHlp, "fUpdateFlags: %#x\n", pContext->state.u32UpdateFlags);1512 pHlp->pfnPrintf(pHlp, "shidPixel: %#x (%d)\n", pContext->state.shidPixel, pContext->state.shidPixel);1513 pHlp->pfnPrintf(pHlp, "shidVertex: %#x (%d)\n", pContext->state.shidVertex, pContext->state.shidVertex);1514 1515 for (uint32_t iWhich = 0; iWhich < 2; iWhich++)1516 {1517 uint32_t cConsts = iWhich == 0 ? pContext->state.cPixelShaderConst : pContext->state.cVertexShaderConst;1518 PVMSVGASHADERCONST paConsts = iWhich == 0 ? pContext->state.paPixelShaderConst : pContext->state.paVertexShaderConst;1519 const char *pszName = iWhich ? "paPixelShaderConst" : "paVertexShaderConst";1520 1521 for (uint32_t i = 0; i < cConsts; i++)1522 if (paConsts[i].fValid)1523 {1524 if (paConsts[i].ctype == SVGA3D_CONST_TYPE_FLOAT)1525 pHlp->pfnPrintf(pHlp, "%s[%#x(%u)] = [" FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR "] ctype=FLOAT\n",1526 pszName, i, i,1527 FLOAT_FMT_ARGS(paConsts[i].value[0]), FLOAT_FMT_ARGS(paConsts[i].value[1]),1528 FLOAT_FMT_ARGS(paConsts[i].value[2]), FLOAT_FMT_ARGS(paConsts[i].value[3]));1529 else1530 pHlp->pfnPrintf(pHlp, "%s[%#x(%u)] = [%#x, %#x, %#x, %#x] ctype=%s\n",1531 pszName, i, i,1532 paConsts[i].value[0], paConsts[i].value[1],1533 paConsts[i].value[2], paConsts[i].value[3],1534 paConsts[i].ctype == SVGA3D_CONST_TYPE_INT ? "INT"1535 : paConsts[i].ctype == SVGA3D_CONST_TYPE_BOOL ? "BOOL" : "UNKNOWN");1536 }1537 }1538 1539 for (uint32_t iWhich = 0; iWhich < 2; iWhich++)1540 {1541 uint32_t cShaders = iWhich == 0 ? pContext->cPixelShaders : pContext->cVertexShaders;1542 PVMSVGA3DSHADER paShaders = iWhich == 0 ? pContext->paPixelShader : pContext->paVertexShader;1543 const char *pszName = iWhich == 0 ? "paPixelShaders" : "paVertexShaders";1544 for (uint32_t i = 0; i < cShaders; i++)1545 if (paShaders[i].id == i)1546 {1547 pHlp->pfnPrintf(pHlp, "%s[%u]: id=%#x cid=%#x type=%s(%d) cbData=%#x pvData=%p\n",1548 pszName, i,1549 paShaders[i].id,1550 paShaders[i].cid,1551 paShaders[i].type == SVGA3D_SHADERTYPE_VS ? "VS"1552 : paShaders[i].type == SVGA3D_SHADERTYPE_PS ? "PS" : "UNKNOWN",1553 paShaders[i].type,1554 paShaders[i].cbData,1555 paShaders[i].pShaderProgram);1556 }1557 }1558 }1559 1560 1561 void vmsvga3dInfoContextWorker(PVGASTATE pThis, PCDBGFINFOHLP pHlp, uint32_t cid, bool fVerbose)1562 {1563 /* Warning! This code is currently racing papContexts reallocation! */1564 /* Warning! This code is currently racing papContexts reallocation! */1565 /* Warning! This code is currently racing papContexts reallocation! */1566 VMSVGA3DSTATE volatile *pState = pThis->svga.p3dState;1567 if (pState)1568 {1569 /*1570 * Deal with a specific request first.1571 */1572 if (cid != UINT32_MAX)1573 {1574 if (cid < pState->cContexts)1575 {1576 PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];1577 if (pContext && pContext->id == cid)1578 {1579 vmsvga3dInfoContextWorkerOne(pHlp, pContext, fVerbose);1580 return;1581 }1582 }1583 pHlp->pfnPrintf(pHlp, "Context ID %#x not found.\n", cid);1584 }1585 else1586 {1587 /*1588 * Dump all.1589 */1590 uint32_t cContexts = pState->cContexts;1591 pHlp->pfnPrintf(pHlp, "cContexts=%d\n", cContexts);1592 for (cid = 0; cid < cContexts; cid++)1593 {1594 PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];1595 if (pContext && pContext->id == cid)1596 {1597 pHlp->pfnPrintf(pHlp, "\n");1598 vmsvga3dInfoContextWorkerOne(pHlp, pContext, fVerbose);1599 }1600 }1601 }1602 }1603 }1604 101 1605 102 /** Values for SVGA3dTextureFilter, prefix SVGA3D_TEX_FILTER_. */ … … 1748 245 }; 1749 246 1750 247 #endif /* VMSVGA3D_DIRECT3D */ 248 249 250 /** 251 * Worker for vmsvga3dUpdateHeapBuffersForSurfaces. 252 * 253 * This will allocate heap buffers if necessary, thus increasing the memory 254 * usage of the process. 255 * 256 * @todo Would be interesting to share this code with the saved state code. 257 * 258 * @returns VBox status code. 259 * @param pState The 3D state structure. 260 * @param pSurface The surface to refresh the heap buffers for. 261 */ 262 static int vmsvga3dSurfaceUpdateHeapBuffers(PVMSVGA3DSTATE pState, PVMSVGA3DSURFACE pSurface) 263 { 264 /* 265 * Currently we've got trouble retreving bit for DEPTHSTENCIL 266 * surfaces both for OpenGL and D3D, so skip these here (don't 267 * wast memory on them). 268 */ 269 uint32_t const fSwitchFlags = pSurface->flags 270 & ( SVGA3D_SURFACE_HINT_INDEXBUFFER | SVGA3D_SURFACE_HINT_VERTEXBUFFER 271 | SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET 272 | SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_CUBEMAP); 273 if ( fSwitchFlags != SVGA3D_SURFACE_HINT_DEPTHSTENCIL 274 && fSwitchFlags != (SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_HINT_TEXTURE)) 275 { 276 277 #ifdef VMSVGA3D_OPENGL 278 /* 279 * Change OpenGL context to the one the surface is associated with. 280 */ 281 PVMSVGA3DCONTEXT pContext = &pState->SharedCtx; 282 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext); 283 #endif 284 285 /* 286 * Work thru each mipmap level for each face. 287 */ 288 for (uint32_t iFace = 0; iFace < pSurface->cFaces; iFace++) 289 { 290 Assert(pSurface->faces[iFace].numMipLevels <= pSurface->faces[0].numMipLevels); 291 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->pMipmapLevels[iFace * pSurface->faces[0].numMipLevels]; 292 for (uint32_t i = 0; i < pSurface->faces[iFace].numMipLevels; i++, pMipmapLevel++) 293 { 294 #ifdef VMSVGA3D_DIRECT3D 295 if (pSurface->u.pSurface) 296 #else 297 if (pSurface->oglId.texture != OPENGL_INVALID_ID) 298 #endif 299 { 300 Assert(pMipmapLevel->cbSurface); 301 Assert(pMipmapLevel->cbSurface == pMipmapLevel->cbSurfacePitch * pMipmapLevel->size.height); /* correct for depth stuff? */ 302 303 /* 304 * Make sure we've got surface memory buffer. 305 */ 306 uint8_t *pbDst = (uint8_t *)pMipmapLevel->pSurfaceData; 307 if (!pbDst) 308 { 309 pMipmapLevel->pSurfaceData = pbDst = (uint8_t *)RTMemAllocZ(pMipmapLevel->cbSurface); 310 AssertReturn(pbDst, VERR_NO_MEMORY); 311 } 312 313 #ifdef VMSVGA3D_DIRECT3D 314 /* 315 * D3D specifics. 316 */ 317 HRESULT hr; 318 switch (fSwitchFlags) 319 { 320 case SVGA3D_SURFACE_HINT_TEXTURE: 321 case SVGA3D_SURFACE_HINT_RENDERTARGET: 322 case SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET: 323 { 324 /* 325 * Lock the buffer and make it accessible to memcpy. 326 */ 327 D3DLOCKED_RECT LockedRect; 328 if (fSwitchFlags & SVGA3D_SURFACE_HINT_TEXTURE) 329 { 330 if (pSurface->bounce.pTexture) 331 { 332 if ( !pSurface->fDirty 333 && fSwitchFlags == (SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET) 334 && i == 0 /* only the first time */) 335 { 336 /** @todo stricter checks for associated context */ 337 uint32_t cid = pSurface->idAssociatedContext; 338 if ( cid >= pState->cContexts 339 || pState->papContexts[cid]->id != cid) 340 { 341 Log(("vmsvga3dSurfaceUpdateHeapBuffers: invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id)); 342 AssertFailedReturn(VERR_INVALID_PARAMETER); 343 } 344 PVMSVGA3DCONTEXT pContext = pState->papContexts[cid]; 345 346 IDirect3DSurface9 *pDst = NULL; 347 hr = pSurface->bounce.pTexture->GetSurfaceLevel(i, &pDst); 348 AssertMsgReturn(hr == D3D_OK, ("GetSurfaceLevel failed with %#x\n", hr), VERR_INTERNAL_ERROR); 349 350 IDirect3DSurface9 *pSrc = NULL; 351 hr = pSurface->u.pTexture->GetSurfaceLevel(i, &pSrc); 352 AssertMsgReturn(hr == D3D_OK, ("GetSurfaceLevel failed with %#x\n", hr), VERR_INTERNAL_ERROR); 353 354 hr = pContext->pDevice->GetRenderTargetData(pSrc, pDst); 355 AssertMsgReturn(hr == D3D_OK, ("GetRenderTargetData failed with %#x\n", hr), VERR_INTERNAL_ERROR); 356 357 pSrc->Release(); 358 pDst->Release(); 359 } 360 361 hr = pSurface->bounce.pTexture->LockRect(i, /* texture level */ 362 &LockedRect, 363 NULL, 364 D3DLOCK_READONLY); 365 } 366 else 367 hr = pSurface->u.pTexture->LockRect(i, /* texture level */ 368 &LockedRect, 369 NULL, 370 D3DLOCK_READONLY); 371 } 372 else 373 hr = pSurface->u.pSurface->LockRect(&LockedRect, 374 NULL, 375 D3DLOCK_READONLY); 376 AssertMsgReturn(hr == D3D_OK, ("LockRect failed with %x\n", hr), VERR_INTERNAL_ERROR); 377 378 /* 379 * Copy the data. Take care in case the pitch differs. 380 */ 381 if (pMipmapLevel->cbSurfacePitch == (uint32_t)LockedRect.Pitch) 382 memcpy(pbDst, LockedRect.pBits, pMipmapLevel->cbSurface); 383 else 384 for (uint32_t j = 0; j < pMipmapLevel->size.height; j++) 385 memcpy(pbDst + j * pMipmapLevel->cbSurfacePitch, 386 (uint8_t *)LockedRect.pBits + j * LockedRect.Pitch, 387 pMipmapLevel->cbSurfacePitch); 388 389 /* 390 * Release the buffer. 391 */ 392 if (fSwitchFlags & SVGA3D_SURFACE_HINT_TEXTURE) 393 { 394 if (pSurface->bounce.pTexture) 395 { 396 hr = pSurface->bounce.pTexture->UnlockRect(i); 397 AssertMsgReturn(hr == D3D_OK, ("UnlockRect failed with %#x\n", hr), VERR_INTERNAL_ERROR); 398 } 399 else 400 hr = pSurface->u.pTexture->UnlockRect(i); 401 } 402 else 403 hr = pSurface->u.pSurface->UnlockRect(); 404 AssertMsgReturn(hr == D3D_OK, ("UnlockRect failed with %#x\n", hr), VERR_INTERNAL_ERROR); 405 break; 406 } 407 408 case SVGA3D_SURFACE_HINT_VERTEXBUFFER: 409 { 410 void *pvD3DData = NULL; 411 hr = pSurface->u.pVertexBuffer->Lock(0, 0, &pvD3DData, D3DLOCK_READONLY); 412 AssertMsgReturn(hr == D3D_OK, ("Lock vertex failed with %x\n", hr), VERR_INTERNAL_ERROR); 413 414 memcpy(pbDst, pvD3DData, pMipmapLevel->cbSurface); 415 416 hr = pSurface->u.pVertexBuffer->Unlock(); 417 AssertMsg(hr == D3D_OK, ("Unlock vertex failed with %x\n", hr)); 418 break; 419 } 420 421 case SVGA3D_SURFACE_HINT_INDEXBUFFER: 422 { 423 void *pvD3DData = NULL; 424 hr = pSurface->u.pIndexBuffer->Lock(0, 0, &pvD3DData, D3DLOCK_READONLY); 425 AssertMsgReturn(hr == D3D_OK, ("Lock index failed with %x\n", hr), VERR_INTERNAL_ERROR); 426 427 memcpy(pbDst, pvD3DData, pMipmapLevel->cbSurface); 428 429 hr = pSurface->u.pIndexBuffer->Unlock(); 430 AssertMsg(hr == D3D_OK, ("Unlock index failed with %x\n", hr)); 431 break; 432 } 433 434 default: 435 AssertMsgFailed(("%#x\n", fSwitchFlags)); 436 } 437 438 #elif defined(VMSVGA3D_OPENGL) 439 /* 440 * OpenGL specifics. 441 */ 442 switch (fSwitchFlags) 443 { 444 case SVGA3D_SURFACE_HINT_TEXTURE: 445 case SVGA3D_SURFACE_HINT_RENDERTARGET: 446 case SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET: 447 { 448 GLint activeTexture; 449 glGetIntegerv(GL_TEXTURE_BINDING_2D, &activeTexture); 450 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext); 451 452 glBindTexture(GL_TEXTURE_2D, pSurface->oglId.texture); 453 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext); 454 455 /* Set row length and alignment of the output data. */ 456 VMSVGAPACKPARAMS SavedParams; 457 vmsvga3dOglSetPackParams(pState, pContext, pSurface, &SavedParams); 458 459 glGetTexImage(GL_TEXTURE_2D, 460 i, 461 pSurface->formatGL, 462 pSurface->typeGL, 463 pbDst); 464 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext); 465 466 vmsvga3dOglRestorePackParams(pState, pContext, pSurface, &SavedParams); 467 468 /* Restore the old active texture. */ 469 glBindTexture(GL_TEXTURE_2D, activeTexture); 470 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext); 471 break; 472 } 473 474 case SVGA3D_SURFACE_HINT_VERTEXBUFFER: 475 case SVGA3D_SURFACE_HINT_INDEXBUFFER: 476 { 477 pState->ext.glBindBuffer(GL_ARRAY_BUFFER, pSurface->oglId.buffer); 478 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext); 479 480 void *pvSrc = pState->ext.glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY); 481 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext); 482 if (RT_VALID_PTR(pvSrc)) 483 memcpy(pbDst, pvSrc, pMipmapLevel->cbSurface); 484 else 485 AssertPtr(pvSrc); 486 487 pState->ext.glUnmapBuffer(GL_ARRAY_BUFFER); 488 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext); 489 490 pState->ext.glBindBuffer(GL_ARRAY_BUFFER, 0); 491 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext); 492 break; 493 } 494 495 default: 496 AssertMsgFailed(("%#x\n", fSwitchFlags)); 497 } 498 #else 499 # error "misconfigured" 500 #endif 501 } 502 /* else: There is no data in hardware yet, so whatever we got is already current. */ 503 } 504 } 505 } 506 507 return VINF_SUCCESS; 508 } 509 510 511 /** 512 * Updates the heap buffers for all surfaces or one specific one. 513 * 514 * @param pThis The VGA device instance data. 515 * @param sid The surface ID, UINT32_MAX if all. 516 * @thread VMSVGAFIFO 517 */ 518 void vmsvga3dUpdateHeapBuffersForSurfaces(PVGASTATE pThis, uint32_t sid) 519 { 520 PVMSVGA3DSTATE pState = pThis->svga.p3dState; 521 AssertReturnVoid(pState); 522 523 if (sid == UINT32_MAX) 524 { 525 uint32_t cSurfaces = pState->cSurfaces; 526 for (sid = 0; sid < cSurfaces; sid++) 527 { 528 PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid]; 529 if (pSurface && pSurface->id == sid) 530 vmsvga3dSurfaceUpdateHeapBuffers(pState, pSurface); 531 } 532 } 533 else if (sid < pState->cSurfaces) 534 { 535 PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid]; 536 if (pSurface && pSurface->id == sid) 537 vmsvga3dSurfaceUpdateHeapBuffers(pState, pSurface); 538 } 539 } 540 541 542 543 544 void vmsvga3dInfoU32Flags(PCDBGFINFOHLP pHlp, uint32_t fFlags, const char *pszPrefix, PCVMSVGAINFOFLAGS32 paFlags, uint32_t cFlags) 545 { 546 for (uint32_t i = 0; i < cFlags; i++) 547 if ((paFlags[i].fFlags & fFlags) == paFlags[i].fFlags) 548 { 549 Assert(paFlags[i].fFlags); 550 pHlp->pfnPrintf(pHlp, " %s%s", pszPrefix, paFlags[i].pszJohnny); 551 fFlags &= ~paFlags[i].fFlags; 552 if (!fFlags) 553 return; 554 } 555 if (fFlags) 556 pHlp->pfnPrintf(pHlp, " UNKNOWN_%#x", fFlags); 557 } 558 559 560 /** 561 * Worker for vmsvgaR3Info that display details of a host window. 562 * 563 * @param pHlp The output methods. 564 * @param idHostWindow The host window handle/id/whatever. 565 */ 566 void vmsvga3dInfoHostWindow(PCDBGFINFOHLP pHlp, uint64_t idHostWindow) 567 { 568 #ifdef RT_OS_WINDOWS 569 HWND hwnd = (HWND)(uintptr_t)idHostWindow; 570 Assert((uintptr_t)hwnd == idHostWindow); 571 if (hwnd != NULL) 572 { 573 WINDOWINFO Info; 574 RT_ZERO(Info); 575 Info.cbSize = sizeof(Info); 576 if (GetWindowInfo(hwnd, &Info)) 577 { 578 pHlp->pfnPrintf(pHlp, " Window rect: xLeft=%d, yTop=%d, xRight=%d, yBottom=%d (cx=%d, cy=%d)\n", 579 Info.rcWindow.left, Info.rcWindow.top, Info.rcWindow.right, Info.rcWindow.bottom, 580 Info.rcWindow.right - Info.rcWindow.left, Info.rcWindow.bottom - Info.rcWindow.top); 581 pHlp->pfnPrintf(pHlp, " Client rect: xLeft=%d, yTop=%d, xRight=%d, yBottom=%d (cx=%d, cy=%d)\n", 582 Info.rcClient.left, Info.rcClient.top, Info.rcClient.right, Info.rcClient.bottom, 583 Info.rcClient.right - Info.rcClient.left, Info.rcClient.bottom - Info.rcClient.top); 584 pHlp->pfnPrintf(pHlp, " Style: %#x", Info.dwStyle); 585 static const VMSVGAINFOFLAGS32 g_aStyles[] = 586 { 587 { WS_POPUP , "POPUP" }, 588 { WS_CHILD , "CHILD" }, 589 { WS_MINIMIZE , "MINIMIZE" }, 590 { WS_VISIBLE , "VISIBLE" }, 591 { WS_DISABLED , "DISABLED" }, 592 { WS_CLIPSIBLINGS , "CLIPSIBLINGS" }, 593 { WS_CLIPCHILDREN , "CLIPCHILDREN" }, 594 { WS_MAXIMIZE , "MAXIMIZE" }, 595 { WS_BORDER , "BORDER" }, 596 { WS_DLGFRAME , "DLGFRAME" }, 597 { WS_VSCROLL , "VSCROLL" }, 598 { WS_HSCROLL , "HSCROLL" }, 599 { WS_SYSMENU , "SYSMENU" }, 600 { WS_THICKFRAME , "THICKFRAME" }, 601 { WS_GROUP , "GROUP" }, 602 { WS_TABSTOP , "TABSTOP" }, 603 }; 604 vmsvga3dInfoU32Flags(pHlp, Info.dwStyle, "", g_aStyles, RT_ELEMENTS(g_aStyles)); 605 pHlp->pfnPrintf(pHlp, "\n"); 606 607 pHlp->pfnPrintf(pHlp, " ExStyle: %#x", Info.dwExStyle); 608 static const VMSVGAINFOFLAGS32 g_aExStyles[] = 609 { 610 { WS_EX_DLGMODALFRAME, "DLGMODALFRAME" }, 611 { 0x00000002, "DRAGDETECT" }, 612 { WS_EX_NOPARENTNOTIFY, "NOPARENTNOTIFY" }, 613 { WS_EX_TOPMOST, "TOPMOST" }, 614 { WS_EX_ACCEPTFILES, "ACCEPTFILES" }, 615 { WS_EX_TRANSPARENT, "TRANSPARENT" }, 616 { WS_EX_MDICHILD, "MDICHILD" }, 617 { WS_EX_TOOLWINDOW, "TOOLWINDOW" }, 618 { WS_EX_WINDOWEDGE, "WINDOWEDGE" }, 619 { WS_EX_CLIENTEDGE, "CLIENTEDGE" }, 620 { WS_EX_CONTEXTHELP, "CONTEXTHELP" }, 621 { WS_EX_RIGHT, "RIGHT" }, 622 /*{ WS_EX_LEFT, "LEFT" }, = 0 */ 623 { WS_EX_RTLREADING, "RTLREADING" }, 624 /*{ WS_EX_LTRREADING, "LTRREADING" }, = 0 */ 625 { WS_EX_LEFTSCROLLBAR, "LEFTSCROLLBAR" }, 626 /*{ WS_EX_RIGHTSCROLLBAR, "RIGHTSCROLLBAR" }, = 0 */ 627 { WS_EX_CONTROLPARENT, "CONTROLPARENT" }, 628 { WS_EX_STATICEDGE, "STATICEDGE" }, 629 { WS_EX_APPWINDOW, "APPWINDOW" }, 630 { WS_EX_LAYERED, "LAYERED" }, 631 { WS_EX_NOINHERITLAYOUT, "NOINHERITLAYOUT" }, 632 { WS_EX_LAYOUTRTL, "LAYOUTRTL" }, 633 { WS_EX_COMPOSITED, "COMPOSITED" }, 634 { WS_EX_NOACTIVATE, "NOACTIVATE" }, 635 }; 636 vmsvga3dInfoU32Flags(pHlp, Info.dwExStyle, "", g_aExStyles, RT_ELEMENTS(g_aExStyles)); 637 pHlp->pfnPrintf(pHlp, "\n"); 638 639 pHlp->pfnPrintf(pHlp, " Window Status: %#x\n", Info.dwWindowStatus); 640 if (Info.cxWindowBorders || Info.cyWindowBorders) 641 pHlp->pfnPrintf(pHlp, " Borders: cx=%u, cy=%u\n", Info.cxWindowBorders, Info.cyWindowBorders); 642 pHlp->pfnPrintf(pHlp, " Window Type: %#x\n", Info.atomWindowType); 643 pHlp->pfnPrintf(pHlp, " Creator Ver: %#x\n", Info.wCreatorVersion); 644 } 645 else 646 pHlp->pfnPrintf(pHlp, " GetWindowInfo: last error %d\n", GetLastError()); 647 } 648 #else 649 pHlp->pfnPrintf(pHlp, " Windows info: Not implemented on this platform\n"); 650 #endif 651 652 } 653 654 655 /** 656 * Looks up an enum value in a translation table. 657 * 658 * @returns The value name. 659 * @param iValue The value to name. 660 * @param pEnumMap Enum value to string mapping. 661 */ 662 const char *vmsvgaLookupEnum(int32_t iValue, PCVMSVGAINFOENUMMAP pEnumMap) 663 { 664 PCVMSVGAINFOENUM paValues = pEnumMap->paValues; 665 666 #ifdef VBOX_STRICT 667 /* 668 * Check that it's really sorted, or the binary lookup won't work right. 669 */ 670 if (!*pEnumMap->pfAsserted) 671 { 672 *pEnumMap->pfAsserted = true; 673 for (uint32_t i = 1; i < pEnumMap->cValues; i++) 674 Assert(paValues[i - 1].iValue <= paValues[i].iValue); 675 } 676 #endif 677 678 /* 679 * Binary search 680 */ 681 uint32_t iStart = 0; 682 uint32_t iEnd = (uint32_t)pEnumMap->cValues; 683 for (;;) 684 { 685 uint32_t i = iStart + (iEnd - iStart) / 2; 686 if (iValue < paValues[i].iValue) 687 { 688 if (i > iStart) 689 iEnd = i; 690 else 691 break; 692 } 693 else if (iValue > paValues[i].iValue) 694 { 695 i++; 696 if (i < iEnd) 697 iStart = i; 698 else 699 break; 700 } 701 else 702 return paValues[i].pszName; 703 } 704 return NULL; 705 } 706 707 708 /** 709 * Formats an enum value as a string, sparse mapping table. 710 * 711 * @returns pszBuffer. 712 * @param pszBuffer The output buffer. 713 * @param cbBuffer The size of the output buffer. 714 * @param pszName The variable name, optional. 715 * @param iValue The enum value. 716 * @param fPrefix Whether to prepend the prefix or not. 717 * @param pEnumMap Enum value to string mapping. 718 */ 719 char *vmsvgaFormatEnumValueEx(char *pszBuffer, size_t cbBuffer, const char *pszName, int32_t iValue, 720 bool fPrefix, PCVMSVGAINFOENUMMAP pEnumMap) 721 { 722 const char *pszValueName = vmsvgaLookupEnum(iValue, pEnumMap); 723 const char *pszPrefix = fPrefix ? pEnumMap->pszPrefix : ""; 724 if (pszValueName) 725 { 726 if (pszName) 727 RTStrPrintf(pszBuffer, cbBuffer, "%s = %s%s (%#x)", pszName, pszPrefix, pszValueName, iValue); 728 else 729 RTStrPrintf(pszBuffer, cbBuffer, "%s%s (%#x)", pszPrefix, pszValueName, iValue); 730 return pszBuffer; 731 } 732 733 if (pszName) 734 RTStrPrintf(pszBuffer, cbBuffer, "%s = %sUNKNOWN_%d (%#x)", pszName, pszPrefix, iValue, iValue); 735 else 736 RTStrPrintf(pszBuffer, cbBuffer, "%sUNKNOWN_%d (%#x)", pszPrefix, iValue, iValue); 737 return pszBuffer; 738 } 739 740 741 /** 742 * Formats an enum value as a string. 743 * 744 * @returns pszBuffer. 745 * @param pszBuffer The output buffer. 746 * @param cbBuffer The size of the output buffer. 747 * @param pszName The variable name, optional. 748 * @param uValue The enum value. 749 * @param pszPrefix The prefix of the enum values. Empty string if 750 * none. This helps reduce the memory footprint 751 * as well as the source code size. 752 * @param papszValues One to one string mapping of the enum values. 753 * @param cValues The number of values in the mapping. 754 */ 755 char *vmsvgaFormatEnumValue(char *pszBuffer, size_t cbBuffer, const char *pszName, uint32_t uValue, 756 const char *pszPrefix, const char * const *papszValues, size_t cValues) 757 { 758 if (uValue < cValues) 759 { 760 if (pszName) 761 RTStrPrintf(pszBuffer, cbBuffer, "%s = %s%s (%#x)", pszName, pszPrefix, papszValues[uValue], uValue); 762 else 763 RTStrPrintf(pszBuffer, cbBuffer, "%s%s (%#x)", pszPrefix, papszValues[uValue], uValue); 764 } 765 else 766 { 767 if (pszName) 768 RTStrPrintf(pszBuffer, cbBuffer, "%s = %sUNKNOWN_%d (%#x)", pszName, pszPrefix, uValue, uValue); 769 else 770 RTStrPrintf(pszBuffer, cbBuffer, "%sUNKNOWN_%d (%#x)", pszPrefix, uValue, uValue); 771 } 772 return pszBuffer; 773 } 774 775 776 /** 777 * DBGF info printer for vmsvga3dAsciiPrint. 778 * 779 * @param pszLine The line to print. 780 * @param pvUser The debug info helpers. 781 */ 782 DECLCALLBACK(void) vmsvga3dAsciiPrintlnInfo(const char *pszLine, void *pvUser) 783 { 784 PCDBGFINFOHLP pHlp = (PCDBGFINFOHLP)pvUser; 785 pHlp->pfnPrintf(pHlp, ">%s<\n", pszLine); 786 } 787 788 789 /** 790 * Log printer for vmsvga3dAsciiPrint. 791 * 792 * @param pszLine The line to print. 793 * @param pvUser Ignored. 794 */ 795 DECLCALLBACK(void) vmsvga3dAsciiPrintlnLog(const char *pszLine, void *pvUser) 796 { 797 size_t cch = strlen(pszLine); 798 while (cch > 0 && pszLine[cch - 1] == ' ') 799 cch--; 800 RTLogPrintf("%.*s\n", cch, pszLine); 801 NOREF(pvUser); 802 } 803 804 805 void vmsvga3dAsciiPrint(PFMVMSVGAASCIIPRINTLN pfnPrintLine, void *pvUser, void const *pvImage, size_t cbImage, 806 uint32_t cx, uint32_t cy, uint32_t cbScanline, SVGA3dSurfaceFormat enmFormat, bool fInvY, 807 uint32_t cchMaxX, uint32_t cchMaxY) 808 { 809 /* 810 * Skip stuff we can't or won't need to handle. 811 */ 812 if (!cx || !cy) 813 return; 814 switch (enmFormat) 815 { 816 /* Compressed. */ 817 case SVGA3D_DXT1: 818 case SVGA3D_DXT2: 819 case SVGA3D_DXT3: 820 case SVGA3D_DXT4: 821 case SVGA3D_DXT5: 822 return; 823 /* Generic. */ 824 case SVGA3D_BUFFER: 825 return; 826 default: 827 break; /* ok */ 828 } 829 830 /* 831 * Figure the pixel conversion factors. 832 */ 833 uint32_t cxPerChar = cx / cchMaxX + 1; 834 uint32_t cyPerChar = cy / cchMaxY + 1; 835 /** @todo try keep aspect... */ 836 uint32_t const cchLine = (cx + cxPerChar - 1) / cxPerChar; 837 uint32_t const cbSrcPixel = vmsvga3dSurfaceFormatSize(enmFormat); 838 839 /* 840 * The very simple conversion we're doing in this function is based on 841 * mapping a block of converted pixels to an ASCII character of similar 842 * weigth. We do that by summing up all the 8-bit gray scale pixels in 843 * that block, applying a conversion factor and getting an index into an 844 * array of increasingly weighty characters. 845 */ 846 static const char s_szPalette[] = " ..`',:;icodxkO08XNWM"; 847 static const uint32_t s_cchPalette = sizeof(s_szPalette) - 1; 848 uint32_t const cPixelsWeightPerChar = cxPerChar * cyPerChar * 256; 849 850 /* 851 * Do the work 852 */ 853 uint32_t *pauScanline = (uint32_t *)RTMemTmpAllocZ(sizeof(pauScanline[0]) * cchLine + cchLine + 1); 854 if (!pauScanline) 855 return; 856 char *pszLine = (char *)&pauScanline[cchLine]; 857 RTCPTRUNION uSrc; 858 uSrc.pv = pvImage; 859 if (fInvY) 860 uSrc.pu8 += (cy - 1) * cbScanline; 861 uint32_t cyLeft = cy; 862 uint32_t cyLeftInScanline = cyPerChar; 863 bool fHitFormatAssert = false; 864 for (;;) 865 { 866 /* 867 * Process the scanline. This is tedious because of all the 868 * different formats. We generally ignore alpha, unless it's 869 * all we've got to work with. 870 * Color to 8-bit grayscale conversion is done by averaging. 871 */ 872 #define CONVERT_SCANLINE(a_RdExpr, a_AddExpr) \ 873 do { \ 874 for (uint32_t xSrc = 0, xDst = 0, cxLeftInChar = cxPerChar; xSrc < cx; xSrc++) \ 875 { \ 876 a_RdExpr; \ 877 pauScanline[xDst] += (a_AddExpr) & 0xff; \ 878 Assert(pauScanline[xDst] <= cPixelsWeightPerChar); \ 879 if (--cxLeftInChar == 0) \ 880 { \ 881 xDst++; \ 882 cxLeftInChar = cxPerChar; \ 883 } \ 884 } \ 885 } while (0) 886 887 switch (enmFormat) 888 { 889 /* Unsigned RGB and super/subsets. */ 890 case SVGA3D_X8R8G8B8: 891 case SVGA3D_A8R8G8B8: 892 CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc], 893 ( ( u32Tmp & 0xff) /* B */ 894 + ((u32Tmp >> 8) & 0xff) /* G */ 895 + ((u32Tmp >> 16) & 0xff) /* R */) / 3); 896 break; 897 case SVGA3D_R5G6B5: 898 CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc], 899 ( ( u16Tmp & 0x1f) * 8 900 + ((u16Tmp >> 5) & 0x3f) * 4 901 + ( u16Tmp >> 11) * 8 ) / 3 ); 902 break; 903 case SVGA3D_X1R5G5B5: 904 case SVGA3D_A1R5G5B5: 905 CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc], 906 ( ( u16Tmp & 0x1f) * 8 907 + ((u16Tmp >> 5) & 0x1f) * 8 908 + ((u16Tmp >> 10) & 0x1f) * 8) / 3 ); 909 break; 910 case SVGA3D_A4R4G4B4: 911 CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc], 912 ( ( u16Tmp & 0xf) * 16 913 + ((u16Tmp >> 4) & 0xf) * 16 914 + ((u16Tmp >> 8) & 0xf) * 16) / 3 ); 915 break; 916 case SVGA3D_A16B16G16R16: 917 CONVERT_SCANLINE(uint64_t const u64Tmp = uSrc.pu64[xSrc], 918 ( ((u64Tmp >> 8) & 0xff) /* R */ 919 + ((u64Tmp >> 24) & 0xff) /* G */ 920 + ((u64Tmp >> 40) & 0xff) /* B */ ) / 3); 921 break; 922 case SVGA3D_A2R10G10B10: 923 CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc], 924 ( ( u32Tmp & 0x3ff) /* B */ 925 + ((u32Tmp >> 10) & 0x3ff) /* G */ 926 + ((u32Tmp >> 20) & 0x3ff) /* R */ ) / (3 * 4)); 927 break; 928 case SVGA3D_G16R16: 929 CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc], 930 ( (u32Tmp & 0xffff) /* R */ 931 + (u32Tmp >> 16 ) /* G */) / 0x200); 932 break; 933 934 /* Depth. */ 935 case SVGA3D_Z_D32: 936 CONVERT_SCANLINE(uint32_t const u32Tmp = ~((uSrc.pu32[xSrc] >> 1) | uSrc.pu32[xSrc]) & UINT32_C(0x44444444), 937 (( u32Tmp >> (2 - 0)) & RT_BIT_32(0)) 938 | ((u32Tmp >> ( 6 - 1)) & RT_BIT_32(1)) 939 | ((u32Tmp >> (10 - 2)) & RT_BIT_32(2)) 940 | ((u32Tmp >> (14 - 3)) & RT_BIT_32(3)) 941 | ((u32Tmp >> (18 - 4)) & RT_BIT_32(4)) 942 | ((u32Tmp >> (22 - 5)) & RT_BIT_32(5)) 943 | ((u32Tmp >> (26 - 6)) & RT_BIT_32(6)) 944 | ((u32Tmp >> (30 - 7)) & RT_BIT_32(7)) ); 945 break; 946 case SVGA3D_Z_D16: 947 CONVERT_SCANLINE(uint16_t const u16Tmp = ~uSrc.pu16[xSrc], 948 ((u16Tmp >> ( 1 - 0)) & RT_BIT_32(0)) 949 | ((u16Tmp >> ( 3 - 1)) & RT_BIT_32(1)) 950 | ((u16Tmp >> ( 5 - 2)) & RT_BIT_32(2)) 951 | ((u16Tmp >> ( 7 - 3)) & RT_BIT_32(3)) 952 | ((u16Tmp >> ( 9 - 4)) & RT_BIT_32(4)) 953 | ((u16Tmp >> (11 - 5)) & RT_BIT_32(5)) 954 | ((u16Tmp >> (13 - 6)) & RT_BIT_32(6)) 955 | ((u16Tmp >> (15 - 7)) & RT_BIT_32(7)) ); 956 break; 957 case SVGA3D_Z_D24S8: 958 CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc], 959 ( u32Tmp & 0xff) /* stencile */ 960 | ((~u32Tmp >> 18) & 0x3f)); 961 break; 962 case SVGA3D_Z_D15S1: 963 CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc], 964 ( (u16Tmp & 0x01) << 7) /* stencile */ 965 | ((~u16Tmp >> 8) & 0x7f)); 966 break; 967 968 /* Pure alpha. */ 969 case SVGA3D_ALPHA8: 970 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc]); 971 break; 972 973 /* Luminance */ 974 case SVGA3D_LUMINANCE8: 975 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc]); 976 break; 977 case SVGA3D_LUMINANCE4_ALPHA4: 978 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc] & 0xf0); 979 break; 980 case SVGA3D_LUMINANCE16: 981 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu16[xSrc] >> 8); 982 break; 983 case SVGA3D_LUMINANCE8_ALPHA8: 984 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu16[xSrc] >> 8); 985 break; 986 987 /* Not supported. */ 988 case SVGA3D_DXT1: 989 case SVGA3D_DXT2: 990 case SVGA3D_DXT3: 991 case SVGA3D_DXT4: 992 case SVGA3D_DXT5: 993 case SVGA3D_BUFFER: 994 AssertFailedBreak(); 995 996 /* Not considered for implementation yet. */ 997 case SVGA3D_BUMPU8V8: 998 case SVGA3D_BUMPL6V5U5: 999 case SVGA3D_BUMPX8L8V8U8: 1000 case SVGA3D_BUMPL8V8U8: 1001 case SVGA3D_ARGB_S10E5: 1002 case SVGA3D_ARGB_S23E8: 1003 case SVGA3D_V8U8: 1004 case SVGA3D_Q8W8V8U8: 1005 case SVGA3D_CxV8U8: 1006 case SVGA3D_X8L8V8U8: 1007 case SVGA3D_A2W10V10U10: 1008 case SVGA3D_R_S10E5: 1009 case SVGA3D_R_S23E8: 1010 case SVGA3D_RG_S10E5: 1011 case SVGA3D_RG_S23E8: 1012 case SVGA3D_Z_D24X8: 1013 case SVGA3D_V16U16: 1014 case SVGA3D_UYVY: 1015 case SVGA3D_YUY2: 1016 case SVGA3D_NV12: 1017 case SVGA3D_AYUV: 1018 case SVGA3D_BC4_UNORM: 1019 case SVGA3D_BC5_UNORM: 1020 case SVGA3D_Z_DF16: 1021 case SVGA3D_Z_DF24: 1022 case SVGA3D_Z_D24S8_INT: 1023 if (!fHitFormatAssert) 1024 { 1025 AssertMsgFailed(("%s is not implemented\n", vmsvgaLookupEnum((int)enmFormat, &g_SVGA3dSurfaceFormat2String))); 1026 fHitFormatAssert = true; 1027 } 1028 /* fall thru */ 1029 default: 1030 /* Lazy programmer fallbacks. */ 1031 if (cbSrcPixel == 4) 1032 CONVERT_SCANLINE(uint32_t const u32Tmp = uSrc.pu32[xSrc], 1033 ( ( u32Tmp & 0xff) 1034 + ((u32Tmp >> 8) & 0xff) 1035 + ((u32Tmp >> 16) & 0xff) 1036 + ((u32Tmp >> 24) & 0xff) ) / 4); 1037 else if (cbSrcPixel == 3) 1038 CONVERT_SCANLINE(RT_NOTHING, 1039 ( (uint32_t)uSrc.pu8[xSrc * 4] 1040 + (uint32_t)uSrc.pu8[xSrc * 4 + 1] 1041 + (uint32_t)uSrc.pu8[xSrc * 4 + 2] ) / 3); 1042 else if (cbSrcPixel == 2) 1043 CONVERT_SCANLINE(uint16_t const u16Tmp = uSrc.pu16[xSrc], 1044 ( ( u16Tmp & 0xf) 1045 + ((u16Tmp >> 4) & 0xf) 1046 + ((u16Tmp >> 8) & 0xf) 1047 + ((u16Tmp >> 12) & 0xf) ) * 4 /* mul 16 div 4 */ ); 1048 else if (cbSrcPixel == 1) 1049 CONVERT_SCANLINE(RT_NOTHING, uSrc.pu8[xSrc]); 1050 else 1051 AssertFailed(); 1052 break; 1053 1054 } 1055 1056 /* 1057 * Print we've reached the end of a block in y direction or if we're at 1058 * the end of the image. 1059 */ 1060 cyLeft--; 1061 if (--cyLeftInScanline == 0 || cyLeft == 0) 1062 { 1063 for (uint32_t i = 0; i < cchLine; i++) 1064 { 1065 uint32_t off = pauScanline[i] * s_cchPalette / cPixelsWeightPerChar; Assert(off < s_cchPalette); 1066 pszLine[i] = s_szPalette[off < sizeof(s_szPalette) - 1 ? off : sizeof(s_szPalette) - 1]; 1067 } 1068 pszLine[cchLine] = '\0'; 1069 pfnPrintLine(pszLine, pvUser); 1070 1071 if (!cyLeft) 1072 break; 1073 cyLeftInScanline = cyPerChar; 1074 RT_BZERO(pauScanline, sizeof(pauScanline[0]) * cchLine); 1075 } 1076 1077 /* 1078 * Advance. 1079 */ 1080 if (!fInvY) 1081 uSrc.pu8 += cbScanline; 1082 else 1083 uSrc.pu8 -= cbScanline; 1084 } 1085 } 1086 1087 1088 1089 /** 1090 * Formats a SVGA3dRenderState structure as a string. 1091 * 1092 * @returns pszBuffer. 1093 * @param pszBuffer Output string buffer. 1094 * @param cbBuffer Size of output buffer. 1095 * @param pRenderState The SVGA3d render state to format. 1096 */ 1097 char *vmsvga3dFormatRenderState(char *pszBuffer, size_t cbBuffer, SVGA3dRenderState const *pRenderState) 1098 { 1099 /* 1100 * List of render state names with type prefix. 1101 * 1102 * First char in the name is a type indicator: 1103 * - '*' = requires special handling. 1104 * - 'f' = SVGA3dbool 1105 * - 'd' = uint32_t 1106 * - 'r' = float 1107 * - 'b' = SVGA3dBlendOp 1108 * - 'c' = SVGA3dColor, SVGA3dColorMask 1109 * - 'e' = SVGA3dBlendEquation 1110 * - 'm' = SVGA3dColorMask 1111 * - 'p' = SVGA3dCmpFunc 1112 * - 's' = SVGA3dStencilOp 1113 * - 'v' = SVGA3dVertexMaterial 1114 * - 'w' = SVGA3dWrapFlags 1115 */ 1116 static const char * const s_apszRenderStateNamesAndType[] = 1117 { 1118 "*" "INVALID", /* invalid */ 1119 "f" "ZENABLE", /* SVGA3dBool */ 1120 "f" "ZWRITEENABLE", /* SVGA3dBool */ 1121 "f" "ALPHATESTENABLE", /* SVGA3dBool */ 1122 "f" "DITHERENABLE", /* SVGA3dBool */ 1123 "f" "BLENDENABLE", /* SVGA3dBool */ 1124 "f" "FOGENABLE", /* SVGA3dBool */ 1125 "f" "SPECULARENABLE", /* SVGA3dBool */ 1126 "f" "STENCILENABLE", /* SVGA3dBool */ 1127 "f" "LIGHTINGENABLE", /* SVGA3dBool */ 1128 "f" "NORMALIZENORMALS", /* SVGA3dBool */ 1129 "f" "POINTSPRITEENABLE", /* SVGA3dBool */ 1130 "f" "POINTSCALEENABLE", /* SVGA3dBool */ 1131 "x" "STENCILREF", /* uint32_t */ 1132 "x" "STENCILMASK", /* uint32_t */ 1133 "x" "STENCILWRITEMASK", /* uint32_t */ 1134 "r" "FOGSTART", /* float */ 1135 "r" "FOGEND", /* float */ 1136 "r" "FOGDENSITY", /* float */ 1137 "r" "POINTSIZE", /* float */ 1138 "r" "POINTSIZEMIN", /* float */ 1139 "r" "POINTSIZEMAX", /* float */ 1140 "r" "POINTSCALE_A", /* float */ 1141 "r" "POINTSCALE_B", /* float */ 1142 "r" "POINTSCALE_C", /* float */ 1143 "c" "FOGCOLOR", /* SVGA3dColor */ 1144 "c" "AMBIENT", /* SVGA3dColor */ 1145 "*" "CLIPPLANEENABLE", /* SVGA3dClipPlanes */ 1146 "*" "FOGMODE", /* SVGA3dFogMode */ 1147 "*" "FILLMODE", /* SVGA3dFillMode */ 1148 "*" "SHADEMODE", /* SVGA3dShadeMode */ 1149 "*" "LINEPATTERN", /* SVGA3dLinePattern */ 1150 "b" "SRCBLEND", /* SVGA3dBlendOp */ 1151 "b" "DSTBLEND", /* SVGA3dBlendOp */ 1152 "e" "BLENDEQUATION", /* SVGA3dBlendEquation */ 1153 "*" "CULLMODE", /* SVGA3dFace */ 1154 "p" "ZFUNC", /* SVGA3dCmpFunc */ 1155 "p" "ALPHAFUNC", /* SVGA3dCmpFunc */ 1156 "p" "STENCILFUNC", /* SVGA3dCmpFunc */ 1157 "s" "STENCILFAIL", /* SVGA3dStencilOp */ 1158 "s" "STENCILZFAIL", /* SVGA3dStencilOp */ 1159 "s" "STENCILPASS", /* SVGA3dStencilOp */ 1160 "r" "ALPHAREF", /* float */ 1161 "*" "FRONTWINDING", /* SVGA3dFrontWinding */ 1162 "*" "COORDINATETYPE", /* SVGA3dCoordinateType */ 1163 "r" "ZBIAS", /* float */ 1164 "f" "RANGEFOGENABLE", /* SVGA3dBool */ 1165 "c" "COLORWRITEENABLE", /* SVGA3dColorMask */ 1166 "f" "VERTEXMATERIALENABLE", /* SVGA3dBool */ 1167 "v" "DIFFUSEMATERIALSOURCE", /* SVGA3dVertexMaterial */ 1168 "v" "SPECULARMATERIALSOURCE", /* SVGA3dVertexMaterial */ 1169 "v" "AMBIENTMATERIALSOURCE", /* SVGA3dVertexMaterial */ 1170 "v" "EMISSIVEMATERIALSOURCE", /* SVGA3dVertexMaterial */ 1171 "c" "TEXTUREFACTOR", /* SVGA3dColor */ 1172 "f" "LOCALVIEWER", /* SVGA3dBool */ 1173 "f" "SCISSORTESTENABLE", /* SVGA3dBool */ 1174 "c" "BLENDCOLOR", /* SVGA3dColor */ 1175 "f" "STENCILENABLE2SIDED", /* SVGA3dBool */ 1176 "p" "CCWSTENCILFUNC", /* SVGA3dCmpFunc */ 1177 "s" "CCWSTENCILFAIL", /* SVGA3dStencilOp */ 1178 "s" "CCWSTENCILZFAIL", /* SVGA3dStencilOp */ 1179 "s" "CCWSTENCILPASS", /* SVGA3dStencilOp */ 1180 "*" "VERTEXBLEND", /* SVGA3dVertexBlendFlags */ 1181 "r" "SLOPESCALEDEPTHBIAS", /* float */ 1182 "r" "DEPTHBIAS", /* float */ 1183 "r" "OUTPUTGAMMA", /* float */ 1184 "f" "ZVISIBLE", /* SVGA3dBool */ 1185 "f" "LASTPIXEL", /* SVGA3dBool */ 1186 "f" "CLIPPING", /* SVGA3dBool */ 1187 "w" "WRAP0", /* SVGA3dWrapFlags */ 1188 "w" "WRAP1", /* SVGA3dWrapFlags */ 1189 "w" "WRAP2", /* SVGA3dWrapFlags */ 1190 "w" "WRAP3", /* SVGA3dWrapFlags */ 1191 "w" "WRAP4", /* SVGA3dWrapFlags */ 1192 "w" "WRAP5", /* SVGA3dWrapFlags */ 1193 "w" "WRAP6", /* SVGA3dWrapFlags */ 1194 "w" "WRAP7", /* SVGA3dWrapFlags */ 1195 "w" "WRAP8", /* SVGA3dWrapFlags */ 1196 "w" "WRAP9", /* SVGA3dWrapFlags */ 1197 "w" "WRAP10", /* SVGA3dWrapFlags */ 1198 "w" "WRAP11", /* SVGA3dWrapFlags */ 1199 "w" "WRAP12", /* SVGA3dWrapFlags */ 1200 "w" "WRAP13", /* SVGA3dWrapFlags */ 1201 "w" "WRAP14", /* SVGA3dWrapFlags */ 1202 "w" "WRAP15", /* SVGA3dWrapFlags */ 1203 "f" "MULTISAMPLEANTIALIAS", /* SVGA3dBool */ 1204 "x" "MULTISAMPLEMASK", /* uint32_t */ 1205 "f" "INDEXEDVERTEXBLENDENABLE", /* SVGA3dBool */ 1206 "r" "TWEENFACTOR", /* float */ 1207 "f" "ANTIALIASEDLINEENABLE", /* SVGA3dBool */ 1208 "c" "COLORWRITEENABLE1", /* SVGA3dColorMask */ 1209 "c" "COLORWRITEENABLE2", /* SVGA3dColorMask */ 1210 "c" "COLORWRITEENABLE3", /* SVGA3dColorMask */ 1211 "f" "SEPARATEALPHABLENDENABLE", /* SVGA3dBool */ 1212 "b" "SRCBLENDALPHA", /* SVGA3dBlendOp */ 1213 "b" "DSTBLENDALPHA", /* SVGA3dBlendOp */ 1214 "e" "BLENDEQUATIONALPHA", /* SVGA3dBlendEquation */ 1215 "*" "TRANSPARENCYANTIALIAS", /* SVGA3dTransparencyAntialiasType */ 1216 "f" "LINEAA", /* SVGA3dBool */ 1217 "r" "LINEWIDTH", /* float */ 1218 }; 1219 1220 uint32_t iState = pRenderState->state; 1221 if (iState != SVGA3D_RS_INVALID) 1222 { 1223 if (iState < RT_ELEMENTS(s_apszRenderStateNamesAndType)) 1224 { 1225 const char *pszName = s_apszRenderStateNamesAndType[iState]; 1226 char const chType = *pszName++; 1227 1228 union 1229 { 1230 uint32_t u; 1231 float r; 1232 SVGA3dColorMask Color; 1233 } uValue; 1234 uValue.u = pRenderState->uintValue; 1235 1236 switch (chType) 1237 { 1238 case 'f': 1239 if (uValue.u == 0) 1240 RTStrPrintf(pszBuffer, cbBuffer, "%s = false", pszName); 1241 else if (uValue.u == 1) 1242 RTStrPrintf(pszBuffer, cbBuffer, "%s = true", pszName); 1243 else 1244 RTStrPrintf(pszBuffer, cbBuffer, "%s = true (%#x)", pszName, uValue.u); 1245 break; 1246 case 'x': 1247 RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x (%d)", pszName, uValue.u, uValue.u); 1248 break; 1249 case 'r': 1250 RTStrPrintf(pszBuffer, cbBuffer, "%s = %d.%06u (%#x)", 1251 pszName, (int)uValue.r, (unsigned)(uValue.r * 1000000) % 1000000U, uValue.u); 1252 break; 1253 case 'c': //SVGA3dColor, SVGA3dColorMask 1254 RTStrPrintf(pszBuffer, cbBuffer, "%s = RGBA(%d,%d,%d,%d) (%#x)", pszName, 1255 uValue.Color.s.red, uValue.Color.s.green, uValue.Color.s.blue, uValue.Color.s.alpha, uValue.u); 1256 break; 1257 case 'w': //SVGA3dWrapFlags 1258 RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x%s", pszName, uValue.u, 1259 uValue.u <= SVGA3D_WRAPCOORD_ALL ? " (out of bounds" : ""); 1260 break; 1261 default: 1262 AssertFailed(); 1263 case 'b': //SVGA3dBlendOp 1264 case 'e': //SVGA3dBlendEquation 1265 case 'p': //SVGA3dCmpFunc 1266 case 's': //SVGA3dStencilOp 1267 case 'v': //SVGA3dVertexMaterial 1268 case '*': 1269 RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x", pszName, uValue.u); 1270 break; 1271 } 1272 } 1273 else 1274 RTStrPrintf(pszBuffer, cbBuffer, "UNKNOWN_%d_%#x = %#x", iState, iState, pRenderState->uintValue); 1275 } 1276 else 1277 RTStrPrintf(pszBuffer, cbBuffer, "INVALID"); 1278 return pszBuffer; 1279 } 1280 1281 1282 /** 1283 * Formats a SVGA3dTextureState structure as a string. 1284 * 1285 * @returns pszBuffer. 1286 * @param pszBuffer Output string buffer. 1287 * @param cbBuffer Size of output buffer. 1288 * @param pTextureState The SVGA3d texture state to format. 1289 */ 1290 char *vmsvga3dFormatTextureState(char *pszBuffer, size_t cbBuffer, SVGA3dTextureState const *pTextureState) 1291 { 1292 static const char * const s_apszTextureStateNamesAndType[] = 1293 { 1294 "*" "INVALID", /* invalid */ 1295 "x" "BIND_TEXTURE", /* SVGA3dSurfaceId */ 1296 "m" "COLOROP", /* SVGA3dTextureCombiner */ 1297 "a" "COLORARG1", /* SVGA3dTextureArgData */ 1298 "a" "COLORARG2", /* SVGA3dTextureArgData */ 1299 "m" "ALPHAOP", /* SVGA3dTextureCombiner */ 1300 "a" "ALPHAARG1", /* SVGA3dTextureArgData */ 1301 "a" "ALPHAARG2", /* SVGA3dTextureArgData */ 1302 "e" "ADDRESSU", /* SVGA3dTextureAddress */ 1303 "e" "ADDRESSV", /* SVGA3dTextureAddress */ 1304 "l" "MIPFILTER", /* SVGA3dTextureFilter */ 1305 "l" "MAGFILTER", /* SVGA3dTextureFilter */ 1306 "m" "MINFILTER", /* SVGA3dTextureFilter */ 1307 "c" "BORDERCOLOR", /* SVGA3dColor */ 1308 "r" "TEXCOORDINDEX", /* uint32_t */ 1309 "t" "TEXTURETRANSFORMFLAGS", /* SVGA3dTexTransformFlags */ 1310 "g" "TEXCOORDGEN", /* SVGA3dTextureCoordGen */ 1311 "r" "BUMPENVMAT00", /* float */ 1312 "r" "BUMPENVMAT01", /* float */ 1313 "r" "BUMPENVMAT10", /* float */ 1314 "r" "BUMPENVMAT11", /* float */ 1315 "x" "TEXTURE_MIPMAP_LEVEL", /* uint32_t */ 1316 "r" "TEXTURE_LOD_BIAS", /* float */ 1317 "x" "TEXTURE_ANISOTROPIC_LEVEL", /* uint32_t */ 1318 "e" "ADDRESSW", /* SVGA3dTextureAddress */ 1319 "r" "GAMMA", /* float */ 1320 "r" "BUMPENVLSCALE", /* float */ 1321 "r" "BUMPENVLOFFSET", /* float */ 1322 "a" "COLORARG0", /* SVGA3dTextureArgData */ 1323 "a" "ALPHAARG0" /* SVGA3dTextureArgData */ 1324 }; 1325 1326 /* 1327 * Format the stage first. 1328 */ 1329 char *pszRet = pszBuffer; 1330 size_t cchPrefix = RTStrPrintf(pszBuffer, cbBuffer, "[%u] ", pTextureState->stage); 1331 if (cchPrefix < cbBuffer) 1332 { 1333 cbBuffer -= cchPrefix; 1334 pszBuffer += cchPrefix; 1335 } 1336 else 1337 cbBuffer = 0; 1338 1339 /* 1340 * Format the name and value. 1341 */ 1342 uint32_t iName = pTextureState->name; 1343 if (iName != SVGA3D_TS_INVALID) 1344 { 1345 if (iName < RT_ELEMENTS(s_apszTextureStateNamesAndType)) 1346 { 1347 const char *pszName = s_apszTextureStateNamesAndType[iName]; 1348 char chType = *pszName++; 1349 1350 union 1351 { 1352 uint32_t u; 1353 float r; 1354 SVGA3dColorMask Color; 1355 } uValue; 1356 uValue.u = pTextureState->value; 1357 1358 switch (chType) 1359 { 1360 case 'x': 1361 RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x (%d)", pszName, uValue.u, uValue.u); 1362 break; 1363 1364 case 'r': 1365 RTStrPrintf(pszBuffer, cbBuffer, "%s = %d.%06u (%#x)", 1366 pszName, (int)uValue.r, (unsigned)(uValue.r * 1000000) % 1000000U, uValue.u); 1367 break; 1368 1369 case 'a': //SVGA3dTextureArgData 1370 { 1371 static const char * const s_apszValues[] = 1372 { 1373 "INVALID", "CONSTANT", "PREVIOUS", "DIFFUSE", "TEXTURE", "SPECULAR" 1374 }; 1375 vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u, 1376 "SVGA3D_TA_", s_apszValues, RT_ELEMENTS(s_apszValues)); 1377 break; 1378 } 1379 1380 case 'c': //SVGA3dColor, SVGA3dColorMask 1381 RTStrPrintf(pszBuffer, cbBuffer, "%s = RGBA(%d,%d,%d,%d) (%#x)", pszName, 1382 uValue.Color.s.red, uValue.Color.s.green, uValue.Color.s.blue, uValue.Color.s.alpha, uValue.u); 1383 break; 1384 1385 case 'e': //SVGA3dTextureAddress 1386 { 1387 static const char * const s_apszValues[] = 1388 { 1389 "INVALID", "WRAP", "MIRROR", "CLAMP", "BORDER", "MIRRORONCE", "EDGE", 1390 }; 1391 vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u, 1392 "SVGA3D_TEX_ADDRESS_", s_apszValues, RT_ELEMENTS(s_apszValues)); 1393 break; 1394 } 1395 1396 case 'l': //SVGA3dTextureFilter 1397 { 1398 static const char * const s_apszValues[] = 1399 { 1400 "NONE", "NEAREST", "LINEAR", "ANISOTROPIC", "FLATCUBIC", "GAUSSIANCUBIC", "PYRAMIDALQUAD", "GAUSSIANQUAD", 1401 }; 1402 vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u, 1403 "SVGA3D_TEX_FILTER_", s_apszValues, RT_ELEMENTS(s_apszValues)); 1404 break; 1405 } 1406 1407 case 'g': //SVGA3dTextureCoordGen 1408 { 1409 static const char * const s_apszValues[] = 1410 { 1411 "OFF", "EYE_POSITION", "EYE_NORMAL", "REFLECTIONVECTOR", "SPHERE", 1412 }; 1413 vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u, 1414 "SVGA3D_TEXCOORD_GEN_", s_apszValues, RT_ELEMENTS(s_apszValues)); 1415 break; 1416 } 1417 1418 case 'm': //SVGA3dTextureCombiner 1419 { 1420 static const char * const s_apszValues[] = 1421 { 1422 "INVALID", "DISABLE", "SELECTARG1", "SELECTARG2", "MODULATE", "ADD", "ADDSIGNED", "SUBTRACT", 1423 "BLENDTEXTUREALPHA", "BLENDDIFFUSEALPHA", "BLENDCURRENTALPHA", "BLENDFACTORALPHA", "MODULATE2X", 1424 "MODULATE4X", "DSDT", "DOTPRODUCT3", "BLENDTEXTUREALPHAPM", "ADDSIGNED2X", "ADDSMOOTH", "PREMODULATE", 1425 "MODULATEALPHA_ADDCOLOR", "MODULATECOLOR_ADDALPHA", "MODULATEINVALPHA_ADDCOLOR", 1426 "MODULATEINVCOLOR_ADDALPHA", "BUMPENVMAPLUMINANCE", "MULTIPLYADD", "LERP", 1427 }; 1428 vmsvgaFormatEnumValue(pszBuffer, cbBuffer, pszName, uValue.u, 1429 "SVGA3D_TC_", s_apszValues, RT_ELEMENTS(s_apszValues)); 1430 break; 1431 } 1432 1433 default: 1434 AssertFailed(); 1435 RTStrPrintf(pszBuffer, cbBuffer, "%s = %#x\n", pszName, uValue.u); 1436 break; 1437 } 1438 } 1439 else 1440 RTStrPrintf(pszBuffer, cbBuffer, "UNKNOWN_%d_%#x = %#x\n", iName, iName, pTextureState->value); 1441 } 1442 else 1443 RTStrPrintf(pszBuffer, cbBuffer, "INVALID"); 1444 return pszRet; 1445 } 1446 1447 1448 1449 static const char * const g_apszTransformTypes[] = 1450 { 1451 "SVGA3D_TRANSFORM_INVALID", 1452 "SVGA3D_TRANSFORM_WORLD", 1453 "SVGA3D_TRANSFORM_VIEW", 1454 "SVGA3D_TRANSFORM_PROJECTION", 1455 "SVGA3D_TRANSFORM_TEXTURE0", 1456 "SVGA3D_TRANSFORM_TEXTURE1", 1457 "SVGA3D_TRANSFORM_TEXTURE2", 1458 "SVGA3D_TRANSFORM_TEXTURE3", 1459 "SVGA3D_TRANSFORM_TEXTURE4", 1460 "SVGA3D_TRANSFORM_TEXTURE5", 1461 "SVGA3D_TRANSFORM_TEXTURE6", 1462 "SVGA3D_TRANSFORM_TEXTURE7", 1463 "SVGA3D_TRANSFORM_WORLD1", 1464 "SVGA3D_TRANSFORM_WORLD2", 1465 "SVGA3D_TRANSFORM_WORLD3", 1466 }; 1467 1468 static const char * const g_apszFaces[] = 1469 { 1470 "SVGA3D_FACE_INVALID", 1471 "SVGA3D_FACE_NONE", 1472 "SVGA3D_FACE_FRONT", 1473 "SVGA3D_FACE_BACK", 1474 "SVGA3D_FACE_FRONT_BACK", 1475 }; 1476 1477 static const char * const g_apszLightTypes[] = 1478 { 1479 "SVGA3D_LIGHTTYPE_INVALID", 1480 "SVGA3D_LIGHTTYPE_POINT", 1481 "SVGA3D_LIGHTTYPE_SPOT1", 1482 "SVGA3D_LIGHTTYPE_SPOT2", 1483 "SVGA3D_LIGHTTYPE_DIRECTIONAL", 1484 }; 1485 1486 static const char * const g_apszRenderTargets[] = 1487 { 1488 "SVGA3D_RT_DEPTH", 1489 "SVGA3D_RT_STENCIL", 1490 "SVGA3D_RT_COLOR0", 1491 "SVGA3D_RT_COLOR1", 1492 "SVGA3D_RT_COLOR2", 1493 "SVGA3D_RT_COLOR3", 1494 "SVGA3D_RT_COLOR4", 1495 "SVGA3D_RT_COLOR5", 1496 "SVGA3D_RT_COLOR6", 1497 "SVGA3D_RT_COLOR7", 1498 }; 1499 1500 static void vmsvga3dInfoContextWorkerOne(PCDBGFINFOHLP pHlp, PVMSVGA3DCONTEXT pContext, bool fVerbose) 1501 { 1502 char szTmp[128]; 1503 1504 pHlp->pfnPrintf(pHlp, "*** VMSVGA 3d context %#x (%d) ***\n", pContext->id, pContext->id); 1505 #ifdef RT_OS_WINDOWS 1506 pHlp->pfnPrintf(pHlp, "hwnd: %p\n", pContext->hwnd); 1507 if (fVerbose) 1508 vmsvga3dInfoHostWindow(pHlp, (uintptr_t)pContext->hwnd); 1509 # ifdef VMSVGA3D_DIRECT3D 1510 pHlp->pfnPrintf(pHlp, "pDevice: %p\n", pContext->pDevice); 1511 # else 1512 pHlp->pfnPrintf(pHlp, "hdc: %p\n", pContext->hdc); 1513 pHlp->pfnPrintf(pHlp, "hglrc: %p\n", pContext->hglrc); 1514 # endif 1515 #else 1516 /** @todo Other hosts... */ 1517 #endif 1518 pHlp->pfnPrintf(pHlp, "sidRenderTarget: %#x\n", pContext->sidRenderTarget); 1519 1520 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->aSidActiveTexture); i++) 1521 if (pContext->aSidActiveTexture[i] != SVGA3D_INVALID_ID) 1522 pHlp->pfnPrintf(pHlp, "aSidActiveTexture[%u]: %#x\n", i, pContext->aSidActiveTexture[i]); 1523 1524 pHlp->pfnPrintf(pHlp, "fUpdateFlags: %#x\n", pContext->state.u32UpdateFlags); 1525 1526 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aRenderState); i++) 1527 if (pContext->state.aRenderState[i].state != SVGA3D_RS_INVALID) 1528 pHlp->pfnPrintf(pHlp, "aRenderState[%3d]: %s\n", i, 1529 vmsvga3dFormatRenderState(szTmp, sizeof(szTmp), &pContext->state.aRenderState[i])); 1530 1531 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aTextureState); i++) 1532 for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aTextureState[i]); j++) 1533 if (pContext->state.aTextureState[i][j].name != SVGA3D_TS_INVALID) 1534 pHlp->pfnPrintf(pHlp, "aTextureState[%3d][%3d]: %s\n", i, j, 1535 vmsvga3dFormatTextureState(szTmp, sizeof(szTmp), &pContext->state.aTextureState[i][j])); 1536 1537 AssertCompile(RT_ELEMENTS(g_apszTransformTypes) == SVGA3D_TRANSFORM_MAX); 1538 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aTransformState); i++) 1539 if (pContext->state.aTransformState[i].fValid) 1540 { 1541 pHlp->pfnPrintf(pHlp, "aTransformState[%s(%u)]:\n", g_apszTransformTypes[i], i); 1542 for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aTransformState[i].matrix); j++) 1543 pHlp->pfnPrintf(pHlp, 1544 (j % 4) == 0 ? " [ " FLOAT_FMT_STR : (j % 4) < 3 ? ", " FLOAT_FMT_STR : ", " FLOAT_FMT_STR "]\n", 1545 FLOAT_FMT_ARGS(pContext->state.aTransformState[i].matrix[j])); 1546 } 1547 1548 AssertCompile(RT_ELEMENTS(g_apszFaces) == SVGA3D_FACE_MAX); 1549 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aMaterial); i++) 1550 if (pContext->state.aMaterial[i].fValid) 1551 { 1552 pHlp->pfnPrintf(pHlp, "aTransformState[%s(%u)]: shininess=" FLOAT_FMT_STR "\n", 1553 g_apszFaces[i], i, FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.shininess)); 1554 pHlp->pfnPrintf(pHlp, " diffuse =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n", 1555 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[0]), 1556 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[1]), 1557 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[2]), 1558 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[3])); 1559 pHlp->pfnPrintf(pHlp, " ambient =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n", 1560 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[0]), 1561 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[1]), 1562 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[2]), 1563 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[3])); 1564 pHlp->pfnPrintf(pHlp, " specular=[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n", 1565 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[0]), 1566 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[1]), 1567 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[2]), 1568 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[3])); 1569 pHlp->pfnPrintf(pHlp, " emissive=[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n", 1570 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[0]), 1571 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[1]), 1572 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[2]), 1573 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[3])); 1574 } 1575 1576 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aClipPlane); i++) 1577 if (pContext->state.aClipPlane[i].fValid) 1578 pHlp->pfnPrintf(pHlp, "aClipPlane[%#04x]: [ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n", 1579 FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[0]), 1580 FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[1]), 1581 FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[2]), 1582 FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[3])); 1583 1584 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aLightData); i++) 1585 if (pContext->state.aLightData[i].fValidData) 1586 { 1587 pHlp->pfnPrintf(pHlp, "aLightData[%#04x]: enabled=%RTbool inWorldSpace=%RTbool type=%s(%u)\n", 1588 i, 1589 pContext->state.aLightData[i].fEnabled, 1590 pContext->state.aLightData[i].data.inWorldSpace, 1591 (uint32_t)pContext->state.aLightData[i].data.type < RT_ELEMENTS(g_apszLightTypes) 1592 ? g_apszLightTypes[pContext->state.aLightData[i].data.type] : "UNKNOWN", 1593 pContext->state.aLightData[i].data.type); 1594 pHlp->pfnPrintf(pHlp, " diffuse =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n", 1595 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[0]), 1596 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[1]), 1597 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[2]), 1598 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[3])); 1599 pHlp->pfnPrintf(pHlp, " specular =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n", 1600 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[0]), 1601 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[1]), 1602 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[2]), 1603 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[3])); 1604 pHlp->pfnPrintf(pHlp, " ambient =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n", 1605 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[0]), 1606 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[1]), 1607 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[2]), 1608 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[3])); 1609 pHlp->pfnPrintf(pHlp, " position =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n", 1610 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[0]), 1611 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[1]), 1612 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[2]), 1613 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[3])); 1614 pHlp->pfnPrintf(pHlp, " direction=[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n", 1615 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[0]), 1616 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[1]), 1617 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[2]), 1618 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[3])); 1619 pHlp->pfnPrintf(pHlp, " range=" FLOAT_FMT_STR " falloff=" FLOAT_FMT_STR "\n", 1620 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.range), 1621 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.falloff)); 1622 pHlp->pfnPrintf(pHlp, " attenuation0=" FLOAT_FMT_STR " attenuation1=" FLOAT_FMT_STR " attenuation2=" FLOAT_FMT_STR "\n", 1623 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.attenuation0), 1624 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.attenuation1), 1625 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.attenuation2)); 1626 pHlp->pfnPrintf(pHlp, " theta=" FLOAT_FMT_STR " phi=" FLOAT_FMT_STR "\n", 1627 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.theta), 1628 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.phi)); 1629 } 1630 1631 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aRenderTargets); i++) 1632 if (pContext->state.aRenderTargets[i] != SVGA3D_INVALID_ID) 1633 pHlp->pfnPrintf(pHlp, "aRenderTargets[%s/%u] = %#x (%d)\n", 1634 i < RT_ELEMENTS(g_apszRenderTargets) ? g_apszRenderTargets[i] : "UNKNOWN", i, 1635 pContext->state.aRenderTargets[i], pContext->state.aRenderTargets[i]); 1636 1637 pHlp->pfnPrintf(pHlp, "RectScissor: (x,y,cx,cy)=(%u,%u,%u,%u)\n", 1638 pContext->state.RectViewPort.x, pContext->state.RectViewPort.y, 1639 pContext->state.RectViewPort.w, pContext->state.RectViewPort.h); 1640 pHlp->pfnPrintf(pHlp, "zRange: (min,max)=(" FLOAT_FMT_STR ", " FLOAT_FMT_STR ")\n", 1641 FLOAT_FMT_ARGS(pContext->state.zRange.min), 1642 FLOAT_FMT_ARGS(pContext->state.zRange.max)); 1643 pHlp->pfnPrintf(pHlp, "fUpdateFlags: %#x\n", pContext->state.u32UpdateFlags); 1644 pHlp->pfnPrintf(pHlp, "shidPixel: %#x (%d)\n", pContext->state.shidPixel, pContext->state.shidPixel); 1645 pHlp->pfnPrintf(pHlp, "shidVertex: %#x (%d)\n", pContext->state.shidVertex, pContext->state.shidVertex); 1646 1647 for (uint32_t iWhich = 0; iWhich < 2; iWhich++) 1648 { 1649 uint32_t cConsts = iWhich == 0 ? pContext->state.cPixelShaderConst : pContext->state.cVertexShaderConst; 1650 PVMSVGASHADERCONST paConsts = iWhich == 0 ? pContext->state.paPixelShaderConst : pContext->state.paVertexShaderConst; 1651 const char *pszName = iWhich ? "paPixelShaderConst" : "paVertexShaderConst"; 1652 1653 for (uint32_t i = 0; i < cConsts; i++) 1654 if (paConsts[i].fValid) 1655 { 1656 if (paConsts[i].ctype == SVGA3D_CONST_TYPE_FLOAT) 1657 pHlp->pfnPrintf(pHlp, "%s[%#x(%u)] = [" FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR "] ctype=FLOAT\n", 1658 pszName, i, i, 1659 FLOAT_FMT_ARGS(paConsts[i].value[0]), FLOAT_FMT_ARGS(paConsts[i].value[1]), 1660 FLOAT_FMT_ARGS(paConsts[i].value[2]), FLOAT_FMT_ARGS(paConsts[i].value[3])); 1661 else 1662 pHlp->pfnPrintf(pHlp, "%s[%#x(%u)] = [%#x, %#x, %#x, %#x] ctype=%s\n", 1663 pszName, i, i, 1664 paConsts[i].value[0], paConsts[i].value[1], 1665 paConsts[i].value[2], paConsts[i].value[3], 1666 paConsts[i].ctype == SVGA3D_CONST_TYPE_INT ? "INT" 1667 : paConsts[i].ctype == SVGA3D_CONST_TYPE_BOOL ? "BOOL" : "UNKNOWN"); 1668 } 1669 } 1670 1671 for (uint32_t iWhich = 0; iWhich < 2; iWhich++) 1672 { 1673 uint32_t cShaders = iWhich == 0 ? pContext->cPixelShaders : pContext->cVertexShaders; 1674 PVMSVGA3DSHADER paShaders = iWhich == 0 ? pContext->paPixelShader : pContext->paVertexShader; 1675 const char *pszName = iWhich == 0 ? "paPixelShaders" : "paVertexShaders"; 1676 for (uint32_t i = 0; i < cShaders; i++) 1677 if (paShaders[i].id == i) 1678 { 1679 pHlp->pfnPrintf(pHlp, "%s[%u]: id=%#x cid=%#x type=%s(%d) cbData=%#x pvData=%p\n", 1680 pszName, i, 1681 paShaders[i].id, 1682 paShaders[i].cid, 1683 paShaders[i].type == SVGA3D_SHADERTYPE_VS ? "VS" 1684 : paShaders[i].type == SVGA3D_SHADERTYPE_PS ? "PS" : "UNKNOWN", 1685 paShaders[i].type, 1686 paShaders[i].cbData, 1687 paShaders[i].pShaderProgram); 1688 } 1689 } 1690 } 1691 1692 1693 void vmsvga3dInfoContextWorker(PVGASTATE pThis, PCDBGFINFOHLP pHlp, uint32_t cid, bool fVerbose) 1694 { 1695 /* Warning! This code is currently racing papContexts reallocation! */ 1696 /* Warning! This code is currently racing papContexts reallocation! */ 1697 /* Warning! This code is currently racing papContexts reallocation! */ 1698 VMSVGA3DSTATE volatile *pState = pThis->svga.p3dState; 1699 if (pState) 1700 { 1701 /* 1702 * Deal with a specific request first. 1703 */ 1704 if (cid != UINT32_MAX) 1705 { 1706 if (cid < pState->cContexts) 1707 { 1708 PVMSVGA3DCONTEXT pContext = pState->papContexts[cid]; 1709 if (pContext && pContext->id == cid) 1710 { 1711 vmsvga3dInfoContextWorkerOne(pHlp, pContext, fVerbose); 1712 return; 1713 } 1714 } 1715 #ifdef VMSVGA3D_OPENGL 1716 else if ( cid == VMSVGA3D_SHARED_CTX_ID 1717 && pState->SharedCtx.id == cid) 1718 { 1719 vmsvga3dInfoContextWorkerOne(pHlp, &((PVMSVGA3DSTATE)pState)->SharedCtx, fVerbose); 1720 return; 1721 } 1722 #endif 1723 pHlp->pfnPrintf(pHlp, "Context ID %#x not found.\n", cid); 1724 } 1725 else 1726 { 1727 #ifdef VMSVGA3D_OPENGL 1728 /* 1729 * Dump the shared context. 1730 */ 1731 if (pState->SharedCtx.id == VMSVGA3D_SHARED_CTX_ID) 1732 { 1733 pHlp->pfnPrintf(pHlp, "Shared context:\n"); 1734 vmsvga3dInfoContextWorkerOne(pHlp, &((PVMSVGA3DSTATE)pState)->SharedCtx, fVerbose); 1735 } 1736 #endif 1737 1738 /* 1739 * Dump the per-screen contexts. 1740 */ 1741 /** @todo multi screen */ 1742 1743 /* 1744 * Dump all. 1745 */ 1746 uint32_t cContexts = pState->cContexts; 1747 pHlp->pfnPrintf(pHlp, "cContexts=%d\n", cContexts); 1748 for (cid = 0; cid < cContexts; cid++) 1749 { 1750 PVMSVGA3DCONTEXT pContext = pState->papContexts[cid]; 1751 if (pContext && pContext->id == cid) 1752 { 1753 pHlp->pfnPrintf(pHlp, "\n"); 1754 vmsvga3dInfoContextWorkerOne(pHlp, pContext, fVerbose); 1755 } 1756 } 1757 } 1758 } 1759 } 1760 1761 1762 #ifdef VMSVGA3D_DIRECT3D 1751 1763 /** 1752 1764 * Release all shared surface objects. … … 1761 1773 return 0; 1762 1774 } 1763 1764 #elif defined(VMSVGA3D_OPENGL) 1765 /** @todo */ 1766 1767 #else 1768 # error "Build config error." 1769 #endif 1775 #endif /* VMSVGA3D_DIRECT3D */ 1770 1776 1771 1777 … … 1776 1782 1777 1783 pHlp->pfnPrintf(pHlp, "*** VMSVGA 3d surface %#x (%d)%s ***\n", pSurface->id, pSurface->id, pSurface->fDirty ? " - dirty" : ""); 1778 #if defined(VMSVGA3D_OPENGL) && defined(VMSVGA3D_OGL_WITH_SHARED_CTX)1784 #ifdef VMSVGA3D_OPENGL 1779 1785 pHlp->pfnPrintf(pHlp, "idWeakContextAssociation: %#x\n", pSurface->idWeakContextAssociation); 1780 1786 #else -
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-internal.h
r57151 r57152 90 90 * Defined Constants And Macros * 91 91 *********************************************************************************************************************************/ 92 /** Experimental: Create a dedicated context for handling surfaces in, thus 93 * avoiding orphaned surfaces after context destruction. 92 #ifdef VMSVGA3D_OPENGL 93 /** OpenGL: Create a dedicated context for handling surfaces in, thus 94 * avoiding orphaned surfaces after context destruction. 94 95 * 95 96 * This cures, for instance, an assertion on fedora 21 that happens in … … 102 103 * switches context when setting up the surface the first time. Not sure 103 104 * if we really need to, but as this is an experiment, I'm playing it safe. 104 * /105 #ifdef VMSVGA3D_OPENGL 105 * @remarks The define has been made default, thus should no longer be used. 106 */ 106 107 # define VMSVGA3D_OGL_WITH_SHARED_CTX 107 #endif108 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX109 108 /** Fake surface ID for the shared context. */ 110 109 # define VMSVGA3D_SHARED_CTX_ID UINT32_C(0xffffeeee) 111 #endif112 113 #ifdef VMSVGA3D_OPENGL114 110 115 111 /** @def VBOX_VMSVGA3D_GL_HACK_LEVEL … … 507 503 { 508 504 uint32_t id; 509 #ifdef VMSVGA3D_O GL_WITH_SHARED_CTX505 #ifdef VMSVGA3D_OPENGL 510 506 uint32_t idWeakContextAssociation; 511 507 #else … … 572 568 { 573 569 SSMFIELD_ENTRY( VMSVGA3DSURFACE, id), 574 # ifdef VMSVGA3D_OGL_WITH_SHARED_CTX570 # ifdef VMSVGA3D_OPENGL 575 571 SSMFIELD_ENTRY( VMSVGA3DSURFACE, idWeakContextAssociation), 576 572 # else … … 960 956 VBOXVMSVGASHADERIF ShaderIf; 961 957 962 # ifdef VMSVGA3D_O GL_WITH_SHARED_CTX958 # ifdef VMSVGA3D_OPENGL 963 959 /** The shared context. */ 964 960 VMSVGA3DCONTEXT SharedCtx; -
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-ogl.cpp
r57151 r57152 1818 1818 void vmsvga3dBackSurfaceDestroy(PVMSVGA3DSTATE pState, PVMSVGA3DSURFACE pSurface) 1819 1819 { 1820 #if defined(VMSVGA3D_OGL_WITH_SHARED_CTX)1821 1820 PVMSVGA3DCONTEXT pContext = &pState->SharedCtx; 1822 1821 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext); 1823 #else1824 /** @todo stricter checks for associated context */1825 PVMSVGA3DCONTEXT pContext;1826 uint32_t cid = pSurface->idAssociatedContext;1827 if ( cid <= pState->cContexts1828 && pState->papContexts[cid]->id == cid)1829 {1830 pContext = pState->papContexts[cid];1831 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);1832 }1833 /* If there is a GL buffer or something associated with the surface, we1834 really need something here, so pick any active context. */1835 else if (pSurface->oglId.buffer != OPENGL_INVALID_ID)1836 {1837 for (cid = 0; cid < pState->cContexts; cid++)1838 {1839 if (pState->papContexts[cid]->id == cid)1840 {1841 pContext = pState->papContexts[cid];1842 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);1843 break;1844 }1845 }1846 AssertReturn(pContext, VERR_INTERNAL_ERROR); /* otherwise crashes/fails; create temp context if this ever triggers! */1847 }1848 #endif1849 1822 1850 1823 switch (pSurface->flags & VMSVGA3D_SURFACE_HINT_SWITCH_MASK) … … 2050 2023 { 2051 2024 GLint activeTexture = 0; 2052 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX2053 2025 uint32_t idPrevCtx = pState->idActiveContext; 2054 2026 pContext = &pState->SharedCtx; 2055 2027 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext); 2056 #endif2057 2028 2058 2029 glGenTextures(1, &pSurface->oglId.texture); … … 2113 2084 2114 2085 pSurface->flags |= SVGA3D_SURFACE_HINT_TEXTURE; 2115 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX 2116 LogFlow(("vmsvga3dBackCreateTexture: sid=%x idAssociatedContext %#x -> %#x; oglId.texture=%#x\n", 2117 pSurface->id, pSurface->idAssociatedContext, idAssociatedContext, pSurface->oglId.texture)); 2118 pSurface->idAssociatedContext = idAssociatedContext; 2119 #endif 2120 2121 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX 2086 2122 2087 if (idPrevCtx < pState->cContexts && pState->papContexts[idPrevCtx]->id == idPrevCtx) 2123 2088 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pState->papContexts[idPrevCtx]); 2124 #endif2125 2089 return VINF_SUCCESS; 2126 2090 } … … 2480 2444 glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &cbStrictBufSize); 2481 2445 Assert(VMSVGA3D_GL_IS_SUCCESS(pContext)); 2482 # ifdef VMSVGA3D_OGL_WITH_SHARED_CTX2483 2446 AssertMsg(cbStrictBufSize >= (int32_t)pMipLevel->cbSurface, 2484 2447 ("cbStrictBufSize=%#x cbSurface=%#x pContext->id=%#x\n", (uint32_t)cbStrictBufSize, pMipLevel->cbSurface, pContext->id)); 2485 # else2486 AssertMsg(cbStrictBufSize >= (int32_t)pMipLevel->cbSurface,2487 ("cbStrictBufSize=%#x cbSurface=%#x isAssociatedContext=%#x pContext->id=%#x\n", (uint32_t)cbStrictBufSize, pMipLevel->cbSurface, pSurface->idAssociatedContext, pContext->id));2488 # endif2489 2448 #endif 2490 2449 … … 2628 2587 2629 2588 pSurface = pState->papSurfaces[sid]; 2630 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX2631 AssertReturn(pSurface->idAssociatedContext != SVGA3D_INVALID_ID, VERR_INTERNAL_ERROR);2632 #endif2633 2589 2634 2590 Assert(filter != SVGA3D_TEX_FILTER_FLATCUBIC); … … 2638 2594 Log(("vmsvga3dGenerateMipmaps: sid=%x filter=%d\n", sid, filter)); 2639 2595 2640 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX2641 2596 cid = SVGA3D_INVALID_ID; 2642 2597 pContext = &pState->SharedCtx; 2643 2598 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext); 2644 #else2645 /* @todo stricter checks for associated context */2646 cid = pSurface->idAssociatedContext;2647 2648 if ( cid >= pState->cContexts2649 || pState->papContexts[cid]->id != cid)2650 {2651 Log(("vmsvga3dGenerateMipmaps invalid context id!\n"));2652 return VERR_INVALID_PARAMETER;2653 }2654 pContext = pState->papContexts[cid];2655 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);2656 #endif2657 2599 2658 2600 if (pSurface->oglId.texture == OPENGL_INVALID_ID) … … 2700 2642 2701 2643 pSurface = pState->papSurfaces[sid]; 2702 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX 2703 AssertReturn(pSurface->idAssociatedContext != SVGA3D_INVALID_ID, VERR_INTERNAL_ERROR); 2704 #endif 2705 2706 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX 2644 2707 2645 /* @todo stricter checks for associated context */ 2708 2646 Log(("vmsvga3dCommandPresent: sid=%x cRects=%d\n", sid, cRects)); … … 2711 2649 2712 2650 pContext = &pState->SharedCtx; 2713 # ifdef VMSVGA3D_OGL_WITH_SHARED_CTX_EXPERIMENT_12714 if ( pSurface->idWeakContextAssociation < pState->cContexts2715 && pState->papContexts[pSurface->idWeakContextAssociation]->id == pSurface->idWeakContextAssociation)2716 pContext = pState->papContexts[pSurface->idWeakContextAssociation];2717 # endif2718 2651 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext); 2719 2652 cid = pContext->id; 2720 #else2721 /* @todo stricter checks for associated context */2722 cid = pSurface->idAssociatedContext;2723 Log(("vmsvga3dCommandPresent: sid=%x cRects=%d cid=%x\n", sid, cRects, cid));2724 for (uint32_t i=0; i < cRects; i++)2725 {2726 Log(("vmsvga3dCommandPresent: rectangle %d src=(%d,%d) (%d,%d)(%d,%d)\n", i, pRect[i].srcx, pRect[i].srcy, pRect[i].x, pRect[i].y, pRect[i].x + pRect[i].w, pRect[i].y + pRect[i].h));2727 }2728 2729 if ( cid >= pState->cContexts2730 || pState->papContexts[cid]->id != cid)2731 {2732 Log(("vmsvga3dCommandPresent invalid context id!\n"));2733 return VERR_INVALID_PARAMETER;2734 }2735 pContext = pState->papContexts[cid];2736 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);2737 #endif2738 2653 VMSVGA3D_CLEAR_GL_ERRORS(); 2739 2654 … … 3109 3024 3110 3025 AssertReturn(pState, VERR_NO_MEMORY); 3111 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX3112 3026 AssertReturn( cid < SVGA3D_MAX_CONTEXT_IDS 3113 3027 || (cid == VMSVGA3D_SHARED_CTX_ID && (fFlags & VMSVGA3D_DEF_CTX_F_SHARED_CTX)), VERR_INVALID_PARAMETER); 3114 #else3115 AssertReturn(cid < SVGA3D_MAX_CONTEXT_IDS, VERR_INVALID_PARAMETER);3116 #endif3117 3028 #if !defined(VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE) || !(defined(RT_OS_DARWIN)) 3118 3029 AssertReturn(!(fFlags & VMSVGA3D_DEF_CTX_F_OTHER_PROFILE), VERR_INTERNAL_ERROR_3); … … 3129 3040 #endif 3130 3041 3131 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX3132 3042 if (cid == VMSVGA3D_SHARED_CTX_ID) 3133 3043 pContext = &pState->SharedCtx; 3134 3044 else 3135 #endif3136 3045 { 3137 3046 if (cid >= pState->cContexts) … … 3158 3067 3159 3068 /* 3160 * Find the shared context(necessary for sharing e.g. textures between contexts).3069 * Find or create the shared context if needed (necessary for sharing e.g. textures between contexts). 3161 3070 */ 3162 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX3163 3071 PVMSVGA3DCONTEXT pSharedCtx = NULL; 3164 3072 if (!(fFlags & (VMSVGA3D_DEF_CTX_F_INIT | VMSVGA3D_DEF_CTX_F_SHARED_CTX))) … … 3171 3079 } 3172 3080 } 3173 #else3174 // TODO isn't this default on Linux since OpenGL 1.1?3175 /* Find the first active context to share the display list with (necessary for sharing e.g. textures between contexts). */3176 PVMSVGA3DCONTEXT pSharedCtx = NULL;3177 for (uint32_t i = 0; i < pState->cContexts; i++)3178 if ( pState->papContexts[i]->id != SVGA3D_INVALID_ID3179 && i != cid3180 # ifdef VBOX_VMSVGA3D_DUAL_OPENGL_PROFILE3181 && pState->papContexts[i]->fOtherProfile == RT_BOOL(fFlags & VMSVGA3D_DEF_CTX_F_OTHER_PROFILE)3182 # endif3183 )3184 {3185 Log(("Sharing display lists between cid=%d and cid=%d\n", pContext->id, i));3186 pSharedCtx = pState->papContexts[i];3187 break;3188 }3189 #endif3190 3081 3191 3082 /* … … 3289 3180 NativeNSViewRef pHostView = (NativeNSViewRef)pThis->svga.u64HostWindowId; 3290 3181 vmsvga3dCocoaCreateViewAndContext(&pContext->cocoaView, &pContext->cocoaContext, 3291 # if defined(VMSVGA3D_OGL_WITH_SHARED_CTX) && !defined(VMSVGA3D_OGL_WITH_SHARED_CTX_EXPERIMENT_1) /* Only attach one subview, the one we'll present in. */ 3292 pSharedCtx ? NULL : pHostView, /** @todo screen objects and stuff. */ 3293 # else 3294 pHostView, 3295 # endif 3182 pSharedCtx ? NULL : pHostView, /* Only attach one subview, the one we'll present in. */ /** @todo screen objects and stuff. */ 3296 3183 pThis->svga.uWidth, pThis->svga.uHeight, 3297 3184 pShareContext, pContext->fOtherProfile); … … 3447 3334 } 3448 3335 3449 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX /* This is done on windows - prevents various assertions at runtime, as well as shutdown & reset assertions when destroying surfaces. */3450 /* Check for all surfaces that are associated with this context to remove all dependencies */3451 for (uint32_t sid = 0; sid < pState->cSurfaces; sid++)3452 {3453 PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];3454 if ( pSurface->idAssociatedContext == cid3455 && pSurface->id == sid)3456 {3457 int rc;3458 3459 Log(("vmsvga3dContextDestroy: remove all dependencies for surface %x\n", sid));3460 3461 uint32_t surfaceFlags = pSurface->flags;3462 SVGA3dSurfaceFormat format = pSurface->format;3463 SVGA3dSurfaceFace face[SVGA3D_MAX_SURFACE_FACES];3464 uint32_t multisampleCount = pSurface->multiSampleCount;3465 SVGA3dTextureFilter autogenFilter = pSurface->autogenFilter;3466 SVGA3dSize *pMipLevelSize;3467 uint32_t cFaces = pSurface->cFaces;3468 3469 pMipLevelSize = (SVGA3dSize *)RTMemAllocZ(pSurface->faces[0].numMipLevels * pSurface->cFaces * sizeof(SVGA3dSize));3470 AssertReturn(pMipLevelSize, VERR_NO_MEMORY);3471 3472 for (uint32_t iFace = 0; iFace < pSurface->cFaces; iFace++)3473 {3474 for (uint32_t i = 0; i < pSurface->faces[0].numMipLevels; i++)3475 {3476 uint32_t idx = i + iFace * pSurface->faces[0].numMipLevels;3477 memcpy(&pMipLevelSize[idx], &pSurface->pMipmapLevels[idx].size, sizeof(SVGA3dSize));3478 }3479 }3480 memcpy(face, pSurface->faces, sizeof(pSurface->faces));3481 3482 /* Recreate the surface with the original settings; destroys the contents, but that seems fairly safe since the context is also destroyed. */3483 rc = vmsvga3dSurfaceDestroy(pThis, sid);3484 AssertRC(rc);3485 3486 rc = vmsvga3dSurfaceDefine(pThis, sid, surfaceFlags, format, face, multisampleCount, autogenFilter, face[0].numMipLevels * cFaces, pMipLevelSize);3487 AssertRC(rc);3488 }3489 }3490 #endif3491 3492 3336 if (pContext->idFramebuffer != OPENGL_INVALID_ID) 3493 3337 { … … 3590 3434 AssertReturn(pState, VERR_NO_MEMORY); 3591 3435 3592 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX3593 3436 /* Resize the shared context too. */ 3594 3437 if (pState->SharedCtx.id == VMSVGA3D_SHARED_CTX_ID) 3595 3438 vmsvga3dChangeModeOneContext(pThis, pState, &pState->SharedCtx); 3596 #endif3597 3439 3598 3440 /* Resize all active contexts. */ … … 4754 4596 { 4755 4597 Log(("vmsvga3dSetRenderTarget: create renderbuffer to be used as render target; surface id=%x type=%d format=%d\n", target.sid, pRenderTarget->flags, pRenderTarget->internalFormatGL)); 4756 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX4757 4598 pContext = &pState->SharedCtx; 4758 4599 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext); 4759 #endif 4600 4760 4601 pState->ext.glGenRenderbuffers(1, &pRenderTarget->oglId.renderbuffer); 4761 4602 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext); … … 4770 4611 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext); 4771 4612 4772 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX4773 4613 pState->ext.glBindRenderbuffer(GL_RENDERBUFFER, OPENGL_INVALID_ID); 4774 4614 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext); … … 4776 4616 pContext = pState->papContexts[cid]; 4777 4617 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext); 4778 # ifdef VMSVGA3D_OGL_WITH_SHARED_CTX_EXPERIMENT_14779 4618 pRenderTarget->idWeakContextAssociation = cid; 4780 # endif 4781 #else 4782 LogFlow(("vmsvga3dSetRenderTarget: sid=%x idAssociatedContext %#x -> %#x\n", pRenderTarget->id, pRenderTarget->idAssociatedContext, cid)); 4783 pRenderTarget->idAssociatedContext = cid; 4784 #endif 4785 } 4786 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX 4787 else 4788 #endif 4789 { 4790 pState->ext.glBindRenderbuffer(GL_RENDERBUFFER, pRenderTarget->oglId.renderbuffer); 4791 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext); 4792 } 4793 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX 4794 Assert(pRenderTarget->idAssociatedContext == cid); 4795 #endif 4619 } 4620 4621 pState->ext.glBindRenderbuffer(GL_RENDERBUFFER, pRenderTarget->oglId.renderbuffer); 4622 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext); 4796 4623 Assert(!pRenderTarget->fDirty); 4797 4624 AssertReturn(pRenderTarget->oglId.texture != OPENGL_INVALID_ID, VERR_INVALID_PARAMETER); … … 5131 4958 if (pSurface->oglId.texture == OPENGL_INVALID_ID) 5132 4959 { 5133 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX5134 Assert(pSurface->idAssociatedContext == SVGA3D_INVALID_ID);5135 #endif5136 4960 Log(("CreateTexture (%d,%d) level=%d\n", pSurface->pMipmapLevels[0].size.width, pSurface->pMipmapLevels[0].size.height, pSurface->faces[0].numMipLevels)); 5137 4961 int rc = vmsvga3dBackCreateTexture(pState, pContext, cid, pSurface); … … 5883 5707 { 5884 5708 Log(("vmsvga3dDrawPrimitives: create vertex buffer fDirty=%d size=%x bytes\n", pVertexSurface->fDirty, pVertexSurface->pMipmapLevels[0].cbSurface)); 5885 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX5886 5709 PVMSVGA3DCONTEXT pSavedCtx = pContext; 5887 5710 pContext = &pState->SharedCtx; 5888 5711 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext); 5889 #endif5890 5712 5891 5713 pState->ext.glGenBuffers(1, &pVertexSurface->oglId.buffer); … … 5905 5727 pVertexSurface->flags |= SVGA3D_SURFACE_HINT_VERTEXBUFFER; 5906 5728 5907 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX5908 5729 pState->ext.glBindBuffer(GL_ARRAY_BUFFER, OPENGL_INVALID_ID); 5909 5730 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext); … … 5911 5732 pContext = pSavedCtx; 5912 5733 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext); 5913 #endif 5914 } 5915 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX 5916 else 5917 #endif 5918 { 5919 Assert(pVertexSurface->fDirty == false); 5920 pState->ext.glBindBuffer(GL_ARRAY_BUFFER, pVertexSurface->oglId.buffer); 5921 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext); 5922 } 5923 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX 5924 pVertexSurface->idAssociatedContext = pContext->id; 5925 LogFlow(("vmsvga3dDrawPrimitivesProcessVertexDecls: sid=%x idAssociatedContext %#x -> %#x\n", pVertexSurface->id, pVertexSurface->idAssociatedContext, pContext->id)); 5926 #endif 5734 } 5735 5736 Assert(pVertexSurface->fDirty == false); 5737 pState->ext.glBindBuffer(GL_ARRAY_BUFFER, pVertexSurface->oglId.buffer); 5738 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext); 5927 5739 5928 5740 /* Setup the vertex declarations. */ … … 6201 6013 { 6202 6014 Log(("vmsvga3dDrawPrimitives: create index buffer fDirty=%d size=%x bytes\n", pIndexSurface->fDirty, pIndexSurface->pMipmapLevels[0].cbSurface)); 6203 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX6204 6015 pContext = &pState->SharedCtx; 6205 6016 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext); 6206 #endif6207 6017 6208 6018 pState->ext.glGenBuffers(1, &pIndexSurface->oglId.buffer); … … 6223 6033 pIndexSurface->flags |= SVGA3D_SURFACE_HINT_INDEXBUFFER; 6224 6034 6225 #ifdef VMSVGA3D_OGL_WITH_SHARED_CTX6226 6035 pState->ext.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, OPENGL_INVALID_ID); 6227 6036 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext); … … 6229 6038 pContext = pState->papContexts[cid]; 6230 6039 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext); 6231 #endif6232 6040 } 6233 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX 6234 else 6235 #endif 6236 { 6237 Assert(pIndexSurface->fDirty == false); 6238 6239 pState->ext.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pIndexSurface->oglId.buffer); 6240 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext); 6241 } 6242 #ifndef VMSVGA3D_OGL_WITH_SHARED_CTX 6243 LogFlow(("vmsvga3dDrawPrimitives: sid=%x idAssociatedContext %#x -> %#x\n", pIndexSurface->id, pIndexSurface->idAssociatedContext, pContext->id)); 6244 pIndexSurface->idAssociatedContext = pContext->id; 6245 #endif 6041 Assert(pIndexSurface->fDirty == false); 6042 6043 pState->ext.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pIndexSurface->oglId.buffer); 6044 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext); 6246 6045 } 6247 6046 -
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-savedstate.cpp
r57151 r57152 184 184 LogFlow(("vmsvga3dLoadExec: Loading cid=%#x\n", cid)); 185 185 186 #ifdef VMSVGA3D_O GL_WITH_SHARED_CTX186 #ifdef VMSVGA3D_OPENGL 187 187 if (cid == VMSVGA3D_SHARED_CTX_ID) 188 188 { … … 311 311 } 312 312 313 #ifdef VMSVGA3D_O GL_WITH_SHARED_CTX313 #ifdef VMSVGA3D_OPENGL 314 314 /* Make the shared context the current one. */ 315 315 if (pState->SharedCtx.id == VMSVGA3D_SHARED_CTX_ID) … … 399 399 } 400 400 401 #ifdef VMSVGA3D_O GL_WITH_SHARED_CTX401 #ifdef VMSVGA3D_OPENGL 402 402 /* Reinitialize the shared context. */ 403 403 LogFlow(("vmsvga3dLoadExec: pState->SharedCtx.id=%#x\n", pState->SharedCtx.id)); … … 514 514 AssertRCReturn(rc, rc); 515 515 516 #ifdef VMSVGA3D_O GL_WITH_SHARED_CTX516 #ifdef VMSVGA3D_OPENGL 517 517 /* Save the shared context. */ 518 518 if (pState->SharedCtx.id == VMSVGA3D_SHARED_CTX_ID) … … 745 745 void *pData = NULL; 746 746 747 # ifdef VMSVGA3D_OGL_WITH_SHARED_CTX748 747 PVMSVGA3DCONTEXT pContext = &pState->SharedCtx; 749 748 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext); 750 # else751 /* @todo stricter checks for associated context */752 uint32_t cid = pSurface->idAssociatedContext;753 if ( cid >= pState->cContexts754 || pState->papContexts[cid]->id != cid)755 {756 Log(("vmsvga3dSaveExec: invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id));757 AssertFailedReturn(VERR_INVALID_PARAMETER);758 }759 PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];760 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);761 # endif762 749 763 750 Assert(pMipmapLevel->cbSurface); -
trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d.cpp
r57151 r57152 97 97 RT_ZERO(*pSurface); 98 98 pSurface->id = sid; 99 #ifdef VMSVGA3D_O GL_WITH_SHARED_CTX99 #ifdef VMSVGA3D_OPENGL 100 100 pSurface->idWeakContextAssociation = SVGA3D_INVALID_ID; 101 101 #else … … 368 368 369 369 PVMSVGA3DCONTEXT pContext; 370 #ifdef VMSVGA3D_O GL_WITH_SHARED_CTX370 #ifdef VMSVGA3D_OPENGL 371 371 Log(("vmsvga3dSurfaceStretchBlt: src sid=%x (%d,%d)(%d,%d) dest sid=%x (%d,%d)(%d,%d) mode=%x\n", 372 372 sidSrc, pSrcBox->x, pSrcBox->y, pSrcBox->x + pSrcBox->w, pSrcBox->y + pSrcBox->h, … … 391 391 } 392 392 pContext = pState->papContexts[cid]; 393 # ifdef VMSVGA3D_OPENGL394 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);395 # endif396 393 #endif 397 394 … … 534 531 535 532 #else /* VMSVGA3D_OPENGL */ 536 # ifdef VMSVGA3D_OGL_WITH_SHARED_CTX537 533 PVMSVGA3DCONTEXT pContext = &pState->SharedCtx; 538 # else539 /** @todo stricter checks for associated context */540 uint32_t cid = pSurface->idAssociatedContext;541 if ( cid >= pState->cContexts542 || pState->papContexts[cid]->id != cid)543 {544 Log(("vmsvga3dSurfaceDMA invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id));545 AssertFailedReturn(VERR_INVALID_PARAMETER);546 }547 PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];548 # endif549 534 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext); 550 535 #endif
Note:
See TracChangeset
for help on using the changeset viewer.