📄 driververif.cpp
字号:
IDirect3DMobileVertexBuffer *pInVB = NULL;
IDirect3DMobileVertexBuffer *pOutVB = NULL;
//
// FVF sizes for this test
//
CONST UINT uiInVertSize = sizeof(D3DQA_ORTTEST_IN); // X,Y,Z
CONST UINT uiOutVertSize = sizeof(D3DQA_ORTTEST_OUT); // X,Y,Z,RHW
//
// Used for VB locks, to access floating point positional data (X,Y,Z,RHW)
//
D3DQA_ORTTEST_IN *pInPos = NULL;
D3DQA_ORTTEST_OUT *pOutPos = NULL;
//
// Iterators for ortho view volume
//
float fNear, fFar, fWidth, fHeight;
//
// 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, D3DQA_ORTTEST_OUT_FVF, 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, D3DQA_ORTTEST_IN_FVF, 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)
{
for(fWidth = D3DQA_PV_ORTH_MIN_WIDTH; fWidth <= D3DQA_PV_ORTH_MAX_WIDTH; fWidth+=D3DQA_PV_ORTH_WIDTH_STEP)
{
for(fHeight = D3DQA_PV_ORTH_MIN_HEIGHT; fHeight <= D3DQA_PV_ORTH_MAX_HEIGHT; fHeight+=D3DQA_PV_ORTH_HEIGHT_STEP)
{
//
// Retval is just a pointer to ProjMatrix; no need to examine it
//
(void)D3DMatrixOrthoLH(&ProjMatrix, // D3DXMATRIX *pOut
fWidth, // float w
fHeight, // float h
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++)
{
//
// Range: [-fWidth/2.0f, fWidth/2.0f]
//
float fX = (uiXStep/(float)D3DQA_PV_PROJ_XDIVS) * 2.0f - 1.0f;
for(uiYStep = 0; uiYStep <= D3DQA_PV_PROJ_YDIVS; uiYStep++)
{
//
// Range: [-fHeight/2.0f, fHeight/2.0f]
//
float fY = (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++)
{
//
// X
//
pInPos[uiVertIter].x = fX;
//
// Y
//
pInPos[uiVertIter].y = fY;
//
// Z
//
pInPos[uiVertIter].z = fNear + (uiVertIter+1) * ((fFar-fNear)/D3DQA_PV_PROJ_VERTS);
}
//
// 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 = (1 + fX*(2.0f/fWidth)) * ((float)Viewport.Width / 2.0f);
dDeltaX = fabs(pOutPos[uiVertIter].x - fExpectedX);
//
// Transformed Y (inverted due to projection)
//
fExpectedY = (1 - fY*(2.0f/fHeight)) * ((float)Viewport.Height / 2.0f);;
dDeltaY = fabs(pOutPos[uiVertIter].y - fExpectedY);
//
// Transformed Z
//
fTempZ = (1.0f/(fFar - fNear));
fExpectedZ = fNear + (uiVertIter+1) * ((fFar-fNear)/D3DQA_PV_PROJ_VERTS);
fExpectedZ *= fTempZ;
fExpectedZ -= fTempZ * fNear;
dDeltaZ = fabs(pOutPos[uiVertIter].z - fExpectedZ);
//
// RHW
//
fExpectedRHW = 1.0f;
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("Ortho volume. Near: %g, Far: %g, Width: %g, Height: %g."), fNear, fFar, fWidth, fHeight);
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 threshold 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;
}
//
// ExecuteViewportTest
//
// This test transforms vertices (ProcessVertices) with a variety of different
// viewport sizes and offsets.
//
// 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::ExecuteViewportTest()
{
DebugOut(_T("Beginning ExecuteViewportTest.\n"));
//
// A simple default is set, for field-of-view
//
CONST float fFov = ((2*D3DQA_PI)*(1.0f/6.0f));
//
// Input and output Vertex buffers for ProcessVertices
//
IDirect3DMobileVertexBuffer *pInVB = NULL;
IDirect3DMobileVertexBuffer *pOutVB = NULL;
//
// FVF structures and bit masks for use with this test
//
#define D3DQA_VWPTEST_IN_FVF D3DMFVF_XYZ_FLOAT
struct D3DQA_VWPTEST_IN
{
FLOAT x, y, z;
};
#define D3DQA_VWPTEST_OUT_FVF D3DMFVF_XYZRHW_FLOAT
struct D3DQA_VWPTEST_OUT
{
FLOAT x, y, z, rhw;
};
//
// For vertex buffer locks
//
D3DQA_VWPTEST_IN *pInPos = NULL;
D3DQA_VWPTEST_OUT *pOutPos = NULL;
//
// FVF sizes for this test
//
CONST UINT uiInVertSize = sizeof(D3DQA_VWPTEST_IN); // X,Y,Z
CONST UINT uiOutVertSize = sizeof(D3DQA_VWPTEST_OUT); // X,Y,Z,RHW
//
// Device viewport
//
D3DMVIEWPORT Viewport;
//
// Iteration counter (for debug output purposes)
//
UINT uiIter = 1;
//
// Per-component values for confirming ProcessVertices success
//
float fExpectedX, fExpectedY, fExpectedZ, fExpectedRHW;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -