Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

295 lines
7.7 KiB

/*==========================================================================;
*
* Copyright (C) 1995 Microsoft Corporation. All Rights Reserved.
*
* File: d3dmem.c
* Content: Direct3D mem allocation
*@@BEGIN_MSINTERNAL
*
* History:
* Date By Reason
* ==== == ======
* 10/12/95 stevela Initial rev with this header.
*@@END_MSINTERNAL
*
***************************************************************************/
#include "pch.cpp"
#pragma hdrstop
static D3DMALLOCFUNCTION malloc_function = (D3DMALLOCFUNCTION) MemAlloc;
static D3DREALLOCFUNCTION realloc_function = (D3DREALLOCFUNCTION) MemReAlloc;
static D3DFREEFUNCTION free_function = MemFree;
#undef DPF_MODNAME
#define DPF_MODNAME "D3DMalloc"
HRESULT D3DAPI D3DMalloc(LPVOID* p_return, size_t size)
{
void* p;
if (!VALID_OUTPTR(p_return)) {
D3D_ERR("Bad pointer given");
return DDERR_OUTOFMEMORY;
}
if (size > 0) {
p = malloc_function(size);
if (p == NULL)
return (DDERR_OUTOFMEMORY);
} else {
p = NULL;
}
*p_return = p;
return (D3D_OK);
}
#undef DPF_MODNAME
#define DPF_MODNAME "D3DRealloc"
HRESULT D3DAPI D3DRealloc(LPVOID* p_inout, size_t size)
{
void* p = *p_inout;
HRESULT err = D3D_OK;
if (!VALID_OUTPTR(p_inout))
{
D3D_ERR("Bad pointer given");
return DDERR_OUTOFMEMORY;
}
if (size > 0)
{
if (p)
{
p = realloc_function(p, size);
if (p == NULL)
return (DDERR_OUTOFMEMORY);
}
else
return D3DMalloc(p_inout, size);
}
else
if (size == 0)
{
D3DFree(p);
p = NULL;
}
else
return (DDERR_INVALIDPARAMS);
*p_inout = p;
return (err);
}
#undef DPF_MODNAME
#define DPF_MODNAME "D3DFree"
VOID D3DAPI D3DFree(LPVOID p)
{
if (p == NULL) return;
if (!VALID_DWORD_PTR(p)) {
D3D_ERR("invalid pointer");
return;
}
if (p) {
free_function(p);
}
}
#define CACHE_LINE 32
HRESULT MallocAligned(void** p_return, size_t size)
{
char* p;
size_t offset;
HRESULT error;
if (!p_return)
return DDERR_INVALIDPARAMS;
if (size > 0) {
if ((error = D3DMalloc((void**) &p, size + CACHE_LINE)) != DD_OK)
{
*p_return = NULL;
return error;
}
offset = CACHE_LINE - (DWORD)((ULONG_PTR)p & (CACHE_LINE - 1));
p += offset;
((size_t*)p)[-1] = offset;
} else
p = NULL;
*p_return = p;
return DD_OK;
}
void FreeAligned(void* p)
{
if (p) {
size_t offset = ((size_t*)p)[-1];
p = (void*) ((unsigned char*)p - offset);
D3DFree(p);
}
}
HRESULT ReallocAligned(void** p_inout, size_t size)
{
char* p = (char*)*p_inout;
HRESULT error;
if (!p_inout)
return DDERR_INVALIDPARAMS;
if (size > 0) {
if (p) {
size_t old_offset = ((size_t*)p)[-1];
size_t new_offset;
p -= old_offset;
if ((error = D3DRealloc((void**) &p, size + CACHE_LINE)) != DD_OK)
return error;
new_offset = CACHE_LINE - (DWORD)((ULONG_PTR)p & (CACHE_LINE - 1));
if (old_offset != new_offset)
memmove(p + new_offset, p + old_offset, size);
p += new_offset;
((size_t*)p)[-1] = new_offset;
} else
return MallocAligned(p_inout, size);
} else if (size == 0) {
FreeAligned(p);
p = NULL;
} else
return DDERR_INVALIDPARAMS;
*p_inout = p;
return DD_OK;
}
//----------------------------------------------------------------------------
// Growing aligned buffer implementation.
//
HRESULT CAlignedBuffer32::Grow(DWORD growSize)
{
if (allocatedBuf)
D3DFree(allocatedBuf);
size = growSize;
if (D3DMalloc(&allocatedBuf, size + 31) != DD_OK)
{
allocatedBuf = 0;
alignedBuf = 0;
size = 0;
return DDERR_OUTOFMEMORY;
}
alignedBuf = (LPVOID)(((ULONG_PTR)allocatedBuf + 31 ) & ~31);
return D3D_OK;
}
#undef DPF_MODNAME
#define DPF_MODNAME "CBufferDDS::Grow"
//----------------------------------------------------------------------
// Growing buffer using DDS implementation.
//
HRESULT CBufferDDS::Grow(LPDIRECT3DDEVICEI lpDevI, DWORD growSize)
{
DWORD dwRefCnt = 1;
if (growSize <= size)
return D3D_OK;
if (allocatedBuf)
{
// Save reference count before deleting
dwRefCnt = allocatedBuf->AddRef() - 1;
// Release till gone!
while (allocatedBuf->Release());
}
size = growSize;
DDSURFACEDESC2 ddsd;
memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
ddsd.dwSize = sizeof(DDSURFACEDESC2);
ddsd.dwFlags = DDSD_WIDTH | DDSD_CAPS;
ddsd.dwWidth = size + 31;
ddsd.ddsCaps.dwCaps = DDSCAPS_EXECUTEBUFFER | DDSCAPS_SYSTEMMEMORY;
LPDIRECTDRAWSURFACE4 lpDDS4;
HRESULT ret = lpDevI->lpDirect3DI->lpDD4->CreateSurface(&ddsd, &lpDDS4, NULL);
if (ret != DD_OK)
{
D3D_ERR("Failed to allocate Vertex Buffer");
size = 0;
return ret;
}
ret = lpDDS4->QueryInterface(IID_IDirectDrawSurface, (LPVOID*)&allocatedBuf);
if (ret != DD_OK)
{
D3D_ERR("failed to QI for DDS1");
allocatedBuf = 0;
size = 0;
return ret;
}
ret = lpDDS4->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_NOSYSLOCK, NULL);
if (ret != DD_OK)
{
D3D_ERR("Could not lock system memory Vertex Buffer.");
allocatedBuf = 0;
size = 0;
return ret;
}
lpDDS4->Release();
alignedBuf = ddsd.lpSurface;
// Restore reference count
while (--dwRefCnt)
allocatedBuf->AddRef();
return D3D_OK;
}
//----------------------------------------------------------------------
// Growing aligned vertex buffer implementation.
//
HRESULT CBufferVB::Grow(LPDIRECT3DDEVICEI lpDevI, DWORD growSize)
{
D3DVERTEXBUFFERDESC vbdesc = {sizeof(D3DVERTEXBUFFERDESC), 0, D3DFVF_TLVERTEX, 0};
DWORD dwRefCnt = 1;
// Note the assumption that base is not zero only for DP2 HAL
if (IS_DP2HAL_DEVICE(lpDevI))
{
CDirect3DDeviceIDP2 *dev = static_cast<CDirect3DDeviceIDP2*>(lpDevI);
HRESULT ret;
ret = dev->FlushStates(growSize);
if (ret != D3D_OK)
{
D3D_ERR("Error trying to render batched commands in CBufferVB::Grow");
return ret;
}
base = 0;
}
if (growSize <= size)
return D3D_OK;
if (allocatedBuf)
{
if (IS_DP2HAL_DEVICE(lpDevI))
{
CDirect3DDeviceIDP2 &dev = *static_cast<CDirect3DDeviceIDP2*>(lpDevI);
if (dev.lpDP2CurrBatchVBI == allocatedBuf)
{
dev.lpDP2CurrBatchVBI->Release();
dev.lpDP2CurrBatchVBI = NULL;
}
}
// Save reference count before deleting
dwRefCnt = allocatedBuf->AddRef() - 1;
// Release till gone!
while (allocatedBuf->Release());
}
vbdesc.dwNumVertices = (growSize + 31) / sizeof(D3DTLVERTEX);
size = vbdesc.dwNumVertices * sizeof(D3DTLVERTEX);
if (!IS_DP2HAL_DEVICE(lpDevI) || !IS_HW_DEVICE(lpDevI))
{
vbdesc.dwCaps = D3DVBCAPS_SYSTEMMEMORY;
}
if (lpDevI->lpDirect3DI->CreateVertexBufferI(&vbdesc, &allocatedBuf, D3DDP_DONOTCLIP | D3DVBFLAGS_CREATEMULTIBUFFER) != DD_OK)
{
allocatedBuf = 0;
size = 0;
return DDERR_OUTOFMEMORY;
}
// Restore reference count
while (--dwRefCnt)
allocatedBuf->AddRef();
allocatedBuf->Lock(DDLOCK_WAIT, &alignedBuf, NULL);
return D3D_OK;
}