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

📄 driververif.cpp

📁 微软的Windows Mobile D3D测试代码.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	//
	#define D3DQA_PRJTEST_IN_FVF D3DMFVF_XYZ_FLOAT
	struct D3DQA_PRJTEST_IN
	{
		FLOAT x, y, z;
	};

	#define D3DQA_PRJTEST_OUT_FVF D3DMFVF_XYZRHW_FLOAT
	struct D3DQA_PRJTEST_OUT
	{
		FLOAT x, y, z, rhw;
	};

	//
	// For vertex buffer locks
	//
	D3DQA_PRJTEST_OUT *pOutPos = NULL;
	D3DQA_PRJTEST_IN *pInPos = NULL;

	//
	// Because this test is not particularly concerned with aspect ratios,
	// a simplistic default is set.
	//
	CONST float fAspect = 1.0f;

	//
	// A simple default is set, for field-of-view
	//
	CONST float fFov = ((2*D3DQA_PI)*(1.0f/6.0f));

	//
	// Iterator for verts in the per-iteration VB
	//
	UINT uiVertIter;

	//
	// Input and output Vertex buffers for ProcessVertices
	//
	IDirect3DMobileVertexBuffer *pInVB = NULL;
	IDirect3DMobileVertexBuffer *pOutVB = NULL;

	//
	// FVF sizes for this test
	//
	CONST UINT uiInVertSize = sizeof(D3DQA_PRJTEST_IN);  // X,Y,Z
	CONST UINT uiOutVertSize = sizeof(D3DQA_PRJTEST_OUT);// X,Y,Z,RHW

	//
	// Iterators for near and far planes
	//
	float fNear, fFar;

	//
	// Device viewport
	//
	D3DMVIEWPORT Viewport;

	//
	// An intermediate value for Z tranformation computation
	//
	float fTempZ;

	//
	// Iteration counter (for debug output purposes)
	//
	UINT uiIter = 1;

	//
	// Per-component values for confirming ProcessVertices success
	//
	float fExpectedX, fExpectedY, fExpectedZ, fExpectedRHW;
	double dDeltaX, dDeltaY, dDeltaZ, dDeltaRHW;
	double dLargestDelta = 0.0f;

	//
	// Projection matrix that is modified based on near/far planes during test iterations
	//
	D3DMMATRIX ProjMatrix;

	//
	// Iterator for selecting a set of points to process
	//
	UINT uiXStep, uiYStep;

	//
	// The test will return TPR_FAIL if even one result exceeds the tolerance, but to aid in
	// debugging the test will continue to execute until reaching the number of failures below.
	//
	CONST UINT uiFailureThreshhold = 25;
	UINT uiNumFailures = 0;

	//
	// Tux Test Case Result; all non-pass blocks set this to another value
	//
	INT Result = TPR_PASS;

	if (!IsReady())
	{
		DebugOut(_T("Due to failed initialization, the test must be aborted.\n"));
		Result = TPR_ABORT;
		goto cleanup;
	}

	//
	// Disable clipping
	//
	if( FAILED( m_pd3dDevice->SetRenderState(D3DMRS_CLIPPING, FALSE)))
	{
		DebugOut(_T("IDirect3DMobileDevice::SetRenderState failed.\n"));
		Result = TPR_ABORT;
		goto cleanup;
	}

	//
	// Disable lighting
	//
	if( FAILED( m_pd3dDevice->SetRenderState(D3DMRS_LIGHTING, FALSE)))
	{
		DebugOut(_T("IDirect3DMobileDevice::SetRenderState failed.\n"));
		Result = TPR_ABORT;
		goto cleanup;
	}

	if (FAILED(m_pd3dDevice->GetViewport(&Viewport)))
	{
		DebugOut(_T("IDirect3DMobileDevice::GetViewport failed.\n"));
		Result = TPR_ABORT;
		goto cleanup;
	}

	//
	// Creates a Vertex Buffer; sets stream source and vertex shader type (FVF)
	//
	pOutVB = CreateActiveBuffer(m_pd3dDevice, D3DQA_PV_PROJ_VERTS, D3DMFVF_XYZRHW_FLOAT, uiOutVertSize, D3DMUSAGE_DONOTCLIP);
	if (NULL == pOutVB)
	{
		DebugOut(_T("CreateActiveBuffer failed.\n"));
		Result = TPR_ABORT;
		goto cleanup;
	}

	//
	// Creates a Vertex Buffer; sets stream source and vertex shader type (FVF)
	//
	pInVB = CreateActiveBuffer(m_pd3dDevice, D3DQA_PV_PROJ_VERTS, D3DMFVF_XYZ_FLOAT, uiInVertSize, 0);
	if (NULL == pInVB)
	{
		DebugOut(_T("CreateActiveBuffer failed.\n"));
		Result = TPR_ABORT;
		goto cleanup;
	}

	//
	// Iterate through various combinations of near/far planes, tested points
	//
	for(fNear = D3DQA_PV_NEAR_STEP; fNear < D3DQA_PV_MAX_NEAR; fNear+=D3DQA_PV_NEAR_STEP)
	{
		for(fFar = fNear+D3DQA_PV_FAR_STEP; fFar < D3DQA_PV_MAX_FAR; fFar+=D3DQA_PV_FAR_STEP)
		{

			//
			// Retval is just a pointer to ProjMatrix; no need to examine it
			//
			(void)D3DMatrixPerspectiveFovLH( &ProjMatrix,// D3DMATRIX* pOut,
			                                 fFov,       // FLOAT fovy,
			                                 fAspect,    // FLOAT Aspect,
			                                 fNear,      // FLOAT zn,
			                                 fFar );     // FLOAT zf
                                   
			//
			// Set the projection matrix for transformation
			//
			if( FAILED( m_pd3dDevice->SetTransform( D3DMTS_PROJECTION, &ProjMatrix, D3DMFMT_D3DMVALUE_FLOAT)))
			{
				DebugOut(_T("IDirect3DMobileDevice::SetTransform failed.\n"));
				Result = TPR_ABORT;
				goto cleanup;
			}
					
			for(uiXStep = 0; uiXStep <= D3DQA_PV_PROJ_XDIVS; uiXStep++)
			{
				//
				// Multiplier range: [-1.0f, 1.0f]
				//
				float fMultiplierX = (uiXStep/(float)D3DQA_PV_PROJ_XDIVS) * 2.0f - 1.0f;

				for(uiYStep = 0; uiYStep <= D3DQA_PV_PROJ_YDIVS; uiYStep++)
				{
					//
					// Multiplier range: [-1.0f, 1.0f]
					//
					float fMultiplierY = (uiYStep/(float)D3DQA_PV_PROJ_YDIVS) * 2.0f - 1.0f;

					//
					// Lock the input vertex buffer
					//
					if( FAILED( pInVB->Lock(0,                               // UINT OffsetToLock,
					                        uiInVertSize*D3DQA_PV_PROJ_VERTS,// UINT SizeToLock,
					                        (VOID**)(&pInPos),               // VOID** ppbData,
					                        0)))                             // DWORD Flags
					{
						DebugOut(_T("IDirect3DMobileVertexBuffer::Lock failed.\n"));
						Result = TPR_ABORT;
						goto cleanup;
					}

					//
					// Fill the input vertex buffer
					//
					for (uiVertIter=0; uiVertIter < D3DQA_PV_PROJ_VERTS; uiVertIter++)
					{
						//
						// Z
						// 
						pInPos[uiVertIter].z = fNear + (uiVertIter+1) * ((fFar-fNear)/D3DQA_PV_PROJ_VERTS);

						//
						// X
						// 
						pInPos[uiVertIter].x = fMultiplierX * (pInPos[uiVertIter].z * (float)tan (0.5 * fFov));

						//
						// Y
						// 
						pInPos[uiVertIter].y = fMultiplierY * (pInPos[uiVertIter].z * (float)tan (0.5 * fFov));
					}

					//
					// Unlock the input vertex buffer
					//
					pInVB->Unlock();



					//
					// Perform TnL on input VB, store in output VB
					//
					if( FAILED( m_pd3dDevice->ProcessVertices(0,                   // UINT SrcStartIndex,
					                                          0,                   // UINT DestIndex,
					                                          D3DQA_PV_PROJ_VERTS, // UINT VertexCount,
					                                          pOutVB,              // IDirect3DMobileVertexBuffer* pDestBuffer,
					                                          0)))                 // DWORD Flags
					{
						DebugOut(_T("IDirect3DMobileDevice::ProcessVertices failed.\n"));
						Result = TPR_ABORT;
						goto cleanup;
					}

					//
					// Lock results of ProcessVertices
					//
					if( FAILED( pOutVB->Lock(0,                                 // UINT OffsetToLock,
					                         uiOutVertSize*D3DQA_PV_PROJ_VERTS, // UINT SizeToLock,
					                         (VOID**)(&pOutPos),                // VOID** ppbData,
					                         0)))                               // DWORD Flags
					{
						DebugOut(_T("IDirect3DMobileVertexBuffer::Lock failed.\n"));
						Result = TPR_ABORT;
						goto cleanup;
					}

					//
					// Examine the output vertex buffer
					//
					for (uiVertIter=0; uiVertIter < D3DQA_PV_PROJ_VERTS; uiVertIter++)
					{
						//
						// Transformed X
						//
						fExpectedX = (uiXStep/(float)D3DQA_PV_PROJ_XDIVS) * Viewport.Width;
						dDeltaX = fabs(pOutPos[uiVertIter].x - fExpectedX);

						//
						// Transformed Y (note expected inversion due to projection)
						// 
						fExpectedY = Viewport.Height - (uiYStep/(float)D3DQA_PV_PROJ_YDIVS) * Viewport.Height;
						dDeltaY = fabs(pOutPos[uiVertIter].y - fExpectedY);

						//
						// Transformed Z, RHW
						//
						fTempZ = (fNear + (uiVertIter+1) * ((fFar-fNear)/D3DQA_PV_PROJ_VERTS));
						fExpectedRHW = 1.0f / fTempZ;
						fExpectedZ = fTempZ*(fFar / (fFar-fNear));
						fExpectedZ -= (fFar / (fFar-fNear)) * fNear;
						fExpectedZ = fExpectedZ * (1.0f / fTempZ);
						dDeltaZ = fabs(pOutPos[uiVertIter].z - fExpectedZ);
						dDeltaRHW = fabs(pOutPos[uiVertIter].rhw - fExpectedRHW);

						//
						// Exceeds previous largest diff?
						//
						if (dLargestDelta < dDeltaX) dLargestDelta = dDeltaX;
						if (dLargestDelta < dDeltaY) dLargestDelta = dDeltaY;
						if (dLargestDelta < dDeltaZ) dLargestDelta = dDeltaZ;
						if (dLargestDelta < dDeltaRHW) dLargestDelta = dDeltaRHW;

						if ((dDeltaX > (D3DQA_PV_ADDEND_STEP + m_fTestTolerance)) || (dDeltaY > (D3DQA_PV_ADDEND_STEP + m_fTestTolerance)) || (dDeltaZ > m_fTestTolerance) || (dDeltaRHW > m_fTestTolerance))
						{
							DebugOut(_T("Clipping plane pair.  Near: %g, Far: %g."),fNear,fFar);

							DebugOut(_T("[%lu] Processed Vert (Expected, Actual, Delta):  X(%g, %g, %g); Y(%g, %g, %g); Z(%g, %g, %g); RHW(%g, %g, %g)"),
								  uiIter,
								  fExpectedX, pOutPos[uiVertIter].x, dDeltaX, 
								  fExpectedY, pOutPos[uiVertIter].y, dDeltaY, 
								  fExpectedZ, pOutPos[uiVertIter].z, dDeltaZ,
								  fExpectedRHW, pOutPos[uiVertIter].rhw, dDeltaRHW);


							//
							// Is the difference unacceptable?
							//
							if (dDeltaX > (D3DQA_PV_ADDEND_STEP + m_fTestTolerance))
							{
								DebugOut(_T("X Delta exceeds tolerance.\n"));
								Result = TPR_FAIL;
							}
							if (dDeltaY > (D3DQA_PV_ADDEND_STEP + m_fTestTolerance))
							{
								DebugOut(_T("Y Delta exceeds tolerance.\n"));
								Result = TPR_FAIL;
							}
							if (dDeltaZ > m_fTestTolerance)
							{
								DebugOut(_T("Z Delta exceeds tolerance.\n"));
								Result = TPR_FAIL;
							}
							if (dDeltaRHW > m_fTestTolerance)
							{
								DebugOut(_T("RHW Delta exceeds tolerance.\n"));
								Result = TPR_FAIL;
							}

							uiNumFailures++;
							if (uiNumFailures >= uiFailureThreshhold)
							{
								DebugOut(_T("Failure threshhold exceeded.\n"));
								Result = TPR_FAIL; // Should have been set to this previously anyway
								goto cleanup;
							}


						}
						uiIter++;
					}

					//
					// Release the lock (the target value has been stored elsewhere)
					//
					pOutVB->Unlock();

				}
			}
		}
	}

cleanup:

	DebugOut(_T("Largest diff was: %g"), dLargestDelta);
	DebugOut(_T("Diff threshhold is: %g"), m_fTestTolerance);


	//
	// Unlock if not already unlocked (no op if it is already unlocked)
	//
	if (pInVB)
		pInVB->Unlock();
	if (pOutVB)
		pOutVB->Unlock();

	//
	// Clean up the vertex buffers
	//
	if (pInVB)
		pInVB->Release();
	if (pOutVB)
		pOutVB->Release();

	//
	// Clear active vertex buffer ref-count
	//
	if (m_pd3dDevice)
		m_pd3dDevice->SetStreamSource( 0,     // UINT StreamNumber
									   NULL,  // IDirect3DMobileVertexBuffer* pStreamData
									   0);    // UINT Stride

	//
	// Return tux test case result
	//
	return Result;
}

//
// ExecuteOrthoProjTest
//  
//   This test exercises ProcessVertices in the user scenario of an orthographic projection.
//
//   The technique used to verify this functionality is to attempt a variety of transforms
//   with various projection matrices, compute the expected results in QA code, then compare
//   the ProcessVertices result with the expected values.
//   
//   For simplicity, it is expected that clipping is off.
//
// Arguments:
//
//   None
//
// Return Value:
//
//  TPR_PASS, TPR_FAIL, or TPR_SKIP, depending on test result
//
INT DriverVerifTest::ExecuteOrthoProjTest()
{

	DebugOut(_T("Beginning ExecuteOrthoProjTest.\n"));

	//
	// FVF structures and bit masks for use with this test
	//
	#define D3DQA_ORTTEST_IN_FVF D3DMFVF_XYZ_FLOAT
	struct D3DQA_ORTTEST_IN
	{
		FLOAT x, y, z;
	};

	#define D3DQA_ORTTEST_OUT_FVF D3DMFVF_XYZRHW_FLOAT
	struct D3DQA_ORTTEST_OUT
	{
		FLOAT x, y, z, rhw;
	};

	//
	// Because this test is not particularly concerned with aspect ratios,
	// a simplistic default is set.
	//
	CONST float fAspect = 1.0f;

	//
	// A simple default is set, for field-of-view
	//
	CONST float fFov = ((2*D3DQA_PI)*(1.0f/6.0f));

	//
	// Iterator for verts in the per-iteration VB
	//
	UINT uiVertIter;

	//
	// Input and output Vertex buffers for ProcessVertices
	//

⌨️ 快捷键说明

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