⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drawprim.c

📁 Lido PXA270平台开发板的最新BSP,包括源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/******************************************************************************
<module>
* Name         : DrawPrim.c
* Title        : D3DM DrawPrimitives Callback
* Author(s)    : Imagination Technologies
* Created      : 2 March 2004
*
* Copyright    : 2004 by Imagination Technologies Limited.
*                All rights reserved.  No part of this software, either
*                material or conceptual may be copied or distributed,
*                transmitted, transcribed, stored in a retrieval system
*                or translated into any human or computer language in any
*                form by any means, electronic, mechanical, manual or
*                other-wise, or disclosed to third parties without the
*                express written permission of Imagination Technologies
*                Limited, Unit 8, HomePark Industrial Estate,
*                King's Langley, Hertfordshire, WD4 8LZ, U.K.
*
* Description  : DrawPrimitive Entry Point for processing D3DMobile DP Commands, 
*				 and DP Operation Handlers
*
* Platform     : Windows CE
*
</module>
********************************************************************************/

#include "context.h"


void Clear(	LPD3DM_CONTEXT	psContext,
			DWORD			dwFlags,
			DWORD			dwFillColour,
			float			fFillDepth,
			DWORD			dwNumRects,
			LPD3DMRECT		psRects);
void SetViewPort(LPD3DM_CONTEXT psContext, LPD3DMRECT psRect);

/*----------------------------------------------------------------------------
<function>
	FUNCTION:   D3DM_DP_OP_DefaultHandler

	PURPOSE:    

	PARAMETERS:	In:  psContext - Context to operate on
				In:	 pvCommandData - Pointer to command ops to execute
				In:  nCount - number of ops of this type to process
	RETURNS:	number of bytes processed
</function>
------------------------------------------------------------------------------*/
ULONG D3DM_DP_OP_DefaultHandler(LPD3DM_CONTEXT psContext, LPVOID pvCommandData, WORD nCount)
{
	D3DM_DPF((DPF_ERROR, "D3DM_DP_OP_DefaultHandler: Unsupported operation requested"));
	return 0;
}

/*----------------------------------------------------------------------------
<function>
	FUNCTION:   D3DM_DP_OP_BeginScene

	PURPOSE:    

	PARAMETERS:	In:  psContext - Context to operate on
				In:	 pvCommandData - Pointer to command ops to execute
				In:  nCount - number of ops of this type to process
	RETURNS:	number of bytes processed
</function>
------------------------------------------------------------------------------*/
ULONG D3DM_DP_OP_BeginScene(LPD3DM_CONTEXT psContext, LPVOID pvCommandData, WORD nCount)
{
	D3DM_DPF((DPF_ENTRY, "->D3DM_DP_OP_BeginScene"));

	// Can't trust Begin/EndScene Ops 
	// just ignore and infer:
	// beginscene from first primitive/clear
	// endscene from present or setrendertarget

	D3DM_DPF((DPF_EXIT, "<-D3DM_DP_OP_BeginScene"));
	return 0;
}
/*----------------------------------------------------------------------------
<function>
	FUNCTION:   D3DM_DP_OP_EndScene

	PURPOSE:    

	PARAMETERS:	In:  psContext - Context to operate on
				In:	 pvCommandData - Pointer to command ops to execute
				In:  nCount - number of ops of this type to process
	RETURNS:	number of bytes processed
</function>
------------------------------------------------------------------------------*/
ULONG D3DM_DP_OP_EndScene(LPD3DM_CONTEXT psContext, LPVOID pvCommandData, WORD nCount)
{
	D3DM_DPF((DPF_ENTRY, "->D3DM_DP_OP_EndScene"));

	// Can't trust Begin/EndScene Ops 
	// just ignore and infer:
	// beginscene from first primitive/clear
	// endscene from present or setrendertarget

	D3DM_DPF((DPF_EXIT, "<-D3DM_DP_OP_EndScene"));
	return 0;
}
/*----------------------------------------------------------------------------
<function>
	FUNCTION:   D3DM_DP_OP_Present

	PURPOSE:    

	PARAMETERS:	In:  psContext - Context to operate on
				In:	 pvCommandData - Pointer to command ops to execute
				In:  nCount - number of ops of this type to process
	RETURNS:	number of bytes processed
</function>
------------------------------------------------------------------------------*/
ULONG D3DM_DP_OP_Present(LPD3DM_CONTEXT psContext, LPVOID pvCommandData, WORD nCount)
{
	WORD					i;
	ULONG					ulBytesProcessed;
	LPD3DM_PRESENT			psCurrentOp;

	ulBytesProcessed = 0;
	psCurrentOp		 = (LPD3DM_PRESENT) pvCommandData;

	D3DM_DPF((DPF_ENTRY, "->D3DM_DP_OP_CursorProperties"));


	/* We infer endscene from Present - always call this to flush any clears */
	DoEndScene(psContext);


	for(i=0; i <nCount; i++)
	{
		/* Process current Present */
		LPD3DM_SURFACE	psSurface = (LPD3DM_SURFACE) psCurrentOp->PresentSurface;		
		ulBytesProcessed += sizeof(D3DM_PRESENT);

		if(psSurface->eSurfaceType != D3DMRTYPE_BACKBUFFER &&
			psSurface->eSurfaceType != D3DMRTYPE_FRONTBUFFER)
		{
			/* Can't present non image surfaces */
			D3DM_DPF((DPF_ERROR, "D3DM_DP_OP_Present:Invalid buffer type submitted for Presentation"));
			psContext->hrLastError = D3DM_GENERICFAILURE;
			return ulBytesProcessed;
		}

		/* Check Scene validity */
		if(IS_RENDER_TARGET(psSurface) && SCENE_IS_INVALID(psSurface))
		{
			/* Scene is invalidated due to Power management*/
			continue;
		}

	    if(psContext->SwapEffect == D3DMSWAPEFFECT_FLIP)
		{
			PresentFlip(psContext->psCurrentRenderTarget, psContext->nVSyncInterval);
			
			/* advance to next surface */
			psContext->sChain.psCurrentBuffer = psContext->sChain.psCurrentBuffer->psNext;
			SetRenderTarget(psContext, 
							psContext->sChain.psCurrentBuffer, 
							psContext->psCurrentDepthBuffer,
							IMG_FALSE);
		}
		else
		{
			Copy(psCurrentOp);
		}

		/* Move past variable length array at end of struct */
		ulBytesProcessed += (sizeof(RECT) * psCurrentOp->NumClippingRects);
		psCurrentOp		  = (LPD3DM_PRESENT) ((DWORD)pvCommandData) + ulBytesProcessed;
	}

	D3DM_DPF((DPF_EXIT, "<-D3DM_DP_OP_CursorProperties"));
	return ulBytesProcessed;
}
/*----------------------------------------------------------------------------
<function>
	FUNCTION:   D3DM_DP_OP_CopyRect

	PURPOSE:    

	PARAMETERS:	In:  psContext - Context to operate on
				In:	 pvCommandData - Pointer to command ops to execute
				In:  nCount - number of ops of this type to process
	RETURNS:	number of bytes processed
</function>
------------------------------------------------------------------------------*/
ULONG D3DM_DP_OP_CopyRect(LPD3DM_CONTEXT psContext, LPVOID pvCommandData, WORD nCount)
{
	WORD					i;
	ULONG					ulBytesProcessed;
	LPD3DM_COPYRECT			psCurrentOp;

	ulBytesProcessed = 0;
	psCurrentOp		 = (LPD3DM_COPYRECT) pvCommandData;

	D3DM_DPF((DPF_ENTRY, "->D3DM_DP_OP_CopyRect"));

	for(i=0; i <nCount; i++, psCurrentOp++)
	{
		/* Process current Copy Rect */
		CopyRectangle(psCurrentOp);
		ulBytesProcessed += sizeof(D3DM_COPYRECT);
	}

	D3DM_DPF((DPF_EXIT, "<-D3DM_DP_OP_CopyRect"));
	return ulBytesProcessed;
}
/*----------------------------------------------------------------------------
<function>
	FUNCTION:   D3DM_DP_OP_Clear

	PURPOSE:    

	PARAMETERS:	In:  psContext - Context to operate on
				In:	 pvCommandData - Pointer to command ops to execute
				In:  nCount - number of ops of this type to process
	RETURNS:	number of bytes processed
</function>
------------------------------------------------------------------------------*/
ULONG D3DM_DP_OP_Clear(LPD3DM_CONTEXT psContext, LPVOID pvCommandData, WORD nCount)
{
	WORD					i;
	ULONG					ulBytesProcessed;
	LPD3DM_CLEAR			psCurrentOp;

	ulBytesProcessed = 0;
	psCurrentOp		 = (LPD3DM_CLEAR) pvCommandData;

	D3DM_DPF((DPF_ENTRY, "->D3DM_DP_OP_Clear"));

	for(i=0; i <nCount; i++, psCurrentOp++)
	{
		if (psContext->psCurrentRenderTarget)
		{
			// FillStencil, no stencils
			Clear(psContext, 
				  psCurrentOp->Flags, 
				  psCurrentOp->FillColor,
				  psCurrentOp->FillDepth,
				  psCurrentOp->NumRects,
				  (LPD3DMRECT)&psCurrentOp->Rects);
		}

		/* Process current operation */
		ulBytesProcessed += sizeof(D3DM_CLEAR);
	}

	D3DM_DPF((DPF_EXIT, "<-D3DM_DP_OP_Clear"));
	return ulBytesProcessed;
}


/*****************************************************************************
 FUNCTION	: SetRenderTarget
    
 PURPOSE	: Core code to change render-target

 PARAMETERS	: psContext		- valid D3D context
			  psSurfData	- Valid Surface data for the new render-target
			  
 RETURNS	: none
*****************************************************************************/
void SetRenderTarget(LPD3DM_CONTEXT psContext, 
					 LPD3DM_SURFACE psNewRenderTarget,
					 LPD3DM_SURFACE psNewDepthBuffer,
					 IMG_BOOL		bDisallowEndScene)
{
	LPD3DM_SURFACE			psCurrentRenderTarget;
	D3DMRECT				sFSRect;

	D3DM_DPF((DPF_MESSAGE, "SetRenderTarget: New render-target %#8.8lX", psNewRenderTarget));

	/* has RT surface changed? */
	if(psContext->psCurrentRenderTarget == psNewRenderTarget)
	{
		return;
	}

	/* Validate the new render-target */
	if(!IS_RENDER_TARGET(psNewRenderTarget))
	{
		D3DM_DPF((DPF_ERROR, "SetRenderTarget: surface is not a render target, failing" ));
		return;
	}

	/*
		Do we have something started on the current render surface?
		If so we'd better sort it out...
	*/
	psCurrentRenderTarget = psContext->psCurrentRenderTarget;
	if(psCurrentRenderTarget)
	{
		/*
			To handle mid-scene texture renders:
			
			When switching away from a non-texture render-target (i.e. 
			probably the render-target for the whole scene) to a texture,
			we save the current HW-context so that the scene can be 
			continued later when we switch back.

			When switching away from a texture (either to another texture
			or to a non-texture) we always render the scene. Note that
			this behaviour assumes that applications do not perform sub-
			renders within mid-scene texture-renders, or render their
			textures incrementally throughout the main scene! - wouldn't
			that be nice.

		*/
		if(!bDisallowEndScene										&&
		  (psCurrentRenderTarget->eSurfaceType == D3DMRTYPE_TEXTURE ||
		   psCurrentRenderTarget->eSurfaceType == D3DMRTYPE_SURFACE))
		{
			/*
				Switching from a texture, or to a non texture, or to 
				something with the same dimensions -- so render the scene.
			*/
			D3DM_DPF((DPF_MESSAGE, "SetRenderTarget: ending scene (render needed) on surface 0x%8.8lX", psCurrentRenderTarget ));

			DoEndScene(psContext);
		}
	}

	/* Record that the new render-target surface and depth buffer are being used by this context */
	psContext->psCurrentRenderTarget	= psNewRenderTarget;
	psContext->psCurrentDepthBuffer		= psNewDepthBuffer;

	/* Associate depth buffer with render target */
	psNewRenderTarget->sDescription.sSurface.psAssocDepthSurface = psNewDepthBuffer;

	/* Check if we need to force a Z-Buffer meminfo creation */
	if(psNewDepthBuffer && (psNewDepthBuffer->dwFlags & D3DM_SURFACE_FLAGS_CREATE_Z_BUFFER))
	{
		/* Create Z buffer */
		ZLSAlloc(psContext);
		psNewDepthBuffer->dwFlags &= ~D3DM_SURFACE_FLAGS_CREATE_Z_BUFFER;
	}

	/*
		Size of render surface has changed so need
		to recalc TA region clip for FS.
	*/
	VLSetRect(&sFSRect,
			  0,
			  0,
			  psNewRenderTarget->dwWidth - 1,
			  psNewRenderTarget->dwHeight - 1);

	psNewRenderTarget->sDescription.sSurface.dwFSRegionClip = CalcTARegionClip(psContext, &sFSRect);

	/*
		Render surface can't be twiddled.
		May cause problems if already blit to
	*/
	if(psNewRenderTarget->eSurfaceType == D3DMRTYPE_TEXTURE			&&
	   psNewRenderTarget->dwFlags & D3DM_SURFACE_FLAGS_TWIDDLED)
	{
		/* We cant render to a twiddled surface */
		UnTwiddleSurface(psNewRenderTarget);
	}

	/* Readjust our vp transform */
	SetupViewportTransform(psContext);

	/*
		Update all the TA and 3D-core registers that relate to the 
		render-target
	*/
	SetupRenderTargetRegs(psContext);

	/* resubmit the HW state */
	ResubmitHWState(psContext);
}

/*----------------------------------------------------------------------------
<function>
	FUNCTION:   D3DM_DP_OP_RenderTarget

	PURPOSE:    

	PARAMETERS:	In:  psContext - Context to operate on
				In:	 pvCommandData - Pointer to command ops to execute
				In:  nCount - number of ops of this type to process
	RETURNS:	number of bytes processed
</function>
------------------------------------------------------------------------------*/
ULONG D3DM_DP_OP_RenderTarget(LPD3DM_CONTEXT psContext, LPVOID pvCommandData, WORD nCount)
{
	WORD					i;
	ULONG					ulBytesProcessed;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -