|
|
/*==========================================================================;
* * 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
|