DevVGA-SVGA3d-shared.h revision 0ffa3979e9b800f5931dd30c51ec3c0aadc3a1f1
/** @file
* VMware SVGA device -- 3D part
*/
/*
* Copyright (C) 2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#ifndef __DEVVMWARE3D_STATE_H__
#define __DEVVMWARE3D_STATE_H__
{
int rc;
/* Must initialize now as the recreation calls below rely on an initialized 3d subsystem. */
/* Get the generic 3d state first. */
/* Fetch all active contexts. */
{
/* Get the context id */
if (cid != SVGA3D_INVALID_ID)
{
pContext->cPixelShaders = 0;
pContext->cVertexShaders = 0;
/* Fetch all pixel shaders. */
for (uint32_t j = 0; j < cPixelShaders; j++)
{
/* Fetch the id first. */
if (shid != SVGA3D_INVALID_ID)
{
/* Fetch a copy of the shader struct. */
}
}
/* Fetch all vertex shaders. */
for (uint32_t j = 0; j < cVertexShaders; j++)
{
/* Fetch the id first. */
if (shid != SVGA3D_INVALID_ID)
{
/* Fetch a copy of the shader struct. */
}
}
/* Fetch pixel shader constants. */
for (uint32_t j = 0; j < cPixelShaderConst; j++)
{
rc = SSMR3GetStructEx(pSSM, &ShaderConst, sizeof(ShaderConst), 0, g_aVMSVGASHADERCONSTFields, NULL);
if (ShaderConst.fValid)
{
rc = vmsvga3dShaderSetConst(pThis, cid, j, SVGA3D_SHADERTYPE_PS, ShaderConst.ctype, 1, ShaderConst.value);
}
}
/* Fetch vertex shader constants. */
for (uint32_t j = 0; j < cVertexShaderConst; j++)
{
rc = SSMR3GetStructEx(pSSM, &ShaderConst, sizeof(ShaderConst), 0, g_aVMSVGASHADERCONSTFields, NULL);
if (ShaderConst.fValid)
{
rc = vmsvga3dShaderSetConst(pThis, cid, j, SVGA3D_SHADERTYPE_VS, ShaderConst.ctype, 1, ShaderConst.value);
}
}
}
}
/* Fetch all surfaces. */
{
/* Fetch the id first. */
if (sid != SVGA3D_INVALID_ID)
{
/* Fetch the surface structure first. */
{
PVMSVGA3DMIPMAPLEVEL pMipmapLevel = (PVMSVGA3DMIPMAPLEVEL)RTMemAlloc(cMipLevels * sizeof(VMSVGA3DMIPMAPLEVEL));
/* Load the mip map level info. */
{
{
/* Load the mip map level struct. */
rc = SSMR3GetStructEx(pSSM, &pMipmapLevel[idx], sizeof(pMipmapLevel[idx]), 0, g_aVMSVGA3DMIPMAPLEVELFields, NULL);
}
}
rc = vmsvga3dSurfaceDefine(pThis, sid, surface.flags, surface.format, surface.faces, surface.multiSampleCount, surface.autogenFilter, cMipLevels, pMipmapLevelSize);
}
/* Load the mip map level data. */
{
bool fDataPresent = false;
/* Fetch the data present boolean first. */
Log(("Surface sid=%x: load mipmap level %d with %x bytes data (present=%d).\n", sid, j, pMipmapLevel->cbSurface, fDataPresent));
if (fDataPresent)
{
pMipmapLevel->fDirty = true;
}
else
{
pMipmapLevel->fDirty = false;
}
}
}
}
/* Reinitialize all active contexts. */
{
if (cid != SVGA3D_INVALID_ID)
{
/* First set the render targets as they change the internal state (reset viewport etc) */
Log(("vmsvga3dLoadExec: Recreate render targets BEGIN\n"));
{
{
}
}
Log(("vmsvga3dLoadExec: Recreate render targets END\n"));
/* Recreate the render state */
Log(("vmsvga3dLoadExec: Recreate render state BEGIN\n"));
{
}
Log(("vmsvga3dLoadExec: Recreate render state END\n"));
/* Recreate the texture state */
Log(("vmsvga3dLoadExec: Recreate texture state BEGIN\n"));
{
for (uint32_t j = 0; j < SVGA3D_TS_MAX; j++)
{
}
}
Log(("vmsvga3dLoadExec: Recreate texture state END\n"));
/* Reprogram the clip planes. */
{
}
/* Reprogram the light data. */
{
}
/* Recreate the transform state. */
{
{
vmsvga3dSetTransform(pThis, cid, (SVGA3dTransformType)j, pContext->state.aTransformState[j].matrix);
}
}
/* Reprogram the material data. */
{
{
}
}
}
}
return VINF_SUCCESS;
}
{
int rc;
/* Save a copy of the generic 3d state first. */
/* Save all active contexts. */
{
/* Save the id first. */
if (cid != SVGA3D_INVALID_ID)
{
/* Save a copy of the context structure first. */
/* Save all pixel shaders. */
{
/* Save the id first. */
{
/* Save a copy of the shader struct. */
}
}
/* Save all vertex shaders. */
{
/* Save the id first. */
{
/* Save a copy of the shader struct. */
/* Fetch the shader code and save it. */
}
}
/* Save pixel shader constants. */
{
rc = SSMR3PutStructEx(pSSM, &pContext->state.paPixelShaderConst[j], sizeof(pContext->state.paPixelShaderConst[j]), 0, g_aVMSVGASHADERCONSTFields, NULL);
}
/* Save vertex shader constants. */
{
rc = SSMR3PutStructEx(pSSM, &pContext->state.paVertexShaderConst[j], sizeof(pContext->state.paVertexShaderConst[j]), 0, g_aVMSVGASHADERCONSTFields, NULL);
}
}
}
/* Save all active surfaces. */
{
/* Save the id first. */
{
/* Save a copy of the surface structure first. */
/* Save the mip map level info. */
{
{
/* Save a copy of the mip map level struct. */
rc = SSMR3PutStructEx(pSSM, pMipmapLevel, sizeof(*pMipmapLevel), 0, g_aVMSVGA3DMIPMAPLEVELFields, NULL);
}
}
/* Save the mip map level data. */
{
{
Log(("Surface sid=%d: save mipmap level %d with %x bytes data.\n", sid, i, pMipmapLevel->cbSurface));
#ifdef VMSVGA3D_DIRECT3D
#else
#endif
{
if (pMipmapLevel->fDirty)
{
/* Data follows */
}
else
{
/* No data follows */
}
}
else
{
#ifdef VMSVGA3D_DIRECT3D
void *pData;
bool fRenderTargetTexture = false;
bool fTexture = false;
bool fVertex = false;
bool fSkipSave = false;
switch (pSurface->flags & (SVGA3D_SURFACE_HINT_INDEXBUFFER | SVGA3D_SURFACE_HINT_VERTEXBUFFER | SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET | SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_CUBEMAP))
{
/* @todo unable to easily fetch depth surface data in d3d 9 */
fSkipSave = true;
break;
fRenderTargetTexture = true;
/* no break */
fTexture = true;
/* no break */
{
if (fTexture)
{
{
&& i == 0 /* only the first time */)
{
/* @todo stricter checks for associated context */
{
Log(("vmsvga3dSaveExec invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id));
}
AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: GetSurfaceLevel failed with %x\n", hr), VERR_INTERNAL_ERROR);
AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: GetSurfaceLevel failed with %x\n", hr), VERR_INTERNAL_ERROR);
AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: GetRenderTargetData failed with %x\n", hr), VERR_INTERNAL_ERROR);
}
NULL,
}
else
NULL,
}
else
NULL,
AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: LockRect failed with %x\n", hr), VERR_INTERNAL_ERROR);
/* Copy the data one line at a time in case the internal pitch is different. */
{
memcpy((uint8_t *)pData + j * pMipmapLevel->cbSurfacePitch, (uint8_t *)LockedRect.pBits + j * LockedRect.Pitch, pMipmapLevel->cbSurfacePitch);
}
if (fTexture)
{
{
AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: UnlockRect failed with %x\n", hr), VERR_INTERNAL_ERROR);
}
else
}
else
AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: UnlockRect failed with %x\n", hr), VERR_INTERNAL_ERROR);
break;
}
fVertex = true;
/* no break */
{
if (fVertex)
else
AssertMsg(hr == D3D_OK, ("vmsvga3dSaveExec: Lock %s failed with %x\n", (fVertex) ? "vertex" : "index", hr));
if (fVertex)
else
AssertMsg(hr == D3D_OK, ("vmsvga3dSaveExec: Unlock %s failed with %x\n", (fVertex) ? "vertex" : "index", hr));
break;
}
default:
AssertFailed();
break;
}
if (!fSkipSave)
{
/* Data follows */
/* And write the surface data. */
}
else
{
/* No data follows */
}
#elif defined(VMSVGA3D_OPENGL)
# ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
# else
/* @todo stricter checks for associated context */
{
Log(("vmsvga3dSaveExec: invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id));
}
# endif
switch (pSurface->flags & (SVGA3D_SURFACE_HINT_INDEXBUFFER | SVGA3D_SURFACE_HINT_VERTEXBUFFER | SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET | SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_CUBEMAP))
{
default:
AssertFailed();
/* no break */
/* @todo fetch data from the renderbuffer */
/* No data follows */
break;
{
/* Set row length and alignment of the output data. */
i,
pData);
/* Data follows */
/* And write the surface data. */
/* Restore the old active texture. */
break;
}
{
/* Data follows */
/* And write the surface data. */
}
}
if (pData)
#else
#error "Unexpected 3d backend"
#endif
}
}
}
}
}
return VINF_SUCCESS;
}
static uint32_t vmsvga3dSaveShaderConst(PVMSVGA3DCONTEXT pContext, uint32_t reg, SVGA3dShaderType type, SVGA3dShaderConstType ctype, uint32_t val1, uint32_t val2, uint32_t val3, uint32_t val4)
{
/* Choose a sane upper limit. */
if (type == SVGA3D_SHADERTYPE_VS)
{
{
pContext->state.paVertexShaderConst = (PVMSVGASHADERCONST)RTMemRealloc(pContext->state.paVertexShaderConst, sizeof(VMSVGASHADERCONST) * (reg + 1));
}
}
else
{
{
pContext->state.paPixelShaderConst = (PVMSVGASHADERCONST)RTMemRealloc(pContext->state.paPixelShaderConst, sizeof(VMSVGASHADERCONST) * (reg + 1));
}
}
return VINF_SUCCESS;
}
#endif /* __DEVVMWARE3D_STATE_H__ */