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.
 
 
 
 
 
 

814 lines
27 KiB

/*==========================================================================;
*
* Copyright (C) 1997 Microsoft Corporation. All Rights Reserved.
*
* File: beginend.c
* Content: Begin/End implementation
*
***************************************************************************/
#include "pch.cpp"
#pragma hdrstop
#include "drawprim.hpp"
#include "d3dfei.h"
// This should be moved with other DP flags so that no one uses this bit
#define __NON_FVF_INPUT 0x80000000
//---------------------------------------------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "MoveData"
_inline void MoveData(LPVOID lpData, DWORD destOffset, DWORD srcOffset,
DWORD size)
{
memcpy((char*)lpData + destOffset, (char*)lpData + srcOffset, size);
}
//---------------------------------------------------------------------
void CleanupBeginEnd(LPDIRECT3DDEVICEI lpDevI)
{
lpDevI->lpVertexIndices = NULL;
lpDevI->lpvVertexData = NULL;
lpDevI->dwBENumVertices = 0;
lpDevI->dwBENumIndices = 0;
lpDevI->dwHintFlags &= ~D3DDEVBOOL_HINTFLAGS_INBEGIN_ALL;
}
//---------------------------------------------------------------------
HRESULT
DoFlushBeginEnd(LPDIRECT3DDEVICEI lpDevI)
{
HRESULT ret;
lpDevI->lpwIndices = NULL;
lpDevI->dwNumIndices = 0;
lpDevI->lpClipFlags = (D3DFE_CLIPCODE*)lpDevI->HVbuf.GetAddress();
lpDevI->position.lpvData = lpDevI->lpvVertexData;
ret = lpDevI->ProcessPrimitive();
return ret;
}
//---------------------------------------------------------------------
__inline void Dereference(LPDIRECT3DDEVICEI lpDevI, DWORD indexStart, DWORD numVer)
{
char *dst_vptr = (char*)lpDevI->lpvVertexBatch;
char *src_vptr = (char*)lpDevI->lpvVertexData;
WORD *iptr = &lpDevI->lpVertexIndices[indexStart];
DWORD size = lpDevI->position.dwStride;
for (DWORD i=0; i < numVer; i++)
{
memcpy(dst_vptr, &src_vptr[iptr[i]*size], size);
dst_vptr += size;
}
}
//---------------------------------------------------------------------
HRESULT
DoFlushBeginIndexedEnd(LPDIRECT3DDEVICEI lpDevI)
{
HRESULT ret;
DWORD i;
static BOOL offScreen; // all vertices are off screen
lpDevI->dwNumVertices = lpDevI->dwBENumVertices;
lpDevI->lpwIndices = lpDevI->lpVertexIndices;
lpDevI->lpClipFlags = (D3DFE_CLIPCODE*)lpDevI->HVbuf.GetAddress();
lpDevI->position.lpvData = lpDevI->lpvVertexData;
if ( (lpDevI->dwHintFlags & D3DDEVBOOL_HINTFLAGS_INBEGIN) &&
(!(lpDevI->dwHintFlags & D3DDEVBOOL_HINTFLAGS_INBEGIN_FIRST_FLUSH)) )
{ // if this is the first flush
lpDevI->dwHintFlags |= D3DDEVBOOL_HINTFLAGS_INBEGIN_FIRST_FLUSH;
offScreen = 0;
if (lpDevI->dwBENumIndices < lpDevI->dwMaxIndexCount)
{ // single flush case
/*
If the user is using a large vertex array for relatively few prims
we need to dereference the indexed prims into another array. Otherwise
we waste too much time transforming and lighting vertices that we never use.
Since BeginIndexed requires that the user pass in an array of vertices we
know that this->lpvVertexBatch is not being used. So derefernce into it.
We know it's there because the index space gets created at the same time.
Also note that since the max size fo the index array is bigger than
the vertex array we may have to do this in several small batches.
*/
if (!FVF_TRANSFORMED(lpDevI->dwVIDIn))
{
if (lpDevI->dwBENumIndices*INDEX_BATCH_SCALE < lpDevI->dwBENumVertices)
{
WORD *iptr;
DWORD indexStart = 0;
DWORD numPrims;
DWORD numIndices = lpDevI->dwBENumIndices;
switch (lpDevI->primType)
{
case D3DPT_LINELIST :
{
do
{
numPrims = min(numIndices/2, lpDevI->dwMaxVertexCount/2);
DWORD numVer = numPrims << 1;
Dereference(lpDevI, indexStart, numVer);
lpDevI->dwNumVertices = numVer;
lpDevI->dwNumPrimitives = numPrims;
lpDevI->position.lpvData = lpDevI->lpvVertexBatch;
ret = lpDevI->ProcessPrimitive();
if (ret != D3D_OK)
{
return ret;
}
indexStart += numVer;
numIndices -= numVer;
} while (numIndices > 1);
break;
}
case D3DPT_LINESTRIP :
do
{
numPrims = min(numIndices-1, lpDevI->dwMaxVertexCount-1);
DWORD numVer = numPrims + 1;
Dereference(lpDevI, indexStart, numVer);
lpDevI->dwNumVertices = numPrims+1;
lpDevI->dwNumPrimitives = numPrims;
lpDevI->position.lpvData = lpDevI->lpvVertexBatch;
ret = lpDevI->ProcessPrimitive();
if (ret != D3D_OK)
{
return ret;
}
indexStart += numPrims;
numIndices -= numPrims;
} while (numIndices > 1);
break;
case D3DPT_TRIANGLELIST :
do
{
numPrims = min(numIndices/3, lpDevI->dwMaxVertexCount/3);
DWORD numVer = numPrims*3;
Dereference(lpDevI, indexStart, numVer);
lpDevI->dwNumVertices = numVer;
lpDevI->dwNumPrimitives = numPrims;
lpDevI->position.lpvData = lpDevI->lpvVertexBatch;
ret = lpDevI->ProcessPrimitive();
if (ret != D3D_OK)
{
return ret;
}
indexStart += numVer;
numIndices -= numVer;
} while (numIndices > 2);
break;
case D3DPT_TRIANGLESTRIP :
do
{
numPrims = min(numIndices-2, lpDevI->dwMaxVertexCount-2);
DWORD numVer = numPrims + 2;
Dereference(lpDevI, indexStart, numVer);
lpDevI->dwNumVertices = numVer;
lpDevI->dwNumPrimitives = numPrims;
lpDevI->position.lpvData = lpDevI->lpvVertexBatch;
ret = lpDevI->ProcessPrimitive();
if (ret != D3D_OK)
{
return ret;
}
indexStart += numPrims;
numIndices -= numPrims;
} while (numIndices > 2);
break;
case D3DPT_TRIANGLEFAN :
// lock in center of fan
char *tmp = (char*)lpDevI->lpvVertexBatch;
char *src = (char*)lpDevI->lpvVertexData;
DWORD size = lpDevI->position.dwStride;
memcpy(lpDevI->lpvVertexBatch,
&src[lpDevI->lpVertexIndices[0]*size], size);
lpDevI->lpvVertexBatch = tmp + size;
indexStart = 1;
do
{
numPrims = min(numIndices-2, lpDevI->dwMaxVertexCount-2);
Dereference(lpDevI, indexStart, numPrims + 1);
lpDevI->dwNumVertices = numPrims+2;
lpDevI->dwNumPrimitives = numPrims;
lpDevI->position.lpvData = tmp;
ret = lpDevI->ProcessPrimitive();
if (ret != D3D_OK)
{
return ret;
}
indexStart += numPrims;
numIndices -= numPrims;
} while (numIndices > 2);
lpDevI->lpvVertexBatch = tmp; // Restore
break;
} // end of prim type switch
return D3D_OK;
}
// else fall through to the no batching case
}
// no batching case
ret = lpDevI->ProcessPrimitive(__PROCPRIMOP_INDEXEDPRIM);
return ret;
}
else
{
// this is the first of n possible batches so t&l all vertices just once
ret = lpDevI->ProcessPrimitive(__PROCPRIMOP_PROCVERONLY);
if (ret != D3D_OK)
{
return ret;
}
// This flag is cleared in CleanupBeginEnd
lpDevI->dwHintFlags |= D3DDEVBOOL_HINTFLAGS_INBEGIN_BIG_PRIM;
if (lpDevI->dwClipIntersection)
{
// all vertices are off screen so we can just bail
offScreen = 1; // so we can early out next flush
return D3D_OK;
}
}
} // end if if first flush
// for secondary flushes don't bother to draw if we don't need to
if (!offScreen)
ret = DoDrawIndexedPrimitive(lpDevI);
return ret;
} // end of DoFlushBeginIndexedEnd()
//---------------------------------------------------------------------
// Computes the number of primitives
// Input: lpDevI->primType
// dwNumVertices
// Output: lpDevI->dwNumPrimitives
// lpDevI->D3DStats
// return value = "Real" number of vertices (indices)
#undef DPF_MODNAME
#define DPF_MODNAME "GetNumPrimBE"
inline DWORD GetNumPrimBE(LPDIRECT3DDEVICEI lpDevI, DWORD dwNumVertices)
{
lpDevI->dwNumPrimitives = 0;
switch (lpDevI->primType)
{
case D3DPT_POINTLIST:
lpDevI->D3DStats.dwPointsDrawn += dwNumVertices;
lpDevI->dwNumPrimitives = dwNumVertices;
return dwNumVertices;
case D3DPT_LINELIST:
lpDevI->dwNumPrimitives = dwNumVertices >> 1;
lpDevI->D3DStats.dwLinesDrawn += lpDevI->dwNumPrimitives;
return lpDevI->dwNumPrimitives << 1;
case D3DPT_LINESTRIP:
if (dwNumVertices < 2)
return 0;
lpDevI->dwNumPrimitives = dwNumVertices - 1;
lpDevI->D3DStats.dwLinesDrawn += lpDevI->dwNumPrimitives;
return dwNumVertices;
case D3DPT_TRIANGLEFAN:
case D3DPT_TRIANGLESTRIP:
if (dwNumVertices < 3)
return 0;
lpDevI->dwNumPrimitives = dwNumVertices - 2;
lpDevI->D3DStats.dwTrianglesDrawn += lpDevI->dwNumPrimitives;
return dwNumVertices;
case D3DPT_TRIANGLELIST:
lpDevI->dwNumPrimitives = dwNumVertices / 3;
lpDevI->D3DStats.dwTrianglesDrawn += lpDevI->dwNumPrimitives;
return lpDevI->dwNumPrimitives * 3;
}
return 0;
}
//---------------------------------------------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "BeginEnd"
HRESULT FlushBeginEndBatch(LPDIRECT3DDEVICEI lpDevI, BOOL leaving)
{
HRESULT ret;
#ifdef _X86_
unsigned short fpsave, fptemp;
#endif
if (lpDevI->dwBENumIndices == 0xFFFFFFFF)
lpDevI->dwNumVertices = GetNumPrimBE(lpDevI, lpDevI->dwBENumVertices);
else
lpDevI->dwNumIndices = GetNumPrimBE(lpDevI, lpDevI->dwBENumIndices);
if (lpDevI->dwNumPrimitives < 1)
{
return DDERR_INVALIDPARAMS;
}
ret = (*lpDevI->pfnDoFlushBeginEnd)(lpDevI);
/*
* ReInit the device Begin/End states
*/
if (!leaving)
/*
* Figure out how many and which vertices to keep for next batch.
*/
{
DWORD *dataCountPtr;
DWORD vertexSize; // size in bytes
DWORD offset; // start offset
lpDevI->wFlushed = TRUE;
if (lpDevI->lpVertexIndices)
{
dataCountPtr = &(lpDevI->dwBENumIndices);
lpDevI->lpcCurrentPtr = (char*)lpDevI->lpVertexIndices;
vertexSize = 2;
offset = lpDevI->dwBENumIndices * 2;
}
else
{
dataCountPtr = &(lpDevI->dwBENumVertices);
lpDevI->lpcCurrentPtr = (char*)lpDevI->lpvVertexData;
vertexSize = lpDevI->position.dwStride;
offset = lpDevI->dwBENumVertices * lpDevI->position.dwStride;
}
switch (lpDevI->primType)
{
case D3DPT_LINELIST:
if (*dataCountPtr & 1)
{
MoveData(lpDevI->lpcCurrentPtr, 0, offset - vertexSize,
vertexSize);
*dataCountPtr = 1;
lpDevI->lpcCurrentPtr += vertexSize;
} else
*dataCountPtr = 0;
break;
case D3DPT_LINESTRIP:
MoveData(lpDevI->lpcCurrentPtr, 0, offset - vertexSize, vertexSize);
*dataCountPtr = 1;
lpDevI->lpcCurrentPtr += vertexSize;
break;
case D3DPT_TRIANGLEFAN:
MoveData(lpDevI->lpcCurrentPtr, vertexSize, offset - vertexSize,
vertexSize);
*dataCountPtr = 2;
lpDevI->lpcCurrentPtr += (vertexSize << 1);
break;
case D3DPT_TRIANGLESTRIP:
{
DWORD size = vertexSize << 1;
MoveData(lpDevI->lpcCurrentPtr, 0, offset - size, size);
*dataCountPtr = 2;
lpDevI->lpcCurrentPtr += size;
break;
}
case D3DPT_POINTLIST:
*dataCountPtr = 0;
break;
case D3DPT_TRIANGLELIST:
{
DWORD rem = (*dataCountPtr % 3);
if ( rem != 0 )
{
DWORD size = rem * vertexSize;
MoveData(lpDevI->lpcCurrentPtr, 0, offset - size, size);
}
*dataCountPtr = rem;
lpDevI->lpcCurrentPtr += rem * vertexSize;
}
break;
default:
D3D_ERR( "Unknown or unsupported primitive type requested in BeginEnd" );
ret = D3DERR_INVALIDPRIMITIVETYPE;
}
}
return ret;
}
//---------------------------------------------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "CheckBegin"
HRESULT CheckBegin(LPDIRECT3DDEVICEI lpDevI,
D3DPRIMITIVETYPE ptPrimitiveType,
DWORD dwVertexType,
DWORD dwFlags)
{
lpDevI->dwFlags = 0;
#if DBG
switch (ptPrimitiveType)
{
case D3DPT_POINTLIST:
case D3DPT_LINELIST:
case D3DPT_LINESTRIP:
case D3DPT_TRIANGLELIST:
case D3DPT_TRIANGLESTRIP:
case D3DPT_TRIANGLEFAN:
break;
default:
D3D_ERR( "Invalid primitive type given to Begin" );
return DDERR_INVALIDPARAMS;
}
if (dwFlags & __NON_FVF_INPUT)
{
switch ((D3DVERTEXTYPE)dwVertexType)
{
case D3DVT_TLVERTEX:
case D3DVT_LVERTEX:
case D3DVT_VERTEX:
break;
default:
D3D_ERR( "Invalid vertex type given to Begin" );
return DDERR_INVALIDPARAMS;
}
if (!IsDPFlagsValid(dwFlags & ~__NON_FVF_INPUT))
return DDERR_INVALIDPARAMS;
lpDevI->dwVIDIn = d3dVertexToFVF[dwVertexType];
dwFlags &= ~__NON_FVF_INPUT;
}
else
{
if (ValidateFVF(dwVertexType) != D3D_OK)
return DDERR_INVALIDPARAMS;
lpDevI->dwVIDIn = dwVertexType;
}
/*
* validate parms
*/
TRY
{
if (!VALID_DIRECT3DDEVICE3_PTR(lpDevI))
{
D3D_ERR( "Invalid Direct3DDevice pointer" );
return DDERR_INVALIDOBJECT;
}
}
EXCEPT( EXCEPTION_EXECUTE_HANDLER )
{
D3D_ERR( "Exception encountered validating parameters" );
return DDERR_INVALIDPARAMS;
}
#else
lpDevI->dwVIDIn = dwVertexType;
#endif
HRESULT err = CheckDeviceSettings(lpDevI);
if (err != D3D_OK)
return err;
err = CheckVertexBatch(lpDevI);
if (err != D3D_OK)
return err;
// acts as boolean
lpDevI->dwHintFlags |= D3DDEVBOOL_HINTFLAGS_INBEGIN;
// indicates first flush
lpDevI->dwHintFlags &= ~D3DDEVBOOL_HINTFLAGS_INBEGIN_FIRST_FLUSH;
lpDevI->primType = ptPrimitiveType;
lpDevI->position.dwStride = GetVertexSizeFVF(lpDevI->dwVIDIn);
lpDevI->dwBENumVertices = 0;
ComputeOutputFVF(lpDevI);
// dwMaxVertexCount should be even to properly break a primitive when
// flushing
lpDevI->dwMaxVertexCount = (BEGIN_DATA_BLOCK_MEM_SIZE /
lpDevI->position.dwStride) & ~1;
lpDevI->dwMaxIndexCount = BEGIN_DATA_BLOCK_SIZE * 16;
lpDevI->dwBENumIndices = 0;
lpDevI->lpvVertexData = NULL;
lpDevI->lpVertexIndices = NULL;
lpDevI->dwFlags |= dwFlags;
lpDevI->wFlushed = FALSE;
if (lpDevI->dwVIDIn & D3DFVF_NORMAL)
lpDevI->dwFlags |= D3DPV_LIGHTING;
return D3D_OK;
}
//*********************************************************************
// API calls
//*********************************************************************
#undef DPF_MODNAME
#define DPF_MODNAME "Begin"
HRESULT D3DAPI
DIRECT3DDEVICEI::Begin(D3DPRIMITIVETYPE ptPrimitiveType,
DWORD dwVertexType,
DWORD dwFlags)
{
HRESULT ret;
CLockD3DMT lockObject(this, DPF_MODNAME, REMIND("")); // Takes D3D lock (MT only).
// Release in the destructor
/*
* Check/validate parameters, initialize related fields in the device.
*/
if ((ret = CheckBegin(this, ptPrimitiveType, dwVertexType, dwFlags)) != D3D_OK)
{
return ret;
}
Profile(PROF_BEGIN,ptPrimitiveType,dwVertexType);
this->dwBENumIndices = 0xffffffff; // mark as being in Begin rather
// than BeginIndexed
lpvVertexData = lpvVertexBatch;
lpcCurrentPtr = (char*)lpvVertexBatch;
pfnDoFlushBeginEnd = DoFlushBeginEnd;
if ( IS_MT_DEVICE(this) )
EnterCriticalSection(&BeginEndCSect);
return D3D_OK;
}
//---------------------------------------------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "BeginIndexed"
HRESULT D3DAPI
DIRECT3DDEVICEI::BeginIndexed(D3DPRIMITIVETYPE ptPrimitiveType,
DWORD vtVertexType,
LPVOID lpvVertices,
DWORD dwNumVertices,
DWORD dwFlags)
{
HRESULT ret;
CLockD3DMT lockObject(this, DPF_MODNAME, REMIND("")); // Takes D3D lock (MT only).
// Release in the destructor
#if DBG
if (ptPrimitiveType == D3DPT_POINTLIST)
{
D3D_ERR( "BeginIndexed does not support D3DPT_POINTLIST" );
return DDERR_INVALIDPARAMS;
}
/*
* validate lpvVertices & dwNumVertices
*/
if ( dwNumVertices > 65535ul )
{
D3D_ERR( "BeginIndexed vertex array > 64K" );
return DDERR_INVALIDPARAMS;
}
if ( dwNumVertices == 0ul )
{
D3D_ERR( "Number of vertices for BeginIndexed is zero" );
return DDERR_INVALIDPARAMS;
}
TRY
{
if (!VALID_PTR(lpvVertices, sizeof(D3DVERTEX)*dwNumVertices))
{
D3D_ERR( "Invalid vertex pointer" );
return DDERR_INVALIDPARAMS;
}
}
EXCEPT( EXCEPTION_EXECUTE_HANDLER )
{
D3D_ERR( "Exception encountered validating parameters" );
return DDERR_INVALIDPARAMS;
}
#endif
/*
* Check/validate parameters, initialize related fields in the device.
*/
if ((ret = CheckBegin(this, ptPrimitiveType, vtVertexType, dwFlags)) != D3D_OK)
return ret;
Profile(PROF_BEGININDEXED,ptPrimitiveType,vtVertexType);
this->dwBENumVertices = dwNumVertices;
this->lpvVertexData = lpvVertices;
this->pfnDoFlushBeginEnd = DoFlushBeginIndexedEnd;
this->lpVertexIndices = this->lpIndexBatch;
this->lpcCurrentPtr = (char*)this->lpIndexBatch;
if ( IS_MT_DEVICE(this) )
EnterCriticalSection(&this->BeginEndCSect);
return D3D_OK;
}
//---------------------------------------------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "Begin(D3DVERTEXTYPE)"
HRESULT D3DAPI
DIRECT3DDEVICEI::Begin(D3DPRIMITIVETYPE ptPrimitiveType,
D3DVERTEXTYPE vertexType,
DWORD dwFlags)
{
#if DBG
dwFlags |= __NON_FVF_INPUT;
return Begin(ptPrimitiveType, (DWORD)vertexType, dwFlags);
#else
return Begin(ptPrimitiveType, (DWORD)d3dVertexToFVF[vertexType], dwFlags);
#endif
}
//---------------------------------------------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "BeginIndexed(D3DVERTEXTYPE)"
HRESULT D3DAPI
DIRECT3DDEVICEI::BeginIndexed(D3DPRIMITIVETYPE ptPrimitiveType,
D3DVERTEXTYPE vertexType,
LPVOID lpvVertices,
DWORD dwNumVertices,
DWORD dwFlags)
{
#if DBG
dwFlags |= __NON_FVF_INPUT;
return BeginIndexed(ptPrimitiveType, (DWORD) vertexType, lpvVertices,
dwNumVertices, dwFlags);
#else
return BeginIndexed(ptPrimitiveType, (DWORD) d3dVertexToFVF[vertexType], lpvVertices,
dwNumVertices, dwFlags);
#endif
}
//---------------------------------------------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "Vertex"
HRESULT D3DAPI
DIRECT3DDEVICEI::Vertex(LPVOID lpVertex)
{
D3DVERTEX *dataPtr;
HRESULT ret = D3D_OK;
#if DBG
// validate parms
TRY
{
if (!VALID_DIRECT3DDEVICE3_PTR(this))
{
D3D_ERR( "Invalid Direct3DDevice pointer in Vertex" );
return DDERR_INVALIDOBJECT;
}
if (lpVertex == NULL || (! VALID_PTR(lpVertex, 32)) )
{
D3D_ERR( "Invalid vertex pointer in Vertex" );
return DDERR_INVALIDPARAMS;
}
}
EXCEPT( EXCEPTION_EXECUTE_HANDLER )
{
D3D_ERR( "Exception encountered validating parameters in Vertex" );
CleanupBeginEnd(this);
return DDERR_INVALIDPARAMS;
}
if (!(this->dwHintFlags & D3DDEVBOOL_HINTFLAGS_INBEGIN))
{
D3D_ERR( "Vertex call not in Begin" );
CleanupBeginEnd(this);
return D3DERR_NOTINBEGIN;
}
#endif
// store the data
if (dwBENumVertices >= dwMaxVertexCount)
{
CLockD3DMT lockObject(this, DPF_MODNAME, REMIND("")); // Takes D3D lock (MT only).
// Release in the destructor
if ((ret = FlushBeginEndBatch(this, FALSE)) != D3D_OK)
{
CleanupBeginEnd(this);
return ret;
}
}
memcpy(lpcCurrentPtr, lpVertex, this->position.dwStride);
lpcCurrentPtr += this->position.dwStride;
dwBENumVertices++;
return D3D_OK;
}
//---------------------------------------------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "Index"
HRESULT D3DAPI
DIRECT3DDEVICEI::Index(WORD dwIndex)
{
WORD *dataPtr;
DWORD *dataCountPtr;
HRESULT ret = D3D_OK;
#if DBG
// validate parms
TRY
{
if (!VALID_DIRECT3DDEVICE3_PTR(this))
{
D3D_ERR( "Invalid Direct3DDevice pointer in Index" );
return DDERR_INVALIDOBJECT;
}
}
EXCEPT( EXCEPTION_EXECUTE_HANDLER )
{
D3D_ERR( "Exception encountered validating parameters in Index" );
CleanupBeginEnd(this);
return DDERR_INVALIDPARAMS;
}
if (!(this->dwHintFlags & D3DDEVBOOL_HINTFLAGS_INBEGIN))
{
D3D_ERR( "Index call not in Begin" );
CleanupBeginEnd(this);
return D3DERR_NOTINBEGIN;
}
// check if data valid
if (this->dwBENumVertices < dwIndex)
{
D3D_ERR( "Invalid index value passed to Index" );
CleanupBeginEnd(this);
return DDERR_INVALIDPARAMS;
}
#endif
// store the data
if (dwBENumIndices >= dwMaxIndexCount)
{
CLockD3DMT lockObject(this, DPF_MODNAME, REMIND("")); // Takes D3D lock (MT only).
// Release in the destructor
if ((ret = FlushBeginEndBatch(this, FALSE)) != D3D_OK)
{
CleanupBeginEnd(this);
return ret;
}
}
*(WORD*)lpcCurrentPtr = dwIndex;
dwBENumIndices++;
lpcCurrentPtr += 2;
return D3D_OK;
} // end of D3DDev2_Index()
//---------------------------------------------------------------------
#undef DPF_MODNAME
#define DPF_MODNAME "End"
HRESULT D3DAPI
DIRECT3DDEVICEI::End(DWORD dwFlags)
{
HRESULT ret;
CLockD3DMT lockObject(this, DPF_MODNAME, REMIND("")); // Takes D3D lock (MT only).
// Release in the destructor
#if DBG
/*
* validate parms
*/
TRY
{
if (!VALID_DIRECT3DDEVICE3_PTR(this))
{
D3D_ERR( "Invalid Direct3DDevice pointer" );
return DDERR_INVALIDOBJECT;
}
}
EXCEPT( EXCEPTION_EXECUTE_HANDLER )
{
D3D_ERR( "Exception encountered validating parameters" );
return DDERR_INVALIDPARAMS;
}
if ( !(this->dwHintFlags & D3DDEVBOOL_HINTFLAGS_INBEGIN))
{
D3D_ERR( "End not in Begin/BeginIndex" );
return D3DERR_NOTINBEGIN;
}
#endif
if ( IS_MT_DEVICE(this) )
LeaveCriticalSection(&this->BeginEndCSect);
/*
* Draw the primitives
*/
ret = FlushBeginEndBatch(this, TRUE);
if (IS_DP2HAL_DEVICE(this) &&
this->dwHintFlags & D3DDEVBOOL_HINTFLAGS_INBEGIN_BIG_PRIM)
{
CDirect3DDeviceIDP2 *dev = static_cast<CDirect3DDeviceIDP2*>(this);
ret = dev->EndPrim(this->dwNumVertices * this->dwOutputSize);
}
CleanupBeginEnd(this);
return ret;
}