📄 driververif.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
#define INITGUID 1
#include "DriverVerif.h"
#include "ImageManagement.h"
#include "KatoUtils.h"
#include "BufferTools.h"
#include "VerifTestCases.h"
#include "QAMath.h"
#include "DebugOutput.h"
#include <tux.h>
#include <tchar.h>
#include <stdio.h>
//
// Release with NULL-check before and NULL-clear after
//
#define SAFERELEASE(_o) if(_o) { _o->Release(); _o=NULL; } else { DebugOut(_T("Attempted to release a NULL object.\n")); }
//
// Short define for value cast
//
#define _M(_F) D3DM_MAKE_D3DMVALUE(_F)
//
// DriverVerifTest
//
// Constructor for DriverVerifTest class; however, most initialization is deferred.
//
// Arguments:
//
// none
//
// Return Value:
//
// none
//
DriverVerifTest::DriverVerifTest()
{
m_bInitSuccess = FALSE;
}
//
// DriverVerifTest
//
// Initialize DriverVerifTest object
//
// Arguments:
//
// UINT uiAdapterOrdinal: D3DM Adapter ordinal
// WCHAR *pSoftwareDevice: Pointer to wide character string identifying a D3DM software device to instantiate
// UINT uiTestCase: Test case ordinal (to be displayed in window)
//
// Return Value
//
// HRESULT indicates success or failure
//
HRESULT DriverVerifTest::Init(LPTEST_CASE_ARGS pTestCaseArgs, LPWINDOW_ARGS pWindowArgs, UINT uiTestCase)
{
if (FAILED(D3DMInitializer::Init(D3DQA_PURPOSE_RAW_TEST, // D3DQA_PURPOSE Purpose
pWindowArgs, // LPWINDOW_ARGS pWindowArgs
pTestCaseArgs->pwchSoftwareDeviceFilename, // TCHAR *ptchDriver
uiTestCase))) // UINT uiTestCase
{
DebugOut(_T("Aborting initialization, due to prior initialization failure.\n"));
return E_FAIL;
}
m_bInitSuccess = TRUE;
m_fTestTolerance = pTestCaseArgs->fTestTolerance;
return S_OK;
}
//
// IsReady
//
// Accessor method for "initialization state" of DriverVerifTest object. "Half
// initialized" states should not occur.
//
// Return Value:
//
// BOOL: TRUE if the object is initialized; FALSE if it is not.
//
BOOL DriverVerifTest::IsReady()
{
if (FALSE == m_bInitSuccess)
{
DebugOut(_T("DriverVerifTest is not ready.\n"));
return FALSE;
}
DebugOut(_T("DriverVerifTest is ready.\n"));
return D3DMInitializer::IsReady();
}
//
// ~DriverVerifTest
//
// Destructor for DriverVerifTest. Currently; there is nothing
// to do here.
//
DriverVerifTest::~DriverVerifTest()
{
return; // Success
}
//
// SetDegenerateViewAndProj
//
// Sets viewport extents and projection matrix such that the product is an identity matrix.
// Useful for doing isolated tests on world and view matrices.
//
// Arguments:
//
//
// Return Value
//
// HRESULT indicates success or failure
//
HRESULT DriverVerifTest::SetDegenerateViewAndProj()
{
//
// Constants that cause the projection matrix and viewport transformations
// to become degenerate
//
CONST D3DMMATRIX ProjMatrix = {_M( 1.0f), _M( 0.0f), _M( 0.0f), _M( 0.0f),
_M( 0.0f), _M(-1.0f), _M( 0.0f), _M( 0.0f),
_M( 0.0f), _M( 0.0f), _M( 1.0f), _M( 0.0f),
_M(-1.0f), _M( 1.0f), _M( 0.0f), _M( 1.0f)};
CONST UINT ViewportWidth = 2;
CONST UINT ViewportHeight = 2;
//
// For retrieving/resetting viewport extents
//
D3DMVIEWPORT Viewport;
//
// Retrieve viewport
//
if (FAILED(m_pd3dDevice->GetViewport(&Viewport)))
{
DebugOut(_T("IDirect3DMobileDevice::GetViewport failed.\n"));
return E_FAIL;
}
//
// Tweak viewport; set to degenerate case
//
Viewport.Height = ViewportHeight;
Viewport.Width = ViewportWidth;
if (FAILED(m_pd3dDevice->SetViewport(&Viewport)))
{
DebugOut(_T("IDirect3DMobileDevice::SetViewport failed.\n"));
return E_FAIL;
}
//
// Indicate proj matrix to D3DM
//
if( FAILED( m_pd3dDevice->SetTransform(D3DMTS_PROJECTION, // D3DTRANSFORMSTATETYPE State,
&ProjMatrix, // CONST D3DMMATRIX* pMatrix
D3DMFMT_D3DMVALUE_FLOAT))) // D3DMFORMAT Format
{
DebugOut(_T("IDirect3DMobileDevice::SetTransform failed.\n"));
return E_FAIL;
}
return S_OK;
}
//
// ExecuteTexTransRotate
//
// This is a test of texture transforms, using rotation matrices.
//
// This function iterates through various rotation types. These rotation types include X, Y, and Z
// axis rotations, in various orders (e.g., rotating in XYZ order is distinct from ZYX order).
//
// For each rotation type, the X, Y, and Z angles of rotation are selected by an exhaustive iteration
// of a predefined angle list (currently includes 8 angles of rotation).
//
// The result of the texture transform (acheived through ProcessVertices) is compared to the
// "expected" outcome. The "expected" outcome is computed by this test, through simple matrix
// mathematics.
//
// If a comparison of any component (expected vs. actual) is not within the specified tolerance, the
// test will return TPR_FAIL. However, regardless of comparison failures, every iteration of the test
// will execute. The return of TPR_FAIL is deferred until all iterations are complete.
//
// Note: clipping has been turned off at initialization time.
//
// Arguments:
//
// fTolerance: Specifies the allowable difference between the driver-computed result for each
// texture component, and the test-computed result for each texture component.
//
// Return Value:
//
// TPR_PASS, TPR_FAIL, or TPR_SKIP, depending on test result
//
INT DriverVerifTest::ExecuteTexTransRotate()
{
//
// FVF structures and bit masks for use with this test
//
#define D3DQA_TTRTEST_IN_FVF (D3DMFVF_XYZ_FLOAT | D3DMFVF_TEX1 | D3DMFVF_TEXCOORDSIZE3(0))
struct D3DQA_TTRTEST_IN
{
FLOAT x, y, z;
FLOAT tu, tv, tr; // One set of 3D texture coordinates
};
#define D3DQA_TTRTEST_OUT_FVF (D3DMFVF_XYZRHW_FLOAT | D3DMFVF_TEX1 | D3DMFVF_TEXCOORDSIZE3(0))
struct D3DQA_TTRTEST_OUT
{
FLOAT x, y, z, rhw;
FLOAT tu, tv, tr; // One set of 3D texture coordinates
};
//
// Input and output Vertex buffers for ProcessVertices
//
IDirect3DMobileVertexBuffer *pVBIn = NULL;
IDirect3DMobileVertexBuffer *pVBOut = NULL;
//
// Device Capabilities
//
D3DMCAPS Caps;
D3DMVECTOR ResultTexCoordsExpected; // Manually-computed texture coordinates, to be compared with D3D result
D3DMMATRIX TexTransMatrix; // Matrix used to transform texture coordinates
D3DMMATRIX TexTransMatrixInverse; // Inverse of transformation matrix; for debugging purposes
UINT uiRotIndexX, uiRotIndexY, uiRotIndexZ; // Angles of rotation for each axis
UINT RotType; // Index into D3DQA_ROTTYPE; specifies axis of rotation (1 to 3 axis)
UINT uiIteration = 0; // This is a counter, used for logging/debugging purposes, of the current iteration
D3DQA_TTRTEST_IN InputVertex; // Untransformed vertices
D3DQA_TTRTEST_OUT *pOutputVert = NULL; // Pointer for resultant data (from ProcessVertices)
BYTE *pVertices = NULL; // Pointer for vertex buffer locking
UINT uiRotXFirst, uiRotXLast; // angle iteration constraints for the X-Axis (depends on rotation-type iteration)
UINT uiRotYFirst, uiRotYLast; // angle iteration constraints for the Y-Axis (depends on rotation-type iteration)
UINT uiRotZFirst, uiRotZLast; // angle iteration constraints for the Z-Axis (depends on rotation-type iteration)
//
// Tux Test Case Result; all non-pass blocks set this to another value
//
INT Result = TPR_PASS;
//
// 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;
DebugOut(_T("Beginning ExecuteTexTransRotate.\n"));
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;
}
//
// Query the device's capabilities
//
if( FAILED( m_pd3dDevice->GetDeviceCaps(&Caps)))
{
DebugOut(_T("IDirect3DMobileDevice::GetDeviceCaps failed.\n"));
Result = TPR_ABORT;
goto cleanup;
}
//
// If the device supports directional lights, assume that it supports lighting
// with at least one MaxActiveLights. Otherwise, the test cannot execute.
//
if (!(D3DMDEVCAPS_TEXTURE & Caps.DevCaps))
{
DebugOut(_T("Texturing not supported. Skipping test.\n"));
Result = TPR_SKIP;
goto cleanup;
}
ZeroMemory(&InputVertex,sizeof(D3DQA_TTRTEST_IN));
//
// Creates a Vertex Buffer; sets stream source and vertex shader type (FVF)
//
pVBOut = CreateActiveBuffer(m_pd3dDevice, 1, D3DQA_TTRTEST_OUT_FVF, sizeof(D3DQA_TTRTEST_OUT),
D3DMUSAGE_DONOTCLIP);
if (NULL == pVBOut)
{
DebugOut(_T("CreateActiveBuffer failed.\n"));
Result = TPR_ABORT;
goto cleanup;
}
//
// Creates a Vertex Buffer; sets stream source and vertex shader type (FVF)
//
pVBIn = CreateActiveBuffer(m_pd3dDevice, 1, D3DQA_TTRTEST_IN_FVF, sizeof(D3DQA_TTRTEST_IN),
D3DMUSAGE_DONOTCLIP);
if (NULL == pVBIn)
{
DebugOut(_T("CreateActiveBuffer failed.\n"));
Result = TPR_ABORT;
goto cleanup;
}
//
// Fill the input vertex buffer
//
InputVertex.x = 0.0f;
InputVertex.y = 0.0f;
InputVertex.z = 0.0f;
InputVertex.tu = 0.5f;
InputVertex.tv = 0.5f;
InputVertex.tr = 0.5f;
//
// Set up input vertices (lock, copy data into buffer, unlock)
//
if( FAILED( pVBIn->Lock( 0, sizeof(D3DQA_TTRTEST_IN), (VOID**)&pVertices, 0 ) ) )
{
DebugOut(_T("IDirect3DMobileVertexBuffer::Lock failed.\n"));
Result = TPR_ABORT;
goto cleanup;
}
memcpy( pVertices, &InputVertex, sizeof(D3DQA_TTRTEST_IN) );
if( FAILED( pVBIn->Unlock() ) )
{
DebugOut(_T("IDirect3DMobileVertexBuffer::Unlock failed.\n"));
Result = TPR_ABORT;
goto cleanup;
}
//
// Indicate that texture transforms are to affect 3 texture dimensions
//
if (FAILED(m_pd3dDevice->SetTextureStageState( 0, D3DMTSS_TEXTURETRANSFORMFLAGS, D3DMTTFF_COUNT3 )))
{
DebugOut(_T("IDirect3DMobileDevice::SetTextureStageState failed.\n"));
Result = TPR_ABORT;
goto cleanup;
}
//
// Indicate that the texture stage is active; PV will fail otherwise
//
if (FAILED(m_pd3dDevice->SetTextureStageState( 0, D3DMTSS_COLORARG1, D3DMTA_CURRENT )))
{
DebugOut(_T("IDirect3DMobileDevice::SetTextureStageState failed.\n"));
Result = TPR_ABORT;
goto cleanup;
}
//
// Iterate through a variety of texture coordinate transformations
//
for (RotType = D3DQA_FIRST_ROTTYPE; RotType <= D3DQA_LAST_ROTTYPE; RotType++)
{
DebugOut(_T("\n"));
DebugOut(_T("==============================================================\n"));
DebugOut(_T("Now beginning iterations of rotation type: %s \n"), D3DQA_ROTTYPE_NAMES[RotType]);
DebugOut(_T("==============================================================\n"));
DebugOut(_T("\n"));
//
// Some of the rotation specs (e.g., YZ) do not involve a rotation about
// the X axis; thus, only one iteration of the X-Axis loop is needed for
// these cases.
//
if (UsesXRot((D3DQA_ROTTYPE)RotType))
{
uiRotXFirst = 0;
uiRotXLast = D3DQA_NUM_SAMPLE_ROT_ANGLES-1; // Adjust for zero-based indexing
}
else
{
uiRotXFirst = uiRotXLast = 0;
}
for(uiRotIndexX = uiRotXFirst; uiRotIndexX <= uiRotXLast; uiRotIndexX++)
{
//
// Retrieve the amount (angle) of X-axis rotation for this iteration
//
float fRotX = ROTANGLES[uiRotIndexX];
//
// Some of the rotation specs (e.g., XZ) do not involve a rotation about
// the Y axis; thus, only one iteration of the Y-Axis loop is needed for
// these cases.
//
if (UsesYRot((D3DQA_ROTTYPE)RotType))
{
uiRotYFirst = 0;
uiRotYLast = D3DQA_NUM_SAMPLE_ROT_ANGLES-1; // Adjust for zero-based indexing
}
else
{
uiRotYFirst = uiRotYLast = 0;
}
for(uiRotIndexY = uiRotYFirst; uiRotIndexY <= uiRotYLast; uiRotIndexY++)
{
//
// Retrieve the amount (angle) of Y-axis rotation for this iteration
//
float fRotY = ROTANGLES[uiRotIndexY];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -