/**************************************************************************** * * File: testd3d8.cpp * Project: DxDiag (DirectX Diagnostic Tool) * Author: Jason Sandlin (jasonsa@microsoft.com) * Purpose: Test D3D8/AGP Texturing functionality on this machine * * (C) Copyright 2000 Microsoft Corp. All rights reserved. * ****************************************************************************/ #include #define DIRECT3D_VERSION 0x0800 // file uses DX8 #include #include #include "reginfo.h" #include "sysinfo.h" #include "dispinfo.h" #include "testagp.h" #include "resource.h" #ifndef ReleasePpo #define ReleasePpo(ppo) \ if (*(ppo) != NULL) \ { \ (*(ppo))->Release(); \ *(ppo) = NULL; \ } \ else (VOID)0 #endif typedef IDirect3D8* (WINAPI* LPDIRECT3DCREATE8)(UINT SDKVersion); #define D3DFVF_VERTEX (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1) #define MAX_FORMATS 64 #define MAX_MODES 256 #define MAX_CONFIRMED_MODES 256 struct D3DVERTEX { D3DXVECTOR3 p; D3DXVECTOR3 n; FLOAT tu, tv; D3DVERTEX() {}; D3DVERTEX( D3DXVECTOR3 vp, D3DXVECTOR3 vn, FLOAT fTu, FLOAT fTv ) : p(vp), n(vn), tu(fTu), tv(fTv) {} }; struct D3DModeInfo { DWORD Width; // Screen width in this mode DWORD Height; // Screen height in this mode D3DFORMAT Format; // Pixel format in this mode DWORD dwBehavior; // Hardware / Software / Mixed vertex processing }; enum TESTID { TESTID_LOAD_D3D8_DLL=1, TESTID_GET_D3DCREATE8, TESTID_D3DCREATE8, TESTID_ENUMADAPTERMODES, TESTID_GETDEVICECAPS, TESTID_NOMODEFOUND, TESTID_CREATE_TEST_WINDOW, TESTID_CREATE_DEVICE, TESTID_GETBACKBUFFER, TESTID_GETDESC, TESTID_CREATE_VERTEX_BUFFER, TESTID_CREATE_INDEX_BUFFER, TESTID_LOCK, TESTID_UNLOCK, TESTID_SETLIGHT, TESTID_LIGHTENABLE, TESTID_SETTRANSFORM, TESTID_SETRENDERSTATE, TESTID_CREATETEXTURE, TESTID_SETTEXTURESTAGESTATE, TESTID_SETTEXTURE, TESTID_SETVERTEXSHADER, TESTID_USER_CANCELLED, TESTID_VIEWPORT_CLEAR, TESTID_BEGINSCENE, TESTID_SETMATERIAL, TESTID_SETSTREAMSOURCE, TESTID_SETINDICES, TESTID_DRAW_INDEXED_PRIMITIVE, TESTID_ENDSCENE, TESTID_PRESENT, TESTID_USER_VERIFY_D3D7_RENDERING, TESTID_USER_VERIFY_D3D8_RENDERING, TESTID_LOAD_DDRAW_DLL, TESTID_GET_DIRECTDRAWCREATE, TESTID_DIRECTDRAWCREATE, TESTID_SETCOOPERATIVELEVEL_FULLSCREEN, TESTID_SETCOOPERATIVELEVEL_NORMAL, TESTID_SETDISPLAYMODE, TESTID_CREATEPRIMARYSURFACE_FLIP_ONEBACK, TESTID_GETATTACHEDSURFACE, TESTID_QUERY_D3D, TESTID_SETVIEWPORT, TESTID_ENUMTEXTUREFORMATS, TESTID_CREATESURFACE, TESTID_GETDC, TESTID_RELEASEDC, }; BOOL BTranslateError(HRESULT hr, TCHAR* psz, BOOL bEnglish = FALSE); // from main.cpp static HRESULT SelectModeAndFormat( DisplayInfo* pDisplayInfo, IDirect3D8* pD3D8, D3DModeInfo* pSelectedMode, D3DDEVTYPE* pSelectedDeviceType ); static HRESULT Test3D( BOOL bUseTexture, IDirect3D8* pD3D8, HWND hwndMain, DWORD iAdapter, D3DModeInfo selectedMode, D3DDEVTYPE selectedDeviceType, LONG* piStepThatFailed ); static HRESULT CreateTestWindow(HWND hwndMain, HWND* phwnd); static HRESULT InitVertexBuffer( IDirect3DDevice8* pd3dDevice, const D3DVERTEX* vertexArray, DWORD dwNumVertices, LPDIRECT3DVERTEXBUFFER8* ppVB, LONG* piStepThatFailed ); static HRESULT InitIndexBuffer( IDirect3DDevice8* pd3dDevice, const WORD* wIndexArray, DWORD dwNumIndices, LPDIRECT3DINDEXBUFFER8* ppIB, LONG* piStepThatFailed ); static HRESULT DrawTwoSides( BOOL bUseTexture, IDirect3DDevice8* pd3dDevice, D3DMATERIAL8* pMtrl, LPDIRECT3DVERTEXBUFFER8 pVB1, LPDIRECT3DINDEXBUFFER8 pIB1, LPDIRECT3DVERTEXBUFFER8 pVB2, LPDIRECT3DINDEXBUFFER8 pIB2, LONG* piStepThatFailed ); //----------------------------------------------------------------------------- // Name: TestD3Dv8() // Desc: //----------------------------------------------------------------------------- VOID TestD3Dv8( BOOL bUseTexture, HWND hwndMain, DisplayInfo* pDisplayInfo) { HRESULT hr = S_OK; TCHAR sz[MAX_PATH]; TCHAR szTitle[MAX_PATH]; HINSTANCE hInstD3D8 = NULL; IDirect3D8* pD3D8 = NULL; HWND hwnd = NULL; D3DModeInfo selectedMode; D3DDEVTYPE selectedDeviceType; if( pDisplayInfo == NULL ) return; LoadString(NULL, IDS_APPFULLNAME, szTitle, MAX_PATH); LPDIRECT3DCREATE8 pD3DCreate8 = NULL; TCHAR szPath[MAX_PATH]; GetSystemDirectory(szPath, MAX_PATH); lstrcat(szPath, TEXT("\\d3d8.dll")); // This may fail if DX8 isn't on the system hInstD3D8 = LoadLibrary(szPath); if (hInstD3D8 == NULL) { pDisplayInfo->m_testResultD3D8.m_iStepThatFailed = TESTID_LOAD_D3D8_DLL; pDisplayInfo->m_testResultD3D8.m_hr = E_FAIL; goto LEnd; } pD3DCreate8 = (LPDIRECT3DCREATE8)GetProcAddress(hInstD3D8, "Direct3DCreate8"); if (pD3DCreate8 == NULL) { FreeLibrary(hInstD3D8); hInstD3D8 = NULL; pDisplayInfo->m_testResultD3D8.m_iStepThatFailed = TESTID_GET_D3DCREATE8; pDisplayInfo->m_testResultD3D8.m_hr = E_POINTER; goto LEnd; } pD3D8 = pD3DCreate8(D3D_SDK_VERSION); if( pD3D8 == NULL ) { // We have the wrong headers since d3d8.dll loaded but D3DCreate8() failed. pDisplayInfo->m_testResultD3D8.m_iStepThatFailed = TESTID_D3DCREATE8; pDisplayInfo->m_testResultD3D8.m_hr = E_FAIL; goto LEnd; } // Enum and select a support mode and format and device type if( FAILED( SelectModeAndFormat( pDisplayInfo, pD3D8, &selectedMode, &selectedDeviceType ) ) ) goto LEnd; // Save the cursor POINT ptMouse; GetCursorPos(&ptMouse); // Run the test if (FAILED(hr = Test3D( bUseTexture, pD3D8, hwndMain, pDisplayInfo->m_iAdapter, selectedMode, selectedDeviceType, &pDisplayInfo->m_testResultD3D8.m_iStepThatFailed))) { pDisplayInfo->m_testResultD3D8.m_hr = hr; goto LEnd; } // Restore the cursor position SetCursorPos( ptMouse.x, ptMouse.y ); // Tell the user if they canceled if (pDisplayInfo->m_testResultD3D8.m_iStepThatFailed == TESTID_USER_CANCELLED) { LoadString(NULL, IDS_YOUCANCELLED, sz, MAX_PATH); MessageBox(hwndMain, sz, szTitle, MB_OK); pDisplayInfo->m_testResultD3D8.m_bCancelled = TRUE; goto LEnd; } // Confirm the test succeeded LoadString(NULL, IDS_CONFIRMD3DTEST, sz, MAX_PATH); if (IDNO == MessageBox(hwndMain, sz, szTitle, MB_YESNO)) { pDisplayInfo->m_testResultD3D8.m_iStepThatFailed = TESTID_USER_VERIFY_D3D8_RENDERING; pDisplayInfo->m_testResultD3D8.m_hr = S_OK; goto LEnd; } LEnd: ReleasePpo( &pD3D8 ); if( hInstD3D8 ) { FreeLibrary(hInstD3D8); hInstD3D8 = NULL; } } //----------------------------------------------------------------------------- // Name: Test3D() // Desc: Generate a spinning 3D cube //----------------------------------------------------------------------------- HRESULT Test3D( BOOL bUseTexture, IDirect3D8* pD3D8, HWND hwndMain, DWORD iAdapter, D3DModeInfo selectedMode, D3DDEVTYPE selectedDeviceType, LONG* piStepThatFailed ) { LPDIRECT3DDEVICE8 pd3dDevice = NULL; LPDIRECT3DTEXTURE8 pTexture = NULL; LPDIRECT3DVERTEXBUFFER8 pVBFront = NULL; LPDIRECT3DINDEXBUFFER8 pIBFront = NULL; LPDIRECT3DVERTEXBUFFER8 pVBBack = NULL; LPDIRECT3DINDEXBUFFER8 pIBBack = NULL; LPDIRECT3DVERTEXBUFFER8 pVBLeft = NULL; LPDIRECT3DINDEXBUFFER8 pIBLeft = NULL; LPDIRECT3DVERTEXBUFFER8 pVBRight = NULL; LPDIRECT3DINDEXBUFFER8 pIBRight = NULL; LPDIRECT3DVERTEXBUFFER8 pVBTop = NULL; LPDIRECT3DINDEXBUFFER8 pIBTop = NULL; LPDIRECT3DVERTEXBUFFER8 pVBBottom = NULL; LPDIRECT3DINDEXBUFFER8 pIBBottom = NULL; LPDIRECT3DSURFACE8 pBackBuffer = NULL; D3DMATERIAL8 mtrlWhite; D3DMATERIAL8 mtrlRed; D3DMATERIAL8 mtrlBlue; D3DMATERIAL8 mtrlGreen; D3DXMATRIX matRotY; D3DXMATRIX matRotX; D3DXMATRIX mat; D3DSURFACE_DESC d3dsdBackBuffer; FLOAT fRotY; FLOAT fRotX; HRESULT hr; HWND hwnd; MSG msg; DWORD i; static const D3DVERTEX vertexArrayFront[] = { D3DVERTEX(D3DXVECTOR3(-1.0, -1.0, -1.0), D3DXVECTOR3(0.0, 0.0, -1.0), 1.0f, 0.0f), D3DVERTEX(D3DXVECTOR3( 1.0, -1.0, -1.0), D3DXVECTOR3(0.0, 0.0, -1.0), 0.0f, 0.0f), D3DVERTEX(D3DXVECTOR3(-1.0, 1.0, -1.0), D3DXVECTOR3(0.0, 0.0, -1.0), 1.0f, 1.0f), D3DVERTEX(D3DXVECTOR3( 1.0, 1.0, -1.0), D3DXVECTOR3(0.0, 0.0, -1.0), 0.0f, 1.0f), }; static const WORD indexArrayFront[] = { 0, 2, 1, 2, 3, 1, }; static const D3DVERTEX vertexArrayBack[] = { D3DVERTEX(D3DXVECTOR3(-1.0, -1.0, 1.0), D3DXVECTOR3(0.0, 0.0, 1.0), 0.0f, 0.0f), D3DVERTEX(D3DXVECTOR3( 1.0, -1.0, 1.0), D3DXVECTOR3(0.0, 0.0, 1.0), 1.0f, 0.0f), D3DVERTEX(D3DXVECTOR3(-1.0, 1.0, 1.0), D3DXVECTOR3(0.0, 0.0, 1.0), 0.0f, 1.0f), D3DVERTEX(D3DXVECTOR3( 1.0, 1.0, 1.0), D3DXVECTOR3(0.0, 0.0, 1.0), 1.0f, 1.0f), }; static const WORD indexArrayBack[] = { 0, 1, 2, 2, 1, 3, }; static const D3DVERTEX vertexArrayLeft[] = { D3DVERTEX(D3DXVECTOR3(-1.0, -1.0, -1.0), D3DXVECTOR3(-1.0, 0.0, 0.0), 0.0f, 0.0f), D3DVERTEX(D3DXVECTOR3(-1.0, -1.0, 1.0), D3DXVECTOR3(-1.0, 0.0, 0.0), 1.0f, 0.0f), D3DVERTEX(D3DXVECTOR3(-1.0, 1.0, -1.0), D3DXVECTOR3(-1.0, 0.0, 0.0), 0.0f, 1.0f), D3DVERTEX(D3DXVECTOR3(-1.0, 1.0, 1.0), D3DXVECTOR3(-1.0, 0.0, 0.0), 1.0f, 1.0f), }; static const WORD indexArrayLeft[] = { 0, 1, 2, 2, 1, 3, }; static const D3DVERTEX vertexArrayRight[] = { D3DVERTEX(D3DXVECTOR3(1.0, -1.0, -1.0), D3DXVECTOR3(1.0, 0.0, 0.0), 1.0f, 0.0f), D3DVERTEX(D3DXVECTOR3(1.0, -1.0, 1.0), D3DXVECTOR3(1.0, 0.0, 0.0), 0.0f, 0.0f), D3DVERTEX(D3DXVECTOR3(1.0, 1.0, -1.0), D3DXVECTOR3(1.0, 0.0, 0.0), 1.0f, 1.0f), D3DVERTEX(D3DXVECTOR3(1.0, 1.0, 1.0), D3DXVECTOR3(1.0, 0.0, 0.0), 0.0f, 1.0f), }; static const WORD indexArrayRight[] = { 0, 2, 1, 2, 3, 1, }; static const D3DVERTEX vertexArrayTop[] = { D3DVERTEX(D3DXVECTOR3(-1.0, 1.0, -1.0), D3DXVECTOR3(0.0, 1.0, 0.0), 0.0f, 1.0f), D3DVERTEX(D3DXVECTOR3( 1.0, 1.0, -1.0), D3DXVECTOR3(0.0, 1.0, 0.0), 1.0f, 1.0f), D3DVERTEX(D3DXVECTOR3(-1.0, 1.0, 1.0), D3DXVECTOR3(0.0, 1.0, 0.0), 0.0f, 0.0f), D3DVERTEX(D3DXVECTOR3( 1.0, 1.0, 1.0), D3DXVECTOR3(0.0, 1.0, 0.0), 1.0f, 0.0f), }; static const WORD indexArrayTop[] = { 0, 2, 1, 2, 3, 1, }; static const D3DVERTEX vertexArrayBottom[] = { D3DVERTEX(D3DXVECTOR3(-1.0, -1.0, -1.0), D3DXVECTOR3(0.0, -1.0, 0.0), 1.0f, 1.0f), D3DVERTEX(D3DXVECTOR3( 1.0, -1.0, -1.0), D3DXVECTOR3(0.0, -1.0, 0.0), 0.0f, 1.0f), D3DVERTEX(D3DXVECTOR3(-1.0, -1.0, 1.0), D3DXVECTOR3(0.0, -1.0, 0.0), 1.0f, 0.0f), D3DVERTEX(D3DXVECTOR3( 1.0, -1.0, 1.0), D3DXVECTOR3(0.0, -1.0, 0.0), 0.0f, 0.0f), }; static const WORD indexArrayBottom[] = { 0, 1, 2, 2, 1, 3, }; ShowCursor(FALSE); // Create test window if (FAILED(hr = CreateTestWindow(hwndMain, &hwnd))) { *piStepThatFailed = TESTID_CREATE_TEST_WINDOW; goto LEnd; } // Set up the presentation parameters D3DPRESENT_PARAMETERS d3dpp; ZeroMemory( &d3dpp, sizeof(d3dpp) ); d3dpp.Windowed = FALSE; d3dpp.BackBufferCount = 1; d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.EnableAutoDepthStencil = FALSE; d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE; d3dpp.hDeviceWindow = hwnd; d3dpp.BackBufferWidth = selectedMode.Width; d3dpp.BackBufferHeight = selectedMode.Height; d3dpp.BackBufferFormat = selectedMode.Format; // Create the device if( FAILED( hr = pD3D8->CreateDevice( iAdapter, selectedDeviceType, hwnd, selectedMode.dwBehavior, &d3dpp, &pd3dDevice ) ) ) { *piStepThatFailed = TESTID_CREATE_DEVICE; goto LEnd; } if( pd3dDevice == NULL ) { *piStepThatFailed = TESTID_CREATE_DEVICE; hr = E_POINTER; goto LEnd; } // Get the desc of the backbuffer if( FAILED( hr = pd3dDevice->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer ) ) ) { *piStepThatFailed = TESTID_GETBACKBUFFER; goto LEnd; } if( pBackBuffer == NULL ) { *piStepThatFailed = TESTID_GETBACKBUFFER; hr = E_POINTER; goto LEnd; } if( FAILED( hr = pBackBuffer->GetDesc( &d3dsdBackBuffer ) ) ) { *piStepThatFailed = TESTID_GETDESC; goto LEnd; } ReleasePpo(&pBackBuffer); // Init the vertex/index buffer for the Front if( FAILED( hr = InitVertexBuffer( pd3dDevice, vertexArrayFront, sizeof(vertexArrayFront)/sizeof(D3DVERTEX), &pVBFront, piStepThatFailed ) ) ) goto LEnd; if( FAILED( hr = InitIndexBuffer( pd3dDevice, indexArrayFront, sizeof(indexArrayFront)/sizeof(WORD), &pIBFront, piStepThatFailed ) ) ) goto LEnd; // Init the vertex/index buffer for the Back if( FAILED( hr = InitVertexBuffer( pd3dDevice, vertexArrayBack, sizeof(vertexArrayBack)/sizeof(D3DVERTEX), &pVBBack, piStepThatFailed ) ) ) goto LEnd; if( FAILED( hr = InitIndexBuffer( pd3dDevice, indexArrayBack, sizeof(indexArrayBack)/sizeof(WORD), &pIBBack, piStepThatFailed ) ) ) goto LEnd; // Init the vertex/index buffer for the Left if( FAILED( hr = InitVertexBuffer( pd3dDevice, vertexArrayLeft, sizeof(vertexArrayLeft)/sizeof(D3DVERTEX), &pVBLeft, piStepThatFailed ) ) ) goto LEnd; if( FAILED( hr = InitIndexBuffer( pd3dDevice, indexArrayLeft, sizeof(indexArrayLeft)/sizeof(WORD), &pIBLeft, piStepThatFailed ) ) ) goto LEnd; // Init the vertex/index buffer for the Right if( FAILED( hr = InitVertexBuffer( pd3dDevice, vertexArrayRight, sizeof(vertexArrayRight)/sizeof(D3DVERTEX), &pVBRight, piStepThatFailed ) ) ) goto LEnd; if( FAILED( hr = InitIndexBuffer( pd3dDevice, indexArrayRight, sizeof(indexArrayRight)/sizeof(WORD), &pIBRight, piStepThatFailed ) ) ) goto LEnd; // Init the vertex/index buffer for the Top if( FAILED( hr = InitVertexBuffer( pd3dDevice, vertexArrayTop, sizeof(vertexArrayTop)/sizeof(D3DVERTEX), &pVBTop, piStepThatFailed ) ) ) goto LEnd; if( FAILED( hr = InitIndexBuffer( pd3dDevice, indexArrayTop, sizeof(indexArrayTop)/sizeof(WORD), &pIBTop, piStepThatFailed ) ) ) goto LEnd; // Init the vertex/index buffer for the Bottom if( FAILED( hr = InitVertexBuffer( pd3dDevice, vertexArrayBottom, sizeof(vertexArrayBottom)/sizeof(D3DVERTEX), &pVBBottom, piStepThatFailed ) ) ) goto LEnd; if( FAILED( hr = InitIndexBuffer( pd3dDevice, indexArrayBottom, sizeof(indexArrayBottom)/sizeof(WORD), &pIBBottom, piStepThatFailed ) ) ) goto LEnd; // Add a light D3DLIGHT8 light; ZeroMemory( &light, sizeof(D3DLIGHT8) ); light.Type = D3DLIGHT_DIRECTIONAL; light.Diffuse.r = 1.0f; light.Diffuse.g = 1.0f; light.Diffuse.b = 1.0f; light.Direction.x = 0.0f; light.Direction.y = 0.0f; light.Direction.z = 1.0f; if( FAILED( hr = pd3dDevice->SetLight( 0, &light ) ) ) { *piStepThatFailed = TESTID_SETLIGHT; goto LEnd; } if( FAILED( hr = pd3dDevice->LightEnable( 0, TRUE ) ) ) { *piStepThatFailed = TESTID_LIGHTENABLE; goto LEnd; } // Set up matrices mat = D3DXMATRIX(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); if( FAILED( hr = pd3dDevice->SetTransform( D3DTS_WORLD, &mat ) ) ) { *piStepThatFailed = TESTID_SETTRANSFORM; goto LEnd; } mat = D3DXMATRIX(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 5.0f, 1.0f); if( FAILED( hr = pd3dDevice->SetTransform( D3DTS_VIEW, &mat ) ) ) { *piStepThatFailed = TESTID_SETTRANSFORM; goto LEnd; } D3DXMatrixPerspectiveFovLH( &mat, D3DXToRadian(60.0f), (float) d3dsdBackBuffer.Width / (float) d3dsdBackBuffer.Height, 1.0f, 1000.0f ); if( FAILED( hr = pd3dDevice->SetTransform( D3DTS_PROJECTION, &mat ) ) ) { *piStepThatFailed = TESTID_SETTRANSFORM; goto LEnd; } fRotY = 3.14f; fRotX = 0.0f; if( FAILED( hr = pd3dDevice->SetRenderState( D3DRS_DITHERENABLE, TRUE ) ) ) { *piStepThatFailed = TESTID_SETRENDERSTATE; goto LEnd; } if( FAILED( hr = pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0x40404040 ) ) ) { *piStepThatFailed = TESTID_SETRENDERSTATE; goto LEnd; } ZeroMemory( &mtrlWhite, sizeof(D3DMATERIAL8) ); mtrlWhite.Diffuse.r = mtrlWhite.Ambient.r = 1.0f; mtrlWhite.Diffuse.g = mtrlWhite.Ambient.g = 1.0f; mtrlWhite.Diffuse.b = mtrlWhite.Ambient.b = 1.0f; mtrlWhite.Diffuse.a = mtrlWhite.Ambient.a = 0.0f; ZeroMemory( &mtrlRed, sizeof(D3DMATERIAL8) ); mtrlRed.Diffuse.r = mtrlRed.Ambient.r = 1.0f; mtrlRed.Diffuse.g = mtrlRed.Ambient.g = 0.0f; mtrlRed.Diffuse.b = mtrlRed.Ambient.b = 0.0f; mtrlRed.Diffuse.a = mtrlRed.Ambient.a = 0.0f; ZeroMemory( &mtrlGreen, sizeof(D3DMATERIAL8) ); mtrlGreen.Diffuse.r = mtrlGreen.Ambient.r = 0.0f; mtrlGreen.Diffuse.g = mtrlGreen.Ambient.g = 1.0f; mtrlGreen.Diffuse.b = mtrlGreen.Ambient.b = 0.0f; mtrlGreen.Diffuse.a = mtrlGreen.Ambient.a = 0.0f; ZeroMemory( &mtrlBlue, sizeof(D3DMATERIAL8) ); mtrlBlue.Diffuse.r = mtrlBlue.Ambient.r = 0.0f; mtrlBlue.Diffuse.g = mtrlBlue.Ambient.g = 0.0f; mtrlBlue.Diffuse.b = mtrlBlue.Ambient.b = 1.0f; mtrlBlue.Diffuse.a = mtrlBlue.Ambient.a = 0.0f; if( bUseTexture ) { D3DCAPS8 d3dCaps; // Load default texture in resource anDefaultTextureResource[i] if( FAILED( hr = D3DXCreateTextureFromResourceEx( pd3dDevice, NULL, TEXT("DIRECTX"), D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, d3dsdBackBuffer.Format, D3DPOOL_DEFAULT, D3DX_FILTER_TRIANGLE|D3DX_FILTER_MIRROR, D3DX_FILTER_TRIANGLE|D3DX_FILTER_MIRROR, 0, NULL, NULL, &pTexture ) ) ) { *piStepThatFailed = TESTID_CREATETEXTURE; goto LEnd; } if( FAILED( hr = pd3dDevice->GetDeviceCaps( &d3dCaps ) ) ) { *piStepThatFailed = TESTID_GETDEVICECAPS; goto LEnd; } if( d3dCaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFLINEAR ) { if (FAILED(hr = pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR ))) { *piStepThatFailed = TESTID_SETTEXTURESTAGESTATE; goto LEnd; } } if( d3dCaps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFLINEAR ) { if (FAILED(hr = pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR ))) { *piStepThatFailed = TESTID_SETTEXTURESTAGESTATE; goto LEnd; } } if (FAILED( hr = pd3dDevice->SetTexture( 0, pTexture ) ) ) { *piStepThatFailed = TESTID_SETTEXTURE; goto LEnd; } if (FAILED(hr = pd3dDevice->SetTextureStageState( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP ) ) ) { *piStepThatFailed = TESTID_SETTEXTURESTAGESTATE; goto LEnd; } if (FAILED(hr = pd3dDevice->SetTextureStageState( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP ) ) ) { *piStepThatFailed = TESTID_SETTEXTURESTAGESTATE; goto LEnd; } if (FAILED(hr = pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ) ) ) { *piStepThatFailed = TESTID_SETTEXTURESTAGESTATE; goto LEnd; } if (FAILED(hr = pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ) ) ) { *piStepThatFailed = TESTID_SETTEXTURESTAGESTATE; goto LEnd; } if (FAILED(hr = pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ) ) ) { *piStepThatFailed = TESTID_SETTEXTURESTAGESTATE; goto LEnd; } // Set color if( FAILED( hr = pd3dDevice->SetMaterial( &mtrlWhite ) ) ) { *piStepThatFailed = TESTID_SETMATERIAL; goto LEnd; } } if( FAILED( hr = pd3dDevice->SetVertexShader( D3DFVF_VERTEX ) ) ) { *piStepThatFailed = TESTID_SETVERTEXSHADER; goto LEnd; } // Here's the draw loop: for (i = 0; i < 600; i++) { if (PeekMessage(&msg, hwnd, WM_KEYDOWN, WM_KEYDOWN, PM_REMOVE)) { *piStepThatFailed = TESTID_USER_CANCELLED; goto LEnd; } if( FAILED( hr = pd3dDevice->TestCooperativeLevel() ) ) { *piStepThatFailed = TESTID_USER_CANCELLED; goto LEnd; } // Build world matrix D3DXMatrixRotationY( &matRotY, fRotY ); D3DXMatrixRotationX( &matRotX, fRotX ); D3DXMatrixMultiply( &mat, &matRotY, &matRotX ); if( FAILED( hr = pd3dDevice->SetTransform( D3DTS_WORLD, &mat ) ) ) { *piStepThatFailed = TESTID_SETTRANSFORM; goto LEnd; } // Clear the backbuffer if (FAILED(hr = pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0L ))) { *piStepThatFailed = TESTID_VIEWPORT_CLEAR; goto LEnd; } // Begin the scene if( FAILED(hr = pd3dDevice->BeginScene() ) ) { *piStepThatFailed = TESTID_BEGINSCENE; goto LEnd; } // Green, Front/Back if( FAILED( hr = DrawTwoSides( bUseTexture, pd3dDevice, &mtrlGreen, pVBFront, pIBFront, pVBBack, pIBBack, piStepThatFailed ) ) ) goto LEnd; // Red, Left/Right if( FAILED( hr = DrawTwoSides( bUseTexture, pd3dDevice, &mtrlRed, pVBLeft, pIBLeft, pVBRight, pIBRight, piStepThatFailed ) ) ) goto LEnd; // Blue, Top/Bottom if( FAILED( hr = DrawTwoSides( bUseTexture, pd3dDevice, &mtrlBlue, pVBTop, pIBTop, pVBBottom, pIBBottom, piStepThatFailed ) ) ) goto LEnd; // End the scene. if (FAILED(hr = pd3dDevice->EndScene())) { *piStepThatFailed = TESTID_ENDSCENE; goto LEnd; } if (FAILED(hr = pd3dDevice->Present( NULL, NULL, NULL, NULL ) ) ) { *piStepThatFailed = TESTID_PRESENT; goto LEnd; } fRotY += 0.05f; fRotX += 0.02f; Sleep(10); } LEnd: ShowCursor(TRUE); ReleasePpo(&pTexture); ReleasePpo(&pVBFront); ReleasePpo(&pIBFront); ReleasePpo(&pVBBack); ReleasePpo(&pIBBack); ReleasePpo(&pVBLeft); ReleasePpo(&pIBLeft); ReleasePpo(&pVBRight); ReleasePpo(&pIBRight); ReleasePpo(&pVBTop); ReleasePpo(&pIBTop); ReleasePpo(&pVBBottom); ReleasePpo(&pIBBottom); ReleasePpo(&pBackBuffer); ReleasePpo(&pd3dDevice); if (hwnd != NULL) SendMessage(hwnd, WM_CLOSE, 0, 0); return hr; } //----------------------------------------------------------------------------- // Name: CreateTestWindow() // Desc: //----------------------------------------------------------------------------- HRESULT CreateTestWindow(HWND hwndMain, HWND* phwnd) { static BOOL bClassRegistered = FALSE; WNDCLASS wndClass; TCHAR* pszClass = TEXT("DxDiag D3D8 Test Window"); // Don't need to localize HINSTANCE hInst = (HINSTANCE)GetWindowLongPtr(hwndMain, GWLP_HINSTANCE); TCHAR szTitle[MAX_PATH]; if (!bClassRegistered) { ZeroMemory(&wndClass, sizeof(wndClass)); wndClass.style = CS_HREDRAW | CS_VREDRAW; wndClass.lpfnWndProc = DefWindowProc; wndClass.cbClsExtra = 0; wndClass.cbWndExtra = 0; wndClass.hInstance = hInst; wndClass.hIcon = NULL; wndClass.hCursor = NULL; wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndClass.lpszMenuName = NULL; wndClass.lpszClassName = pszClass; if (NULL == RegisterClass(&wndClass)) return E_FAIL; bClassRegistered = TRUE; } LoadString(NULL, IDS_APPFULLNAME, szTitle, MAX_PATH); *phwnd = CreateWindow( pszClass, szTitle, WS_OVERLAPPED, 0, 0, 0, 0, hwndMain, NULL, hInst, NULL); if (*phwnd == NULL) return E_FAIL; ShowWindow(*phwnd, SW_SHOW); return S_OK; } //----------------------------------------------------------------------------- // Name: SortModesCallback() // Desc: Callback function for sorting display modes (used by BuildDeviceList). //----------------------------------------------------------------------------- static int SortModesCallback( const VOID* arg1, const VOID* arg2 ) { D3DDISPLAYMODE* p1 = (D3DDISPLAYMODE*)arg1; D3DDISPLAYMODE* p2 = (D3DDISPLAYMODE*)arg2; if( p1->Format > p2->Format ) return -1; if( p1->Format < p2->Format ) return +1; if( p1->Width < p2->Width ) return -1; if( p1->Width > p2->Width ) return +1; if( p1->Height < p2->Height ) return -1; if( p1->Height > p2->Height ) return +1; return 0; } //----------------------------------------------------------------------------- // Name: SelectModeAndFormat() // Desc: //----------------------------------------------------------------------------- HRESULT SelectModeAndFormat( DisplayInfo* pDisplayInfo, IDirect3D8* pD3D8, D3DModeInfo* pSelectedMode, D3DDEVTYPE* pSelectedDeviceType ) { // Enumerate all display modes on this adapter HRESULT hr; D3DDISPLAYMODE modes[MAX_MODES]; D3DFORMAT formats[MAX_FORMATS]; DWORD dwBehavior[MAX_FORMATS]; D3DModeInfo confirmedModes[MAX_CONFIRMED_MODES]; ZeroMemory( pSelectedMode, sizeof(D3DModeInfo) ); DWORD dwNumConfirmedModes = 0; DWORD dwNumFormats = 0; DWORD dwNumModes = 0; DWORD dwNumAdapterModes = pD3D8->GetAdapterModeCount( pDisplayInfo->m_iAdapter ); DWORD dwBestMatchMode = 0; for( UINT iMode = 0; iMode < dwNumAdapterModes; iMode++ ) { // Get the display mode attributes D3DDISPLAYMODE DisplayMode; if( FAILED( hr = pD3D8->EnumAdapterModes( pDisplayInfo->m_iAdapter, iMode, &DisplayMode ) ) ) { pDisplayInfo->m_testResultD3D8.m_iStepThatFailed = TESTID_ENUMADAPTERMODES; pDisplayInfo->m_testResultD3D8.m_hr = hr; return hr; } // Check if the mode already exists (to filter out refresh rates) for( DWORD m=0L; mGetDeviceCaps( pDisplayInfo->m_iAdapter, DeviceTypes[iDevice], &d3dCaps ) ) ) { pDisplayInfo->m_testResultD3D8.m_iStepThatFailed = TESTID_GETDEVICECAPS; pDisplayInfo->m_testResultD3D8.m_hr = hr; return hr; } // Examine each format supported by the adapter for( DWORD f=0; fCheckDeviceType( pDisplayInfo->m_iAdapter, DeviceTypes[iDevice], formats[f], formats[f], FALSE ) ) ) continue; // Figure out the behavior if( d3dCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ) { if( d3dCaps.DevCaps & D3DDEVCAPS_PUREDEVICE ) { dwBehavior[f] = D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE; } else { dwBehavior[f] = D3DCREATE_HARDWARE_VERTEXPROCESSING; } } else { dwBehavior[f] = D3DCREATE_SOFTWARE_VERTEXPROCESSING; } } // Add all enumerated display modes with confirmed formats to the // device's list of valid modes for( DWORD m=0L; m 0 ) break; } if( dwNumConfirmedModes > 0 ) { *pSelectedDeviceType = DeviceTypes[iDevice]; *pSelectedMode = confirmedModes[dwBestMatchMode]; return S_OK; } else { pDisplayInfo->m_testResultD3D8.m_iStepThatFailed = TESTID_NOMODEFOUND; pDisplayInfo->m_testResultD3D8.m_hr = E_FAIL; return E_FAIL; } } //----------------------------------------------------------------------------- // Name: InitVertexBuffer() // Desc: //----------------------------------------------------------------------------- HRESULT InitVertexBuffer( IDirect3DDevice8* pd3dDevice, const D3DVERTEX* vertexArray, DWORD dwNumVertices, LPDIRECT3DVERTEXBUFFER8* ppVB, LONG* piStepThatFailed ) { HRESULT hr = S_OK; DWORD i; D3DVERTEX* vVertex = NULL; if( FAILED( hr = pd3dDevice->CreateVertexBuffer( dwNumVertices*sizeof(D3DVERTEX), D3DUSAGE_WRITEONLY, D3DFVF_VERTEX, D3DPOOL_MANAGED, ppVB ) ) ) { *piStepThatFailed = TESTID_CREATE_VERTEX_BUFFER; goto LEnd; } if( *ppVB == NULL ) { *piStepThatFailed = TESTID_CREATE_VERTEX_BUFFER; hr = E_POINTER; goto LEnd; } if( FAILED( hr = (*ppVB)->Lock( 0, 0, (BYTE**)&vVertex, 0 ) ) ) { *piStepThatFailed = TESTID_LOCK; goto LEnd; } if( vVertex == NULL ) { *piStepThatFailed = TESTID_LOCK; goto LEnd; } for( i=0; iUnlock() ) ) { *piStepThatFailed = TESTID_UNLOCK; goto LEnd; } LEnd: return hr; } //----------------------------------------------------------------------------- // Name: InitIndexBuffer() // Desc: //----------------------------------------------------------------------------- HRESULT InitIndexBuffer( IDirect3DDevice8* pd3dDevice, const WORD* wIndexArray, DWORD dwNumIndices, LPDIRECT3DINDEXBUFFER8* ppIB, LONG* piStepThatFailed ) { HRESULT hr = S_OK; DWORD i; WORD* pwIndices = NULL; if( FAILED( hr = pd3dDevice->CreateIndexBuffer( dwNumIndices*sizeof(WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, ppIB ) ) ) { *piStepThatFailed = TESTID_CREATE_INDEX_BUFFER; goto LEnd; } if( *ppIB == NULL ) { *piStepThatFailed = TESTID_CREATE_INDEX_BUFFER; hr = E_POINTER; goto LEnd; } if( FAILED( hr = (*ppIB)->Lock( 0, dwNumIndices*sizeof(WORD), (BYTE**) &pwIndices, 0 ) ) ) { *piStepThatFailed = TESTID_LOCK; goto LEnd; } if( pwIndices == NULL ) { *piStepThatFailed = TESTID_LOCK; goto LEnd; } for( i=0; iUnlock() ) ) { *piStepThatFailed = TESTID_UNLOCK; goto LEnd; } LEnd: return hr; } //----------------------------------------------------------------------------- // Name: DrawTwoSides() // Desc: //----------------------------------------------------------------------------- HRESULT DrawTwoSides( BOOL bUseTexture, IDirect3DDevice8* pd3dDevice, D3DMATERIAL8* pMtrl, LPDIRECT3DVERTEXBUFFER8 pVB1, LPDIRECT3DINDEXBUFFER8 pIB1, LPDIRECT3DVERTEXBUFFER8 pVB2, LPDIRECT3DINDEXBUFFER8 pIB2, LONG* piStepThatFailed ) { HRESULT hr; if( !bUseTexture ) { // Set color if( FAILED( hr = pd3dDevice->SetMaterial( pMtrl ) ) ) { *piStepThatFailed = TESTID_SETMATERIAL; goto LEnd; } } // #1 if( FAILED( hr = pd3dDevice->SetStreamSource( 0, pVB1, sizeof(D3DVERTEX) ) ) ) { *piStepThatFailed = TESTID_SETSTREAMSOURCE; goto LEnd; } if( FAILED( hr = pd3dDevice->SetIndices( pIB1, 0 ) ) ) { *piStepThatFailed = TESTID_SETINDICES; goto LEnd; } if( FAILED( hr = pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 4, 0, 2 ) ) ) { *piStepThatFailed = TESTID_DRAW_INDEXED_PRIMITIVE; goto LEnd; } // #2 if( FAILED( hr = pd3dDevice->SetStreamSource( 0, pVB2, sizeof(D3DVERTEX) ) ) ) { *piStepThatFailed = TESTID_SETSTREAMSOURCE; goto LEnd; } if( FAILED( hr = pd3dDevice->SetIndices( pIB2, 0 ) ) ) { *piStepThatFailed = TESTID_SETINDICES; goto LEnd; } if( FAILED( hr = pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 4, 0, 2 ) ) ) { *piStepThatFailed = TESTID_DRAW_INDEXED_PRIMITIVE; goto LEnd; } LEnd: return hr; }