diff options
Diffstat (limited to 'src/mesa/drivers/d3d/D3DTextureMgr.cpp')
-rw-r--r-- | src/mesa/drivers/d3d/D3DTextureMgr.cpp | 947 |
1 files changed, 0 insertions, 947 deletions
diff --git a/src/mesa/drivers/d3d/D3DTextureMgr.cpp b/src/mesa/drivers/d3d/D3DTextureMgr.cpp deleted file mode 100644 index a6600cab02c..00000000000 --- a/src/mesa/drivers/d3d/D3DTextureMgr.cpp +++ /dev/null @@ -1,947 +0,0 @@ -/*===========================================================================*/ -/* */ -/* Mesa-3.0 DirectX 6 Driver */ -/* */ -/* By Leigh McRae */ -/* */ -/* http://www.altsoftware.com/ */ -/* */ -/* Copyright (c) 1999-1998 alt.software inc. All Rights Reserved */ -/*===========================================================================*/ -#include "D3DHAL.h" -/*===========================================================================*/ -/* Local function prototypes. */ -/*===========================================================================*/ -static void UpdateTexture( PTM_OBJECT pTMObj, BOOL bVideo, RECT *pRect, UCHAR *pixels ); -static BOOL LoadTextureInVideo( PMESAD3DHAL pHAL, PTM_OBJECT pTMObj ); -static BOOL FreeTextureMemory( PMESAD3DHAL pHAL, PTM_OBJECT pTMObject ); -static BOOL DestroyTextureObject( PMESAD3DHAL pHAL, PTM_OBJECT pTMObject ); -HRESULT CALLBACK EnumPFHook( LPDDPIXELFORMAT lpDDPixFmt, LPVOID lpContext ); -/*===========================================================================*/ -/* This function will simply set the top of stack to NULL. I only used it */ -/* just incase I want to add something later. */ -/*===========================================================================*/ -/* RETURN: TRUE. */ -/*===========================================================================*/ -BOOL InitTMgrHAL( PMESAD3DHAL pHAL ) -{ - DPF(( DBG_FUNC, "InitTMgrHAL();" )); - - /* Be clean my friend. */ - pHAL->pTMList = NULL; - - return TRUE; -} -/*===========================================================================*/ -/* This function will walk the Texture Managers linked list and destroy all */ -/* surfaces (SYSTEM/VIDEO). The texture objects themselves also will be */ -/* freed. */ -/* NOTE: this is per/context. */ -/*===========================================================================*/ -/* RETURN: */ -/*===========================================================================*/ -void TermTMgrHAL( PMESAD3DHAL pHAL ) -{ - DPF(( DBG_FUNC, "TermTMgrHAL();" )); - - if ( pHAL && pHAL->pTMList ) - { - /* Destroy the surface and remove the TMO from the stack. */ - while( DestroyTextureObject(pHAL,NULL) ); - - /* Be clean my friend. */ - pHAL->pTMList = NULL; - } -} -/*===========================================================================*/ -/* This function is a HACK as I don't know how I can disable a texture with-*/ -/* out booting it out. Is there know state change? */ -/*===========================================================================*/ -/* RETURN: */ -/*===========================================================================*/ -extern "C" void DisableTMgrHAL( PMESAD3DSHARED pShared ) -{ - PMESAD3DHAL pHAL = (PMESAD3DHAL)pShared; - - DPF(( DBG_FUNC, "DisableTMgrHAL();" )); - - /* Check too see that we have a valid context. */ - if ( (pHAL == NULL) && (pHAL->lpD3DDevice != NULL) ) - { - DPF(( DBG_TXT_WARN, "Null HAL/Direct3D Device!" )); - return; - } - - // TODO: This is a hack to shut off textures. - pHAL->lpD3DDevice->SetTexture( 0, NULL ); -} -/*===========================================================================*/ -/* This function is the only entry into the TextureManager that Mesa/wgl */ -/* will see. It uses a dwAction to specify what we are doing. I did this as*/ -/* depending on the cards resources the action taken can change. */ -/* When this function is called we will always search the Texture Managers */ -/* linked list (per context remember) and try and find a structure that has */ -/* the same dwName. If we have a match we pull it out of the list and put it*/ -/* at the top of the list (TOL). If we don't find one then we create a struc*/ -/* and put it a TOL. This TOL idea makes for some caching as we will always */ -/* destroy Texture Surfaces from the bottom up... */ -/* All texture objects at this point will create a texture surface in System*/ -/* memory (SMEM). Then we will copy the Mesa texture into the surface using */ -/* the 'pixel' struc to get the translation info. So now this means that all*/ -/* textures that Mesa gives me I will have a Surface with a copy. If Mesa */ -/* changes the texture the I update the surface in (SMEM). */ -/* Now we have a texture struc and a Texture Surface in SMEM. At this point*/ -/* we create another surface on the card (VMEM). Finally we blt from the */ -/* SMEM to the VMEM and set the texture as current. Why do I need two? First*/ -/* this solves square textures. If the cards CAPS is square textures only */ -/* then I change the dimensions of the VMEM surface and the blt solves it for*/ -/* me. Second it saves me from filling D3D textures over and over if the */ -/* card needs to be creating and destroying surfaces because of low memory. */ -/* The surface in SMEM is expected to work always. When a surface has to be*/ -/* created in VMEM then we put it in a loop that tries to create the surface.*/ -/* If we create the surface ok then we brake from the loop. If we fail then */ -/* we will call 'FreeTextureMemory' that will return TRUE/FALSE as to whether*/ -/* memory was freed. If memory was freed then we can try again. If no memory*/ -/* was freed then it just can't fit. */ -/* 'FreeTextureMemory' will find the end of the list and start freeing VMEM */ -/* (never SMEM) surfaces that are not locked. */ -/* BIND - when we bind and there is a texture struct with a texture surface */ -/* in VMEM then we just make it current. If we have a struct and a surface */ -/* in SMEM but no VMEM surface then we create the surface in VMEM and blt */ -/* from the SMEM surface. If we have nothing its just like a creation... */ -/*===========================================================================*/ -/* RETURN: TRUE, FALSE. */ -/*===========================================================================*/ -extern "C" BOOL CreateTMgrHAL( PMESAD3DSHARED pShared, DWORD dwName, int level, DWORD dwRequestFlags, - RECT *rectDirty, DWORD dwWidth, DWORD dwHeight, DWORD dwAction, void *pPixels ) -{ - PMESAD3DHAL pHAL = (PMESAD3DHAL)pShared; - PTM_OBJECT pTMObj, - pTemp; - DDSURFACEDESC2 ddsd2; - HRESULT rc; - - - DPF(( DBG_FUNC, "CreateTMgrHAL();" )); - - DPF(( DBG_TXT_INFO, "Texture:" )); - DPF(( DBG_TXT_INFO, "cx: %d cy: %d", dwWidth, dwHeight )); - DPF(( DBG_TXT_INFO, "Rect:" )); - if ( rectDirty ) - { - DPF(( DBG_TXT_INFO, "x0: %d y0: %d", rectDirty->left, rectDirty->top )); - DPF(( DBG_TXT_INFO, "x1: %d y1: %d", rectDirty->right, rectDirty->bottom )); - } - - /* Check too see that we have a valid context. */ - if ( (pHAL == NULL) && (pHAL->lpD3DDevice != NULL) ) - { - DPF(( DBG_TXT_WARN, "Null HAL/Direct3D Device!" )); - return FALSE; - } - - /*=================================================*/ - /* See if we can find this texture object by name. */ - /*=================================================*/ - for( pTMObj = pHAL->pTMList; pTMObj && (pTMObj->dwName != dwName); pTMObj = pTMObj->next ); - - /*=========================================================*/ - /* Allocate a new object if we didn't get a matching name. */ - /*=========================================================*/ - if ( pTMObj == NULL ) - { - pTMObj = (PTM_OBJECT)ALLOC( sizeof(TM_OBJECT) ); - if ( pTMObj == NULL ) - return FALSE; - memset( pTMObj, 0, sizeof(TM_OBJECT) ); - - /* Put the object at the beginning of the list. */ - pTMObj->next = pHAL->pTMList; - if ( pTMObj->next ) - { - pTemp = pTMObj->next; - pTemp->prev = pTMObj; - } - pHAL->pTMList = pTMObj; - } - else - { - /*===============================================================*/ - /* Make some caching happen by pulling this object to the front. */ - /*===============================================================*/ - if ( pHAL->pTMList != pTMObj ) - { - /* Pull the object out of the list. */ - if ( pTMObj->prev ) - { - pTemp = pTMObj->prev; - pTemp->next = pTMObj->next; - } - if ( pTMObj->next ) - { - pTemp = pTMObj->next; - pTemp->prev = pTMObj->prev; - } - - pTMObj->prev = NULL; - pTMObj->next = NULL; - - /* Put the object at the front of the list. */ - pTMObj->next = pHAL->pTMList; - if ( pTMObj->next ) - { - pTemp = pTMObj->next; - pTemp->prev = pTMObj; - } - pHAL->pTMList = pTMObj; - } - } - - /*========================================================*/ - /* If we are doing BIND and the texture is in VID memory. */ - /*========================================================*/ - if ( (dwAction == TM_ACTION_BIND) && pTMObj->lpDDS_Video ) - { - DPF(( DBG_TXT_PROFILE, "Cache HIT (%d)", dwName )); - - /* Make this the current texture. */ - rc = pHAL->lpD3DDevice->SetTexture( 0, pTMObj->lpD3DTexture2 ); - if ( FAILED(rc) ) - { - DPF(( DBG_TXT_WARN, "Failed SetTexture() (%s)", ErrorStringD3D(rc) )); - pHAL->lpD3DDevice->SetTexture( 0, NULL ); - return FALSE; - } - - return TRUE; - } - - /*=================================================================*/ - /* If we are doing BIND and the texture is at least in SYS memory. */ - /*=================================================================*/ - if ( (dwAction == TM_ACTION_BIND) && pTMObj->lpDDS_System ) - { - DPF(( DBG_TXT_PROFILE, "Cache MISS (%d)", dwName )); - - /* Create the texture on the card. */ - rc = LoadTextureInVideo( pHAL, pTMObj ); - if ( rc == FALSE ) - return FALSE; - - /* Make this the current texture. */ - rc = pHAL->lpD3DDevice->SetTexture( 0, pTMObj->lpD3DTexture2 ); - if ( FAILED(rc) ) - { - DPF(( DBG_TXT_WARN, "Failed SetTexture() (%s)", ErrorStringD3D(rc) )); - pHAL->lpD3DDevice->SetTexture( 0, NULL ); - return FALSE; - } - - return TRUE; - } - - /*=========================================================*/ - /* If we are doing UPDATE then try in VID first for speed. */ - /*=========================================================*/ - if ( (dwAction == TM_ACTION_UPDATE) && pTMObj->lpDDS_Video && - !(pHAL->D3DHWDevDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_SQUAREONLY) ) - { - DPF(( DBG_TXT_INFO, "Fix the SubTexture update Leigh!" )); - - /* Update the texture on the card. */ - UpdateTexture( pTMObj, TRUE, rectDirty, (UCHAR *)pPixels ); - - /* We updated the texture in VID so kill the SYS so we know its dirty. */ - if ( pTMObj->lpDDS_System ) - { - DPF(( DBG_TXT_INFO, "Release texture (SYS)" )); - DX_RESTORE( pTMObj->lpDDS_System ); - pTMObj->lpDDS_System->Release(); - pTMObj->lpDDS_System = NULL; - } - - /* Make this the current texture. */ - rc = pHAL->lpD3DDevice->SetTexture( 0, pTMObj->lpD3DTexture2 ); - if ( FAILED(rc) ) - { - DPF(( DBG_TXT_WARN, "Failed SetTexture() (%s)", ErrorStringD3D(rc) )); - pHAL->lpD3DDevice->SetTexture( 0, NULL ); - return FALSE; - } - - return TRUE; - } - - /*===========================================================*/ - /* If we are doing UPDATE then try in SYS still gives speed. */ - /*===========================================================*/ - if ( (dwAction == TM_ACTION_UPDATE) && pTMObj->lpDDS_System ) - { - DPF(( DBG_TXT_INFO, "Fix the SubTexture update Leigh!" )); - - /* Update the texture in SYS. */ - UpdateTexture( pTMObj, FALSE, NULL, (UCHAR *)pPixels ); - - /* We updated the SYS texture only so now blt to the VID. */ - rc = LoadTextureInVideo( pHAL, pTMObj ); - if ( rc == FALSE ) - return FALSE; - - /* Make this the current texture. */ - rc = pHAL->lpD3DDevice->SetTexture( 0, pTMObj->lpD3DTexture2 ); - if ( FAILED(rc) ) - { - DPF(( DBG_TXT_WARN, "Failed SetTexture() (%s)", ErrorStringD3D(rc) )); - pHAL->lpD3DDevice->SetTexture( 0, NULL ); - return FALSE; - } - - return TRUE; - } - - /* At this point we have a valid Texture Manager Object with updated */ - /* links. We now need to create or update a texture surface that is */ - /* in system memory. Every texture has a copy in system so we can use*/ - /* blt to solve problems with textures allocated on the card (square */ - /* only textures, pixelformats...). */ - - // TODO: make support for update also. Dirty rectangle basicly... - - /* Kill the interface if we have one no matter what. */ - if ( pTMObj->lpD3DTexture2 ) - { - DPF(( DBG_TXT_INFO, "Release Texture2" )); - pTMObj->lpD3DTexture2->Release(); - pTMObj->lpD3DTexture2 = NULL; - } - - /* Kill the system surface. TODO: should try to get the SubIMage going again */ - if ( pTMObj->lpDDS_System ) - { - DPF(( DBG_TXT_INFO, "Release texture (SYS)" )); - DX_RESTORE( pTMObj->lpDDS_System ); - pTMObj->lpDDS_System->Release(); - pTMObj->lpDDS_System = NULL; - } - - /* Kill the Video surface. TODO: need some reuse system... */ - if ( pTMObj->lpDDS_Video ) - { - DPF(( DBG_TXT_INFO, "Release texture (VID)" )); - DX_RESTORE( pTMObj->lpDDS_Video ); - pTMObj->lpDDS_Video->Release(); - pTMObj->lpDDS_Video = NULL; - } - - /*================================================================*/ - /* Translate the the Mesa/OpenGL pixel channels to the D3D flags. */ - /*================================================================*/ - switch( dwRequestFlags ) - { - case GL_ALPHA: - dwRequestFlags = DDPF_ALPHA; - DPF(( DBG_TXT_WARN, "GL_ALPHA not supported!)" )); - return FALSE; - - case GL_INTENSITY: - case GL_LUMINANCE: - DPF(( DBG_TXT_WARN, "GL_INTENSITY/GL_LUMINANCE not supported!)" )); - dwRequestFlags = DDPF_LUMINANCE; - return FALSE; - - case GL_LUMINANCE_ALPHA: - DPF(( DBG_TXT_WARN, "GL_LUMINANCE_ALPHA not supported!)" )); - dwRequestFlags = DDPF_LUMINANCE | DDPF_ALPHAPIXELS; - return FALSE; - - case GL_RGB: - DPF(( DBG_TXT_INFO, "Texture -> GL_RGB" )); - dwRequestFlags = DDPF_RGB; - break; - - case GL_RGBA: - DPF(( DBG_TXT_INFO, "Texture -> GL_RGBA" )); - dwRequestFlags = DDPF_RGB | DDPF_ALPHAPIXELS; - break; - } - - /*==============================*/ - /* Populate the texture object. */ - /*==============================*/ - pTMObj->dwName = dwName; - pTMObj->lpD3DDevice = pHAL->lpD3DDevice; - pTMObj->dwFlags = dwRequestFlags; - if ( pHAL->D3DHWDevDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_SQUAREONLY ) - { - DPF(( DBG_TXT_INFO, "Convert to Square..." )); - pTMObj->dwSHeight = dwHeight; - pTMObj->dwSWidth = dwWidth; - - /* Shrink non-square textures. */ - pTMObj->dwVHeight = (dwHeight > dwWidth) ? dwWidth : dwHeight; - pTMObj->dwVWidth = (dwHeight > dwWidth) ? dwWidth : dwHeight; - } - else - { - pTMObj->dwSHeight = dwHeight; - pTMObj->dwSWidth = dwWidth; - pTMObj->dwVHeight = dwHeight; - pTMObj->dwVWidth = dwWidth; - } - - /*========================*/ - /* Create SYSTEM surface. */ - /*========================*/ - - /* Request a surface in system memory. */ - memset( &ddsd2, 0, sizeof(DDSURFACEDESC2) ); - ddsd2.dwSize = sizeof( DDSURFACEDESC2 ); - ddsd2.dwWidth = pTMObj->dwSWidth; - ddsd2.dwHeight = pTMObj->dwSHeight; - ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; - ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_SYSTEMMEMORY; - ddsd2.ddsCaps.dwCaps2 = 0L; - memset( &ddsd2.ddpfPixelFormat, 0, sizeof(DDPIXELFORMAT) ); - ddsd2.ddpfPixelFormat.dwSize = sizeof( DDPIXELFORMAT ); - ddsd2.ddpfPixelFormat.dwFlags = dwRequestFlags; - rc = pHAL->lpD3DDevice->EnumTextureFormats( EnumPFHook, &ddsd2.ddpfPixelFormat ); - if ( FAILED(rc) ) - { - RIP( pHAL, "EnumerTextureFormats (SYSTEM)->", ErrorStringD3D(rc) ); - return FALSE; - } - - /* Create the surface using the enumerated pixelformat. */ - rc = pHAL->lpDD4->CreateSurface( &ddsd2, &pTMObj->lpDDS_System, NULL ); - if ( FAILED(rc) ) - { - RIP( pHAL, "CreateSurface (TEXTURE/SYSTEM)->", ErrorStringD3D(rc) ); - return FALSE; - } - - /* Solve the pixel mapping info using the surface pixelformat. */ - Solve8BitChannelPixelFormat( &ddsd2.ddpfPixelFormat, &pTMObj->pixel ); - - /*===================================================================*/ - /* Fill the texture using the PixelInfo structure to do the mapping. */ - /*===================================================================*/ - UpdateTexture( pTMObj, FALSE, NULL, (UCHAR *)pPixels ); - - /*=======================*/ - /* Create VIDEO surface. */ - /*=======================*/ - rc = LoadTextureInVideo( pHAL, pTMObj ); - if ( rc == FALSE ) - return FALSE; - - /* Make this the current texture. */ - rc = pHAL->lpD3DDevice->SetTexture( 0, pTMObj->lpD3DTexture2 ); - if ( FAILED(rc) ) - { - DPF(( DBG_TXT_WARN, "Failed SetTexture() (%s)", ErrorStringD3D(rc) )); - pHAL->lpD3DDevice->SetTexture( 0, NULL ); - return FALSE; - } - - return TRUE; -} -/*===========================================================================*/ -/* This function will handle the creation and destruction of the texture */ -/* surfaces on the card. Using the dw'V'Width/Height dimensions the call */ -/* try and create the texture on the card and keep using FreeTextureMemory */ -/* until the surace can be created. Once the surface is created we get the */ -/* interface that we will use to make it the current texture. I didn't put */ -/* the code to make the texture current in this function as BIND needs to */ -/* use the same code and this function doesn't always get called when we do a*/ -/* bind. */ -/*===========================================================================*/ -/* RETURN: TRUE, FALSE. */ -/*===========================================================================*/ -static BOOL LoadTextureInVideo( PMESAD3DHAL pHAL, PTM_OBJECT pTMObj ) -{ - DDSURFACEDESC2 ddsd2; - HRESULT rc; - - DPF(( DBG_FUNC, "LoadTextureInVideo();" )); - - /* Kill the interface if we have one no matter what. */ - if ( pTMObj->lpD3DTexture2 ) - { - DPF(( DBG_TXT_INFO, "Release Texture2" )); - pTMObj->lpD3DTexture2->Release(); - pTMObj->lpD3DTexture2 = NULL; - } - - /* Kill the Video surface. TODO: need some reuse system... */ - if ( pTMObj->lpDDS_Video ) - { - DPF(( DBG_TXT_INFO, "Release texture (VID)" )); - DX_RESTORE( pTMObj->lpDDS_Video ); - pTMObj->lpDDS_Video->Release(); - pTMObj->lpDDS_Video = NULL; - } - - /* Request a surface in Video memory. */ - memset( &ddsd2, 0, sizeof(DDSURFACEDESC2) ); - ddsd2.dwSize = sizeof( DDSURFACEDESC2 ); - ddsd2.dwWidth = pTMObj->dwVWidth; - ddsd2.dwHeight = pTMObj->dwVHeight; - ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; - ddsd2.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY; - ddsd2.ddsCaps.dwCaps2 = 0L; - memset( &ddsd2.ddpfPixelFormat, 0, sizeof(DDPIXELFORMAT) ); - ddsd2.ddpfPixelFormat.dwSize = sizeof( DDPIXELFORMAT ); - ddsd2.ddpfPixelFormat.dwFlags = pTMObj->dwFlags; - rc = pHAL->lpD3DDevice->EnumTextureFormats( EnumPFHook, &ddsd2.ddpfPixelFormat ); - if ( FAILED(rc) ) - { - RIP( pHAL, "EnumerTextureFormats ->", ErrorStringD3D(rc) ); - return FALSE; - } - - /* Make sure we lock so we don't nuke this texture trying to free memory for it. */ - pTMObj->bLock = TRUE; - - /* Start a loop that will free all textures until we have created the texture */ - /* surface or we can't free up more memory. */ - do - { - /* Try to create the texture surface. */ - rc = pHAL->lpDD4->CreateSurface( &ddsd2, &pTMObj->lpDDS_Video, NULL ); - if ( !FAILED(rc) ) - break; - - DPF(( DBG_TXT_INFO, "Free Texture Memory" )); - - /* DestroyTexture will return TRUE if a surface was freed. */ - } while( FreeTextureMemory(pHAL,NULL) ); - - /* Make sure we unlock or we won't be able to nuke the TMO later. */ - pTMObj->bLock = FALSE; - - /* Did we create a valid texture surface? */ - if ( FAILED(rc) ) - { - DPF(( DBG_TXT_WARN, "Failed to load texture" )); - pHAL->lpD3DDevice->SetTexture( 0, NULL ); - return FALSE; - } - - DX_RESTORE( pTMObj->lpDDS_System ); - DX_RESTORE( pTMObj->lpDDS_Video ); - - DPF(( DBG_TXT_INFO, "Texture Blt SYSTEM -> VID" )); - - /* Now blt the texture in system memory to the card. */ - rc = pTMObj->lpDDS_Video->Blt( NULL, pTMObj->lpDDS_System, NULL, DDBLT_WAIT, NULL ); - if ( FAILED(rc) ) - { - RIP( pHAL, "Blt (TEXTURE) ->", ErrorStringD3D(rc) ); - return FALSE; - } - - /* Get the Texture interface that is used to render with. */ - pTMObj->lpDDS_Video->QueryInterface( IID_IDirect3DTexture2, (void **)&pTMObj->lpD3DTexture2 ); - if ( pTMObj->lpD3DTexture2 == NULL ) - { - DPF(( DBG_TXT_WARN, "Failed QueryTextureInterface" )); - pHAL->lpD3DDevice->SetTexture( 0, NULL ); - return FALSE; - } - - return TRUE; -} -/*===========================================================================*/ -/* If this function gets a texture object struc then we will try and free */ -/* it. If we get a NULL then we will search from the bottom up and free one */ -/* VMEM surface. I can only free when the surface isn't locked and of course*/ -/* there must be a VMEM surface. We never free SMEM surfaces as that isn't */ -/* the point. */ -/* TODO: should have a pointer to the bottom of the stack really. */ -/*===========================================================================*/ -/* RETURN: */ -/*===========================================================================*/ -static BOOL FreeTextureMemory( PMESAD3DHAL pHAL, PTM_OBJECT pTMObject ) -{ - PTM_OBJECT pCurrent; - BOOL bFreed = FALSE; - - DPF(( DBG_FUNC, "FreeTextureMemory();" )); - DPF(( DBG_TXT_WARN, "FREE TEXTURE!" )); - - /* Just to be safe. */ - if ( !pHAL || !pHAL->pTMList ) - { - DPF(( DBG_TXT_WARN, "FreeTextureMemory() -> NULL pHAL/pHAL->pTMList" )); - return FALSE; - } - - /* Free the last texture in the list. */ - if ( pTMObject == NULL ) - { - DPF(( DBG_TXT_INFO, "Free Last texture in cache" )); - - /* Find the last texture object. */ - for( pCurrent = pHAL->pTMList; pCurrent->next; pCurrent = pCurrent->next ); - - /* Now backup until we find a texture on the card. */ - while( pCurrent && (pCurrent->lpDDS_Video == NULL) && (pCurrent->bLock == FALSE) ) - pCurrent = pCurrent->prev; - - /* Didn't find anything. */ - if ( pCurrent == NULL ) - { - DPF(( DBG_TXT_INFO, "No texture memory freed" )); - return FALSE; - } - } - else - { - /* See if we can find this texture object. */ - for( pCurrent = pHAL->pTMList; pCurrent && (pCurrent != pTMObject); pCurrent = pCurrent->next ); - - /* Didn't find anything. */ - if ( pCurrent == NULL ) - { - DPF(( DBG_TXT_INFO, "Requested texture to be freed NOT FOUND" )); - return FALSE; - } - } - - /* Can't free this baby. */ - if ( pCurrent->bLock == TRUE ) - { - DPF(( DBG_TXT_WARN, "Requested texture LOCKED" )); - return FALSE; - } - - /* Free the texture memory. */ - if ( pCurrent->lpD3DTexture2 ) - { - DPF(( DBG_TXT_INFO, "Release Texture2" )); - pCurrent->lpD3DTexture2->Release(); - pCurrent->lpD3DTexture2 = NULL; - bFreed = TRUE; - } - if ( pCurrent->lpDDS_Video ) - { - DPF(( DBG_TXT_INFO, "Release texture (VID):" )); - DPF(( DBG_TXT_INFO, "dwName: %d", pCurrent->dwName )); - DPF(( DBG_TXT_INFO, "cx: %d, cy: %d", pCurrent->dwVWidth, pCurrent->dwVHeight )); - pCurrent->lpDDS_Video->Release(); - pCurrent->lpDDS_Video = NULL; - bFreed = TRUE; - } - - return bFreed; -} -/*===========================================================================*/ -/* This function searches the linked list of texture objects in the supplied*/ -/* D3Dwrapper structure. If it finds a match it will free it and pull it out*/ -/* of the linked list. The function works on the bases of a matching pointer*/ -/* to the object (not matching content). */ -/* If the function gets passed a NULL then we want to free the last texture */ -/* object in the list. Used in a loop to destory all. */ -/*===========================================================================*/ -/* RETURN: TRUE, FALSE. */ -/*===========================================================================*/ -static BOOL DestroyTextureObject( PMESAD3DHAL pHAL, PTM_OBJECT pTMObject ) -{ - PTM_OBJECT pCurrent; - - DPF(( DBG_FUNC, "DestoryTextureObject();" )); - - /* Just to be safe. */ - if ( !pHAL || !pHAL->pTMList ) - { - DPF(( DBG_TXT_WARN, "DestroyTextureObject() -> NULL pHAL/pHAL->pTMList" )); - return FALSE; - } - - /* Free the last texture in the list. */ - if ( pTMObject == NULL ) - { - /* Find the last texture object. */ - for( pCurrent = pHAL->pTMList; pCurrent->next; pCurrent = pCurrent->next ); - } - else - { - /* See if we can find this texture object. */ - for( pCurrent = pHAL->pTMList; pCurrent && (pCurrent != pTMObject); pCurrent = pCurrent->next ); - - /* Didn't find anything. */ - if ( pCurrent == NULL ) - { - DPF(( DBG_TXT_WARN, "No textures to be freed" )); - return FALSE; - } - } - - /* Can't free this baby. */ - if ( pCurrent->bLock == TRUE ) - { - DPF(( DBG_TXT_WARN, "Requested texture to be freed LOCKED" )); - return FALSE; - } - - /* Free the texture memory. */ - if ( pCurrent->lpD3DTexture2 ) - { - DPF(( DBG_TXT_INFO, "Release Texture2" )); - pCurrent->lpD3DTexture2->Release(); - pCurrent->lpD3DTexture2 = NULL; - } - if ( pCurrent->lpDDS_Video ) - { - DPF(( DBG_TXT_INFO, "Release texture (VID):" )); - pCurrent->lpDDS_Video->Release(); - pCurrent->lpDDS_Video = NULL; - } - if ( pCurrent->lpDDS_System ) - { - DPF(( DBG_TXT_INFO, "Release texture (SYS):" )); - pCurrent->lpDDS_System->Release(); - pCurrent->lpDDS_System = NULL; - } - - /* Pull this texture out of the list. */ - if ( pCurrent == pHAL->pTMList ) - pHAL->pTMList = NULL; - if ( pCurrent->prev ) - (pCurrent->prev)->next = pCurrent->next; - if ( pCurrent->next ) - (pCurrent->next)->prev = pCurrent->prev; - FREE( pCurrent ); - - return TRUE; -} -/*===========================================================================*/ -/* This function is the callback function that gets called when we are doing*/ -/* an enumeration of the texture formats supported by this device. The choice*/ -/* is made by checking to see if we have a match with the supplied D3D pixel-*/ -/* format. So the enumeration has to pass a desired D3D PF as the user var. */ -/*===========================================================================*/ -/* RETURN: D3DENUMRET_OK, D3DENUMRET_CANCEL. */ -/*===========================================================================*/ -static void UpdateTexture( PTM_OBJECT pTMObj, BOOL bVideo, RECT *pRect, UCHAR *pixels ) -{ - LPDIRECTDRAWSURFACE4 lpDDS; - DDSURFACEDESC2 ddsd2; - DWORD srcPitch, - dwHeight, - dwWidth, - dwCol, - dwColor; - UCHAR *pSrc, - *pSrcRow, - *pDest, - *pDestRow; - int rc; - - // TODO: Do I need to pass the h/w when its in the object! - DPF(( DBG_FUNC, "UpdateTexture();" )); - - /* Get the surface pointer we are looking for. */ - lpDDS = (bVideo) ? pTMObj->lpDDS_Video : pTMObj->lpDDS_System; - - /*===================================================================*/ - /* Fill the texture using the PixelInfo structure to do the mapping. */ - /*===================================================================*/ - - /* Get the surface pointer. */ - memset( &ddsd2, 0, sizeof(DDSURFACEDESC2) ); - ddsd2.dwSize = sizeof(DDSURFACEDESC2); - rc = lpDDS->Lock( NULL, &ddsd2, DDLOCK_WAIT, NULL ); - if ( FAILED(rc) ) - { - RIP( NULL, "Lock (TEXTURE/SYSTEM)->", ErrorStringD3D(rc) ); - return; - } - - /* For now we are only updating the system surface so use its dimensions. */ - dwWidth = (bVideo) ? pTMObj->dwVWidth : pTMObj->dwSWidth; - dwHeight = (bVideo) ? pTMObj->dwVHeight : pTMObj->dwSHeight; - - /* If we are updating the whole surface then the pDest/pSrc will */ - /* always be the same. */ - if ( pRect == NULL ) - { - pDest = (UCHAR *)ddsd2.lpSurface; - pSrc = pixels; - } - - /* Fill the texture surface based on the pixelformat flags. */ - if ( pTMObj->dwFlags == (DDPF_RGB | DDPF_ALPHAPIXELS) ) - { - srcPitch = dwWidth * 4; - if ( pRect ) - { - pDest = ((UCHAR *)ddsd2.lpSurface) + (pRect->top * ddsd2.lPitch) + (pRect->left * pTMObj->pixel.cb); - pSrc = pixels + (pRect->top * dwWidth * 4) + (pRect->left * 4); - dwHeight = (pRect->bottom - pRect->top); - dwWidth = (pRect->right - pRect->left); - } - - for( pDestRow = pDest, pSrcRow = pSrc; dwHeight > 0; dwHeight--, pDestRow += ddsd2.lPitch, pSrcRow += srcPitch ) - { - for( dwCol = 0, pDest = pDestRow, pSrc = pSrcRow; dwCol < dwWidth; dwCol++ ) - { - dwColor = ( ((DWORD)(*(pSrc ) * pTMObj->pixel.rScale)) << pTMObj->pixel.rShift ); - dwColor |= ( ((DWORD)(*(pSrc+1) * pTMObj->pixel.gScale)) << pTMObj->pixel.gShift ); - dwColor |= ( ((DWORD)(*(pSrc+2) * pTMObj->pixel.bScale)) << pTMObj->pixel.bShift ); - if ( pTMObj->pixel.aScale == -1.0 ) - dwColor |= ( (*(pSrc+3) & 0x80) ? (1 << pTMObj->pixel.aShift) : 0 ); - else - dwColor |= ( ((DWORD)(*(pSrc+3) * pTMObj->pixel.aScale)) << pTMObj->pixel.aShift ); - memcpy( pDest, &dwColor, pTMObj->pixel.cb ); - pDest += pTMObj->pixel.cb; - pSrc += 4; - } - } - } - else if ( pTMObj->dwFlags == DDPF_RGB ) - { - srcPitch = dwWidth * 3; - if ( pRect ) - { - pDest = ((UCHAR *)ddsd2.lpSurface) + (pRect->top * ddsd2.lPitch) + (pRect->left * pTMObj->pixel.cb); - pSrc = pixels + (pRect->top * dwWidth * 3) + (pRect->left * 3); - dwHeight = (pRect->bottom - pRect->top); - dwWidth = (pRect->right - pRect->left); - } - - for( pDestRow = pDest, pSrcRow = pSrc; dwHeight > 0; dwHeight--, pDestRow += ddsd2.lPitch, pSrcRow += srcPitch ) - { - for( dwCol = 0, pDest = pDestRow, pSrc = pSrcRow; dwCol < dwWidth; dwCol++ ) - { - dwColor = ( ((DWORD)(*(pSrc ) * pTMObj->pixel.rScale)) << pTMObj->pixel.rShift ); - dwColor |= ( ((DWORD)(*(pSrc+1) * pTMObj->pixel.gScale)) << pTMObj->pixel.gShift ); - dwColor |= ( ((DWORD)(*(pSrc+2) * pTMObj->pixel.bScale)) << pTMObj->pixel.bShift ); - memcpy( pDest, &dwColor, pTMObj->pixel.cb ); - pDest += pTMObj->pixel.cb; - pSrc += 3; - } - } - } - else if ( pTMObj->dwFlags == (DDPF_LUMINANCE | DDPF_ALPHAPIXELS) ) - { - srcPitch = dwWidth * 2; - if ( pRect ) - { - pDest = ((UCHAR *)ddsd2.lpSurface) + (pRect->top * ddsd2.lPitch) + (pRect->left * pTMObj->pixel.cb); - pSrc = pixels + (pRect->top * dwWidth * 2) + (pRect->left * 2); - dwHeight = (pRect->bottom - pRect->top); - dwWidth = (pRect->right - pRect->left); - } - - for( pDestRow = pDest, pSrcRow = pSrc; dwHeight > 0; dwHeight--, pDestRow += ddsd2.lPitch, pSrcRow += srcPitch ) - { - for( dwCol = 0, pDest = pDestRow, pSrc = pSrcRow; dwCol < dwWidth; dwCol++ ) - { - dwColor = ( ((DWORD)(*(pSrc ) * pTMObj->pixel.rScale)) << pTMObj->pixel.rShift ); - if ( pTMObj->pixel.aScale == -1.0 ) - dwColor |= ( (*(pSrc+1) & 0x80) ? (1 << pTMObj->pixel.aShift) : 0 ); - else - dwColor |= ( ((DWORD)(*(pSrc+1) * pTMObj->pixel.aScale)) << pTMObj->pixel.aShift ); - memcpy( pDest, &dwColor, pTMObj->pixel.cb ); - pDest += pTMObj->pixel.cb; - pSrc += 2; - } - } - } - else if ( pTMObj->dwFlags == DDPF_LUMINANCE ) - { - srcPitch = dwWidth; - if ( pRect ) - { - pDest = ((UCHAR *)ddsd2.lpSurface) + (pRect->top * ddsd2.lPitch) + (pRect->left * pTMObj->pixel.cb); - pSrc = pixels + (pRect->top * dwWidth) + (pRect->left); - dwHeight = (pRect->bottom - pRect->top); - dwWidth = (pRect->right - pRect->left); - } - - for( pDestRow = pDest, pSrcRow = pSrc; dwHeight > 0; dwHeight--, pDestRow += ddsd2.lPitch, pSrcRow += srcPitch ) - { - for( dwCol = 0, pDest = pDestRow, pSrc = pSrcRow; dwCol < dwWidth; dwCol++ ) - { - dwColor = ( ((DWORD)(*pSrc * pTMObj->pixel.rScale)) << pTMObj->pixel.rShift ); - memcpy( pDest, &dwColor, pTMObj->pixel.cb ); - pDest += pTMObj->pixel.cb; - pSrc++; - } - } - } - else if ( pTMObj->dwFlags == DDPF_ALPHAPIXELS ) - { - srcPitch = dwWidth; - if ( pRect ) - { - pDest = ((UCHAR *)ddsd2.lpSurface) + (pRect->top * ddsd2.lPitch) + (pRect->left * pTMObj->pixel.cb); - pSrc = pixels + (pRect->top * dwWidth) + (pRect->left); - dwHeight = (pRect->bottom - pRect->top); - dwWidth = (pRect->right - pRect->left); - } - - for( pDestRow = pDest, pSrcRow = pSrc; dwHeight > 0; dwHeight--, pDestRow += ddsd2.lPitch, pSrcRow += srcPitch ) - { - for( dwCol = 0, pDest = pDestRow, pSrc = pSrcRow; dwCol < dwWidth; dwCol++ ) - { - if ( pTMObj->pixel.aScale == -1.0 ) - dwColor = ( (*pSrc & 0x80) ? (1 << pTMObj->pixel.aShift) : 0 ); - else - dwColor = ( ((DWORD)(*pSrc * pTMObj->pixel.aScale)) << pTMObj->pixel.aShift ); - memcpy( pDest, &dwColor, pTMObj->pixel.cb ); - pDest += pTMObj->pixel.cb; - pSrc++; - } - } - } - - /* Unlock the surface. */ - rc = lpDDS->Unlock( NULL ); - if ( FAILED(rc) ) - { - RIP( NULL, "Unlock (TEXTURE/SYSTEM)->", ErrorStringD3D(rc) ); - } -} -/*===========================================================================*/ -/* This function is the callback function that gets called when we are doing*/ -/* an enumeration of the texture formats supported by this device. The choice*/ -/* is made by checking to see if we have a match with the supplied D3D pixel-*/ -/* format. So the enumeration has to pass a desired D3D PF as the user var. */ -/*===========================================================================*/ -/* RETURN: D3DENUMRET_OK, D3DENUMRET_CANCEL. */ -/*===========================================================================*/ -HRESULT CALLBACK EnumPFHook( LPDDPIXELFORMAT lpDDPixFmt, LPVOID lpContext ) -{ - LPDDPIXELFORMAT lpDDPixFmtRequest = (LPDDPIXELFORMAT)lpContext; - PIXELINFO pixel; - - DPF(( DBG_FUNC, "EnumPFHook();" )); - - if ( lpDDPixFmt->dwFlags == lpDDPixFmtRequest->dwFlags ) - { - /* Are we looking for an alpha channel? */ - if ( lpDDPixFmtRequest->dwFlags & DDPF_ALPHAPIXELS ) - { - /* Try for something that has more then 1bits of Alpha. */ - Solve8BitChannelPixelFormat( lpDDPixFmt, &pixel ); - if ( pixel.aScale == -1.0 ) - { - /* Save this format no matter what as its a match of sorts. */ - memcpy( lpDDPixFmtRequest, lpDDPixFmt, sizeof(DDPIXELFORMAT) ); - return D3DENUMRET_OK; - } - } - - /* Save this format as its a good match. */ - memcpy( lpDDPixFmtRequest, lpDDPixFmt, sizeof(DDPIXELFORMAT) ); - - /* We are happy at this point so lets leave. */ - return D3DENUMRET_CANCEL; - } - - return D3DENUMRET_OK; -} - - |