📄 driververif.cpp
字号:
//
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 + -