windows-nt/Source/XPSP1/NT/multimedia/directx/dxg/d3d8/fw/buffer.cpp

255 lines
6.9 KiB
C++
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
/*==========================================================================;
*
* Copyright (C) 1999-2000 Microsoft Corporation. All Rights Reserved.
*
* File: buffer.cpp
* Content: Implementation of the CBuffer class.
*
*
***************************************************************************/
#include "ddrawpr.h"
#include "buffer.hpp"
#undef DPF_MODNAME
#define DPF_MODNAME "CBuffer::CBuffer"
// Constructor returns an error code
// if the object could not be fully
// constructed
CBuffer::CBuffer(CBaseDevice *pDevice,
DWORD cbLength,
DWORD dwFVF,
D3DFORMAT Format,
D3DRESOURCETYPE Type,
DWORD dwUsage,
DWORD dwActualUsage,
D3DPOOL Pool,
D3DPOOL ActualPool,
REF_TYPE refType,
HRESULT *phr
) :
CResource(pDevice, Pool, refType),
m_pbBuffer(NULL),
#if DBG
m_isLockable((dwActualUsage & (D3DUSAGE_LOCK | D3DUSAGE_LOADONCE)) != 0),
m_SceneStamp(0xFFFFFFFF),
m_TimesLocked(0),
#endif // DBG
m_LockCount(0)
{
// Determine if we need to allocate
// any memory
if (ActualPool == D3DPOOL_SYSTEMMEM ||
IsTypeD3DManaged(pDevice, Type, ActualPool))
{
// cbLength must be a DWORD multiple
cbLength = (cbLength + 3) & (DWORD) ~3;
m_pbBuffer = new BYTE[cbLength];
if (m_pbBuffer == NULL)
{
DPF_ERR("Out Of Memory allocating vertex or index buffer");
*phr = E_OUTOFMEMORY;
return;
}
DXGASSERT((cbLength & 3) == 0);
}
// We need to call the driver
// to get a handle for all cases
// Create a DDSURFACEINFO and CreateSurfaceData object
DDSURFACEINFO SurfInfo;
ZeroMemory(&SurfInfo, sizeof(SurfInfo));
D3D8_CREATESURFACEDATA CreateSurfaceData;
ZeroMemory(&CreateSurfaceData, sizeof(CreateSurfaceData));
// Set up the basic information
CreateSurfaceData.hDD = pDevice->GetHandle();
CreateSurfaceData.pSList = &SurfInfo;
CreateSurfaceData.dwSCnt = 1;
CreateSurfaceData.Type = Type;
CreateSurfaceData.dwUsage = dwActualUsage;
CreateSurfaceData.Pool = DetermineCreationPool(Device(), Type, dwActualUsage, ActualPool);
CreateSurfaceData.Format = Format;
CreateSurfaceData.MultiSampleType = D3DMULTISAMPLE_NONE;
CreateSurfaceData.dwFVF = dwFVF;
if (Pool == D3DPOOL_DEFAULT &&
CreateSurfaceData.Pool == D3DPOOL_SYSTEMMEM)
{
// If we are using sys-mem in cases where the
// user asked for POOL_DEFAULT, we need to let
// the thunk layer know so that Reset will
// fail if this buffer hasn't been released
CreateSurfaceData.bTreatAsVidMem = TRUE;
}
// Specify the surface data
SurfInfo.cpWidth = cbLength;
SurfInfo.cpHeight = 1;
SurfInfo.pbPixels = m_pbBuffer;
SurfInfo.iPitch = cbLength;
// Call thunk to get our handles
*phr = pDevice->GetHalCallbacks()->CreateSurface(&CreateSurfaceData);
if (FAILED(*phr))
return;
// Cache away our handle
SetKernelHandle(SurfInfo.hKernelHandle);
return;
} // CBuffer::CBuffer
#undef DPF_MODNAME
#define DPF_MODNAME "CBuffer::~CBuffer"
// Destructor
CBuffer::~CBuffer()
{
// Tell the thunk layer that we need to
// be freed.
if (CBaseObject::BaseKernelHandle())
{
D3D8_DESTROYSURFACEDATA DestroySurfData;
DestroySurfData.hDD = Device()->GetHandle();
DestroySurfData.hSurface = CBaseObject::BaseKernelHandle();
Device()->GetHalCallbacks()->DestroySurface(&DestroySurfData);
}
delete [] m_pbBuffer;
} // CBuffer::~CBuffer
#undef DPF_MODNAME
#define DPF_MODNAME "CBuffer::OnBufferChangeImpl"
void CBuffer::OnBufferChangeImpl(UINT cbOffsetToLock, UINT cbSizeToLock)
{
// 0 for cbSizeToLock; means the rest of the buffer
// We use this as a special value.
DWORD cbOffsetMax;
if (cbSizeToLock == 0)
cbOffsetMax = 0;
else
cbOffsetMax = cbOffsetToLock + cbSizeToLock;
if (!IsDirty())
{
m_cbDirtyMin = cbOffsetToLock;
m_cbDirtyMax = cbOffsetMax;
OnResourceDirty();
}
else
{
if (m_cbDirtyMin > cbOffsetToLock)
m_cbDirtyMin = cbOffsetToLock;
// An cbOffsetMax of zero means all the way to the
// end of the buffer
if (m_cbDirtyMax < cbOffsetMax || cbOffsetMax == 0)
m_cbDirtyMax = cbOffsetMax;
// We should already be marked as dirty
DXGASSERT(IsDirty());
}
return;
} // OnBufferChangeImpl
#undef DPF_MODNAME
#define DPF_MODNAME "CBuffer::MarkAllDirty"
void CBuffer::MarkAllDirty()
{
// Mark our dirty bounds as being the whole
// thing.
m_cbDirtyMin = 0;
// Zero for max is a special value meaning
// all they way to the end
m_cbDirtyMax = 0;
// Mark ourselves as dirty
OnResourceDirty();
} // CBuffer::MarkAllDirty
// Methods for CCommandBuffer
#undef DPF_MODNAME
#define DPF_MODNAME "CCommandBuffer::Create"
// Static class function for creating a command buffer object.
// (Because it is static; it doesn't have a this pointer.)
// Creation function for Command Buffers
HRESULT CCommandBuffer::Create(CBaseDevice *pDevice,
DWORD cbLength,
D3DPOOL Pool,
CCommandBuffer **ppCmdBuffer)
{
HRESULT hr;
// Zero-out return parameter
*ppCmdBuffer = NULL;
// Allocate new buffer
CCommandBuffer *pCmdBuffer;
DXGASSERT(Pool == D3DPOOL_SYSTEMMEM);
pCmdBuffer = new CCommandBuffer(pDevice,
cbLength,
Pool,
&hr);
if (pCmdBuffer == NULL)
{
DPF_ERR("Out of Memory creating command buffer");
return E_OUTOFMEMORY;
}
if (FAILED(hr))
{
// Command buffers are always internal and hence
// need to be released through DecrementUseCount
DPF_ERR("Error during initialization of command buffer");
pCmdBuffer->DecrementUseCount();
return hr;
}
// We're done; just return the object
*ppCmdBuffer = pCmdBuffer;
return hr;
} // static CCommandBuffer::Create
#undef DPF_MODNAME
#define DPF_MODNAME "CCommandBuffer::Clone"
HRESULT CCommandBuffer::Clone(D3DPOOL Pool,
CResource **ppResource) const
{
HRESULT hr;
*ppResource = new CCommandBuffer(Device(), m_cbLength, Pool, &hr);
if (*ppResource == NULL)
{
DPF_ERR("Failed to allocate command buffer");
return E_OUTOFMEMORY;
}
if (FAILED(hr))
{
DPF_ERR("Failure creating command buffer");
}
return hr;
} // CCommandBuffer::Clone
// End of file : buffer.cpp