📄 texture.c
字号:
psContext->hrLastError = D3DMERR_DRIVERUNSUPPORTED;
return FALSE;
}
/* record the number of levels */
psMapDetails->dwMipLevels = pTexDesc->TotalLevels;
/* record the scale factors */
psMapDetails->dwUScale = dwScaleU;
psMapDetails->dwVScale = dwScaleV;
/* Scale up the TSP width and height */
dwScaledWidth = psSurface->sDescription.sTexture.dwScaledWidth = pTexDesc->Width * dwScaleU;
dwScaledHeight = psSurface->sDescription.sTexture.dwScaledHeight = pTexDesc->Height * dwScaleV;
/* Now retreive the scaled hardware texture sizes */
if(!GetSizeInfo(dwScaledWidth, &dwTSPSizeWidth, &dwScaleU, &dwLevelU))
{
D3DM_DPF((DPF_ERROR, "SetUpMAPDetails:Invalid texture width (%d) and height (%d)!", pTexDesc->Width, pTexDesc->Height));
psContext->hrLastError = D3DMERR_DRIVERUNSUPPORTED;
return FALSE;
}
if(!GetSizeInfo(dwScaledHeight, &dwTSPSizeHeight, &dwScaleV, &dwLevelV))
{
D3DM_DPF((DPF_ERROR, "SetUpMAPDetails:Invalid texture width (%d) and height (%d)!", pTexDesc->Width, pTexDesc->Height));
psContext->hrLastError = D3DMERR_DRIVERUNSUPPORTED;
return FALSE;
}
/* Put the hardware texture sizes into TSP lyr 1 */
psMapDetails->sTSPCtl.dwLCtl1 &= MBX1_TSPPL1_TUSIZECLRMASK &
MBX1_TSPPL1_TVSIZECLRMASK;
psMapDetails->sTSPCtl.dwLCtl1 |= dwTSPSizeWidth << MBX1_TSPPL1_TUSIZESHIFT;
psMapDetails->sTSPCtl.dwLCtl1 |= dwTSPSizeHeight << MBX1_TSPPL1_TVSIZESHIFT;
/* Allocate the chain */
if(!AllocateMipMapChain(psSurface))
{
D3DM_DPF((DPF_ERROR, "SetUpMAPDetails:Failed MipMapAllocation"));
return FALSE;
}
/* Set up address in control word */
psMapDetails->sTSPCtl.dwLCtl2 |= (((psSurface->psMemInfo->uiDevAddr.uiAddr) >>
MBX1_TSPPL2_TEXADDRALIGNSHIFT) <<
MBX1_TSPPL2_TEXADDRSHIFT) &
(~MBX1_TSPPL2_TEXADDRCLRMASK);
return(TRUE);
}
/*----------------------------------------------------------------------------
<function>
FUNCTION: CreateTexture
PURPOSE: Sets up the currently requested mip map level
PARAMETERS: In: pcsd - surface creation data
RETURNS:
</function>
------------------------------------------------------------------------------*/
VOID CreateTexture(D3DM_CREATESURFACE_DATA *pcsd)
{
/***************************
* TEXTURE_MAP *
***************************/
LPD3DM_SURFACE psSurface;
LPD3DM_CONTEXT psContext;
PVR_DEVFORMAT *psDevFormat = NULL;
D3DMTEXTURE_DESC *pTexDesc;
pTexDesc = &pcsd->TextureDesc;
psSurface = NULL;
psContext = (LPD3DM_CONTEXT) pcsd->nContextId;
/* Check for supported format */
psDevFormat = GetFormatDescriptorD3DM(psContext, pcsd->TextureDesc.Format);
if(psDevFormat == NULL || !(psDevFormat->sD3DDevFormat.Usage & D3DMUSAGE_TEXTURE))
{
D3DM_DPF((DPF_ERROR ,"CreateTexture:Unsupported texture format requested"));
pcsd->rval = D3DMERR_WRONGTEXTUREFORMAT;
return;
}
if(!ValidatePoolType(pcsd->SurfaceType, pcsd->TextureDesc.Pool))
{
D3DM_DPF((DPF_ERROR, "CreateTexture:Unsupported memory pool requested"));
pcsd->rval = D3DMERR_DRIVERUNSUPPORTED;
return;
}
/* Allocate the surface structure */
psSurface = D3DMAllocate(sizeof(D3DM_SURFACE));
if(psSurface == NULL)
{
D3DM_DPF((DPF_WARN, "CreateTexture:Insufficient system memory to create surface"));
pcsd->rval = D3DMERR_DRIVERINTERNALERROR;
return;
}
memset(psSurface, 0, sizeof(D3DM_SURFACE));
/* Fill in common surface details */
psSurface->psContext = psContext;
psSurface->eSurfaceType = pcsd->SurfaceType;
psSurface->dwUsage = pTexDesc->Usage;
psSurface->eFormat = pTexDesc->Format;
psSurface->eMultiSampleType = pTexDesc->MultiSampleType;
psSurface->dwWidth = pcsd->SurfaceDesc.Width;
psSurface->dwHeight = pcsd->SurfaceDesc.Height;
psSurface->dwBpp = psDevFormat->dwBpp;
if(psContext->psCurrentTexFirstLevel == NULL)
{
/* No Map is currently under construction so start a new one */
/* Create texture map details */
psSurface->sDescription.sTexture.psMapDetails = D3DMAllocate(sizeof(MAP_DETAILS));
if(psSurface->sDescription.sTexture.psMapDetails == NULL)
{
D3DM_DPF((DPF_ERROR, "CreateTexture:Insufficient system memory to create tex map details"));
pcsd->rval = D3DMERR_DRIVERINTERNALERROR;
goto error_exit;
}
memset(psSurface->sDescription.sTexture.psMapDetails, 0, sizeof(MAP_DETAILS));
/* Set up the Mip Map */
if(!SetUpMAPDetails(pTexDesc, psSurface))
{
D3DM_DPF((DPF_ERROR, "CreateTexture:Couldn't set up Map details"));
pcsd->rval = psContext->hrLastError;
goto error_exit;
}
/* Record stride values and first level value */
psSurface->dwStridePixel = (psSurface->sDescription.sTexture.dwScaledWidth + (MBX1_TEXSTRIDE_PIXEL_GRAN - 1))
& ~(MBX1_TEXSTRIDE_PIXEL_GRAN - 1);
psSurface->dwStrideByte = (psSurface->dwStridePixel * psSurface->dwBpp) >> 3;
psSurface->sDescription.sTexture.dwMipMapLevel = 0;
/* Zero memory if apphint set */
if(psContext->sRegData.dwFlags2 & D3DMREG2_ZERO_TEXTURE_MEMORY)
{
memset(psSurface->psMemInfo->pvLinAddr, 0, psSurface->psMemInfo->ui32AllocSize);
}
if(pTexDesc->TotalLevels > 1)
{
/* Store a pointer to this top map for next consecutive level construction */
psContext->psCurrentTexFirstLevel = psSurface;
}
psSurface->sDescription.sTexture.psMapDetails->psCurrentTopLevel = psSurface;
PDUMPREGISTERTEX(psContext->psPDContext, psSurface->psMemInfo);
}
else
{
/* Set up this level of the map under construction */
DWORD dwOffset;
DWORD dwLastMapSizeInBytes;
DWORD dwScaledHeight, dwScaledWidth;
PMAP_DETAILS psMapDetails;
LPD3DM_SURFACE psLastSurface;
psLastSurface = psContext->psCurrentTexFirstLevel;
psMapDetails = psLastSurface->sDescription.sTexture.psMapDetails;
/* Find last created surface */
while(psLastSurface->sDescription.sTexture.psNextLevel != NULL)
psLastSurface = psLastSurface->sDescription.sTexture.psNextLevel;
/* Store a pointer to this level surface */
psLastSurface->sDescription.sTexture.psNextLevel = psSurface;
/* Find texture level offset of last surface */
dwOffset = psLastSurface->sDescription.sTexture.dwLevelOffset;
/* Setup common variables */
psSurface->sDescription.sTexture.psMapDetails = psMapDetails;
psSurface->psMemInfo = psLastSurface->psMemInfo;
psSurface->dwFlags |= D3DM_SURFACE_FLAGS_MIPMAPSUBLEVEL;
psSurface->dwBpp = psLastSurface->dwBpp;
psSurface->sDescription.sTexture.dwTextureFormat = psLastSurface->sDescription.sTexture.dwTextureFormat;
/* Check for minimum sizes for compressed textures */
dwScaledWidth = psSurface->dwWidth * psMapDetails->dwUScale;
dwScaledHeight = psSurface->dwHeight * psMapDetails->dwVScale;
if(psSurface->eFormat == MBXFOURCC_PVRTC4 && (dwScaledWidth < 8 || dwScaledHeight < 8))
{
if(dwScaledWidth < 8)
{
psSurface->sDescription.sTexture.dwScaledWidth = 8;
}
if(dwScaledHeight < 8)
{
psSurface->sDescription.sTexture.dwScaledHeight = 8;
}
}
else if(psSurface->eFormat == MBXFOURCC_PVRTC2 && (dwScaledWidth < 16 || dwScaledHeight < 8))
{
if(dwScaledWidth < 16)
{
psSurface->sDescription.sTexture.dwScaledWidth = 8;
}
if(dwScaledHeight < 8)
{
psSurface->sDescription.sTexture.dwScaledHeight = 8;
}
}
else
{
psSurface->sDescription.sTexture.dwScaledWidth = dwScaledWidth;
psSurface->sDescription.sTexture.dwScaledHeight = dwScaledHeight;
/* Update the level count */
psMapDetails->dwSuppliedLevels++;
}
psSurface->dwStridePixel = (psSurface->sDescription.sTexture.dwScaledWidth + (MBX1_TEXSTRIDE_PIXEL_GRAN - 1))
& ~(MBX1_TEXSTRIDE_PIXEL_GRAN - 1);
psSurface->dwStrideByte = (psSurface->dwStridePixel * psSurface->dwBpp) >> 3;
/* Calculate size of previous level */
dwLastMapSizeInBytes = psLastSurface->dwStrideByte *
psLastSurface->sDescription.sTexture.dwScaledHeight;
psSurface->sDescription.sTexture.dwLevelOffset = dwOffset + dwLastMapSizeInBytes;
psSurface->sDescription.sTexture.dwMipMapLevel = pTexDesc->Level;
if(pTexDesc->Level == pTexDesc->TotalLevels - 1)
{
/* This is the last level */
psContext->psCurrentTexFirstLevel = NULL;
psSurface->dwFlags |= D3DM_SURFACE_FLAGS_LAST_SUPPLIED_MIPMAP;
}
}
/* Record the surface pointer as surface ID */
pcsd->nSurfaceId = (ULONG) psSurface;
/* Record the correct size for the requested level even if we've scaled up */
pTexDesc->Size = (psSurface->dwWidth * psSurface->dwHeight * psSurface->dwBpp) >> 3;
pcsd->rval = D3DM_OK;
return;
error_exit:
/* clean up and exit */
if(psSurface->psMemInfo)
D3DMFreeDeviceMem(&psContext->sDevData, psSurface->psMemInfo);
if(psSurface->sDescription.sTexture.psMapDetails)
D3DMFree(psSurface->sDescription.sTexture.psMapDetails);
D3DMFree(psSurface);
}
/*----------------------------------------------------------------------------
<function>
FUNCTION: DestroyTexture
PURPOSE:
PARAMETERS: In: pcsd - surface creation data
RETURNS:
</function>
------------------------------------------------------------------------------*/
VOID DestroyTexture(D3DM_DESTROYSURFACE_DATA *pdsd)
{
LPD3DM_SURFACE psSurface = (LPD3DM_SURFACE) pdsd->nSurfaceId;
LPD3DM_CONTEXT psContext = psSurface->psContext;
if(psSurface->sDescription.sTexture.dwMipMapLevel == 0)
{
DWORD i;
/* Base Texture */
/* Free FB surface Allocation */
D3DMFreeDeviceMem(&psContext->sDevData, psSurface->psMemInfo);
/* Free up map details */
D3DMFree(psSurface->sDescription.sTexture.psMapDetails);
/* Remove layer references to this texture */
for(i=0; i<sPVRD3DMCaps.MaxSimultaneousTextures; i++)
{
PLAYER_TSTATE psLState = &psContext->sTState.sLState[i];
if(psLState->psSurfData == psSurface)
{
psLState->psSurfData = NULL;
}
}
}
/* Free Surface Mem */
D3DMFree(psSurface);
}
/*****************************************************************************
End of file (Texture.c).
*****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -