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.
197 lines
7.2 KiB
197 lines
7.2 KiB
/*==========================================================================;
|
|
*
|
|
* Copyright (C) 1998 Microsoft Corporation. All Rights Reserved.
|
|
*
|
|
* File: dpgen.h
|
|
* Content: Generate some functions for Draw Primitive
|
|
*
|
|
***************************************************************************/
|
|
|
|
#ifdef __DRAWPRIMFUNC
|
|
|
|
//---------------------------------------------------------------------
|
|
// Draws indexed and non-indexed primitives which do not require clipping
|
|
//
|
|
#ifdef __DRAWPRIMINDEX
|
|
HRESULT CDirect3DDeviceIDP::DrawIndexPrim()
|
|
{
|
|
D3DHAL_DRAWONEINDEXEDPRIMITIVEDATA dpData;
|
|
DWORD &dwNumElements = this->dwNumIndices;
|
|
#else
|
|
HRESULT CDirect3DDeviceIDP::DrawPrim()
|
|
{
|
|
D3DHAL_DRAWONEPRIMITIVEDATA dpData;
|
|
DWORD &dwNumElements = this->dwNumVertices;
|
|
#endif
|
|
const WORD vertexType = D3DVT_TLVERTEX; // XXX While we do not have DDI
|
|
// Do we need to map new texture stage operations to DX5 renderstates?
|
|
if(this->dwFEFlags & D3DFE_MAP_TSS_TO_RS) {
|
|
MapTSSToRS();
|
|
this->dwFEFlags &= ~D3DFE_MAP_TSS_TO_RS; // Reset request bit
|
|
}
|
|
if(this->dwFEFlags & D3DFE_NEED_TEXTURE_UPDATE)
|
|
{
|
|
HRESULT ret = UpdateTextures();
|
|
if(ret != D3D_OK)
|
|
{
|
|
D3D_ERR("UpdateTextures failed. Device probably doesn't support current texture (check return code).");
|
|
return ret;
|
|
}
|
|
this->dwFEFlags &= ~D3DFE_NEED_TEXTURE_UPDATE;
|
|
}
|
|
|
|
if (dwNumElements < LOWVERTICESNUMBERDP &&
|
|
this->dwCurrentBatchVID == this->dwVIDOut)
|
|
{
|
|
LPD3DHAL_DRAWPRIMCOUNTS lpPC;
|
|
lpPC = this->lpDPPrimCounts;
|
|
if (lpPC->wNumVertices)
|
|
{
|
|
if ((lpPC->wPrimitiveType!=(WORD) this->primType) ||
|
|
(lpPC->wVertexType != vertexType) ||
|
|
(this->primType==D3DPT_TRIANGLESTRIP) ||
|
|
(this->primType==D3DPT_TRIANGLEFAN) ||
|
|
(this->primType==D3DPT_LINESTRIP))
|
|
{
|
|
lpPC = this->lpDPPrimCounts=(LPD3DHAL_DRAWPRIMCOUNTS)
|
|
((LPBYTE)this->lpwDPBuffer + this->dwDPOffset);
|
|
memset( (char *)lpPC, 0, sizeof(D3DHAL_DRAWPRIMCOUNTS));
|
|
// preserve 32 bytes alignment for vertices
|
|
this->dwDPOffset += sizeof(D3DHAL_DRAWPRIMCOUNTS);
|
|
ALIGN32(this->dwDPOffset);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// 32-byte align offset pointer, just in case states have been
|
|
// recorded.
|
|
ALIGN32(this->dwDPOffset);
|
|
}
|
|
ULONG ByteCount;
|
|
if (FVF_DRIVERSUPPORTED(this))
|
|
ByteCount = dwNumElements * this->dwOutputSize;
|
|
else
|
|
ByteCount = dwNumElements << 5; // D3DTLVERTEX
|
|
if (this->dwDPOffset + ByteCount > this->dwDPMaxOffset)
|
|
{
|
|
CLockD3DST lockObject(this, DPF_MODNAME, REMIND("")); // Takes D3D lock (ST only).
|
|
//DPF(0,"overflowed ByteCount=%08lx",ByteCount);
|
|
HRESULT ret;
|
|
ret = this->FlushStates();
|
|
if (ret != D3D_OK)
|
|
{
|
|
D3D_ERR("Error trying to render batched commands in Draw*Prim");
|
|
return ret;
|
|
}
|
|
lpPC = this->lpDPPrimCounts;
|
|
ALIGN32(this->dwDPOffset);
|
|
}
|
|
lpPC->wPrimitiveType = (WORD)this->primType;
|
|
lpPC->wVertexType = (WORD)vertexType;
|
|
lpPC->wNumVertices += (WORD)dwNumElements;
|
|
BYTE *lpVertex = (BYTE*)((char *)this->lpwDPBuffer + this->dwDPOffset);
|
|
#ifdef __DRAWPRIMINDEX
|
|
DWORD i;
|
|
BYTE *pV = (BYTE*)this->lpvOut;
|
|
if (FVF_DRIVERSUPPORTED(this) || this->dwVIDOut == D3DFVF_TLVERTEX)
|
|
for (i=0; i < this->dwNumIndices; i++)
|
|
{
|
|
memcpy(lpVertex, pV + this->lpwIndices[i] * this->dwOutputSize,
|
|
this->dwOutputSize);
|
|
lpVertex += this->dwOutputSize;
|
|
}
|
|
else
|
|
for (i=0; i < this->dwNumIndices; i++)
|
|
{
|
|
MapFVFtoTLVertex1(this, (D3DTLVERTEX*)lpVertex,
|
|
(DWORD*)(pV + this->lpwIndices[i] *
|
|
this->dwOutputSize));
|
|
lpVertex += sizeof(D3DTLVERTEX);
|
|
}
|
|
#else // !__DRAWPRIMINDEX
|
|
if (FVF_DRIVERSUPPORTED(this) || this->dwVIDOut == D3DFVF_TLVERTEX)
|
|
memcpy(lpVertex, this->lpvOut, ByteCount);
|
|
else
|
|
MapFVFtoTLVertex(lpVertex);
|
|
#endif //__DRAWPRIMINDEX
|
|
this->dwDPOffset += ByteCount;
|
|
return D3D_OK;
|
|
}
|
|
else
|
|
{
|
|
CLockD3DST lockObject(this, DPF_MODNAME, REMIND("")); // Takes D3D lock (ST only).
|
|
HRESULT ret;
|
|
ret = this->FlushStates();
|
|
if (ret != D3D_OK)
|
|
{
|
|
D3D_ERR("Error trying to render batched commands in Draw*Prim");
|
|
return ret;
|
|
}
|
|
dpData.dwhContext = this->dwhContext;
|
|
dpData.dwFlags = this->dwFlags;
|
|
dpData.PrimitiveType = this->primType;
|
|
if (FVF_DRIVERSUPPORTED(this))
|
|
{
|
|
dpData.dwFVFControl = this->dwVIDOut;
|
|
dpData.lpvVertices = this->lpvOut;
|
|
}
|
|
else
|
|
{
|
|
if (this->dwVIDOut == D3DFVF_TLVERTEX)
|
|
dpData.lpvVertices = this->lpvOut;
|
|
else
|
|
{
|
|
HRESULT ret;
|
|
#ifdef __DRAWPRIMINDEX
|
|
if (this->dwNumIndices * INDEX_BATCH_SCALE < this->dwNumVertices)
|
|
ret = this->MapFVFtoTLVertexIndexed();
|
|
else
|
|
#endif
|
|
ret = MapFVFtoTLVertex(NULL);
|
|
if (ret != D3D_OK)
|
|
return ret;
|
|
dpData.lpvVertices = this->TLVbuf.GetAddress();
|
|
}
|
|
dpData.VertexType = (D3DVERTEXTYPE)vertexType;
|
|
if (this->dwDebugFlags & D3DDEBUG_DISABLEFVF)
|
|
dpData.dwFVFControl = D3DFVF_TLVERTEX;
|
|
}
|
|
dpData.dwNumVertices = this->dwNumVertices;
|
|
dpData.ddrval = D3D_OK;
|
|
#ifdef __DRAWPRIMINDEX
|
|
dpData.lpwIndices = this->lpwIndices;
|
|
dpData.dwNumIndices = this->dwNumIndices;
|
|
#endif
|
|
// Spin waiting on the driver if wait requested
|
|
#if _D3D_FORCEDOUBLE
|
|
CD3DForceFPUDouble ForceFPUDouble(this);
|
|
#endif //_D3D_FORCEDOUBLE
|
|
do {
|
|
DWORD dwRet;
|
|
#ifndef WIN95
|
|
if((dwRet = CheckContextSurface(this)) != D3D_OK)
|
|
{
|
|
return (dwRet);
|
|
}
|
|
#endif //WIN95
|
|
#ifdef __DRAWPRIMINDEX
|
|
CALL_HAL2ONLY(dwRet, this, DrawOneIndexedPrimitive, &dpData);
|
|
#else
|
|
CALL_HAL2ONLY(dwRet, this, DrawOnePrimitive, &dpData);
|
|
#endif
|
|
if (dwRet != DDHAL_DRIVER_HANDLED)
|
|
{
|
|
D3D_ERR ( "Driver not handled in DrawOnePrimitive" );
|
|
// Need sensible return value in this case,
|
|
// currently we return whatever the driver stuck in here.
|
|
}
|
|
|
|
} while ( (this->dwFlags & D3DDP_WAIT) && (dpData.ddrval == DDERR_WASSTILLDRAWING) );
|
|
}
|
|
return dpData.ddrval;
|
|
}
|
|
|
|
#endif //__DRAWPRIMFUNC
|
|
|
|
#undef __DRAWPRIMFUNC
|
|
#undef __DRAWPRIMINDEX
|