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

📄 driververif.cpp

📁 微软的Windows Mobile D3D测试代码.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
						//
						dDelta = fabs(fResult - fExpectedResult);
	
						if (dLargestDelta < dDelta) dLargestDelta = dDelta;

						//
						// Is the difference unacceptable?
						//
						if (dDelta > m_fTestTolerance)
						{
							DebugOut(_T("Mult operation: 2^(%li)*2^(%li) == 2^(%li) "),iExponentOne, iExponentTwo, iExpectedResultExp);

							DebugOut(_T("[Op #%lu]:  Multiplicand1==World[%lu][%lu], Multiplicand2==View[%lu][%lu]"),
								  uiMultOpNum, uiWorldRow, uiWorldCol, uiViewRow, uiViewCol);

							DebugOut(_T("Invalid Result: 2^(%li) * 2^(%li) == %g       (expected: %g * %g == %g)"), iExponentOne, iExponentTwo, fResult, fValOne, fValTwo, fExpectedResult);

							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;
							}
							
						}
						uiMultOpNum++;
					}
				}
			}
		}
	}

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;
}


//
// ExecuteAddTest
//  
//   This test verifies ProcessVertices transformation of vertex positions via the world and view matrices.
//   The technique used by this test is to confirm that addition of specific components is occuring as expected.
//
//   This test expects the viewport and projection to be set up to "cancel" each other out (the result of the
//   projection matrix mult with the viewport matrix should be the identity matrix).
//   
//   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::ExecuteAddTest()
{

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

	//
	// Addends (translations) for X, Y, Z
	//
	float fAddendX, fAddendY, fAddendZ;

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

	//
	// World and view transformation matrices for D3DM TnL
	//
	D3DMMATRIX WorldMatrix, ViewMatrix;

	//
	// FVF sizes for this test
	//
	CONST UINT uiInVertSize = sizeof(float)*3;  // X,Y,Z
	CONST UINT uiOutVertSize = sizeof(float)*4; // X,Y,Z,RHW

	//
	// Difference between expected value and actual value, per component
	//
	double dDeltaX, dDeltaY, dDeltaZ;
	double dLargestDelta = 0.0f;

	//
	// Should translation occur in view matrix, or world matrix?
	//
	UINT uiMatrix;

	//
	// Used for VB locks, to access floating point positional data (X,Y,Z,RHW)
	//
	float *pFloats = NULL;

	//
	// 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;
	}

	//
	// Cause viewport and projection to cancel each other out, for isolated world/view testing
	//
	if (FAILED(SetDegenerateViewAndProj()))
	{
		DebugOut(_T("SetDegenerateViewAndProj failed.\n"));
		Result = TPR_ABORT;
		goto cleanup;
	}

	//
	// Creates a Vertex Buffer; sets stream source and vertex shader type (FVF)
	//
	pOutVB = CreateActiveBuffer(m_pd3dDevice, 1, 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, 1, D3DMFVF_XYZ_FLOAT, uiInVertSize, 0);
	if (NULL == pInVB)
	{
		DebugOut(_T("CreateActiveBuffer failed.\n"));
		Result = TPR_ABORT;
		goto cleanup;
	}


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

	//
	// Fill the input vertex buffer
	//
	pFloats[0] = 0.0f;
	pFloats[1] = 0.0f;
	pFloats[2] = 0.0f;

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

	//
	// Iterate over a variety of addends
	//
	for(fAddendX = 0; fAddendX < D3DQA_PV_MAX_ADDEND; fAddendX+=D3DQA_PV_ADDEND_STEP)
	{
		for(fAddendY = 0; fAddendY < D3DQA_PV_MAX_ADDEND; fAddendY+=D3DQA_PV_ADDEND_STEP)
		{
			for(fAddendZ = 0; fAddendZ < D3DQA_PV_MAX_ADDEND; fAddendZ+=D3DQA_PV_ADDEND_STEP)
			{
				for(uiMatrix = 0; uiMatrix < 2; uiMatrix++)
				{
					float fResultX, fResultY, fResultZ;
					UINT uiAddOpNum = 1;

					//
					// Prepare the view and world matrices
					//
					ZeroMemory(&WorldMatrix,sizeof(D3DMMATRIX));
					ZeroMemory(&ViewMatrix,sizeof(D3DMMATRIX));

					//
					// Set the view and world matrices, initially, to identity
					//
					ViewMatrix.m[0][0] = ViewMatrix.m[1][1] = ViewMatrix.m[2][2] = ViewMatrix.m[3][3] = _M(1.0f);
					WorldMatrix.m[0][0] = WorldMatrix.m[1][1] = WorldMatrix.m[2][2] = WorldMatrix.m[3][3] = _M(1.0f);

					//
					// Initialize translation; either in the view or world matrix.
					//

					switch(uiMatrix)
					{
					case 0:
						ViewMatrix.m[3][0] = _M(fAddendX);
						ViewMatrix.m[3][1] = _M(fAddendY);
						ViewMatrix.m[3][2] = _M(fAddendZ);
						break;
					case 1:
						WorldMatrix.m[3][0] = _M(fAddendX);
						WorldMatrix.m[3][1] = _M(fAddendY);
						WorldMatrix.m[3][2] = _M(fAddendZ);
						break;
					}

					//
					// Indicate world matrix to D3DM
					//
					if( FAILED( m_pd3dDevice->SetTransform(D3DMTS_WORLD,              // D3DTRANSFORMSTATETYPE State,
					                                       &WorldMatrix,              // CONST D3DMMATRIX* pMatrix
					                                       D3DMFMT_D3DMVALUE_FLOAT))) // D3DMFORMAT Format
					{
						DebugOut(_T("IDirect3DMobileDevice::SetTransform failed.\n"));
						Result = TPR_ABORT;
						goto cleanup;
					}

					//
					// Indicate view matrix to D3DM
					//
					if( FAILED( m_pd3dDevice->SetTransform(D3DMTS_VIEW,               // D3DTRANSFORMSTATETYPE State,
					                                       &ViewMatrix,               // CONST D3DMMATRIX* pMatrix
					                                       D3DMFMT_D3DMVALUE_FLOAT))) // D3DMFORMAT Format
					{
						DebugOut(_T("IDirect3DMobileDevice::SetTransform failed.\n"));
						Result = TPR_ABORT;
						goto cleanup;
					}

					//
					// Perform TnL on input VB, store in output VB
					//
					if( FAILED( m_pd3dDevice->ProcessVertices(0,         // UINT SrcStartIndex,
					                                          0,         // UINT DestIndex,
					                                          1,         // 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,      // UINT SizeToLock,
					                         (VOID**)(&pFloats), // VOID** ppbData,
					                         0)))                // DWORD Flags
					{
						DebugOut(_T("IDirect3DMobileVertexBuffer::Lock failed.\n"));
						Result = TPR_ABORT;
						goto cleanup;
					}

					//
					// Results should be translated based on addends
					//
					fResultX = pFloats[0];
					fResultY = pFloats[1];
					fResultZ = pFloats[2];

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

					//
					// What is the difference between the expected result and the actual result, if
					// any?
					//
					dDeltaX = fabs(fResultX - fAddendX);
					dDeltaY = fabs(fResultY - fAddendY);
					dDeltaZ = fabs(fResultZ - fAddendZ);

					//
					// Is the difference unacceptable?
					//

					if ((dDeltaX > m_fTestTolerance) || (dDeltaY > m_fTestTolerance) || (dDeltaZ > m_fTestTolerance))
					{
						DebugOut(_T("Add operation: X-Trans: %g, Y-Trans: %g, Z-Trans: %g"), fAddendX, fAddendY, fAddendZ);

						if (dDeltaX > m_fTestTolerance)
						{
							if (dLargestDelta < dDeltaX) dLargestDelta = dDeltaX;
							DebugOut(_T("Invalid X Result.  Expected: %g; Actual: %g"),fAddendX,fResultX);
							Result = TPR_FAIL;
						}
						if (dDeltaY > m_fTestTolerance)
						{
							if (dLargestDelta < dDeltaY) dLargestDelta = dDeltaY;
							DebugOut(_T("Invalid Y Result.  Expected: %g; Actual: %g"),fAddendY,fResultY);
							Result = TPR_FAIL;
						}

						if (dDeltaZ > m_fTestTolerance)
						{
							if (dLargestDelta < dDeltaZ) dLargestDelta = dDeltaZ;
							DebugOut(_T("Invalid Z Result.  Expected: %g; Actual: %g"),fAddendZ,fResultZ);
							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;
						}

					}

					uiAddOpNum++;
				}
			}
		}
	}

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;
}

//
// ExecutePerspectiveProjTest
//  
//   This test exercises ProcessVertices in the user scenario of a perspective 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::ExecutePerspectiveProjTest()
{

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

	//
	// FVF structures and bit masks for use with this test

⌨️ 快捷键说明

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