HRESULT U2Dx9ShaderMgr::ReloadShader( size_t index, bool bVerbose ) { HRESULT hr = S_OK; if( index >= m_shaders.size() ) return( E_FAIL ); if( index == 0 ) return( S_OK ); size_t defname_length, objname_length; defname_length = m_shaders.at(index).m_szShaderDefFile.length(); objname_length = m_shaders.at(index).m_szShaderObjFile.length(); if( bVerbose ) FMsg("defname_length = %u objname_length = %u\n", defname_length, objname_length ); if( defname_length > 0 && objname_length > 0 ) { if( bVerbose ) FMsg("Shader %u has both a text source name and binary object name. Can't tell whether to compile or create from binary!\n", index ); U2ASSERT( false ); return( E_FAIL ); } if( defname_length > 0 ) { hr = LoadAndAssembleShader( &(m_shaders[index]) ); if( bVerbose ) FMsg("Loaded shader %s : %s\n", SUCCEEDED(hr) ? "SUCCEEDED" : "FAILED ", m_shaders[index].m_szShaderDefFile.c_str() ); } return( hr ); }
HRESULT U2Dx9ShaderMgr::HandleErrorString( const U2String & strError ) { HRESULT hr = S_OK; U2String::size_type i; i = strError.find( TEXT("error") ); U2String err; int column_width = 90; if( i > 0 && i < strError.size() ) { err = strError.substr( i, strError.size() ); i = err.find( TEXT(" "), column_width ); while( i > 0 && i < err.size() ) { U2String spacer = TEXT("\n "); err.insert( i, spacer ); i = err.find( TEXT(" "), i + 2 + spacer.size() + column_width ); } } else { err = strError; } FMsg("[\n%s]\n", err.c_str() ); return( hr ); }
HRESULT U2Dx9ShaderMgr::SetShader( ShaderIndex index ) { // sets device's vertex or pixel shader HRESULT hr = S_OK; MSG_BREAK_AND_RET_VAL_IF( ms_pD3DDev==NULL, TEXT("U2Dx9ShaderMgr::SetShader() U2Dx9ShaderMgr not initialized!\n"), E_FAIL ); if( index < m_shaders.size() ) { U2Dx9ShaderDesc::ShaderType ShaderType; ShaderType = m_shaders.at(index).m_type; switch( ShaderType ) { case U2Dx9ShaderDesc::SHADERTYPE_VERTEX : ms_pD3DDev->SetVertexShader( (IDirect3DVertexShader9*) (m_shaders.at(index).m_pShader) ); break; case U2Dx9ShaderDesc::SHADERTYPE_PIXEL : ms_pD3DDev->SetPixelShader( (IDirect3DPixelShader9*) (m_shaders.at(index).m_pShader) ); break; default: U2ASSERT( false ); hr = E_FAIL; break; } } else { FMsg("U2Dx9ShaderMgr Index out of bounds! %u\n", index ); U2ASSERT( false ); hr = E_FAIL; } return( hr ); }
void U2Dx9ShaderMgr::ListAllShaders() { uint32 i; for( i = 0; i < m_shaders.size() ; ++i) { FMsg("Shader %3.3d %s\n", i, GetShaderObjName(i).c_str() ); } }
// Assemble shader using DX runtime HRESULT U2Dx9ShaderMgr::LoadAndAssembleShader( U2Dx9ShaderDesc * pDesc ) { HRESULT hr = S_OK; FAIL_IF_NULL( pDesc ); FreeShader( pDesc ); LPD3DXBUFFER pbufShader, pbufErrors; //flags: // D3DXSHADER_DEBUG // D3DXSHADER_SKIPVALIDATION // D3DXSHADER_SKIPOPTIMIZATION hr = D3DXAssembleShaderFromFile( pDesc->m_szShaderDefFile.c_str(), NULL, // D3DXMACRO defines NULL, // LPD3DXINcLUDE include, NULL = do #include 0, // flags &pbufShader, &pbufErrors ); if( FAILED( hr )) { FMsg("U2Dx9ShaderMgr::LoadAndAssembleShader( U2Dx9ShaderDesc * pDesc ) Errors:\n"); if( pbufErrors != NULL ) { HandleErrorString( (TCHAR*) pbufErrors->GetBufferPointer() ); } else { FMsg("Error buffer is NULL!\n"); } SAFE_RELEASE( pbufShader ); BREAK_AND_RET_VAL_IF_FAILED( hr ); } hr = CreateShader( pbufShader, pDesc->m_type, pDesc ); if( FAILED(hr) ) { FMsg("LoadAndAssembleShader( U2Dx9ShaderDesc * pDesc ) couldn't create shader : %s\n", pDesc->m_szShaderDefFile.c_str() ); } return( hr ); }
HRESULT DXDiagNVUtil::GetDisplayDeviceMemoryInMB( DWORD dwDevice, int * pDisplayMemory ) { HRESULT hr = S_OK; FAIL_IF_NULL( pDisplayMemory ); *pDisplayMemory = 0; wstring wstr; hr = GetDisplayDeviceProp( dwDevice, L"szDisplayMemoryEnglish", &wstr ); MSG_IF( FAILED(hr), "GetDisplayDeviceMemoryInMB() Couldn't get the property string!\n"); // decode the value to an int // assume 1st string is the integer number int nMem; int num_fields; num_fields = swscanf( wstr.c_str(), L"%d", &nMem ); if( num_fields != 1 ) { FMsg("GetDisplayDeviceMemoryInMB error scanning memory string description!\n"); return( E_FAIL ); } *pDisplayMemory = nMem; return( hr ); }
HRESULT DXDiagNVUtil::InitIDxDiagContainer() { // Call FreeIDxDiagContainer() to clean up things done here HRESULT hr; if( m_pDxDiagRoot != NULL ) { FMsg("DXDiagNVUtil::InitIDxDiagContainer already initialized!\n"); return( S_OK ); } // Init COM. COM may fail if its already been inited with a different // concurrency model. And if it fails you shouldn't release it. hr = CoInitialize(NULL); m_bCleanupCOM = SUCCEEDED(hr); // Get an IDxDiagProvider hr = CoCreateInstance( CLSID_DxDiagProvider, NULL, CLSCTX_INPROC_SERVER, IID_IDxDiagProvider, (LPVOID*) &m_pDxDiagProvider ); if( SUCCEEDED(hr) ) { // Fill out a DXDIAG_INIT_PARAMS struct DXDIAG_INIT_PARAMS dxDiagInitParam; ZeroMemory( &dxDiagInitParam, sizeof(DXDIAG_INIT_PARAMS) ); dxDiagInitParam.dwSize = sizeof(DXDIAG_INIT_PARAMS); dxDiagInitParam.dwDxDiagHeaderVersion = DXDIAG_DX9_SDK_VERSION; dxDiagInitParam.bAllowWHQLChecks = false; dxDiagInitParam.pReserved = NULL; // Init the m_m_pDxDiagProvider hr = m_pDxDiagProvider->Initialize( &dxDiagInitParam ); if( SUCCEEDED(hr) ) { // Get the DxDiag root container hr = m_pDxDiagProvider->GetRootContainer( & m_pDxDiagRoot ); if( FAILED(hr) ) { FMsg("Couldn't GetRootContainer from DxDiagProvider!\n"); assert( false ); FreeIDxDiagContainer(); return( hr ); } } else { FMsg("Couldn't Initialize DxDiagProvider!\n"); assert( false ); FreeIDxDiagContainer(); return( hr ); } } else { FMsg("Couldn't initialize COM!\n"); assert( false ); FreeIDxDiagContainer(); return( hr ); } return( hr ); }
HRESULT U2Dx9ShaderMgr::LoadAndAssembleShader( const TCHAR * file_name, U2Dx9ShaderDesc::ShaderType ShaderType, ShaderIndex * outIndex, bool bVerbose ) { // assemble shader using DX runtime HRESULT hr = S_OK; MSG_BREAK_AND_RET_VAL_IF( ms_pD3DDev==NULL, TEXT("U2Dx9ShaderMgr::LoadAndAssembleShader(..) U2Dx9ShaderMgr not initialized!\n"), E_FAIL ); /* //@@@@@ this is mixing up the shaders // Check to see if shader has already been loaded & created ShaderIndex index; if( IsShaderLoaded( strFilePath, & index )) { FDebug("Shader [%s] already assembled and has index %u\n", strFilePath.c_str(), index ); *outIndex = index; return( S_OK ); } //*/ U2Dx9ShaderDesc* pDesc = U2_NEW U2Dx9ShaderDesc(); LPD3DXBUFFER pbufShader, pbufErrors; //flags: // D3DXSHADER_DEBUG // D3DXSHADER_SKIPVALIDATION // D3DXSHADER_SKIPOPTIMIZATION hr = D3DXAssembleShaderFromFile( file_name, NULL, // D3DXMACRO defines NULL, // LPD3DXINcLUDE include, NULL = do #include 0, // flags &pbufShader, &pbufErrors ); if( FAILED( hr )) { FMsg("U2Dx9ShaderMgr::LoadAndAssembleShader Errors:\n"); if( pbufErrors != NULL ) { HandleErrorString( (TCHAR*) pbufErrors->GetBufferPointer() ); } else { FMsg("Error buffer is NULL!\n"); } SAFE_RELEASE( pbufShader ); BREAK_AND_RET_VAL_IF_FAILED( hr ); } hr = CreateShader( pbufShader, ShaderType, pDesc ); pDesc->m_szShaderDefFile = file_name; pDesc->m_szShaderObjFile = TEXT(""); pDesc->m_type = ShaderType; m_shaders.push_back( *pDesc ); * outIndex = (ShaderIndex) m_shaders.size() - 1; m_shaderIndices.push_back( *outIndex ); return( hr ); }
HRESULT U2Dx9ShaderMgr::LoadAndCreateShaderFromMemory( const char * program_asm_code, // ASCII assembly code const TCHAR * shader_name, U2Dx9ShaderDesc::ShaderType eShaderType, ShaderIndex * outIndex ) { HRESULT hr = S_OK; FAIL_IF_NULL( program_asm_code ); FAIL_IF_NULL( outIndex ); //@@@@@ check if shader exists! U2Dx9ShaderDesc* pDesc = U2_NEW U2Dx9ShaderDesc; pDesc->m_szShaderDefFile = TEXT(""); pDesc->m_type = eShaderType; pDesc->m_szShaderObjFile = shader_name; // typedef struct D3DXMACRO { // LPCSTR Name; // LPCSTR Definition; }; LPD3DXBUFFER pbufShader, pbufErrors; hr = D3DXAssembleShader( program_asm_code, (UINT) strlen( program_asm_code ), NULL, // D3DXMACRO preprocessor definitions NULL, // include directives NULL, // compile option flags & pbufShader, & pbufErrors ); if( FAILED( hr )) { char * pfunc = "D3DXAssembleShader"; switch( hr ) { case D3DERR_INVALIDCALL : FMsg("%s failed with HRESULT = D3DERR_INVALIDCALL\n", pfunc ); break; case D3DXERR_INVALIDDATA : FMsg("%s failed with HRESULT = D3DXERR_INVALIDDATA\n", pfunc ); break; case E_OUTOFMEMORY : FMsg("%s failed with HRESULT = E_OUTOFMEMORY\n", pfunc ); break; default : FMsg("Unknown HRESULT : %u\n", hr ); break; } FMsg("U2Dx9ShaderMgr::D3DXAssembleShader Errors:\n"); if( pbufErrors != NULL ) { HandleErrorString( (TCHAR*) pbufErrors->GetBufferPointer() ); } else { FMsg("Error buffer is NULL!\n"); } SAFE_RELEASE( pbufShader ); BREAK_AND_RET_VAL_IF_FAILED( hr ); } hr = CreateShader( pbufShader, eShaderType, pDesc ); // Add shader description to the array, set its index and return the index //@@@@ make function for this!! m_shaders.push_back( *pDesc ); * outIndex = (ShaderIndex) m_shaders.size() - 1; m_shaderIndices.push_back( *outIndex ); return( hr ); }
/*------------------------------------------------------------------ Retrieve various data through the IDxDiagContainer interface. The DXDiagNVUtil class provides a few convenient wrapper functions, and direct querries using the IDxDiagContainer COM object names are also supported. For a list of all the container and property COM object names, call ListAllDXDiagPropertyNames(..) ------------------------------------------------------------------*/ HRESULT GetGPUAndSystemInfo::GetData() { HRESULT hr = S_OK; //---------------------------------------------------------------------------- hr = m_DXDiagNVUtil.InitIDxDiagContainer(); MSG_AND_RET_VAL_IF( FAILED(hr), "Couldn't initialize DXDiagNVUtil!\n", hr ); wstring wstr; // Get the computer's machine name: m_DXDiagNVUtil.GetProperty( L"DxDiag_SystemInfo", L"szMachineNameEnglish", &wstr ); m_strMachineName = m_DXDiagNVUtil.WStringToString( &wstr ); FMsg("\n\n"); FMsg("------------------------------------------------------------------------\n"); FMsgW(L"machine name: %s\n", wstr.c_str() ); // Get info about physcial memory: m_DXDiagNVUtil.GetPhysicalMemoryInMB( & m_fSystemPhysicalMemoryMB ); FMsg("physical memory: %g MB\n", m_fSystemPhysicalMemoryMB ); // Get info about logical disks IDxDiagContainer * pContainer, *pChild; DWORD dwNumDisks; hr = m_DXDiagNVUtil.GetChildContainer( L"DxDiag_LogicalDisks", & pContainer ); if( SUCCEEDED(hr)) { pContainer->GetNumberOfChildContainers( & dwNumDisks ); wstring drive, space; FMsgW(L"logical disks: %d\n", dwNumDisks ); for( DWORD n=0; n < dwNumDisks; n++ ) { hr = m_DXDiagNVUtil.GetChildByIndex( pContainer, n, &pChild ); if( SUCCEEDED(hr) ) { m_DXDiagNVUtil.GetProperty( pChild, L"szDriveLetter", &drive ); m_DXDiagNVUtil.GetProperty( pChild, L"szFreeSpace", &space ); FMsgW(L" %s Free space = %s\n", drive.c_str(), space.c_str() ); SAFE_RELEASE( pChild ); } } SAFE_RELEASE( pContainer ); } FMsg("------------------------------------------------------------------------\n"); m_DXDiagNVUtil.GetDirectXVersion( &m_dwDXVersionMajor, &m_dwDXVersionMinor, &m_cDXVersionLetter ); FMsg("DirectX Version: %d.%d%c\n", m_dwDXVersionMajor, m_dwDXVersionMinor, m_cDXVersionLetter ); hr = m_DXDiagNVUtil.GetNumDisplayDevices( & m_dwNumDisplayDevices ); MSG_AND_RET_VAL_IF( FAILED(hr), "Couldn't GetNumDisplayDevices()\n", hr ); FMsg("Num Display Devices: %d\n", m_dwNumDisplayDevices ); string str; // for( DWORD dev=0; dev < m_dwNumDisplayDevices; dev ++ ) if( m_dwNumDisplayDevices > 0 ) { DWORD dev = 0; // get info from display devices m_DXDiagNVUtil.GetDisplayDeviceDescription( dev, & m_wstrDeviceDesc ); m_DXDiagNVUtil.GetDisplayDeviceNVDriverVersion( dev, & m_fDriverVersion ); m_DXDiagNVUtil.GetDisplayDeviceMemoryInMB( dev, & m_nDeviceMemoryMB ); // report the info via OutputDebugString FMsgW(L"Device %d Description: %s\n", dev, m_wstrDeviceDesc.c_str() ); FMsg( "Device %d Driver version: %g\n", dev, m_fDriverVersion ); FMsg( "Device %d Physical mem: %d MB\n", dev, m_nDeviceMemoryMB ); // Get info about AGP memory: wstring wstrAGPEnabled, wstrAGPExists, wstrAGPStatus; hr = m_DXDiagNVUtil.GetDisplayDeviceAGPMemoryStatus( dev, &wstrAGPEnabled, &wstrAGPExists, &wstrAGPStatus ); if( SUCCEEDED(hr)) { // create a string from the AGP status strings m_strAGPStatus = ""; str = m_DXDiagNVUtil.WStringToString( &wstrAGPEnabled ); m_strAGPStatus += "AGP Enabled = "; m_strAGPStatus += str; m_strAGPStatus += ", "; str = m_DXDiagNVUtil.WStringToString( &wstrAGPExists ); m_strAGPStatus += "AGP Exists = "; m_strAGPStatus += str; m_strAGPStatus += ", "; str = m_DXDiagNVUtil.WStringToString( &wstrAGPStatus ); m_strAGPStatus += "AGP Status = "; m_strAGPStatus += str; } FMsg("%s\n", m_strAGPStatus.c_str() ); wstring wstrNotes, wstrTestD3D9; m_DXDiagNVUtil.GetProperty( L"DxDiag_DisplayDevices", L"0", L"szTestResultD3D9English", &wstrTestD3D9 ); m_DXDiagNVUtil.GetProperty( L"DxDiag_DisplayDevices", L"0", L"szNotesEnglish", &wstrNotes ); str = m_DXDiagNVUtil.WStringToString( &wstrTestD3D9 ); FMsg("Device 0 szTestResultD3D9English = \"%s\"\n", str.c_str() ); str = m_DXDiagNVUtil.WStringToString( &wstrNotes ); FMsg("Device 0 szNotesEnglish = \"%s\"\n", str.c_str() ); } m_DXDiagNVUtil.GetDebugLevels( & m_wstrDxDebugLevels ); FMsg("DirectX Debug Levels:\n"); FMsgW(L"%s\n", m_wstrDxDebugLevels.c_str() ); // ListAllDXDiagPropertyNames() is slow // It prints out all nodes, child nodes, properties and their values // m_DXDiagNVUtil.ListAllDXDiagPropertyNames(); // Use a call like that below to print out a specific node and it's children. // For example, to list all the display device property names. /* m_DXDiagNVUtil.GetChildContainer( L"DxDiag_DisplayDevices", &pContainer ); m_DXDiagNVUtil.ListAllDXDiagPropertyNames( pContainer, L"DxDiag_DisplayDevices" ); SAFE_RELEASE( pContainer ); // */ m_DXDiagNVUtil.FreeIDxDiagContainer(); return( hr ); }
HRESULT GetGPUAndSystemInfo::IsFPBlendingSupported( IDirect3D9 * pD3D9, FloatingPointBlendModes * pOutResult ) { FMsg("There is a bug with this code in that is does not report that blending works for ordinary backbuffer formats\n"); assert( false ); HRESULT hr = S_OK; FAIL_IF_NULL( pD3D9 ); FAIL_IF_NULL( pOutResult ); bool * pResult; hr = pD3D9->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_SURFACE, D3DFMT_R16F ); pResult = &pOutResult->m_bR16f; if( hr == D3D_OK ) *pResult = true; else if( hr == D3DERR_NOTAVAILABLE ) *pResult = false; else FMsg("Unknown return result for D3DFMT_R16F : %u\n", hr ); hr = pD3D9->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_SURFACE, D3DFMT_A16B16G16R16F ); pResult = &pOutResult->m_bA16B16G16R16f; if( hr == D3D_OK ) *pResult = true; else if( hr == D3DERR_NOTAVAILABLE ) *pResult = false; else FMsg("Unknown return result for D3DFMT_A16B16G16R16F : %u\n", hr ); hr = pD3D9->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, // D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, 0 | D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, // per the DX90SDK docs D3DRTYPE_SURFACE, D3DFMT_A8R8G8B8 ); pResult = &pOutResult->m_bA8R8G8B8; if( hr == D3D_OK ) *pResult = true; else if( hr == D3DERR_NOTAVAILABLE ) *pResult = false; else FMsg("Unknown return result for D3DFMT_A8R8G8B8 : %u\n", hr ); if( pOutResult->m_bA16B16G16R16f == true ) FMsg("D3DFMT_A16B16G16R16F POSTPIXELSHADER_BLENDING is supported\n"); else FMsg("D3DFMT_A16B16G16R16F POSTPIXELSHADER_BLENDING is not supported\n"); if( pOutResult->m_bR16f == true ) FMsg("D3DFMT_R16F POSTPIXELSHADER_BLENDING is supported\n"); else FMsg("D3DFMT_R16F POSTPIXELSHADER_BLENDING is not supported\n"); if( pOutResult->m_bA8R8G8B8 == true ) FMsg("D3DFMT_A8R8G8B8 POSTPIXELSHADER_BLENDING is supported\n"); else FMsg("D3DFMT_A8R8G8B8 POSTPIXELSHADER_BLENDING is not supported\n"); /* Use IDirect3D9::CheckDeviceFormat, with usage (D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_POSTPIXELSHADERBLENDING). HRESULT CheckDeviceFormat( UINT Adapter, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat ); D3DFMT_R16F 111 16-bit float format using 16 bits for the red channel. D3DFMT_G16R16F 112 32-bit float format using 16 bits for the red channel and 16 bits for the green channel. D3DFMT_A16B16G16R16F D3DFMT_R32F 114 32-bit float format using 32 bits for the red channel. D3DFMT_G32R32F 115 64-bit float format using 32 bits for the red channel and 32 bits for the green channel. D3DFMT_A32B32G32R32F D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING D3DUSAGE_QUERY_FILTER (more than just point sampling) Query the resource to verify support for post pixel shader blending support. If IDirect3D9::CheckDeviceFormat fails with D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, post pixel blending operations are not supported. These include alpha test, pixel fog, render-target blending, color write enable, and dithering. MSFT examples from SDK if( pCaps->PixelShaderVersion < D3DPS_VERSION(1,1) ) { if( FAILED( m_pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType, adapterFormat, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8 ) ) ) { return E_FAIL; } } // Need to support post-pixel processing (for alpha blending) if( FAILED( m_pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType, adapterFormat, D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_SURFACE, backBufferFormat ) ) ) { return E_FAIL; } HRESULT CMyD3DApplication::ConfirmDevice( D3DCAPS9* pCaps, DWORD dwBehavior, D3DFORMAT adapterFormat, D3DFORMAT backBufferFormat ) { // Need to support post-pixel processing (for alpha blending) if( FAILED( m_pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType, adapterFormat, D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_SURFACE, backBufferFormat ) ) ) { return E_FAIL; } */ return( hr ); }