|
|
/*==========================================================================;
* * Copyright (C) 1995 Microsoft Corporation. All Rights Reserved. * * File: halbuf.c * Content: Direct3D HAL buffer management *@@BEGIN_MSINTERNAL * * $Id: halbuf.c,v 1.1 1995/11/21 15:12:30 sjl Exp $ * * History: * Date By Reason * ==== == ====== * 06/11/95 stevela Initial rev. * 07/11/95 stevela stuff. * 17/02/96 colinmc Fixed build problem. *@@END_MSINTERNAL * ***************************************************************************/ #include "pch.cpp"
#pragma hdrstop
HRESULT D3DHAL_AllocateBuffer(LPDIRECT3DDEVICEI lpDevI, LPD3DI_BUFFERHANDLE lphBuf, LPD3DEXECUTEBUFFERDESC lpDebDesc, LPDIRECTDRAWSURFACE* lplpBuf) { DDSURFACEDESC ddsd; LPD3DHAL_EXDATA hexData; DWORD dwSize = lpDebDesc->dwBufferSize; HRESULT ddrval;
D3D_INFO(6, "AllocateBuffer, dwhContext = %d, lpDebDesc = %08lx, size = %d", lpDevI->dwhContext, lpDebDesc, lpDebDesc->dwBufferSize);
if ((!lpDebDesc->dwFlags) & D3DDEB_BUFSIZE) { return (DDERR_INVALIDPARAMS); }
D3DMalloc((void**)&hexData, sizeof(D3DHAL_EXDATA)); if (!hexData) { D3D_ERR("Failed to create buffer internal data"); return (D3DERR_EXECUTE_CREATE_FAILED); } memset(hexData, 0, sizeof(D3DHAL_EXDATA));
hexData->debDesc = *lpDebDesc;
/*
* Create the buffer through DirectDraw */ memset(&ddsd, 0, sizeof(DDSURFACEDESC)); ddsd.dwSize = sizeof(DDSURFACEDESC); ddsd.dwFlags = DDSD_WIDTH | DDSD_CAPS; ddsd.dwWidth = hexData->debDesc.dwBufferSize; ddsd.ddsCaps.dwCaps = DDSCAPS_EXECUTEBUFFER; // System memory exebufs only for now
// if (hexData->debDesc.dwCaps & D3DDEBCAPS_VIDEOMEMORY) {
// ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
// } else {
ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; // }
ddrval = lpDevI->lpDD->CreateSurface(&ddsd, &hexData->lpDDS, NULL);
if (ddrval != DD_OK) { D3D_ERR("failed in AllocateBuffer"); D3DFree(hexData); return (D3DERR_EXECUTE_CREATE_FAILED); }
LIST_INSERT_ROOT(&lpDevI->bufferHandles, hexData, link);
*lphBuf = (ULONG_PTR) hexData; *lplpBuf = hexData->lpDDS;
memset(lpDebDesc, 0, sizeof(D3DEXECUTEBUFFERDESC)); lpDebDesc->dwSize = sizeof(D3DEXECUTEBUFFERDESC); lpDebDesc->dwBufferSize = dwSize; if (hexData->debDesc.dwFlags & D3DDEB_CAPS) { lpDebDesc->dwCaps = hexData->debDesc.dwCaps; lpDebDesc->dwCaps &= ~DDSCAPS_VIDEOMEMORY; lpDebDesc->dwCaps |= DDSCAPS_SYSTEMMEMORY; } else lpDebDesc->dwCaps = DDSCAPS_SYSTEMMEMORY; lpDebDesc->dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS;
D3D_INFO(9, "AllocateBuffer, succeeded.");
return (D3D_OK); }
HRESULT D3DHAL_DeallocateBuffer(LPDIRECT3DDEVICEI lpDevI, D3DI_BUFFERHANDLE hBuf) { LPD3DHAL_EXDATA hexData; HRESULT ddrval;
D3D_INFO(6, "DeallocateBuffer, dwhContext = %d, hBuf = %08lx", lpDevI->dwhContext, hBuf);
hexData = (LPD3DHAL_EXDATA) hBuf;
TRY { ddrval = hexData->lpDDS->Release(); if (ddrval != DD_OK) { D3D_ERR("did not free the memory"); return (ddrval); } } EXCEPT (EXCEPTION_EXECUTE_HANDLER) { D3D_INFO(6, "Execute buffer surface was already freed by DirectDraw"); }
LIST_DELETE(hexData, link); D3DFree(hexData);
return (D3D_OK); }
HRESULT D3DHAL_DeallocateBuffers(LPDIRECT3DDEVICEI lpDevI) { while (LIST_FIRST(&lpDevI->bufferHandles)) { D3DHAL_DeallocateBuffer(lpDevI, (D3DI_BUFFERHANDLE) LIST_FIRST(&lpDevI->bufferHandles)); } return (D3D_OK); }
HRESULT D3DHAL_LockBuffer(LPDIRECT3DDEVICEI lpDevI, D3DI_BUFFERHANDLE hBuf, LPD3DEXECUTEBUFFERDESC lpUserDebDesc, LPDIRECTDRAWSURFACE* lplpBuf) { LPD3DHAL_EXDATA hexData; DDSURFACEDESC ddsd; HRESULT ddrval;
D3D_INFO(6, "LockBuffer, dwhContext = %d, hBuf = %08lx", lpDevI->dwhContext, hBuf);
hexData = (LPD3DHAL_EXDATA) hBuf;
#ifdef USE_INTERNAL_LOCK
do { LPDDRAWI_DDRAWSURFACE_INT lpInt; lpInt = (LPDDRAWI_DDRAWSURFACE_INT) hexData->lpDDS; ddrval = DDInternalLock(lpInt->lpLcl, &ddsd.lpSurface); } while (ddrval == DDERR_WASSTILLDRAWING); #else
memset(&ddsd, 0, sizeof(DDSURFACEDESC)); ddsd.dwSize = sizeof(DDSURFACEDESC); do { ddrval = hexData->lpDDS->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL); } while (ddrval == DDERR_WASSTILLDRAWING); #endif
if (ddrval != DD_OK) { D3D_ERR("failed in LockBuffer"); return (D3DERR_EXECUTE_LOCK_FAILED); }
*lplpBuf = hexData->lpDDS; memset(lpUserDebDesc, 0, sizeof(D3DEXECUTEBUFFERDESC)); lpUserDebDesc->dwSize = sizeof(D3DEXECUTEBUFFERDESC); lpUserDebDesc->dwBufferSize = hexData->debDesc.dwBufferSize; lpUserDebDesc->lpData = ddsd.lpSurface; lpUserDebDesc->dwFlags = D3DDEB_LPDATA;
return (D3D_OK); }
HRESULT D3DHAL_UnlockBuffer(LPDIRECT3DDEVICEI lpDevI, D3DI_BUFFERHANDLE hBuf) { LPD3DHAL_EXDATA hexData; HRESULT ddrval;
D3D_INFO(6, "UnlockBuffer, dwhContext = %d, hBuf = %08lx", lpDevI->dwhContext, hBuf);
hexData = (LPD3DHAL_EXDATA) hBuf;
#ifdef USE_INTERNAL_LOCK
{ LPDDRAWI_DDRAWSURFACE_INT lpInt; lpInt = (LPDDRAWI_DDRAWSURFACE_INT) hexData->lpDDS; ddrval = DDInternalUnlock(lpInt->lpLcl); } #else
ddrval = hexData->lpDDS->Unlock(NULL); #endif
if (ddrval != DD_OK) { D3D_ERR("didn't handle handle UnlockBuffer"); return (ddrval); }
return (D3D_OK); }
#ifndef USE_SURFACE_LOCK
HRESULT D3DHAL_LockDibEngine(LPDIRECT3DDEVICEI lpDevI) { #ifndef WIN95
return D3D_OK; #else
HRESULT ret; LPDDRAWI_DIRECTDRAW_GBL pdrv = lpDevI->lpDDGbl; LPWORD pdflags; BOOL isbusy;
pdflags = pdrv->lpwPDeviceFlags; isbusy = 0;
_asm { mov eax, pdflags bts word ptr [eax], BUSY_BIT adc isbusy,0 }
if (isbusy) { D3D_WARN(2, "LOCK_DIBENGINE, dibengine is busy"); ret = DDERR_SURFACEBUSY; } else ret = DD_OK;
return ret; #endif
}
void D3DHAL_UnlockDibEngine(LPDIRECT3DDEVICEI lpDevI) { #ifndef WIN95
return; #else
LPDDRAWI_DIRECTDRAW_GBL pdrv = lpDevI->lpDDGbl; *pdrv->lpwPDeviceFlags &= ~BUSY; #endif
}
#endif
|