📄 halsurf.c
字号:
{
/* Read in the registry settings - FIXME */
GetPVRHALRegSettings(gpsDriverData->dwDevCookie, &gpsDriverData->sRegData, gpsDriverData->sDisplayDevData.psDevInfoKM);
DPFLX(DBG_SURFACE, "Using primary surface data (0x%lx)", psSurfData);
psSurfLcl->lpGbl->fpVidMem = GET_VMIDATA_ELEMENT(gpsDriverData, psData->lpDD, fpPrimary);
psSurfData->psMemInfo = gpsDriverData->psPrimSurfData->psMemInfo;
psSurfData->pvLinAddress = (PVOID) GET_VMIDATA_ELEMENT(gpsDriverData, psData->lpDD, fpPrimary);
}
/* Store it in the DDraw struct for us to access later */
psSurfLcl->lpGbl->dwReserved1 = (DWORD) psSurfData;
/* Copy pixel format over to internal data structure. */
psSurfData->sPixelFormat = sPixelFormat;
psSurfData->dwMBXFormat = dwMBXFormat;
psSurfData->dwFlags = 0;
psSurfData->pvGPESurf = NULL;
}
/* Handle Overlay surfaces */
if(dwSurfaceCaps & DDSCAPS_OVERLAY)
{
/* check if overlay already in use */
#ifdef SUPPORT_OVERLAY
if(gpsDriverData->bOverlayInUse)
#endif
{
/* Only one hardware overlay and it's already in use */
psData->ddRVal = DDERR_NOOVERLAYHW;
dwResult = DDHAL_DRIVER_HANDLED;
goto HALCreateSurfaceExit;
}
/* Surface is to be used for Overlay, make sure it ends up in video memory. */
if(dwSurfaceCaps & DDSCAPS_SYSTEMMEMORY)
{
DPF("Failing Overlay creation due to System Memory cap");
psData->ddRVal = DDERR_INVALIDSURFACETYPE;
dwResult = DDHAL_DRIVER_HANDLED;
goto HALCreateSurfaceExit;
}
/* check pixel format is valid for overlay */
if((psData->lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) &&
(ConvertPixelFormatToOverlay(&sPixelFormat, (DWORD*) &gpsDriverData->sOverlayAttributes.PixFormat)))
{
/* a valid overlay pixel format */
}
else
{
/* an invalid pixel format for overlay use */
psData->ddRVal = DDERR_UNSUPPORTEDFORMAT;
dwResult = DDHAL_DRIVER_HANDLED;
goto HALCreateSurfaceExit;
}
/* impose size constraints for the surface */
if(psData->lpDDSurfaceDesc->dwHeight > 2048)
{
psData->ddRVal = DDERR_TOOBIGHEIGHT;
dwResult = DDHAL_DRIVER_HANDLED;
goto HALCreateSurfaceExit;
}
if(psData->lpDDSurfaceDesc->dwWidth > 2048)
{
psData->ddRVal = DDERR_TOOBIGWIDTH;
dwResult = DDHAL_DRIVER_HANDLED;
goto HALCreateSurfaceExit;
}
gpsDriverData->sOverlayAttributes.wValidFlags = PDP_OVERLAYATTRIB_VALID_VERIFY |
PDP_OVERLAYATTRIB_VALID_PIXFMT;
if(PDP_SetOverlayAttributes(g_PDPHandle, &gpsDriverData->sOverlayAttributes) != PDP_ERROR_OK)
{
DPF("Failing Overlay creation due PDPAL");
psData->ddRVal = DDERR_NOOVERLAYHW;
dwResult = DDHAL_DRIVER_HANDLED;
goto HALCreateSurfaceExit;
}
/* set the inital status of the Overlay */
gpsDriverData->sOverlayAttributes.bOverlayOn = FALSE;
gpsDriverData->sOverlayAttributes.bCKeyOn = FALSE;
gpsDriverData->sOvlFlipTable.dwActiveSurfaces = 0;
/* Mark Overlay busy but remember to clear it if we fail later */
gpsDriverData->bOverlayInUse = TRUE;
}
/*
If alloc of internal data structures failed, kill any laying around off
and return an error.
*/
if(lRet != DD_OK)
{
for(i = 0; i < psData->dwSCnt; i++)
{
psSurfLcl = psData->lplpSList[i];
if(psSurfLcl->lpGbl->dwReserved1)
{
FreeSharedMem((PVOID) psSurfLcl->lpGbl->dwReserved1);
psSurfLcl->lpGbl->dwReserved1 = 0;
}
}
psData->ddRVal = lRet;
dwResult = DDHAL_DRIVER_HANDLED;
goto HALCreateSurfaceExit;
}
/* Create and setup the surfaces */
lRet = CreateSurfaces(dwBPP, &sPixelFormat, psData);
/* Surface set-up failure */
if(lRet != DD_OK)
{
for (i = 0; i < psData->dwSCnt; i++)
{
psSurfLcl = psData->lplpSList[i];
psSurfData = (PSURFDATA) psSurfLcl->lpGbl->dwReserved1;
/* Free any bits that managed to get them self's allocated */
if(psSurfData->psMemInfo)
{
PVRHALFreeDeviceMem(&gpsDriverData->sDisplayDevData,psSurfData->psMemInfo);
}
FreeSharedMem((PVOID) psSurfLcl->lpGbl->dwReserved1);
psSurfLcl->lpGbl->dwReserved1 = 0;
}
if(dwSurfaceCaps & DDSCAPS_OVERLAY)
{
/* Clean up the overlay stuff */
gpsDriverData->bOverlayInUse = FALSE;
}
psData->ddRVal = lRet;
goto HALCreateSurfaceExit;
}
/* Not interested in the primary surface */
if((!(psData->lplpSList[0]->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) &&
(psData->dwSCnt == 1))
{
if((psData->lplpSList[0]->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) &&
(psData->dwSCnt > 1))
{
/* If creating multiple surfaces, ignore the primary surface */
gpsDriverData->dwSurfaceCount+= psData->dwSCnt - 1;
}
else
{
/* Primary surface not included so use count */
gpsDriverData->dwSurfaceCount+= psData->dwSCnt;
}
}
/*
Create MBXSurf class for each surface
*/
for (i = 0; i < psData->dwSCnt; i++)
{
psSurfLcl = psData->lplpSList[i];
psSurfData = (PSURFDATA) psSurfLcl->lpGbl->dwReserved1;
ASSERT(psSurfData);
CreateMBXSurfClass(psSurfData);
}
/* will be DD_OK at this point */
psData->ddRVal = lRet;
HALCreateSurfaceExit:
return(dwResult);
}
/*****************************************************************************
<function>
FUNCTION : HALCanCreateSurface
PARAMETERS : LPDDHAL_CANCREATESURFACEDATA structure
RETURNS : DDHAL return code
<function/>
*****************************************************************************/
DWORD WINAPI HALCanCreateSurface( LPDDHAL_CANCREATESURFACEDATA psData )
{
PVRSRV_DEV_INFO *psDevInfo;
DWORD dwResult = DDHAL_DRIVER_HANDLED;
DPFLX(DBG_DD_ENTRY, "HALCanCreateSurface() called");
/* Extract our driver data from global object */
psDevInfo = gpsDriverData->sDisplayDevData.psDevInfoKM;
/* Driver name should be valid here so copy into driver data */
memcpy(&gpsDriverData->pszDriverName, &psData->lpDD->cDriverName, MAX_DRIVER_NAME);
/* ZBuffers, textures and system mem surface unsupported */
if(psData->lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_ZBUFFER ||
psData->lpDDSurfaceDesc->ddsCaps.dwCaps & (DDSCAPS_TEXTURE | DDSCAPS_MIPMAP)/* ||
psData->lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY*/)
{
psData->ddRVal = DDERR_UNSUPPORTEDFORMAT;
dwResult = DDHAL_DRIVER_HANDLED;
goto HALCanCreateSurfaceExit;
}
/* Handle Overlay surfaces */
if (psData->lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_OVERLAY)
{
/* check if overlay already in use */
#ifdef SUPPORT_OVERLAY
if(gpsDriverData->bOverlayInUse)
#endif
{
/* Only one hardware overlay and it's already in use */
psData->ddRVal = DDERR_NOOVERLAYHW;
dwResult = DDHAL_DRIVER_HANDLED;
goto HALCanCreateSurfaceExit;
}
/* Surface is to be used for Overlay, make sure it ends up in video memory. */
if (psData->lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)
{
DPF("Failing Overlay creation due to System Memory cap");
psData->ddRVal = DDERR_INVALIDSURFACETYPE;
dwResult = DDHAL_DRIVER_HANDLED;
goto HALCanCreateSurfaceExit;
}
/*
check pixel format is valid for overlay
(since the overlay isn't currently in use we can overwrite the pixel format)
*/
if((psData->lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) &&
(ConvertPixelFormatToOverlay(&psData->lpDDSurfaceDesc->ddpfPixelFormat,(DWORD*) &gpsDriverData->sOverlayAttributes.PixFormat)))
{
/* a valid overlay pixel format */
}
else
{
/* an invalid pixel format for overlay use */
psData->ddRVal = DDERR_UNSUPPORTEDFORMAT;
dwResult = DDHAL_DRIVER_HANDLED;
goto HALCanCreateSurfaceExit;
}
/* impose size constraints for the surface */
if(psData->lpDDSurfaceDesc->dwHeight > 2048)
{
psData->ddRVal = DDERR_TOOBIGHEIGHT;
dwResult = DDHAL_DRIVER_HANDLED;
goto HALCanCreateSurfaceExit;
}
if(psData->lpDDSurfaceDesc->dwWidth > 2048)
{
psData->ddRVal = DDERR_TOOBIGWIDTH;
dwResult = DDHAL_DRIVER_HANDLED;
goto HALCanCreateSurfaceExit;
}
gpsDriverData->sOverlayAttributes.wValidFlags = PDP_OVERLAYATTRIB_VALID_VERIFY |
PDP_OVERLAYATTRIB_VALID_PIXFMT;
if(PDP_SetOverlayAttributes(g_PDPHandle, &gpsDriverData->sOverlayAttributes) != PDP_ERROR_OK)
{
DPF("Failing Overlay creation due PDPAL");
psData->ddRVal = DDERR_NOOVERLAYHW;
dwResult = DDHAL_DRIVER_HANDLED;
goto HALCanCreateSurfaceExit;
}
}
else if(psData->lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT &&
psData->lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_FOURCC)
{
/* FOURCC validation of off screen surface creation request */
switch(psData->lpDDSurfaceDesc->ddpfPixelFormat.dwFourCC)
{
case HALFOURCC_UYVY:
case HALFOURCC_YUY2:
case HALFOURCC_YV12:
case HALFOURCC_VLVQ:
case HALFOURCC_IMC2:
{
break;
}
default:
{
#ifdef DEBUG
DWORD dwFourCC = psData->lpDDSurfaceDesc->ddpfPixelFormat.dwFourCC;
DPF("Warning, FOURCC pixel format requested not supported: %c%c%c%c", (dwFourCC & 0xff), ((dwFourCC >> 8) & 0xff), ((dwFourCC >> 16) & 0xff), ((dwFourCC >> 24) & 0xff));
#endif
psData->ddRVal = DDERR_INVALIDSURFACETYPE;
return(DDHAL_DRIVER_HANDLED);
}
}
}
/* Check primary surface create request */
if(psData->lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
{
/* Check that we can support the requested number of back buffers */
if((psData->lpDDSurfaceDesc->dwFlags & DDSD_BACKBUFFERCOUNT) &&
((psData->lpDDSurfaceDesc->dwBackBufferCount + 1) > MAX_FLIP_SURFACES))
{
DPFLX(DBG_SURFACE, "Too many primary back buffers requested (%ld)", psData->lpDDSurfaceDesc->dwBackBufferCount+1);
psData->ddRVal = DDERR_GENERIC;
dwResult = DDHAL_DRIVER_HANDLED;
goto HALCanCreateSurfaceExit;
}
}
psData->ddRVal = DD_OK;
HALCanCreateSurfaceExit:
return(dwResult);
}
/*****************************************************************************
<function>
FUNCTION : HALLock
PARAMETERS : LPDDHAL_LOCKDATA structure
RETURNS : DDHAL return code
<function/>
*****************************************************************************/
DWORD WINAPI HALLock( LPDDHAL_LOCKDATA psData )
{
PSURFDATA psSurfData;
DWORD dwResult = DDHAL_DRIVER_HANDLED;
PVRSRV_DEV_INFO *psDevInfo;
LPDDRAWI_DDRAWSURFACE_LCL psSurfLcl;
DPFLX(DBG_DD_ENTRY, "HALLock() called");
psSurfLcl = psData->lpDDSurface;
/* Extract our driver and surface data. */
psDevInfo = gpsDriverData->sDisplayDevData.psDevInfoKM;
psSurfData = (PSURFDATA) psSurfLcl->lpGbl->dwReserved1;
if(!psSurfData || !gpsDriverData)
{
DPFL4("Invalid internal data pointer in surface, not locking.");
psData->ddRVal = DDERR_GENERIC;
dwResult = DDHAL_DRIVER_HANDLED;
goto HALLockExit;
}
/* Check we haven't already queued a lock */
if(!(psSurfData->dwFlags & SURFDATAFLAGS_LOCKED))
{
if(!(psSurfData->dwFlags & SURFDATAFLAGS_LOCK_PENDING))
{
/* Queue a flush to flush synchronous blits */
if(PVRSRVQueueBlt(gpsDriverData->psDDQueueInfo,
psSurfData->psMemInfo->psSyncInfo,
0,
IMG_NULL,
0,
IMG_NULL) != PVRSRV_OK)
{
psData->ddRVal = DDERR_WASSTILLDRAWING;
return(DDHAL_DRIVER_HANDLED);
}
psSurfData->sLock.ui32ReadOpsPending = PVRSRVGetReadOpsPending(psSurfData->psMemInfo->psSyncInfo, IMG_FALSE);
psSurfData->sLock.ui32NextWriteOp = PVRSRVGetNextWriteOp(psSurfData->psMemInfo->psSyncInfo, IMG_FALSE);
psSurfData->dwFlags |= SURFDATAFLAGS_LOCK_PENDING;
}
while((*psSurfData->psMemInfo->psSyncInfo->pui32LastWriteOp != psSurfData->sLock.ui32NextWriteOp - 1) ||
(psSurfData->psMemInfo->psSyncInfo->ui32ReadOpsComplete != psSurfData->sLock.ui32ReadOpsPending))
{
if(psData->dwFlags & DDLOCK_WAIT)
{
SysKickCmdProc(psDevInfo->pui32KickerAddrKM);
continue;
}
else
{
SysKickCmdProc(psDevInfo->pui32KickerAddrKM);
psData->ddRVal = DDERR_WASSTILLDRAWING;
dwResult = DDHAL_DRIVER_HANDLED;
goto HALLockExit;
}
}
/* Mark the surface as locked */
psSurfData->psMemInfo->psSyncInfo->ui32ReadOpsComplete = 0;
psSurfData->dwFlags |= SURFDATAFLAGS_LOCKED;
psSurfData->dwFlags &= ~SURFDATAFLAGS_LOCK_PENDING;
}
/* If this is the primary we have a valid pointer in fpVidMem. */
if(psSurfData->dwFlags & SURFDATAFLAGS_PRIMARY)
{
psData->lpSurfData = (PVOID) psSurfLcl->lpGbl->fpVidMem;
}
else
{
psData->lpSurfData = (PVOID) psSurfData->psMemInfo->pvLinAddr;
}
DPFL4("Surf 0x%08lx locked, linear address: 0x%08lx", psSurfLcl, psData->lpSurfData);
psData->ddRVal = DD_OK;
if(psData->bHasRect)
{
LPDDPIXELFORMAT psPixelFormat = &psData->lpDDSurface->lpGbl->ddpfSurface;
DWORD dwOffset;
int nBpp;
/*
Detect if the ddpfSurface structure has been allocated, if it has not
then the pixel format must be the same as the primary surface
*/
if(!(psData->lpDDSurface->dwFlags & DDRAWISURF_HASPIXELFORMAT))
{
/* This is where we get the primary surface pixel format details */
psPixelFormat = &(GET_VMIDATA_ELEMENT(gpsDriverData, psData->lpDD, ddpfDisplay));
}
/* We could probably do with some more pixel formats detected here */
nBpp = 1;
if(psPixelFormat->dwFlags & DDPF_RGB)
{
nBpp = psPixelFormat->dwRGBBitCount >> 3;
}
else
{
if (psPixelFormat->dwFlags & DDPF_PALETTEINDEXED8)
{
nBpp = 1;
}
}
dwOffset = psData->rArea.top * psSurfLcl->lpGbl->lPitch;
dwOffset += psData->rArea.left * nBpp;
psData->lpSurfData = (PVOID) ((DWORD) psData->lpSurfData + dwOffset);
}
else
{
psData->lpSurfData = psSurfData->psMemInfo->pvLinAddr;
psSurfLcl->lpGbl->fpVidMem = (DWORD) psData->lpSurfData;
}
HALLockExit:
return(dwResult);
}
/*****************************************************************************
<function>
FUNCTION : HALUnlock
PARAMETERS : LPDDHAL_UNLOCKDATA structure
RETURNS : DDHAL return code
<function/>
*****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -