bool CD3D11Driver::init(SCreationParameters& createParam) { HRESULT result; IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* adapterOutput; unsigned int numModes, i, numerator = 0, denominator = 1, stringLength; DXGI_MODE_DESC* displayModeList; DXGI_ADAPTER_DESC adapterDesc; int error; D3D11_TEXTURE2D_DESC depthBufferDesc; //D3D11_DEPTH_STENCIL_DESC depthStencilDesc; //D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; //D3D11_RASTERIZER_DESC rasterDesc; //D3D11_VIEWPORT viewport; //const SCreationParameters& params = mDevice->getCreationParameters(); // Create a DirectX graphics interface factory. mBackBufferWidth = createParam.BackBufferWidth; mBackBufferHeight = createParam.BackBufferHeight; result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if (FAILED(result)) { return false; } // Use the factory to create an adapter for the primary graphics interface (video card). result = factory->EnumAdapters(0, &adapter); if (FAILED(result)) { return false; } // Enumerate the primary adapter output (monitor). result = adapter->EnumOutputs(0, &adapterOutput); if (FAILED(result)) { return false; } // Get the number of modes that fit the DXGI_FORMAT_R8G8B8A8_UNORM display format for the adapter output (monitor). result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL); if (FAILED(result)) { return false; } // Create a list to hold all the possible display modes for this monitor/video card combination. displayModeList = new DXGI_MODE_DESC[numModes]; if (!displayModeList) { return false; } // Now fill the display mode list structures. result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); if (FAILED(result)) { return false; } // Now go through all the display modes and find the one that matches the screen width and height. // When a match is found store the numerator and denominator of the refresh rate for that monitor. for (i = 0; i < numModes; i++) { if (displayModeList[i].Width == (unsigned int)createParam.BackBufferWidth) { if (displayModeList[i].Height == (unsigned int)createParam.BackBufferHeight) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } } // Get the adapter (video card) description. result = adapter->GetDesc(&adapterDesc); if (FAILED(result)) { return false; } // Store the dedicated video card memory in megabytes. mVideoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); // Convert the name of the video card to a character array and store it. error = wcstombs_s(&stringLength, mVideoCardDescription, 128, adapterDesc.Description, 128); if (error != 0) { return false; } // Release the display mode list. delete[] displayModeList; displayModeList = 0; // Release the adapter output. adapterOutput->Release(); adapterOutput = 0; // Release the adapter. adapter->Release(); adapter = 0; // Release the factory. factory->Release(); factory = 0; UINT createDeviceFlags = 0; #if defined(DEBUG) || defined(_DEBUG) createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL featureLevel; /* 如果将这个标志设为DEBUG,则绘制效率大大降低,且帧频极不稳定 */ //createDeviceFlags = 0; HRESULT hr; hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, 0, 0, D3D11_SDK_VERSION, &md3dDevice, &featureLevel, &md3dDeviceContext); if (FAILED(hr)) return false; #if defined(DEBUG) || defined(_DEBUG) md3dDevice->QueryInterface(__uuidof(ID3D11Debug), reinterpret_cast<void**>(&md3dDebug)); #endif if (featureLevel != D3D_FEATURE_LEVEL_11_0) { throw std::runtime_error("DirectX11 is not supported!"); return false; } UINT numQualityLevels; md3dDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, 4, &numQualityLevels); IDXGIDevice* dxgiDevice = 0; md3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice); IDXGIAdapter* dxgiAdapter = 0; dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&dxgiAdapter); IDXGIFactory* dxgiFactory = 0; dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgiFactory); DXGI_SWAP_CHAIN_DESC swapChainDesc; // Initialize the swap chain description. ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); // Set the width and height of the back buffer. swapChainDesc.BufferDesc.Width = createParam.BackBufferWidth; swapChainDesc.BufferDesc.Height = createParam.BackBufferHeight; // Set regular 32-bit surface for the back buffer. swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // Set the refresh rate of the back buffer. if (createParam.VsyncEnabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator; } else { swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; } // Set multisampling. if (createParam.MultiSamplingQuality == 0) { swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; createParam.MultiSamplingCount = 1; } else { swapChainDesc.SampleDesc.Count = createParam.MultiSamplingCount; UINT numQualityLevels; md3dDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, 4, &numQualityLevels); swapChainDesc.SampleDesc.Quality = min(numQualityLevels - 1, createParam.MultiSamplingQuality); createParam.MultiSamplingQuality = swapChainDesc.SampleDesc.Quality; } // set member attributes of class // Set to a single back buffer. swapChainDesc.BufferCount = 1; // Set the usage of the back buffer. swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // Set the handle for the window to render to. swapChainDesc.OutputWindow = (HWND)createParam.BackBufferWindowHandle; // Set to full screen or windowed mode. if (createParam.WindowStyle & EWS_FULLSCREEN) { swapChainDesc.Windowed = false; } else { swapChainDesc.Windowed = true; } // Set the scan line ordering and scaling to unspecified. swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; // Discard the back buffer contents after presenting. swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; // Don't set the advanced flags. swapChainDesc.Flags = 0; hr = dxgiFactory->CreateSwapChain(md3dDevice, &swapChainDesc, &md3dSwapChain); if (FAILED(hr)) return false; ReleaseCOM(dxgiDevice); ReleaseCOM(dxgiAdapter); ReleaseCOM(dxgiFactory); // Get the pointer to the back buffer. ID3D11Texture2D* backBuffer; result = md3dSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBuffer); if (FAILED(result)) { return false; } md3dDevice->CreateRenderTargetView(backBuffer, 0, &mDefaultRenderTargetView); ReleaseCOM(backBuffer); mDefaultRenderTarget = new CD3D11RenderTarget(md3dDevice, md3dDeviceContext, mDefaultRenderTargetView, createParam.BackBufferWidth, createParam.BackBufferHeight); // Initialize the description of the depth buffer. ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); // Setup the viewport for rendering. setViewport(0, 0, static_cast<f32>(mBackBufferWidth), static_cast<f32>(mBackBufferHeight)); //create resource factory mResourceFactory = new CD3D11ResourceFactory( md3dDevice, md3dDeviceContext, this); IResourceFactory::_setInstance(mResourceFactory); //create geometry creator mGeometryCreator = new CGeometryCreator; IGeometryCreator::_setInstance(mGeometryCreator); //create material manager mMaterialManager = new CMaterialManager; IMaterialManager::_setInstance(mMaterialManager); //create sampler manager mSamplerManager = new CSamplerManager(mResourceFactory); ISamplerManager::_setInstance(mSamplerManager); // create shadermanager mShaderManager = new CShaderManager(mResourceFactory); IShaderManager::_setInstance(mShaderManager); // create inputlayout manager mInputLayoutManager = new CInputLayoutManager(mResourceFactory); IInputLayoutManager::_setInstance(mInputLayoutManager); //create texture manager mTextureManager = new CTextureManager(mDevice, mResourceFactory); ITextureManager::_setInstance(mTextureManager); //create render state manager mRenderStateManager = new CRenderStateManager(mResourceFactory); IRenderStateManager::_setInstance(mRenderStateManager); //create mesh manager mMeshManager = new CMeshManager(mResourceFactory, mGeometryCreator, mTextureManager); IMeshManager::_setInstance(mMeshManager); //create pipeline manager mPipeManager = new CPipelineManager(mResourceFactory); IPipelineManager::_setInstance(mPipeManager); //create resource group manager mResourceGroupManager = new CResourceGroupManager(mTextureManager, mShaderManager, mInputLayoutManager, mRenderStateManager, mPipeManager, mMaterialManager, mMeshManager, mSamplerManager); IResourceGroupManager::_setInstance(mResourceGroupManager); //mResourceFactory->setResourceGroupManager(mResourceGroupManager); // create default depth-stencil-buffer bool multiSampling = (createParam.MultiSamplingCount > 1); mDepthStencilSurface = mTextureManager->createDepthStencilSurface("_default_depth_stencil_surface", 0, 0, createParam.DepthBits, createParam.StencilBits, multiSampling, createParam.MultiSamplingCount, createParam.MultiSamplingQuality, true); if (!mDepthStencilSurface) { GF_PRINT_CONSOLE_INFO("Depth Stencil Surface has failed to be created.\n"); return false; } D3D11DriverState.DepthStencilSurface = mDepthStencilSurface; CD3D11DepthStencilSurface* d3dDepthStencilSurface = dynamic_cast<CD3D11DepthStencilSurface*>(mDepthStencilSurface); mDefaultDepthStencilView = d3dDepthStencilSurface->getDepthStencilView(); D3D11DriverState.DepthStencilView = mDefaultDepthStencilView; // create mShadowMapRasterizeState. This state is only for rendering shadow maps. D3D11_RASTERIZER_DESC shadowRasterizeState; shadowRasterizeState.FillMode = D3D11_FILL_SOLID; shadowRasterizeState.CullMode = D3D11_CULL_BACK; // RENDER BACK FACE shadowRasterizeState.FrontCounterClockwise = TRUE; shadowRasterizeState.DepthBiasClamp = 0.0f; //shadowRasterizeState.DepthBias = 100000; //shadowRasterizeState.SlopeScaledDepthBias = 1.0f; shadowRasterizeState.DepthBias = 0; shadowRasterizeState.SlopeScaledDepthBias = 0; shadowRasterizeState.DepthClipEnable = TRUE; shadowRasterizeState.ScissorEnable = FALSE; shadowRasterizeState.MultisampleEnable = FALSE; shadowRasterizeState.AntialiasedLineEnable = FALSE; hr = md3dDevice->CreateRasterizerState(&shadowRasterizeState, &mShadowMapRasterizeState); if (FAILED(hr)) return false; D3D11DriverState.ShadowMapRasterizerState = mShadowMapRasterizeState; return true; }
//-------------------------------------------------------------------------------------- // Enumerate for each adapter all of the supported display modes, // device types, adapter formats, back buffer formats, window/full screen support, // depth stencil formats, multisampling types/qualities, and presentations intervals. // // For each combination of device type (HAL/REF), adapter format, back buffer format, and // IsWindowed it will call the app's ConfirmDevice callback. This allows the app // to reject or allow that combination based on its caps/etc. It also allows the // app to change the BehaviorFlags. The BehaviorFlags defaults non-pure HWVP // if supported otherwise it will default to SWVP, however the app can change this // through the ConfirmDevice callback. //-------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT CD3D11Enumeration::Enumerate( LPDXUTCALLBACKISD3D11DEVICEACCEPTABLE IsD3D11DeviceAcceptableFunc, void* pIsD3D11DeviceAcceptableFuncUserContext ) { CDXUTPerfEventGenerator eventGenerator( DXUT_PERFEVENTCOLOR, L"DXUT D3D11 Enumeration" ); HRESULT hr; auto pFactory = DXUTGetDXGIFactory(); if( !pFactory ) return E_FAIL; m_bHasEnumerated = true; m_IsD3D11DeviceAcceptableFunc = IsD3D11DeviceAcceptableFunc; m_pIsD3D11DeviceAcceptableFuncUserContext = pIsD3D11DeviceAcceptableFuncUserContext; ClearAdapterInfoList(); for( int index = 0; ; ++index ) { IDXGIAdapter* pAdapter = nullptr; hr = pFactory->EnumAdapters( index, &pAdapter ); if( FAILED( hr ) ) // DXGIERR_NOT_FOUND is expected when the end of the list is hit break; IDXGIAdapter2* pAdapter2 = nullptr; if ( SUCCEEDED( pAdapter->QueryInterface( __uuidof(IDXGIAdapter2), ( LPVOID* )&pAdapter2 ) ) ) { // Succeeds on DirectX 11.1 Runtime systems DXGI_ADAPTER_DESC2 desc; hr = pAdapter2->GetDesc2( &desc ); pAdapter2->Release(); if ( SUCCEEDED(hr) && ( desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE ) ) { // Skip "always there" Microsoft Basics Display Driver pAdapter->Release(); continue; } } auto pAdapterInfo = new (std::nothrow) CD3D11EnumAdapterInfo; if( !pAdapterInfo ) { SAFE_RELEASE( pAdapter ); return E_OUTOFMEMORY; } pAdapterInfo->AdapterOrdinal = index; pAdapter->GetDesc( &pAdapterInfo->AdapterDesc ); pAdapterInfo->m_pAdapter = pAdapter; // Enumerate the device driver types on the adapter. hr = EnumerateDevices( pAdapterInfo ); if( FAILED( hr ) ) { delete pAdapterInfo; continue; } hr = EnumerateOutputs( pAdapterInfo ); if( FAILED( hr ) || pAdapterInfo->outputInfoList.empty() ) { delete pAdapterInfo; continue; } // Get info for each devicecombo on this device if( FAILED( hr = EnumerateDeviceCombos( pAdapterInfo ) ) ) { delete pAdapterInfo; continue; } m_AdapterInfoList.push_back( pAdapterInfo ); } // If we did not get an adapter then we should still enumerate WARP and Ref. if (m_AdapterInfoList.size() == 0) { auto pAdapterInfo = new (std::nothrow) CD3D11EnumAdapterInfo; if( !pAdapterInfo ) { return E_OUTOFMEMORY; } pAdapterInfo->bAdapterUnavailable = true; hr = EnumerateDevices( pAdapterInfo ); // Get info for each devicecombo on this device if( FAILED( hr = EnumerateDeviceCombosNoAdapter( pAdapterInfo ) ) ) { delete pAdapterInfo; } if (SUCCEEDED(hr)) m_AdapterInfoList.push_back( pAdapterInfo ); } // // Check for 2 or more adapters with the same name. Append the name // with some instance number if that's the case to help distinguish // them. // bool bUniqueDesc = true; for( size_t i = 0; i < m_AdapterInfoList.size(); i++ ) { auto pAdapterInfo1 = m_AdapterInfoList[ i ]; for( size_t j = i + 1; j < m_AdapterInfoList.size(); j++ ) { auto pAdapterInfo2 = m_AdapterInfoList[ j ]; if( wcsncmp( pAdapterInfo1->AdapterDesc.Description, pAdapterInfo2->AdapterDesc.Description, DXGI_MAX_DEVICE_IDENTIFIER_STRING ) == 0 ) { bUniqueDesc = false; break; } } if( !bUniqueDesc ) break; } for( auto it = m_AdapterInfoList.begin(); it != m_AdapterInfoList.end(); ++it ) { wcscpy_s((*it)->szUniqueDescription, DXGI_MAX_DEVICE_IDENTIFIER_STRING, (*it)->AdapterDesc.Description); if( !bUniqueDesc ) { WCHAR sz[32]; swprintf_s( sz, 32, L" (#%u)", (*it)->AdapterOrdinal ); wcscat_s( (*it)->szUniqueDescription, DXGI_MAX_DEVICE_IDENTIFIER_STRING, sz ); } } // Check WARP max feature level { static const D3D_FEATURE_LEVEL fLvlWarp[] = { #ifdef USE_DIRECT3D11_3 D3D_FEATURE_LEVEL_12_1, D3D_FEATURE_LEVEL_12_0, #endif D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1 }; ID3D11Device* pDevice = nullptr; hr = DXUT_Dynamic_D3D11CreateDevice( nullptr, D3D_DRIVER_TYPE_WARP, 0, 0, fLvlWarp, _countof(fLvlWarp), D3D11_SDK_VERSION, &pDevice, &m_warpFL, nullptr ); if ( hr == E_INVALIDARG ) { #ifdef USE_DIRECT3D11_3 // DirectX 11.1 runtime will not recognize FL 12.x, so try without it hr = DXUT_Dynamic_D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_WARP, 0, 0, &fLvlWarp[2], _countof(fLvlWarp) - 2, D3D11_SDK_VERSION, &pDevice, &m_warpFL, nullptr); if (hr == E_INVALIDARG) { // DirectX 11.0 runtime will not recognize FL 11.1+, so try without it hr = DXUT_Dynamic_D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_WARP, 0, 0, &fLvlWarp[3], _countof(fLvlWarp) - 3, D3D11_SDK_VERSION, &pDevice, &m_warpFL, nullptr); } #else // DirectX 11.0 runtime will not recognize FL 11.1, so try without it hr = DXUT_Dynamic_D3D11CreateDevice( nullptr, D3D_DRIVER_TYPE_WARP, 0, 0, &fLvlWarp[1], _countof(fLvlWarp) - 1, D3D11_SDK_VERSION, &pDevice, &m_warpFL, nullptr ); #endif } if ( SUCCEEDED(hr) ) { pDevice->Release(); } else m_warpFL = D3D_FEATURE_LEVEL_10_1; } // Check REF max feature level { static const D3D_FEATURE_LEVEL fLvlRef[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1 }; ID3D11Device* pDevice = nullptr; hr = DXUT_Dynamic_D3D11CreateDevice( nullptr, D3D_DRIVER_TYPE_REFERENCE, 0, 0, fLvlRef, _countof(fLvlRef), D3D11_SDK_VERSION, &pDevice, &m_refFL, nullptr ); if ( hr == E_INVALIDARG ) { // DirectX 11.0 runtime will not recognize FL 11.1, so try without it hr = DXUT_Dynamic_D3D11CreateDevice( nullptr, D3D_DRIVER_TYPE_REFERENCE, 0, 0, &fLvlRef[1], _countof(fLvlRef) - 1, D3D11_SDK_VERSION, &pDevice, &m_refFL, nullptr ); } if ( SUCCEEDED(hr) ) { pDevice->Release(); } else m_refFL = D3D_FEATURE_LEVEL_11_0; } return S_OK; }
HRESULT touchmind::Context::CreateDeviceResources() { #ifdef TOUCHMIND_CONTEXT_DEBUG LOG_ENTER; #endif HRESULT hr = S_OK; RECT rcClient; ID3D10Device1 *pDevice = nullptr; IDXGIDevice *pDXGIDevice = nullptr; IDXGIAdapter *pAdapter = nullptr; IDXGIFactory *pDXGIFactory = nullptr; IDXGISurface *pSurface = nullptr; if (m_hwnd == nullptr) { LOG(SEVERITY_LEVEL_WARN) << L"HWND has not been set."; return S_FALSE; } GetClientRect(m_hwnd, &rcClient); UINT nWidth = std::abs(rcClient.right - rcClient.left); UINT nHeight = std::abs(rcClient.bottom - rcClient.top); if (!m_pDevice) { #ifdef TOUCHMIND_CONTEXT_DEBUG LOG(SEVERITY_LEVEL_DEBUG) << L"Creating D3D Device."; #endif #ifdef _DEBUG // GMA950 doesn't work with D3D10_CREATE_DEVICE_DEBUG UINT nDeviceFlags = D3D10_CREATE_DEVICE_BGRA_SUPPORT | D3D10_CREATE_DEVICE_DEBUG; // UINT nDeviceFlags = D3D10_CREATE_DEVICE_BGRA_SUPPORT; #else UINT nDeviceFlags = D3D10_CREATE_DEVICE_BGRA_SUPPORT; #endif hr = _CreateD3DDevice(nullptr, D3D10_DRIVER_TYPE_HARDWARE, nDeviceFlags, &pDevice); if (FAILED(hr)) { LOG(SEVERITY_LEVEL_INFO) << L"Creating hardware support D3D10 device was failed. Try D3D10_DRIVER_TYPE_WARP."; hr = _CreateD3DDevice(nullptr, D3D10_DRIVER_TYPE_WARP, nDeviceFlags, &pDevice); if (FAILED(hr)) { LOG(SEVERITY_LEVEL_FATAL) << L"Creating D3D10 device was failed."; return hr; } } if (SUCCEEDED(hr)) { hr = pDevice->QueryInterface(&m_pDevice); } if (SUCCEEDED(hr)) { hr = pDevice->QueryInterface(&pDXGIDevice); } if (SUCCEEDED(hr)) { hr = pDXGIDevice->GetAdapter(&pAdapter); } if (SUCCEEDED(hr)) { hr = pAdapter->GetParent(IID_PPV_ARGS(&pDXGIFactory)); } if (SUCCEEDED(hr)) { DXGI_SWAP_CHAIN_DESC swapDesc; ::ZeroMemory(&swapDesc, sizeof(swapDesc)); swapDesc.BufferDesc.Width = nWidth; swapDesc.BufferDesc.Height = nHeight; swapDesc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; swapDesc.BufferDesc.RefreshRate.Numerator = 60; swapDesc.BufferDesc.RefreshRate.Denominator = 1; swapDesc.SampleDesc.Count = m_msaaSampleCount; swapDesc.SampleDesc.Quality = m_msaaQuality; swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapDesc.BufferCount = 1; swapDesc.OutputWindow = m_hwnd; swapDesc.Windowed = TRUE; hr = pDXGIFactory->CreateSwapChain(m_pDevice, &swapDesc, &m_pSwapChain); #ifdef DEBUG_GPU_RESOURCE LOG(SEVERITY_LEVEL_INFO) << L"[GPU RESOURCE] IDXGISwapChain = [" << std::hex << m_pSwapChain << L"]" << std::dec; #endif if (FAILED(hr)) { LOG(SEVERITY_LEVEL_FATAL) << L"Creating swap chain was failed."; return hr; } } if (SUCCEEDED(hr)) { hr = _CreateD3DDeviceResources(); } if (SUCCEEDED(hr)) { hr = _RecreateSizedResources(nWidth, nHeight); } if (SUCCEEDED(hr)) { if (m_pRenderEventListener != nullptr) { m_pRenderEventListener->CreateD2DResources(this, m_pD2DFactory, m_pD2DTexture2DRenderTarget); } } } SafeRelease(&pDevice); SafeRelease(&pDXGIDevice); SafeRelease(&pAdapter); SafeRelease(&pDXGIFactory); SafeRelease(&pSurface); #ifdef TOUCHMIND_CONTEXT_DEBUG LOG_LEAVE_HRESULT(hr); #endif return hr; }
void RenderSystem::init_device() { ////////////////////////Create buffer desc//////////////////////////// DXGI_MODE_DESC bufferDesc; ZeroMemory(&bufferDesc, sizeof(DXGI_MODE_DESC)); bufferDesc.Width = m_ScreenWidth; bufferDesc.Height = m_ScreenHeight; bufferDesc.RefreshRate.Numerator = 60; bufferDesc.RefreshRate.Denominator = 1; bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; //Create swapChain Desc DXGI_SWAP_CHAIN_DESC swapChainDesc; ZeroMemory(&swapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC)); swapChainDesc.BufferDesc = bufferDesc; swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount = 1; swapChainDesc.OutputWindow = GetHwnd(); swapChainDesc.Windowed = TRUE; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; /////////////////////////////////////////////////////////////////////////// HRESULT hr; //Create the double buffer chain hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, NULL, NULL, NULL, D3D11_SDK_VERSION, &swapChainDesc, &m_pSwapChain, &m_pD3D11Device, NULL, &m_pD3D11DeviceContext); //DebugHR(hr); //Create back buffer, buffer also is a texture ID3D11Texture2D *pBackBuffer; hr = m_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&pBackBuffer); hr = m_pD3D11Device->CreateRenderTargetView(pBackBuffer, NULL, &m_pRenderTargetView); pBackBuffer->Release(); //DebugHR(hr); //////////////////////////// Initialize the description of the stencil state./////////////////////////////////////////////// D3D11_TEXTURE2D_DESC depthBufferDesc; ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); depthBufferDesc.Width = m_ScreenWidth; depthBufferDesc.Height = m_ScreenHeight; depthBufferDesc.MipLevels = 1; depthBufferDesc.ArraySize = 1; depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthBufferDesc.SampleDesc.Count = 1; depthBufferDesc.SampleDesc.Quality = 0; depthBufferDesc.Usage = D3D11_USAGE_DEFAULT; depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthBufferDesc.CPUAccessFlags = 0; depthBufferDesc.MiscFlags = 0; // Create the texture for the depth buffer using the filled out description. hr = m_pD3D11Device->CreateTexture2D(&depthBufferDesc, NULL, &m_pDepthStencilBuffer); D3D11_DEPTH_STENCIL_DESC depthStencilDesc; ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc)); // Set up the description of the stencil state. depthStencilDesc.DepthEnable = true; depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL; depthStencilDesc.StencilEnable = true; depthStencilDesc.StencilReadMask = 0xFF; depthStencilDesc.StencilWriteMask = 0xFF; // Stencil operations if pixel is front-facing. depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // Stencil operations if pixel is back-facing. depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // Create the depth stencil state. hr = m_pD3D11Device->CreateDepthStencilState(&depthStencilDesc, &m_pDepthStencilState); // Set the depth stencil state. //DebugHR(hr); D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; // Initialize the depth stencil view. ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc)); // Set up the depth stencil view description. depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; // Create the depth stencil view. hr = m_pD3D11Device->CreateDepthStencilView(m_pDepthStencilBuffer.Get(), &depthStencilViewDesc, &m_pDepthStencilView); //DebugHR(hr); // ////////////Clear the second depth stencil state before setting the parameters.////////////////////// D3D11_DEPTH_STENCIL_DESC depthDisabledStencilDesc; ZeroMemory(&depthDisabledStencilDesc, sizeof(depthDisabledStencilDesc)); // Now create a second depth stencil state which turns off the Z buffer for 2D rendering. The only difference is // that DepthEnable is set to false, all other parameters are the same as the other depth stencil state. depthDisabledStencilDesc.DepthEnable = false; depthDisabledStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthDisabledStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; depthDisabledStencilDesc.StencilEnable = true; depthDisabledStencilDesc.StencilReadMask = 0xFF; depthDisabledStencilDesc.StencilWriteMask = 0xFF; depthDisabledStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; depthDisabledStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; depthDisabledStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthDisabledStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // Create the state using the device. hr = m_pD3D11Device->CreateDepthStencilState(&depthDisabledStencilDesc, &m_pDepthDisabledStencilState); //DebugHR(hr); // Setup the raster description which will determine how and what polygons will be drawn. D3D11_RASTERIZER_DESC rasterDesc; rasterDesc.AntialiasedLineEnable = false; rasterDesc.CullMode = D3D11_CULL_BACK; rasterDesc.DepthBias = 0; rasterDesc.DepthBiasClamp = 0.0f; rasterDesc.DepthClipEnable = true; rasterDesc.FillMode = D3D11_FILL_SOLID; rasterDesc.FrontCounterClockwise = false; rasterDesc.MultisampleEnable = false; rasterDesc.ScissorEnable = false; rasterDesc.SlopeScaledDepthBias = 0.0f; // Create the rasterizer state from the description we just filled out. hr = m_pD3D11Device->CreateRasterizerState(&rasterDesc, &m_pRasterState); //DebugHR(hr); /////////////////////////////////////////////////////////////////////////////// unsigned int numModes, i, numerator, denominator, stringLength; IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGISurface *surface; DXGI_ADAPTER_DESC adapterDesc; // Create a DirectX graphics interface factory. CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); // Use the factory to create an adapter for the primary graphics interface (video card). factory->EnumAdapters(0, &adapter); adapter->GetDesc(&adapterDesc); m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); // Convert the name of the video card to a character array and store it. m_videoCardInfo = std::wstring(L"Video Card :") + adapterDesc.Description; }
void Graphics4::init(int windowId, int depthBufferBits, int stencilBufferBits, bool vSync) { #ifdef KORE_VR vsync = false; #else vsync = vSync; #endif for (int i = 0; i < 1024 * 4; ++i) vertexConstants[i] = 0; for (int i = 0; i < 1024 * 4; ++i) fragmentConstants[i] = 0; #ifdef KORE_WINDOWS HWND hwnd = Window::get(windowId)->_data.handle; #endif UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; #ifdef _DEBUG creationFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL featureLevels[] = { #ifdef KORE_WINDOWSAPP D3D_FEATURE_LEVEL_11_1, #endif D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0}; #ifdef KORE_WINDOWSAPP IDXGIAdapter3* adapter = nullptr; #ifdef KORE_HOLOLENS adapter = holographicFrameController->getCompatibleDxgiAdapter().Get(); #endif Kore_Microsoft_affirm(D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_HARDWARE, nullptr, creationFlags, featureLevels, ARRAYSIZE(featureLevels), D3D11_SDK_VERSION, &device, &featureLevel, &context)); #elif KORE_OCULUS IDXGIFactory* dxgiFactory = nullptr; Windows::affirm(CreateDXGIFactory1(__uuidof(IDXGIFactory), (void**)(&dxgiFactory))); Windows::affirm(D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, 0, creationFlags, featureLevels, ARRAYSIZE(featureLevels), D3D11_SDK_VERSION, &device, &featureLevel, &context)); #endif // affirm(device0.As(&device)); // affirm(context0.As(&context)); // m_windowBounds = m_window->Bounds; const int _DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL = 3; const int _DXGI_SWAP_EFFECT_FLIP_DISCARD = 4; if (swapChain != nullptr) { Kore_Microsoft_affirm(swapChain->ResizeBuffers(2, 0, 0, DXGI_FORMAT_B8G8R8A8_UNORM, 0)); } else { #ifdef KORE_WINDOWS DXGI_SWAP_CHAIN_DESC swapChainDesc = {0}; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; // 60Hz swapChainDesc.BufferDesc.RefreshRate.Numerator = 60; swapChainDesc.BufferDesc.Width = System::windowWidth(windowId); // use automatic sizing swapChainDesc.BufferDesc.Height = System::windowHeight(windowId); swapChainDesc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // this is the most common swapchain format // swapChainDesc.Stereo = false; swapChainDesc.SampleDesc.Count = antialiasingSamples() > 1 ? antialiasingSamples() : 1; swapChainDesc.SampleDesc.Quality = antialiasingSamples() > 1 ? D3D11_STANDARD_MULTISAMPLE_PATTERN : 0; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount = 2; // use two buffers to enable flip effect swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; // DXGI_SCALING_NONE; if (isWindows10OrGreater()) { swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; //(DXGI_SWAP_EFFECT) _DXGI_SWAP_EFFECT_FLIP_DISCARD; } else if (isWindows8OrGreater()) { swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; //(DXGI_SWAP_EFFECT) _DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; } else { swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; } swapChainDesc.Flags = 0; swapChainDesc.OutputWindow = Window::get(windowId)->_data.handle; swapChainDesc.Windowed = true; #endif #if defined(KORE_WINDOWSAPP) #ifdef KORE_HOLOLENS // The Windows::Graphics::Holographic::HolographicSpace owns its own swapchain so we don't need to create one here #else DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0}; swapChainDesc.Width = 0; // use automatic sizing swapChainDesc.Height = 0; swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // this is the most common swapchain format swapChainDesc.Stereo = false; swapChainDesc.SampleDesc.Count = antialiasingSamples() > 1 ? antialiasingSamples() : 1; swapChainDesc.SampleDesc.Quality = antialiasingSamples() > 1 ? D3D11_STANDARD_MULTISAMPLE_PATTERN : 0; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount = 2; // use two buffers to enable flip effect swapChainDesc.Scaling = DXGI_SCALING_NONE; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // we recommend using this swap effect for all applications swapChainDesc.Flags = 0; IDXGIDevice1* dxgiDevice; Kore_Microsoft_affirm(device->QueryInterface(IID_IDXGIDevice1, (void**)&dxgiDevice)); IDXGIAdapter* dxgiAdapter; Kore_Microsoft_affirm(dxgiDevice->GetAdapter(&dxgiAdapter)); IDXGIFactory2* dxgiFactory; Kore_Microsoft_affirm(dxgiAdapter->GetParent(__uuidof(IDXGIFactory2), (void**)&dxgiFactory)); Kore_Microsoft_affirm(dxgiFactory->CreateSwapChainForCoreWindow(device, reinterpret_cast<IUnknown*>(CoreWindow::GetForCurrentThread()), &swapChainDesc, nullptr, &swapChain)); Kore_Microsoft_affirm(dxgiDevice->SetMaximumFrameLatency(1)); #endif #elif KORE_OCULUS DXGI_SWAP_CHAIN_DESC scDesc = {0}; scDesc.BufferCount = 2; scDesc.BufferDesc.Width = System::windowWidth(windowId); scDesc.BufferDesc.Height = System::windowHeight(windowId); scDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; scDesc.BufferDesc.RefreshRate.Denominator = 1; scDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; scDesc.OutputWindow = (HWND)System::windowHandle(windowId); ; scDesc.SampleDesc.Count = antialiasingSamples() > 1 ? antialiasingSamples() : 1; scDesc.SampleDesc.Quality = antialiasingSamples() > 1 ? D3D11_STANDARD_MULTISAMPLE_PATTERN : 0; scDesc.Windowed = true; scDesc.SwapEffect = DXGI_SWAP_EFFECT_SEQUENTIAL; Windows::affirm(dxgiFactory->CreateSwapChain(device, &scDesc, &swapChain)); dxgiFactory->Release(); IDXGIDevice1* dxgiDevice = nullptr; Windows::affirm(device->QueryInterface(__uuidof(IDXGIDevice1), (void**)&dxgiDevice)); Windows::affirm(dxgiDevice->SetMaximumFrameLatency(1)); dxgiDevice->Release(); #else UINT flags = 0; #ifdef _DEBUG flags = D3D11_CREATE_DEVICE_DEBUG; #endif HRESULT result = D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, flags, featureLevels, 3, D3D11_SDK_VERSION, &swapChainDesc, &swapChain, &device, nullptr, &context); if (result != S_OK) { Kore_Microsoft_affirm(D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_WARP, nullptr, flags, featureLevels, 3, D3D11_SDK_VERSION, &swapChainDesc, &swapChain, &device, nullptr, &context)); } #endif } #ifdef KORE_HOLOLENS // holographicFrameController manages the targets and views for hololens. // the views have to be created/deleted on the CameraAdded/Removed events // at this point we don't know if this event has alread occured so we cannot // simply set the renderTargetWidth, renderTargetHeight, currentRenderTargetViews and currentDepthStencilView. // to bind the targets for hololens one has to use the VrInterface::beginRender(eye) instead of the methods in this class. ComPtr<ID3D11Device> devicePtr = device; ComPtr<ID3D11DeviceContext> contextPtr = context; Microsoft::WRL::ComPtr<ID3D11Device4> device4Ptr; Microsoft::WRL::ComPtr<ID3D11DeviceContext3> context3Ptr; affirm(devicePtr.As(&device4Ptr)); affirm(contextPtr.As(&context3Ptr)); holographicFrameController->setDeviceAndContext(device4Ptr, context3Ptr); #else createBackbuffer(antialiasingSamples()); currentRenderTargetViews[0] = renderTargetView; currentDepthStencilView = depthStencilView; context->OMSetRenderTargets(1, &renderTargetView, depthStencilView); CD3D11_VIEWPORT viewPort(0.0f, 0.0f, static_cast<float>(renderTargetWidth), static_cast<float>(renderTargetHeight)); context->RSSetViewports(1, &viewPort); #endif D3D11_SAMPLER_DESC samplerDesc; ZeroMemory(&samplerDesc, sizeof(samplerDesc)); samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; for (int i = 0; i < 16; ++i) { lastSamplers[i] = samplerDesc; } initSamplers(); D3D11_BLEND_DESC blendDesc; ZeroMemory(&blendDesc, sizeof(blendDesc)); D3D11_RENDER_TARGET_BLEND_DESC rtbd; ZeroMemory(&rtbd, sizeof(rtbd)); rtbd.BlendEnable = true; rtbd.SrcBlend = D3D11_BLEND_SRC_ALPHA; rtbd.DestBlend = D3D11_BLEND_INV_SRC_ALPHA; rtbd.BlendOp = D3D11_BLEND_OP_ADD; rtbd.SrcBlendAlpha = D3D11_BLEND_ONE; rtbd.DestBlendAlpha = D3D11_BLEND_ZERO; rtbd.BlendOpAlpha = D3D11_BLEND_OP_ADD; #ifdef KORE_WINDOWSAPP rtbd.RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; #else rtbd.RenderTargetWriteMask = D3D10_COLOR_WRITE_ENABLE_ALL; #endif blendDesc.AlphaToCoverageEnable = false; blendDesc.RenderTarget[0] = rtbd; ID3D11BlendState* blending; device->CreateBlendState(&blendDesc, &blending); Kore_Microsoft_affirm(device->CreateBlendState(&blendDesc, &blending)); context->OMSetBlendState(blending, nullptr, 0xffffffff); }
HRESULT Create(HWND wnd) { hWnd = wnd; HRESULT hr; RECT client; GetClientRect(hWnd, &client); xres = client.right - client.left; yres = client.bottom - client.top; hr = LoadDXGI(); if (SUCCEEDED(hr)) hr = LoadD3D(); if (SUCCEEDED(hr)) hr = LoadD3DCompiler(); if (FAILED(hr)) { UnloadDXGI(); UnloadD3D(); UnloadD3DCompiler(); return hr; } IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* output; hr = PCreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if (FAILED(hr)) MessageBox(wnd, _T("Failed to create IDXGIFactory object"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); hr = factory->EnumAdapters(g_ActiveConfig.iAdapter, &adapter); if (FAILED(hr)) { // try using the first one hr = factory->EnumAdapters(0, &adapter); if (FAILED(hr)) MessageBox(wnd, _T("Failed to enumerate adapters"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); } // TODO: Make this configurable hr = adapter->EnumOutputs(0, &output); if (FAILED(hr)) { // try using the first one hr = adapter->EnumOutputs(0, &output); if (FAILED(hr)) MessageBox(wnd, _T("Failed to enumerate outputs"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); } // get supported AA modes aa_modes = EnumAAModes(adapter); if (g_Config.iMultisampleMode >= (int)aa_modes.size()) { g_Config.iMultisampleMode = 0; UpdateActiveConfig(); } DXGI_SWAP_CHAIN_DESC swap_chain_desc; memset(&swap_chain_desc, 0, sizeof(swap_chain_desc)); swap_chain_desc.BufferCount = 1; swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swap_chain_desc.OutputWindow = wnd; swap_chain_desc.SampleDesc.Count = 1; swap_chain_desc.SampleDesc.Quality = 0; swap_chain_desc.Windowed = TRUE; DXGI_MODE_DESC mode_desc; memset(&mode_desc, 0, sizeof(mode_desc)); mode_desc.Width = xres; mode_desc.Height = yres; mode_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; mode_desc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; hr = output->FindClosestMatchingMode(&mode_desc, &swap_chain_desc.BufferDesc, nullptr); if (FAILED(hr)) MessageBox(wnd, _T("Failed to find a supported video mode"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); // forcing buffer resolution to xres and yres.. TODO: The new video mode might not actually be supported! swap_chain_desc.BufferDesc.Width = xres; swap_chain_desc.BufferDesc.Height = yres; #if defined(_DEBUG) || defined(DEBUGFAST) // Creating debug devices can sometimes fail if the user doesn't have the correct // version of the DirectX SDK. If it does, simply fallback to a non-debug device. { hr = PD3D11CreateDeviceAndSwapChain(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, D3D11_CREATE_DEVICE_SINGLETHREADED | D3D11_CREATE_DEVICE_DEBUG, supported_feature_levels, NUM_SUPPORTED_FEATURE_LEVELS, D3D11_SDK_VERSION, &swap_chain_desc, &swapchain, &device, &featlevel, &context); } if (FAILED(hr)) #endif { hr = PD3D11CreateDeviceAndSwapChain(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, D3D11_CREATE_DEVICE_SINGLETHREADED, supported_feature_levels, NUM_SUPPORTED_FEATURE_LEVELS, D3D11_SDK_VERSION, &swap_chain_desc, &swapchain, &device, &featlevel, &context); } if (FAILED(hr)) { MessageBox(wnd, _T("Failed to initialize Direct3D.\nMake sure your video card supports at least D3D 10.0"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); SAFE_RELEASE(device); SAFE_RELEASE(context); SAFE_RELEASE(swapchain); return E_FAIL; } SetDebugObjectName((ID3D11DeviceChild*)context, "device context"); SAFE_RELEASE(factory); SAFE_RELEASE(output); SAFE_RELEASE(adapter); ID3D11Texture2D* buf; hr = swapchain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&buf); if (FAILED(hr)) { MessageBox(wnd, _T("Failed to get swapchain buffer"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); SAFE_RELEASE(device); SAFE_RELEASE(context); SAFE_RELEASE(swapchain); return E_FAIL; } backbuf = new D3DTexture2D(buf, D3D11_BIND_RENDER_TARGET); SAFE_RELEASE(buf); CHECK(backbuf!=nullptr, "Create back buffer texture"); SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetTex(), "backbuffer texture"); SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetRTV(), "backbuffer render target view"); context->OMSetRenderTargets(1, &backbuf->GetRTV(), nullptr); // BGRA textures are easier to deal with in TextureCache, but might not be supported by the hardware UINT format_support; device->CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, &format_support); bgra_textures_supported = (format_support & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0; stateman = new StateManager; return S_OK; }
//-------------------------------------------------------------------------------------- // Create Direct3D device and swap chain //-------------------------------------------------------------------------------------- HRESULT InitDevice() { HRESULT hr = S_OK; RECT rc; GetClientRect( g_hWnd, &rc ); UINT width = rc.right - rc.left; UINT height = rc.bottom - rc.top; UINT createDeviceFlags = 0; #ifdef _DEBUG createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_DRIVER_TYPE driverTypes[] = { D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP, D3D_DRIVER_TYPE_REFERENCE, }; UINT numDriverTypes = ARRAYSIZE( driverTypes ); D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, }; UINT numFeatureLevels = ARRAYSIZE( featureLevels ); for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ ) { g_driverType = driverTypes[driverTypeIndex]; hr = D3D11CreateDevice( nullptr, g_driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext ); if ( hr == E_INVALIDARG ) { // DirectX 11.0 platforms will not recognize D3D_FEATURE_LEVEL_11_1 so we need to retry without it hr = D3D11CreateDevice( nullptr, g_driverType, nullptr, createDeviceFlags, &featureLevels[1], numFeatureLevels - 1, D3D11_SDK_VERSION, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext ); } if( SUCCEEDED( hr ) ) break; } if( FAILED( hr ) ) return hr; // Obtain DXGI factory from device (since we used nullptr for pAdapter above) IDXGIFactory1* dxgiFactory = nullptr; { IDXGIDevice* dxgiDevice = nullptr; hr = g_pd3dDevice->QueryInterface( __uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice) ); if (SUCCEEDED(hr)) { IDXGIAdapter* adapter = nullptr; hr = dxgiDevice->GetAdapter(&adapter); if (SUCCEEDED(hr)) { hr = adapter->GetParent( __uuidof(IDXGIFactory1), reinterpret_cast<void**>(&dxgiFactory) ); adapter->Release(); } dxgiDevice->Release(); } } if (FAILED(hr)) return hr; // Create swap chain IDXGIFactory2* dxgiFactory2 = nullptr; hr = dxgiFactory->QueryInterface( __uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory2) ); if ( dxgiFactory2 ) { // DirectX 11.1 or later hr = g_pd3dDevice->QueryInterface( __uuidof(ID3D11Device1), reinterpret_cast<void**>(&g_pd3dDevice1) ); if (SUCCEEDED(hr)) { (void) g_pImmediateContext->QueryInterface( __uuidof(ID3D11DeviceContext1), reinterpret_cast<void**>(&g_pImmediateContext1) ); } DXGI_SWAP_CHAIN_DESC1 sd; ZeroMemory(&sd, sizeof(sd)); sd.Width = width; sd.Height = height; sd.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.BufferCount = 1; hr = dxgiFactory2->CreateSwapChainForHwnd( g_pd3dDevice, g_hWnd, &sd, nullptr, nullptr, &g_pSwapChain1 ); if (SUCCEEDED(hr)) { hr = g_pSwapChain1->QueryInterface( __uuidof(IDXGISwapChain), reinterpret_cast<void**>(&g_pSwapChain) ); } dxgiFactory2->Release(); } else { // DirectX 11.0 systems DXGI_SWAP_CHAIN_DESC sd; ZeroMemory(&sd, sizeof(sd)); sd.BufferCount = 1; sd.BufferDesc.Width = width; sd.BufferDesc.Height = height; sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.BufferDesc.RefreshRate.Numerator = 60; sd.BufferDesc.RefreshRate.Denominator = 1; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.OutputWindow = g_hWnd; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.Windowed = TRUE; hr = dxgiFactory->CreateSwapChain( g_pd3dDevice, &sd, &g_pSwapChain ); } dxgiFactory->Release(); if (FAILED(hr)) return hr; // Create a render target view ID3D11Texture2D* pBackBuffer = nullptr; hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), reinterpret_cast<void**>( &pBackBuffer ) ); if( FAILED( hr ) ) return hr; hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, nullptr, &g_pRenderTargetView ); pBackBuffer->Release(); if( FAILED( hr ) ) return hr; g_pImmediateContext->OMSetRenderTargets( 1, &g_pRenderTargetView, nullptr ); // Setup the viewport D3D11_VIEWPORT vp; vp.Width = (FLOAT)width; vp.Height = (FLOAT)height; vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; vp.TopLeftX = 0; vp.TopLeftY = 0; g_pImmediateContext->RSSetViewports( 1, &vp ); return S_OK; }
void D3D11::init( int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen, float screenDepth, float screenNear ) { m_vsyncEnabled = vsync; m_isWindows = fullscreen; IDXGIFactory * pfactory; if(FAILED(CreateDXGIFactory(__uuidof(IDXGIFactory),(void**)&pfactory))) return; IDXGIAdapter * pAdapter; if(FAILED(pfactory->EnumAdapters(0,&pAdapter))) return; IDXGIOutput * out; if(FAILED(pAdapter->EnumOutputs(0,&out))) return; int numModes; DXGI_MODE_DESC * displaymodeList; if(FAILED(out->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM,DXGI_ENUM_MODES_INTERLACED,&numModes,NULL))) return; displaymodeList = new DXGI_MODE_DESC[numModes]; if(FAILED(out->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM,DXGI_ENUM_MODES_INTERLACED,&numModes,displaymodeList))) return; int numerator,denomerator; for(int i = 0; i < numModes; ++i) { if(displaymodeList[i].Height == screenHeight && displaymodeList[i].Width == screenWidth) { numerator = displaymodeList[i].RefreshRate.Numerator; denomerator = displaymodeList[i].RefreshRate.Denominator; } } DXGI_ADAPTER_DESC desc; if(FAILED(pAdapter->GetDesc(&desc))) return; int length; m_videoCardMemory = static_cast<int>(desc.DedicatedVideoMemory/1024/1024); wcstombs_s(&length,m_videoCardDescription,128,desc.Description,128); delete[] displaymodeList; displaymodeList = NULL; out->Release(); out = NULL; pAdapter->Release(); pAdapter = NULL; pfactory->Release(); pfactory = NULL; DXGI_SWAP_CHAIN_DESC swapChainDesc; ZeroMemory(&swapChainDesc,sizeof(DXGI_SWAP_CHAIN_DESC)); swapChainDesc.BufferCount = 1; swapChainDesc.BufferDesc.Width = screenWidth; swapChainDesc.BufferDesc.Height = screenHeight; swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; if(m_vsyncEnabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = denomerator; } else { swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; } swapChainDesc.Windowed = m_isWindows; swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; D3D_FEATURE_LEVEL level = D3D_FEATURE_LEVEL_11_0; if(FAILED(D3D11CreateDeviceAndSwapChain(NULL,D3D_DRIVER_TYPE_HARDWARE,NULL,0, &level,1,D3D11_SDK_VERSION,&swapChainDesc,&m_swapChain,&m_device,NULL,&m_deviceContext))) return; ID3D11Texture2D *backbufferTex; if(FAILED(m_swapChain->GetBuffer(0,__uuidof(ID3D11Texture2D),(LPVOID*)&backbufferTex))) return; if(FAILED(m_device->CreateRenderTargetView(backbufferTex,NULL,&m_renderView))) return; backbufferTex->Release(); backbufferTex = 0; D3D11_TEXTURE2D_DESC depthBufferDesc; ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); depthBufferDesc.Width = screenWidth; depthBufferDesc.Height = screenHeight; depthBufferDesc.MipLevels = 1; depthBufferDesc.ArraySize = 1; depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthBufferDesc.SampleDesc.Count = 1; depthBufferDesc.SampleDesc.Quality = 0; depthBufferDesc.Usage = D3D11_USAGE_DEFAULT; depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthBufferDesc.CPUAccessFlags = 0; depthBufferDesc.MiscFlags = 0; if(FAILED(m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer))) return ; D3D11_DEPTH_STENCIL_DESC depthStencilDesc; // Initialize the description of the stencil state. ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc)); // Set up the description of the stencil state. depthStencilDesc.DepthEnable = true; depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; depthStencilDesc.StencilEnable = true; depthStencilDesc.StencilReadMask = 0xFF; depthStencilDesc.StencilWriteMask = 0xFF; // Stencil operations if pixel is front-facing. depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // Stencil operations if pixel is back-facing. depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // Create the depth stencil state. if(FAILED(m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState))) return; // Set the depth stencil state. m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1); D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; // Initialize the depth stencil view. ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc)); // Set up the depth stencil view description. depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; // Create the depth stencil view. if(FAILED(m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView))) return ; // Bind the render target view and depth stencil buffer to the output render pipeline. m_deviceContext->OMSetRenderTargets(1, &m_renderView, m_depthStencilView); D3D11_RASTERIZER_DESC rasterDesc; // Setup the raster description which will determine how and what polygons will be drawn. rasterDesc.AntialiasedLineEnable = false; rasterDesc.CullMode = D3D11_CULL_BACK; rasterDesc.DepthBias = 0; rasterDesc.DepthBiasClamp = 0.0f; rasterDesc.DepthClipEnable = true; rasterDesc.FillMode = D3D11_FILL_SOLID; rasterDesc.FrontCounterClockwise = false; rasterDesc.MultisampleEnable = false; rasterDesc.ScissorEnable = false; rasterDesc.SlopeScaledDepthBias = 0.0f; // Create the rasterizer state from the description we just filled out. if(FAILED(m_device->CreateRasterizerState(&rasterDesc, &m_rasterState))) return ; // Now set the rasterizer state. m_deviceContext->RSSetState(m_rasterState); D3D11_VIEWPORT viewport; // Setup the viewport for rendering. viewport.Width = (float)screenWidth; viewport.Height = (float)screenHeight; viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; viewport.TopLeftX = 0.0f; viewport.TopLeftY = 0.0f; // Create the viewport. m_deviceContext->RSSetViewports(1, &viewport); float fieldOfView, screenAspect; // Setup the projection matrix. fieldOfView = (float)D3DX_PI / 4.0f; screenAspect = (float)screenWidth / (float)screenHeight; // Create the projection matrix for 3D rendering. D3DXMatrixPerspectiveFovLH(&m_projMat, fieldOfView, screenAspect, screenNear, screenDepth); // Initialize the world matrix to the identity matrix. D3DXMatrixIdentity(&m_worldMat); // Create an orthographic projection matrix for 2D rendering. D3DXMatrixOrthoLH(&m_orthoMat, (float)screenWidth, (float)screenHeight, screenNear, screenDepth); }
//-------------------------------------------------------------------------------------- // Create Direct3D device and swap chain //-------------------------------------------------------------------------------------- HRESULT InitDevice() { HRESULT hr = S_OK; RECT rc; GetClientRect( g_hWnd, &rc ); UINT width = rc.right - rc.left; UINT height = rc.bottom - rc.top; UINT createDeviceFlags = 0; #ifdef _DEBUG createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_DRIVER_TYPE driverTypes[] = { D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP, D3D_DRIVER_TYPE_REFERENCE, }; UINT numDriverTypes = ARRAYSIZE( driverTypes ); D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, }; UINT numFeatureLevels = ARRAYSIZE( featureLevels ); for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ ) { g_driverType = driverTypes[driverTypeIndex]; hr = D3D11CreateDevice( nullptr, g_driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext ); if ( hr == E_INVALIDARG ) { // DirectX 11.0 platforms will not recognize D3D_FEATURE_LEVEL_11_1 so we need to retry without it hr = D3D11CreateDevice( nullptr, g_driverType, nullptr, createDeviceFlags, &featureLevels[1], numFeatureLevels - 1, D3D11_SDK_VERSION, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext ); } if( SUCCEEDED( hr ) ) break; } if( FAILED( hr ) ) return hr; // Obtain DXGI factory from device (since we used nullptr for pAdapter above) IDXGIFactory1* dxgiFactory = nullptr; { IDXGIDevice* dxgiDevice = nullptr; hr = g_pd3dDevice->QueryInterface( __uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice) ); if (SUCCEEDED(hr)) { IDXGIAdapter* adapter = nullptr; hr = dxgiDevice->GetAdapter(&adapter); if (SUCCEEDED(hr)) { hr = adapter->GetParent( __uuidof(IDXGIFactory1), reinterpret_cast<void**>(&dxgiFactory) ); adapter->Release(); } dxgiDevice->Release(); } } if (FAILED(hr)) return hr; // Create swap chain IDXGIFactory2* dxgiFactory2 = nullptr; hr = dxgiFactory->QueryInterface( __uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory2) ); if ( dxgiFactory2 ) { // DirectX 11.1 or later hr = g_pd3dDevice->QueryInterface( __uuidof(ID3D11Device1), reinterpret_cast<void**>(&g_pd3dDevice1) ); if (SUCCEEDED(hr)) { (void) g_pImmediateContext->QueryInterface( __uuidof(ID3D11DeviceContext1), reinterpret_cast<void**>(&g_pImmediateContext1) ); } DXGI_SWAP_CHAIN_DESC1 sd; ZeroMemory(&sd, sizeof(sd)); sd.Width = width; sd.Height = height; sd.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.BufferCount = 1; hr = dxgiFactory2->CreateSwapChainForHwnd( g_pd3dDevice, g_hWnd, &sd, nullptr, nullptr, &g_pSwapChain1 ); if (SUCCEEDED(hr)) { hr = g_pSwapChain1->QueryInterface( __uuidof(IDXGISwapChain), reinterpret_cast<void**>(&g_pSwapChain) ); } dxgiFactory2->Release(); } else { // DirectX 11.0 systems DXGI_SWAP_CHAIN_DESC sd; ZeroMemory(&sd, sizeof(sd)); sd.BufferCount = 1; sd.BufferDesc.Width = width; sd.BufferDesc.Height = height; sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.BufferDesc.RefreshRate.Numerator = 60; sd.BufferDesc.RefreshRate.Denominator = 1; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.OutputWindow = g_hWnd; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.Windowed = TRUE; hr = dxgiFactory->CreateSwapChain( g_pd3dDevice, &sd, &g_pSwapChain ); } // Note this tutorial doesn't handle full-screen swapchains so we block the ALT+ENTER shortcut dxgiFactory->MakeWindowAssociation( g_hWnd, DXGI_MWA_NO_ALT_ENTER ); dxgiFactory->Release(); if (FAILED(hr)) return hr; // Create a render target view ID3D11Texture2D* pBackBuffer = nullptr; hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), reinterpret_cast<void**>( &pBackBuffer ) ); if( FAILED( hr ) ) return hr; hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, nullptr, &g_pRenderTargetView ); pBackBuffer->Release(); if( FAILED( hr ) ) return hr; // Create depth stencil texture D3D11_TEXTURE2D_DESC descDepth; ZeroMemory( &descDepth, sizeof(descDepth) ); descDepth.Width = width; descDepth.Height = height; descDepth.MipLevels = 1; descDepth.ArraySize = 1; descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; descDepth.SampleDesc.Count = 1; descDepth.SampleDesc.Quality = 0; descDepth.Usage = D3D11_USAGE_DEFAULT; descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL; descDepth.CPUAccessFlags = 0; descDepth.MiscFlags = 0; hr = g_pd3dDevice->CreateTexture2D( &descDepth, nullptr, &g_pDepthStencil ); if( FAILED( hr ) ) return hr; // Create the depth stencil view D3D11_DEPTH_STENCIL_VIEW_DESC descDSV; ZeroMemory( &descDSV, sizeof(descDSV) ); descDSV.Format = descDepth.Format; descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; descDSV.Texture2D.MipSlice = 0; hr = g_pd3dDevice->CreateDepthStencilView( g_pDepthStencil, &descDSV, &g_pDepthStencilView ); if( FAILED( hr ) ) return hr; g_pImmediateContext->OMSetRenderTargets( 1, &g_pRenderTargetView, g_pDepthStencilView ); // Setup the viewport D3D11_VIEWPORT vp; vp.Width = (FLOAT)width; vp.Height = (FLOAT)height; vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; vp.TopLeftX = 0; vp.TopLeftY = 0; g_pImmediateContext->RSSetViewports( 1, &vp ); // Compile the vertex shader ID3DBlob* pVSBlob = nullptr; hr = CompileShaderFromFile( L"Tutorial05.fx", "VS", "vs_4_0", &pVSBlob ); if( FAILED( hr ) ) { MessageBox( nullptr, L"The FX file cannot be compiled. Please run this executable from the directory that contains the FX file.", L"Error", MB_OK ); return hr; } // Create the vertex shader hr = g_pd3dDevice->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), nullptr, &g_pVertexShader ); if( FAILED( hr ) ) { pVSBlob->Release(); return hr; } // Define the input layout D3D11_INPUT_ELEMENT_DESC layout[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; UINT numElements = ARRAYSIZE( layout ); // Create the input layout hr = g_pd3dDevice->CreateInputLayout( layout, numElements, pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &g_pVertexLayout ); pVSBlob->Release(); if( FAILED( hr ) ) return hr; // Set the input layout g_pImmediateContext->IASetInputLayout( g_pVertexLayout ); // Compile the pixel shader ID3DBlob* pPSBlob = nullptr; hr = CompileShaderFromFile( L"Tutorial05.fx", "PS", "ps_4_0", &pPSBlob ); if( FAILED( hr ) ) { MessageBox( nullptr, L"The FX file cannot be compiled. Please run this executable from the directory that contains the FX file.", L"Error", MB_OK ); return hr; } // Create the pixel shader hr = g_pd3dDevice->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), nullptr, &g_pPixelShader ); pPSBlob->Release(); if( FAILED( hr ) ) return hr; // Create vertex buffer SimpleVertex vertices[] = { { XMFLOAT3( -1.0f, 1.0f, -1.0f ), XMFLOAT4( 0.0f, 0.0f, 1.0f, 1.0f ) }, { XMFLOAT3( 1.0f, 1.0f, -1.0f ), XMFLOAT4( 0.0f, 1.0f, 0.0f, 1.0f ) }, { XMFLOAT3( 1.0f, 1.0f, 1.0f ), XMFLOAT4( 0.0f, 1.0f, 1.0f, 1.0f ) }, { XMFLOAT3( -1.0f, 1.0f, 1.0f ), XMFLOAT4( 1.0f, 0.0f, 0.0f, 1.0f ) }, { XMFLOAT3( -1.0f, -1.0f, -1.0f ), XMFLOAT4( 1.0f, 0.0f, 1.0f, 1.0f ) }, { XMFLOAT3( 1.0f, -1.0f, -1.0f ), XMFLOAT4( 1.0f, 1.0f, 0.0f, 1.0f ) }, { XMFLOAT3( 1.0f, -1.0f, 1.0f ), XMFLOAT4( 1.0f, 1.0f, 1.0f, 1.0f ) }, { XMFLOAT3( -1.0f, -1.0f, 1.0f ), XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f ) }, }; D3D11_BUFFER_DESC bd; ZeroMemory( &bd, sizeof(bd) ); bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof( SimpleVertex ) * 8; bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; bd.CPUAccessFlags = 0; D3D11_SUBRESOURCE_DATA InitData; ZeroMemory( &InitData, sizeof(InitData) ); InitData.pSysMem = vertices; hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer ); if( FAILED( hr ) ) return hr; // Set vertex buffer UINT stride = sizeof( SimpleVertex ); UINT offset = 0; g_pImmediateContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride, &offset ); // Create index buffer WORD indices[] = { 3,1,0, 2,1,3, 0,5,4, 1,5,0, 3,4,7, 0,4,3, 1,6,5, 2,6,1, 2,7,6, 3,7,2, 6,4,5, 7,4,6, }; bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof( WORD ) * 36; // 36 vertices needed for 12 triangles in a triangle list bd.BindFlags = D3D11_BIND_INDEX_BUFFER; bd.CPUAccessFlags = 0; InitData.pSysMem = indices; hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pIndexBuffer ); if( FAILED( hr ) ) return hr; // Set index buffer g_pImmediateContext->IASetIndexBuffer( g_pIndexBuffer, DXGI_FORMAT_R16_UINT, 0 ); // Set primitive topology g_pImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); // Create the constant buffer bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof(ConstantBuffer); bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; bd.CPUAccessFlags = 0; hr = g_pd3dDevice->CreateBuffer( &bd, nullptr, &g_pConstantBuffer ); if( FAILED( hr ) ) return hr; // Initialize the world matrix g_World1 = XMMatrixIdentity(); g_World2 = XMMatrixIdentity(); // Initialize the view matrix XMVECTOR Eye = XMVectorSet( 0.0f, 1.0f, -5.0f, 0.0f ); XMVECTOR At = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f ); XMVECTOR Up = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f ); g_View = XMMatrixLookAtLH( Eye, At, Up ); // Initialize the projection matrix g_Projection = XMMatrixPerspectiveFovLH( XM_PIDIV2, width / (FLOAT)height, 0.01f, 100.0f ); return S_OK; }
/** * @brief * Constructor */ SwapChain::SwapChain(Direct3D11Renderer &direct3D11Renderer, handle nativeWindowHandle) : ISwapChain(direct3D11Renderer), mDxgiSwapChain(nullptr), mD3D11RenderTargetView(nullptr), mD3D11DepthStencilView(nullptr) { // Get the Direct3D 11 device instance ID3D11Device *d3d11Device = direct3D11Renderer.getD3D11Device(); // Get the native window handle const HWND hWnd = reinterpret_cast<HWND>(nativeWindowHandle); // Get a IDXGIFactory1 instance IDXGIDevice *dxgiDevice = nullptr; IDXGIAdapter *dxgiAdapter = nullptr; IDXGIFactory1 *dxgiFactory1 = nullptr; d3d11Device->QueryInterface(&dxgiDevice); dxgiDevice->GetAdapter(&dxgiAdapter); dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory1)); dxgiAdapter->Release(); dxgiDevice->Release(); // Get the width and height of the given native window and ensure they are never ever zero // -> See "getSafeWidthAndHeight()"-method comments for details long width = 1; long height = 1; { // Get the client rectangle of the given native window RECT rect; ::GetClientRect(hWnd, &rect); // Get the width and height... width = rect.right - rect.left; height = rect.bottom - rect.top; // ... and ensure that none of them is ever zero if (width < 1) { width = 1; } if (height < 1) { height = 1; } } // Create the swap chain DXGI_SWAP_CHAIN_DESC dxgiSwapChainDesc; ::ZeroMemory(&dxgiSwapChainDesc, sizeof(dxgiSwapChainDesc)); dxgiSwapChainDesc.BufferCount = 1; dxgiSwapChainDesc.BufferDesc.Width = static_cast<UINT>(width); dxgiSwapChainDesc.BufferDesc.Height = static_cast<UINT>(height); dxgiSwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; dxgiSwapChainDesc.BufferDesc.RefreshRate.Numerator = 60; dxgiSwapChainDesc.BufferDesc.RefreshRate.Denominator = 1; dxgiSwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; dxgiSwapChainDesc.OutputWindow = hWnd; dxgiSwapChainDesc.SampleDesc.Count = 1; dxgiSwapChainDesc.SampleDesc.Quality = 0; dxgiSwapChainDesc.Windowed = TRUE; dxgiFactory1->CreateSwapChain(d3d11Device, &dxgiSwapChainDesc, &mDxgiSwapChain); dxgiFactory1->Release(); // Disable alt-return for automatic fullscreen state change // -> We handle this manually to have more control over it dxgiFactory1->MakeWindowAssociation(hWnd, DXGI_MWA_NO_ALT_ENTER); // Create the Direct3D 11 views if (nullptr != mDxgiSwapChain) { createDirect3D11Views(); } // Assign a default name to the resource for debugging purposes #ifndef DIRECT3D11RENDERER_NO_DEBUG setDebugName("Swap chain"); #endif }
void InitBackendInfo() { HRESULT hr = DX11::D3D::LoadDXGI(); if (SUCCEEDED(hr)) hr = DX11::D3D::LoadD3D(); if (FAILED(hr)) { DX11::D3D::UnloadDXGI(); return; } g_Config.backend_info.APIType = API_D3D; g_Config.backend_info.bSupportsExclusiveFullscreen = true; g_Config.backend_info.bSupportsDualSourceBlend = true; g_Config.backend_info.bSupportsPrimitiveRestart = true; g_Config.backend_info.bSupportsOversizedViewports = false; g_Config.backend_info.bSupportsGeometryShaders = true; g_Config.backend_info.bSupports3DVision = true; g_Config.backend_info.bSupportsPostProcessing = false; IDXGIFactory* factory; IDXGIAdapter* ad; hr = DX11::PCreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if (FAILED(hr)) PanicAlert("Failed to create IDXGIFactory object"); // adapters g_Config.backend_info.Adapters.clear(); g_Config.backend_info.AAModes.clear(); while (factory->EnumAdapters((UINT)g_Config.backend_info.Adapters.size(), &ad) != DXGI_ERROR_NOT_FOUND) { const size_t adapter_index = g_Config.backend_info.Adapters.size(); DXGI_ADAPTER_DESC desc; ad->GetDesc(&desc); // TODO: These don't get updated on adapter change, yet if (adapter_index == g_Config.iAdapter) { std::string samples; std::vector<DXGI_SAMPLE_DESC> modes = DX11::D3D::EnumAAModes(ad); for (unsigned int i = 0; i < modes.size(); ++i) { if (i == 0) samples = _trans("None"); else if (modes[i].Quality) samples = StringFromFormat(_trans("%d samples (quality level %d)"), modes[i].Count, modes[i].Quality); else samples = StringFromFormat(_trans("%d samples"), modes[i].Count); g_Config.backend_info.AAModes.push_back(samples); } bool shader_model_5_supported = (DX11::D3D::GetFeatureLevel(ad) >= D3D_FEATURE_LEVEL_11_0); // Requires the earlydepthstencil attribute (only available in shader model 5) g_Config.backend_info.bSupportsEarlyZ = shader_model_5_supported; // Requires full UAV functionality (only available in shader model 5) g_Config.backend_info.bSupportsBBox = shader_model_5_supported; // Requires the instance attribute (only available in shader model 5) g_Config.backend_info.bSupportsGSInstancing = shader_model_5_supported; } g_Config.backend_info.Adapters.push_back(UTF16ToUTF8(desc.Description)); ad->Release(); } factory->Release(); // Clear ppshaders string vector g_Config.backend_info.PPShaders.clear(); g_Config.backend_info.AnaglyphShaders.clear(); DX11::D3D::UnloadDXGI(); DX11::D3D::UnloadD3D(); }
HRESULT Create(HWND wnd) { hWnd = wnd; HRESULT hr; RECT client; GetClientRect(hWnd, &client); xres = client.right - client.left; yres = client.bottom - client.top; hr = LoadDXGI(); if (SUCCEEDED(hr)) hr = LoadD3D(); if (SUCCEEDED(hr)) hr = LoadD3DCompiler(); if (FAILED(hr)) { UnloadDXGI(); UnloadD3D(); UnloadD3DCompiler(); return hr; } IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* output; hr = PCreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if (FAILED(hr)) MessageBox(wnd, _T("Failed to create IDXGIFactory object"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); hr = factory->EnumAdapters(g_ActiveConfig.iAdapter, &adapter); if (FAILED(hr)) { // try using the first one hr = factory->EnumAdapters(0, &adapter); if (FAILED(hr)) MessageBox(wnd, _T("Failed to enumerate adapters"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); } // TODO: Make this configurable hr = adapter->EnumOutputs(0, &output); if (FAILED(hr)) { // try using the first one IDXGIAdapter* firstadapter; hr = factory->EnumAdapters(0, &firstadapter); if (!FAILED(hr)) hr = firstadapter->EnumOutputs(0, &output); if (FAILED(hr)) MessageBox(wnd, _T("Failed to enumerate outputs!\n") _T("This usually happens when you've set your video adapter to the Nvidia GPU in an Optimus-equipped system.\n") _T("Set Dolphin to use the high-performance graphics in Nvidia's drivers instead and leave Dolphin's video adapter set to the Intel GPU."), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); SAFE_RELEASE(firstadapter); } // get supported AA modes aa_modes = EnumAAModes(adapter); if (std::find_if( aa_modes.begin(), aa_modes.end(), [](const DXGI_SAMPLE_DESC& desc) {return desc.Count == g_Config.iMultisamples;} ) == aa_modes.end()) { g_Config.iMultisamples = 1; UpdateActiveConfig(); } DXGI_SWAP_CHAIN_DESC swap_chain_desc = {}; swap_chain_desc.BufferCount = 1; swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swap_chain_desc.OutputWindow = wnd; swap_chain_desc.SampleDesc.Count = 1; swap_chain_desc.SampleDesc.Quality = 0; swap_chain_desc.Windowed = !g_Config.bFullscreen; DXGI_OUTPUT_DESC out_desc = {}; output->GetDesc(&out_desc); DXGI_MODE_DESC mode_desc = {}; mode_desc.Width = out_desc.DesktopCoordinates.right - out_desc.DesktopCoordinates.left; mode_desc.Height = out_desc.DesktopCoordinates.bottom - out_desc.DesktopCoordinates.top; mode_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; mode_desc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; hr = output->FindClosestMatchingMode(&mode_desc, &swap_chain_desc.BufferDesc, nullptr); if (FAILED(hr)) MessageBox(wnd, _T("Failed to find a supported video mode"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); if (swap_chain_desc.Windowed) { // forcing buffer resolution to xres and yres.. // this is not a problem as long as we're in windowed mode swap_chain_desc.BufferDesc.Width = xres; swap_chain_desc.BufferDesc.Height = yres; } #if defined(_DEBUG) || defined(DEBUGFAST) // Creating debug devices can sometimes fail if the user doesn't have the correct // version of the DirectX SDK. If it does, simply fallback to a non-debug device. { hr = PD3D11CreateDeviceAndSwapChain(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, D3D11_CREATE_DEVICE_SINGLETHREADED | D3D11_CREATE_DEVICE_DEBUG, supported_feature_levels, NUM_SUPPORTED_FEATURE_LEVELS, D3D11_SDK_VERSION, &swap_chain_desc, &swapchain, &device, &featlevel, &context); // Debugbreak on D3D error if (SUCCEEDED(hr) && SUCCEEDED(device->QueryInterface(__uuidof(ID3D11Debug), (void**)&debug))) { ID3D11InfoQueue* infoQueue = nullptr; if (SUCCEEDED(debug->QueryInterface(__uuidof(ID3D11InfoQueue), (void**)&infoQueue))) { infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true); infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true); D3D11_MESSAGE_ID hide[] = { D3D11_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS }; D3D11_INFO_QUEUE_FILTER filter = {}; filter.DenyList.NumIDs = sizeof(hide) / sizeof(D3D11_MESSAGE_ID); filter.DenyList.pIDList = hide; infoQueue->AddStorageFilterEntries(&filter); infoQueue->Release(); } } } if (FAILED(hr)) #endif { hr = PD3D11CreateDeviceAndSwapChain(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, D3D11_CREATE_DEVICE_SINGLETHREADED, supported_feature_levels, NUM_SUPPORTED_FEATURE_LEVELS, D3D11_SDK_VERSION, &swap_chain_desc, &swapchain, &device, &featlevel, &context); } if (FAILED(hr)) { MessageBox(wnd, _T("Failed to initialize Direct3D.\nMake sure your video card supports at least D3D 10.0"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); SAFE_RELEASE(device); SAFE_RELEASE(context); SAFE_RELEASE(swapchain); return E_FAIL; } // prevent DXGI from responding to Alt+Enter, unfortunately DXGI_MWA_NO_ALT_ENTER // does not work so we disable all monitoring of window messages. However this // may make it more difficult for DXGI to handle display mode changes. hr = factory->MakeWindowAssociation(wnd, DXGI_MWA_NO_WINDOW_CHANGES); if (FAILED(hr)) MessageBox(wnd, _T("Failed to associate the window"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); SetDebugObjectName((ID3D11DeviceChild*)context, "device context"); SAFE_RELEASE(factory); SAFE_RELEASE(output); SAFE_RELEASE(adapter); ID3D11Texture2D* buf; hr = swapchain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&buf); if (FAILED(hr)) { MessageBox(wnd, _T("Failed to get swapchain buffer"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR); SAFE_RELEASE(device); SAFE_RELEASE(context); SAFE_RELEASE(swapchain); return E_FAIL; } backbuf = new D3DTexture2D(buf, D3D11_BIND_RENDER_TARGET); SAFE_RELEASE(buf); CHECK(backbuf!=nullptr, "Create back buffer texture"); SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetTex(), "backbuffer texture"); SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetRTV(), "backbuffer render target view"); context->OMSetRenderTargets(1, &backbuf->GetRTV(), nullptr); // BGRA textures are easier to deal with in TextureCache, but might not be supported by the hardware UINT format_support; device->CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, &format_support); bgra_textures_supported = (format_support & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0; stateman = new StateManager; return S_OK; }
bool DX::InitDirect3D() { UINT createDeviceFlags = 0; // Do we want a debug device? #if defined(DEBUG) || defined(_DEBUG) createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif // Create the device and determine the supported feature level featureLevel = D3D_FEATURE_LEVEL_9_1; // Will be overwritten by next line HRESULT hr = D3D11CreateDevice( 0, driverType, 0, createDeviceFlags, 0, 0, D3D11_SDK_VERSION, &device, &featureLevel, &deviceContext); // Handle any device creation or DirectX version errors if( FAILED(hr) ) { MessageBox(0, L"D3D11CreateDevice Failed", 0, 0); return false; } // Check for 4X MSAA quality support HR(device->CheckMultisampleQualityLevels( DXGI_FORMAT_R8G8B8A8_UNORM, 4, &msaa4xQuality)); assert( msaa4xQuality > 0 ); // Potential problem if quality is 0 // Set up a swap chain description DXGI_SWAP_CHAIN_DESC swapChainDesc; swapChainDesc.BufferDesc.Width = windowWidth; swapChainDesc.BufferDesc.Height = windowHeight; swapChainDesc.BufferDesc.RefreshRate.Numerator = 60; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount = 1; swapChainDesc.OutputWindow = hMainWnd; swapChainDesc.Windowed = true; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; swapChainDesc.Flags = 0; if( enable4xMsaa ) { // Set up 4x MSAA swapChainDesc.SampleDesc.Count = 4; swapChainDesc.SampleDesc.Quality = msaa4xQuality - 1; } else { // No MSAA swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; } // To correctly create the swap chain, we must use the IDXGIFactory that // was used to create the device. IDXGIDevice* dxgiDevice = 0; IDXGIAdapter* dxgiAdapter = 0; IDXGIFactory* dxgiFactory = 0; HR(device->QueryInterface( __uuidof(IDXGIDevice), (void**)&dxgiDevice)); HR(dxgiDevice->GetParent( __uuidof(IDXGIAdapter), (void**)&dxgiAdapter)); HR(dxgiAdapter->GetParent( __uuidof(IDXGIFactory), (void**)&dxgiFactory)); // Finally make the swap chain and release the DXGI stuff HR(dxgiFactory->CreateSwapChain(device, &swapChainDesc, &swapChain)); ReleaseMacro(dxgiDevice); ReleaseMacro(dxgiAdapter); ReleaseMacro(dxgiFactory); // The remaining steps also need to happen each time the window // is resized, so just run the OnResize method OnResize(); return true; }
// Direct3D 초기화 HRESULT InitD3D( void ) { HRESULT hr = S_OK; D3D_FEATURE_LEVEL FeatureLevelsRequested[6] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1 }; UINT numLevelsRequested = 6; D3D_FEATURE_LEVEL FeatureLevelsSupported; // 디바이스 생성 hr = D3D11CreateDevice( NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, FeatureLevelsRequested, numLevelsRequested, D3D11_SDK_VERSION, &g_pd3dDevice, &FeatureLevelsSupported, &g_pImmediateContext ); if( FAILED ( hr ) ) { return hr; } // 팩토리 취득 IDXGIDevice * pDXGIDevice; hr = g_pd3dDevice->QueryInterface( __uuidof( IDXGIDevice ), ( void ** )&pDXGIDevice ); IDXGIAdapter * pDXGIAdapter; hr = pDXGIDevice->GetParent( __uuidof( IDXGIAdapter ), ( void ** )&pDXGIAdapter ); IDXGIFactory * pIDXGIFactory; pDXGIAdapter->GetParent( __uuidof( IDXGIFactory ), ( void ** )&pIDXGIFactory); // 스왑체인 작성 DXGI_SWAP_CHAIN_DESC sd; ZeroMemory( &sd, sizeof( sd ) ); sd.BufferCount = 1; sd.BufferDesc.Width = g_nClientWidth; sd.BufferDesc.Height = g_nClientHeight; sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.BufferDesc.RefreshRate.Numerator = 60; sd.BufferDesc.RefreshRate.Denominator = 1; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.OutputWindow = g_hWnd; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.Windowed = TRUE; hr = pIDXGIFactory->CreateSwapChain( g_pd3dDevice, &sd, &g_pSwapChain ); pDXGIDevice->Release(); pDXGIAdapter->Release(); pIDXGIFactory->Release(); if( FAILED ( hr ) ) { return hr; } // 렌더링 타깃 생성 ID3D11Texture2D *pBackBuffer = NULL; D3D11_TEXTURE2D_DESC BackBufferSurfaceDesc; hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), ( LPVOID* )&pBackBuffer ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "Can't get backbuffer." ), _T( "Error" ), MB_OK ); return hr; } pBackBuffer->GetDesc( &BackBufferSurfaceDesc ); hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &g_pRTV ); SAFE_RELEASE( pBackBuffer ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "Can't create render target view." ), _T( "Error" ), MB_OK ); return hr; } g_pImmediateContext->OMSetRenderTargets( 1, &g_pRTV, NULL ); // 래스터라이저 설정 D3D11_RASTERIZER_DESC drd; ZeroMemory( &drd, sizeof( drd ) ); drd.FillMode = D3D11_FILL_SOLID; drd.CullMode = D3D11_CULL_NONE; drd.FrontCounterClockwise = FALSE; drd.DepthClipEnable = TRUE; hr = g_pd3dDevice->CreateRasterizerState( &drd, &g_pRS ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "Can't create rasterizer state." ), _T( "Error" ), MB_OK ); return hr; } g_pImmediateContext->RSSetState( g_pRS ); // 뷰포트 설정 D3D11_VIEWPORT vp; vp.Width = ( FLOAT )g_nClientWidth; vp.Height = ( FLOAT )g_nClientHeight; vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; vp.TopLeftX = 0.0f; vp.TopLeftY = 0.0f; g_pImmediateContext->RSSetViewports( 1, &vp ); return S_OK; }
// nsIMemoryMultiReporter abstract method implementation NS_IMETHOD CollectReports(nsIMemoryMultiReporterCallback* aCb, nsISupports* aClosure) { int32_t winVers, buildNum; HANDLE ProcessHandle = GetCurrentProcess(); int64_t dedicatedBytesUsed = 0; int64_t sharedBytesUsed = 0; int64_t committedBytesUsed = 0; IDXGIAdapter *DXGIAdapter; HMODULE gdi32Handle; PFND3DKMTQS queryD3DKMTStatistics; winVers = gfxWindowsPlatform::WindowsOSVersion(&buildNum); // GPU memory reporting is not available before Windows 7 if (winVers < gfxWindowsPlatform::kWindows7) return NS_OK; if (gdi32Handle = LoadLibrary(TEXT("gdi32.dll"))) queryD3DKMTStatistics = (PFND3DKMTQS)GetProcAddress(gdi32Handle, "D3DKMTQueryStatistics"); if (queryD3DKMTStatistics && GetDXGIAdapter(&DXGIAdapter)) { // Most of this block is understood thanks to wj32's work on Process Hacker DXGI_ADAPTER_DESC adapterDesc; D3DKMTQS queryStatistics; DXGIAdapter->GetDesc(&adapterDesc); DXGIAdapter->Release(); memset(&queryStatistics, 0, sizeof(D3DKMTQS)); queryStatistics.Type = D3DKMTQS_PROCESS; queryStatistics.AdapterLuid = adapterDesc.AdapterLuid; queryStatistics.hProcess = ProcessHandle; if (NT_SUCCESS(queryD3DKMTStatistics(&queryStatistics))) { committedBytesUsed = queryStatistics.QueryResult.ProcessInfo.SystemMemory.BytesAllocated; } memset(&queryStatistics, 0, sizeof(D3DKMTQS)); queryStatistics.Type = D3DKMTQS_ADAPTER; queryStatistics.AdapterLuid = adapterDesc.AdapterLuid; if (NT_SUCCESS(queryD3DKMTStatistics(&queryStatistics))) { ULONG i; ULONG segmentCount = queryStatistics.QueryResult.AdapterInfo.NbSegments; for (i = 0; i < segmentCount; i++) { memset(&queryStatistics, 0, sizeof(D3DKMTQS)); queryStatistics.Type = D3DKMTQS_SEGMENT; queryStatistics.AdapterLuid = adapterDesc.AdapterLuid; queryStatistics.QuerySegment.SegmentId = i; if (NT_SUCCESS(queryD3DKMTStatistics(&queryStatistics))) { bool aperture; // SegmentInformation has a different definition in Win7 than later versions if (winVers < gfxWindowsPlatform::kWindows8) aperture = queryStatistics.QueryResult.SegmentInfoWin7.Aperture; else aperture = queryStatistics.QueryResult.SegmentInfoWin8.Aperture; memset(&queryStatistics, 0, sizeof(D3DKMTQS)); queryStatistics.Type = D3DKMTQS_PROCESS_SEGMENT; queryStatistics.AdapterLuid = adapterDesc.AdapterLuid; queryStatistics.hProcess = ProcessHandle; queryStatistics.QueryProcessSegment.SegmentId = i; if (NT_SUCCESS(queryD3DKMTStatistics(&queryStatistics))) { if (aperture) sharedBytesUsed += queryStatistics.QueryResult .ProcessSegmentInfo .BytesCommitted; else dedicatedBytesUsed += queryStatistics.QueryResult .ProcessSegmentInfo .BytesCommitted; } } } } } FreeLibrary(gdi32Handle); #define REPORT(_path, _amount, _desc) \ do { \ nsresult rv; \ rv = aCb->Callback(EmptyCString(), NS_LITERAL_CSTRING(_path), \ nsIMemoryReporter::KIND_OTHER, \ nsIMemoryReporter::UNITS_BYTES, _amount, \ NS_LITERAL_CSTRING(_desc), aClosure); \ NS_ENSURE_SUCCESS(rv, rv); \ } while (0) REPORT("gpu-committed", committedBytesUsed, "Memory committed by the Windows graphics system."); REPORT("gpu-dedicated", dedicatedBytesUsed, "Out-of-process memory allocated for this process in a " "physical GPU adapter's memory."); REPORT("gpu-shared", sharedBytesUsed, "In-process memory that is shared with the GPU."); #undef REPORT return NS_OK; }
bool DCGPAProfiler::GetAllComputeCounters(CounterList& counterList) { bool retVal = true; // Loading dxgi.dll has a side effect of initializing Real_CreateDXGIFactory1 LIB_HANDLE hDxgiDll = OSUtils::Instance()->GenericLoadLibrary("dxgi.dll"); if (NULL == hDxgiDll) { retVal = false; } else { if (NULL == Real_CreateDXGIFactory1) { retVal = false; } else { // Make sure this isn't called from DllMain (or a detoured LoadLibrary call) // See this note on MSDN https://msdn.microsoft.com/en-us/library/windows/desktop/bb205075%28v=vs.85%29.aspx#DXGI_Responses_From_DLLMain // DXGI Responses from DLLMain // Because a DllMain function can't guarantee the order in which it loads and unloads DLLs, we recommend that your app's DllMain function not call // Direct3D or DXGI functions or methods, including functions or methods that create or release objects.If your app's DllMain function calls into a // particular component, that component might call another DLL that isn't present on the operating system, which causes the operating system to crash. // Direct3D and DXGI might load a set of DLLs, typically a set of drivers, that differs from computer to computer. Therefore, even if your app doesn’t // crash on your development and test computers when its DllMain function calls Direct3D or DXGI functions or methods, it might crash when it runs on // another computer. // // To prevent you from creating an app that might cause the operating system to crash, DXGI provides the following responses in the specified situations : // If your app's DllMain function releases its last reference to a DXGI factory, DXGI raises an exception. // If your app's DllMain function creates a DXGI factory, DXGI returns an error code. IDXGIFactory* pDxgiFactory = NULL; HRESULT hr = Real_CreateDXGIFactory1(__uuidof(IDXGIFactory), reinterpret_cast<void**>(&pDxgiFactory)); if (S_OK != hr) { retVal = false; } else { typedef std::unordered_set<CounterList::value_type> CounterNames; CounterNames counterNames; CounterList adapterCounters; UINT adapterIndex = 0; while (retVal && (S_OK == hr)) { IDXGIAdapter* pDxgiAdapter = NULL; hr = pDxgiFactory->EnumAdapters(adapterIndex, &pDxgiAdapter); if (S_OK == hr) { DXGI_ADAPTER_DESC adapterDesc; hr = pDxgiAdapter->GetDesc(&adapterDesc); if (S_OK == hr) { GDT_HW_GENERATION hwGen; bool hwGenFound = AMDTDeviceInfoUtils::Instance()->GetHardwareGeneration(adapterDesc.DeviceId, hwGen); if (hwGenFound) { adapterCounters.clear(); m_GPAUtils.GetAvailableCountersGdt(hwGen, adapterCounters); m_GPAUtils.FilterNonComputeCountersGdt(hwGen, adapterCounters); for (CounterList::iterator aci = adapterCounters.begin() ; adapterCounters.end() != aci; ++aci) { if (counterNames.end() == counterNames.find(*aci)) { counterNames.insert(*aci); } } } } pDxgiAdapter->Release(); } ++adapterIndex; } // DXGI_ERROR_NOT_FOUND marks that EnumAdapters reached the last adapter in the system if (DXGI_ERROR_NOT_FOUND != hr) { retVal = false; } else { for (CounterNames::iterator cni = counterNames.begin() ; counterNames.end() != cni ; ++cni) { counterList.push_back(*cni); } } pDxgiFactory->Release(); } } } return retVal; }
void VideoBackend::InitBackendInfo() { HRESULT hr = DX11::D3D::LoadDXGI(); if (SUCCEEDED(hr)) hr = DX11::D3D::LoadD3D(); if (FAILED(hr)) { DX11::D3D::UnloadDXGI(); return; } g_Config.backend_info.api_type = APIType::D3D; g_Config.backend_info.MaxTextureSize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; g_Config.backend_info.bSupportsExclusiveFullscreen = true; g_Config.backend_info.bSupportsDualSourceBlend = true; g_Config.backend_info.bSupportsPrimitiveRestart = true; g_Config.backend_info.bSupportsOversizedViewports = false; g_Config.backend_info.bSupportsGeometryShaders = true; g_Config.backend_info.bSupportsComputeShaders = false; g_Config.backend_info.bSupports3DVision = true; g_Config.backend_info.bSupportsPostProcessing = false; g_Config.backend_info.bSupportsPaletteConversion = true; g_Config.backend_info.bSupportsClipControl = true; g_Config.backend_info.bSupportsDepthClamp = true; g_Config.backend_info.bSupportsReversedDepthRange = false; g_Config.backend_info.bSupportsMultithreading = false; g_Config.backend_info.bSupportsGPUTextureDecoding = false; g_Config.backend_info.bSupportsST3CTextures = false; g_Config.backend_info.bSupportsCopyToVram = true; g_Config.backend_info.bSupportsBitfield = false; g_Config.backend_info.bSupportsDynamicSamplerIndexing = false; g_Config.backend_info.bSupportsBPTCTextures = false; g_Config.backend_info.bSupportsFramebufferFetch = false; IDXGIFactory2* factory; IDXGIAdapter* ad; hr = DX11::PCreateDXGIFactory(__uuidof(IDXGIFactory2), (void**)&factory); if (FAILED(hr)) PanicAlert("Failed to create IDXGIFactory object"); // adapters g_Config.backend_info.Adapters.clear(); g_Config.backend_info.AAModes.clear(); while (factory->EnumAdapters((UINT)g_Config.backend_info.Adapters.size(), &ad) != DXGI_ERROR_NOT_FOUND) { const size_t adapter_index = g_Config.backend_info.Adapters.size(); DXGI_ADAPTER_DESC desc; ad->GetDesc(&desc); // TODO: These don't get updated on adapter change, yet if (adapter_index == g_Config.iAdapter) { std::vector<DXGI_SAMPLE_DESC> modes = DX11::D3D::EnumAAModes(ad); // First iteration will be 1. This equals no AA. for (unsigned int i = 0; i < modes.size(); ++i) { g_Config.backend_info.AAModes.push_back(modes[i].Count); } D3D_FEATURE_LEVEL feature_level = D3D::GetFeatureLevel(ad); bool shader_model_5_supported = feature_level >= D3D_FEATURE_LEVEL_11_0; g_Config.backend_info.MaxTextureSize = D3D::GetMaxTextureSize(feature_level); // Requires the earlydepthstencil attribute (only available in shader model 5) g_Config.backend_info.bSupportsEarlyZ = shader_model_5_supported; // Requires full UAV functionality (only available in shader model 5) g_Config.backend_info.bSupportsBBox = g_Config.backend_info.bSupportsFragmentStoresAndAtomics = shader_model_5_supported; // Requires the instance attribute (only available in shader model 5) g_Config.backend_info.bSupportsGSInstancing = shader_model_5_supported; // Sample shading requires shader model 5 g_Config.backend_info.bSupportsSSAA = shader_model_5_supported; } g_Config.backend_info.Adapters.push_back(UTF16ToUTF8(desc.Description)); ad->Release(); } factory->Release(); DX11::D3D::UnloadDXGI(); DX11::D3D::UnloadD3D(); }
bool cInitDirect3D::Init() { UINT createDeviceFlags = 0; #if defined(DEBUG) || defined(_DEBUG) createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL featureLevel; HRESULT hr = D3D11CreateDevice( 0, // default adapter 사용할 IDXGIAdapter 인터페이스 md3dDriverType, //DirectX11 디바이스타입. 0, // no software device 보통 null createDeviceFlags, //디바이스 플래그 0, 0, // 피처레벨을 사용할 배열, 피처레벨 수 D3D11_SDK_VERSION, //SDK버전 &m_pD3dDevice, //넘겨받을 디바이스 인터페이스 &featureLevel, //피처레벨을 얻어낼 포인터 &m_pDeviceContext); //넘겨받을 디바이스 컨텍스트 인터페이스 if (FAILED(hr)) { MessageBox(0, L"D3D11CreateDevice Failed.", 0, 0); return false; } if (featureLevel != D3D_FEATURE_LEVEL_11_0) { MessageBox(0, L"Direct3D Feature Level 11 unsupported.", 0, 0); return false; } // Check 4X MSAA quality support for our back buffer format. // All Direct3D 11 capable devices support 4X MSAA for all render // target formats, so we only need to check quality support. HR(m_pD3dDevice->CheckMultisampleQualityLevels( DXGI_FORMAT_R8G8B8A8_UNORM, 4, &m4xMsaaQuality)); assert(m4xMsaaQuality > 0); // DXGI_SWAP_CHAIN_DESC구조체를 채운다. DXGI_SWAP_CHAIN_DESC sd; ZeroMemory(&sd, sizeof(sd));//구조체 초기화 sd.BufferCount = 1;//백버퍼 개수 sd.BufferDesc.Width = ClientWidth;//백버퍼 가로 sd.BufferDesc.Height = ClientHeight;//백버퍼 세로 sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;//백버퍼 포맷 : RGBA8비트이며 값의 범위0.0~1.0 sd.BufferDesc.RefreshRate.Numerator = 60;//화면 갱신율. 분자. sd.BufferDesc.RefreshRate.Denominator = 1;//화면 갱신율. 분모.(60/1) sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;//백버퍼의 용도 sd.OutputWindow = g_hWnd;//버퍼를 출력할 윈도우 sd.SampleDesc.Count = 1;//멀티 샘플링 수 sd.SampleDesc.Quality = 0;//멀티 샘플링 퀄리티 sd.Windowed = true;//윈도우모드 sd.Flags = 0; // Use 4X MSAA? if (mEnable4xMsaa) { sd.SampleDesc.Count = 4; sd.SampleDesc.Quality = m4xMsaaQuality - 1; } // No MSAA else { sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; } // To correctly create the swap chain, we must use the IDXGIFactory that was // used to create the device. If we tried to use a different IDXGIFactory instance // (by calling CreateDXGIFactory), we get an error: "IDXGIFactory::CreateSwapChain: // This function is being called with a device from a different IDXGIFactory." IDXGIDevice* dxgiDevice = 0; HR(m_pD3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice)); IDXGIAdapter* dxgiAdapter = 0; HR(dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&dxgiAdapter)); IDXGIFactory* dxgiFactory = 0; HR(dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgiFactory)); HR(dxgiFactory->CreateSwapChain(m_pD3dDevice, &sd, &m_pSwapChain)); ReleaseCOM(dxgiDevice); ReleaseCOM(dxgiAdapter); ReleaseCOM(dxgiFactory); // The remaining steps that need to be carried out for d3d creation // also need to be executed every time the window is resized. So // just call the OnResize method here to avoid code duplication. Onresize(); return true; }
// Direct3Dの初期化 HRESULT InitD3D( void ) { HRESULT hr = S_OK; D3D_FEATURE_LEVEL FeatureLevelsRequested[6] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1 }; UINT numLevelsRequested = 6; D3D_FEATURE_LEVEL FeatureLevelsSupported; // デバイス作成 hr = D3D11CreateDevice( NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, FeatureLevelsRequested, numLevelsRequested, D3D11_SDK_VERSION, &g_pd3dDevice, &FeatureLevelsSupported, &g_pImmediateContext ); if( FAILED ( hr ) ) { return hr; } // ファクトリの取得 IDXGIDevice * pDXGIDevice; hr = g_pd3dDevice->QueryInterface( __uuidof( IDXGIDevice ), ( void ** )&pDXGIDevice ); IDXGIAdapter * pDXGIAdapter; hr = pDXGIDevice->GetParent( __uuidof( IDXGIAdapter ), ( void ** )&pDXGIAdapter ); IDXGIFactory * pIDXGIFactory; pDXGIAdapter->GetParent( __uuidof( IDXGIFactory ), ( void ** )&pIDXGIFactory); // スワップチェインの作成 DXGI_SWAP_CHAIN_DESC sd; ZeroMemory( &sd, sizeof( sd ) ); sd.BufferCount = 1; sd.BufferDesc.Width = g_nClientWidth; sd.BufferDesc.Height = g_nClientHeight; sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.BufferDesc.RefreshRate.Numerator = 60; sd.BufferDesc.RefreshRate.Denominator = 1; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.OutputWindow = g_hWnd; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.Windowed = TRUE; hr = pIDXGIFactory->CreateSwapChain( g_pd3dDevice, &sd, &g_pSwapChain ); pDXGIDevice->Release(); pDXGIAdapter->Release(); pIDXGIFactory->Release(); if( FAILED ( hr ) ) { return hr; } // レンダリングターゲットの生成 ID3D11Texture2D *pBackBuffer = NULL; D3D11_TEXTURE2D_DESC BackBufferSurfaceDesc; hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), ( LPVOID* )&pBackBuffer ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "Can't get backbuffer." ), _T( "Error" ), MB_OK ); return hr; } pBackBuffer->GetDesc( &BackBufferSurfaceDesc ); hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &g_pRTV ); SAFE_RELEASE( pBackBuffer ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "Can't create render target view." ), _T( "Error" ), MB_OK ); return hr; } // *** Create depth stencil texture *** D3D11_TEXTURE2D_DESC descDepth; RECT rc; GetClientRect( g_hWnd, &rc ); ZeroMemory( &descDepth, sizeof(descDepth) ); descDepth.Width = rc.right - rc.left; descDepth.Height = rc.bottom - rc.top; descDepth.MipLevels = 1; descDepth.ArraySize = 1; descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; descDepth.SampleDesc.Count = 1; descDepth.SampleDesc.Quality = 0; descDepth.Usage = D3D11_USAGE_DEFAULT; descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL; descDepth.CPUAccessFlags = 0; descDepth.MiscFlags = 0; hr = g_pd3dDevice->CreateTexture2D( &descDepth, NULL, &g_pDepthStencil ); if( FAILED( hr ) ) return hr; // *** Create the depth stencil view *** D3D11_DEPTH_STENCIL_VIEW_DESC descDSV; ZeroMemory( &descDSV, sizeof(descDSV) ); descDSV.Format = descDepth.Format; descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; descDSV.Texture2D.MipSlice = 0; hr = g_pd3dDevice->CreateDepthStencilView( g_pDepthStencil, &descDSV, &g_pDepthStencilView ); if( FAILED( hr ) ) return hr; // *** レンダリングターゲット設定 *** g_pImmediateContext->OMSetRenderTargets( 1, &g_pRTV, g_pDepthStencilView ); // ステンシルステートの作成 D3D11_DEPTH_STENCIL_DESC dsDesc; // Depth test parameters dsDesc.DepthEnable = true; dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; dsDesc.DepthFunc = D3D11_COMPARISON_LESS; // Stencil test parameters dsDesc.StencilEnable = true; dsDesc.StencilReadMask = 0xFF; dsDesc.StencilWriteMask = 0xFF; // Stencil operations if pixel is front-facing dsDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; dsDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; dsDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // Stencil operations if pixel is back-facing dsDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; dsDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; dsDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; dsDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // Create depth stencil state hr = g_pd3dDevice->CreateDepthStencilState( &dsDesc, &g_pDSDepthState ); dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; hr = g_pd3dDevice->CreateDepthStencilState( &dsDesc, &g_pDSDepthState_NoWrite ); // g_pImmediateContext->OMSetDepthStencilState( g_pDSDepthState, 1 ); // ラスタライザの設定 D3D11_RASTERIZER_DESC drd; ZeroMemory( &drd, sizeof( drd ) ); drd.FillMode = D3D11_FILL_SOLID; drd.CullMode = D3D11_CULL_NONE; drd.FrontCounterClockwise = FALSE; drd.DepthClipEnable = TRUE; hr = g_pd3dDevice->CreateRasterizerState( &drd, &g_pRS ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "Can't create rasterizer state." ), _T( "Error" ), MB_OK ); return hr; } g_pImmediateContext->RSSetState( g_pRS ); // ラスタライザの設定(時計回りカリング) ZeroMemory( &drd, sizeof( drd ) ); drd.FillMode = D3D11_FILL_SOLID; drd.CullMode = D3D11_CULL_BACK; drd.FrontCounterClockwise = TRUE; drd.DepthClipEnable = TRUE; hr = g_pd3dDevice->CreateRasterizerState( &drd, &g_pRS_Cull_CW ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "Can't create rasterizer state." ), _T( "Error" ), MB_OK ); return hr; } // g_pImmediateContext->RSSetState( g_pRS_Cull_CW ); // ラスタライザの設定(反時計回りカリング) ZeroMemory( &drd, sizeof( drd ) ); drd.FillMode = D3D11_FILL_SOLID; drd.CullMode = D3D11_CULL_BACK; drd.FrontCounterClockwise = FALSE; drd.DepthClipEnable = TRUE; hr = g_pd3dDevice->CreateRasterizerState( &drd, &g_pRS_Cull_CCW ); if ( FAILED( hr ) ) { MessageBox( NULL, _T( "Can't create rasterizer state." ), _T( "Error" ), MB_OK ); return hr; } // g_pImmediateContext->RSSetState( g_pRS_Cull_CCW ); // ビューポートの設定 D3D11_VIEWPORT vp; vp.Width = ( FLOAT )g_nClientWidth; vp.Height = ( FLOAT )g_nClientHeight; vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; vp.TopLeftX = 0.0f; vp.TopLeftY = 0.0f; g_pImmediateContext->RSSetViewports( 1, &vp ); return S_OK; }
bool D3DManager::Initialize(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullScreen) { HRESULT result; IDXGIFactory * factory = nullptr; IDXGIAdapter * adapter = nullptr; IDXGIOutput * adapterOutput = nullptr; unsigned int numModes; unsigned int numerator = 0; unsigned int denominator = 0; unsigned int stringLenht; DXGI_MODE_DESC * displayModeList = nullptr; DXGI_ADAPTER_DESC adapterDesc; int error; ID3D11Texture2D * backBuffer = nullptr; // Guardo el vsycn m_vsync_enable = vsync; // Creo una interfas con DirectX (IDXGIFactory) result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if (FAILED(result)) { // TODO: Informar del Error return false; } // Uso el IDXGIFactory para crear un adapatador(Placa de Video) result = factory->EnumAdapters(0, &adapter); if (FAILED(result)) { // TODO: Informar del Error return false; } // Enumero la cantidad de monitores (Adaptador de salida) result = adapter->EnumOutputs(0, &adapterOutput); if (FAILED(result)) { // TODO: Informar del Error return false; } // Obtengo el numero de modos que se ajustan al formato DXGI_FORMAT_R8G8B8A8 para el monitor result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL); if (FAILED(result)) { // TODO: Informar del Error return false; } // Creo una lista con todos los posbles modos para esta combinacion placa de video monitor. displayModeList = new DXGI_MODE_DESC[numModes]; // Cargo la lista de display Mode result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); if (FAILED(result)) { // TODO: Informar del Error return false; } for (int i = 0; i < (int)numModes; ++i) { if (displayModeList[i].Width == (unsigned int)screenWidth && displayModeList[i].Height == (unsigned int)screenHeight) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; //TODO: Loquidar el for al encontrar el valor correcto } } if (numerator == 0 && denominator == 0) { // Informar Error return false; } // Obtengo la descripcion del adaptador result = adapter->GetDesc(&adapterDesc); if (FAILED(result)) { // TODO: Informar del Error return false; } // Guardo la cantidad de memorya de video m_videoCardMemory = adapterDesc.DedicatedVideoMemory; // Convierto el nombre de la VGA a string char tmp_string[128]; error = wcstombs_s(&stringLenht, tmp_string, 128, adapterDesc.Description, 128); if (error != 0) { // TODO: Informar del Error return false; } m_videoCardDescription = tmp_string; // Released Memory delete [] displayModeList; displayModeList = nullptr; adapterOutput->Release(); adapterOutput = nullptr; adapter->Release(); adapter = nullptr; factory->Release(); factory = nullptr; if (!InitializeSwapChain(hwnd, fullScreen, screenWidth, screenHeight, numerator, denominator)) { // Todo: Informar El Error return false; } // Obtengo el puntero al BackBuffer result = mp_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBuffer); if (FAILED(result)) { // TODO: Informar del Error return false; } // Creo el render Target View result = mp_device->CreateRenderTargetView(backBuffer, NULL, &mp_renderTargetView); if (FAILED(result)) { // TODO: Informar del Error return false; } // No te Nesesito MUERE backBuffer->Release(); backBuffer = nullptr; if (!InitializeDepthBuffer(screenWidth, screenHeight)) { // TODO: Informar del Error return false; } if (!InitializeDepthStencilBuffer()) { // TODO: Informar del Error return false; } if (!InitializeStencilView()) { // TODO: Informar del Error return false; } mp_deviceContext->OMSetRenderTargets(1, &mp_renderTargetView, mp_depthStencilView); if (!InitializeRasterizerStete()) { // TODO: Informar del Error return false; } InitializeViewport(screenWidth, screenHeight); if (!InitializeAlphaBlending()) { // TODO: Informar del Error return false; } if (!InitializeZBuffer()) { // TODO: Informar del Error return false; } return true; }
HRESULT DXManager::getVideoCardInfo() { HRESULT result; IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* adapterOutput; DXGI_MODE_DESC* displayModeList; DXGI_ADAPTER_DESC adapterDesc; unsigned int numModes, i, stringLength; int error; result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if (FAILED(result)) { return false; } result = factory->EnumAdapters(0, &adapter); if (FAILED(result)) { return false; } result = adapter->EnumOutputs(0, &adapterOutput); if (FAILED(result)) { return false; } result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL); if (FAILED(result)) { return false; } displayModeList = new DXGI_MODE_DESC[numModes]; if (!displayModeList) { return false; } result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); if (FAILED(result)) { return false; } for (i = 0; i<numModes; i++) { if (displayModeList[i].Width == (unsigned int)m_ScreenWidth) { if (displayModeList[i].Height == (unsigned int)m_ScreenHeight) { mNumerator = displayModeList[i].RefreshRate.Numerator; mDenominator = displayModeList[i].RefreshRate.Denominator; } } } result = adapter->GetDesc(&adapterDesc); if (FAILED(result)) { return false; } m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); //MB Video Ram error = wcstombs_s(&stringLength, m_videoCardDescription, 128, adapterDesc.Description, 128); if (error != 0) { return false; } delete[] displayModeList; displayModeList = 0; adapterOutput->Release(); adapterOutput = 0; adapter->Release(); adapter = 0; factory->Release(); factory = 0; return S_OK; }
D3D11Interface::D3D11Interface(HWND hwnd, bool fullscreen, unsigned int width, unsigned int height, bool vsyncEnabled) { IDXGIFactory* factory = 0; IDXGIAdapter* adapter = 0; IDXGIOutput* adapterOutput = 0; DXGI_MODE_DESC* displayModeList = 0; DXGI_ADAPTER_DESC adapterDesc; DXGI_SWAP_CHAIN_DESC swapChainDesc; D3D_FEATURE_LEVEL featureLevel; D3D11_TEXTURE2D_DESC depthBufferDesc; D3D11_DEPTH_STENCIL_DESC depthStencilDesc; D3D11_DEPTH_STENCIL_VIEW_DESC dsViewDesc; unsigned int numModes; unsigned int numerator = 0, denominator = 1; //get the monitor refresh rate to prevent performance issues //create a DX graphics interface factory HRESULT m_lastError = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if(FAILED(m_lastError)) { throw Kiwi::Exception(L"D3D11Interface::Initialize", L"Failed to create graphics interface factory"); return; } //now use it to create an adapter for the primary video card m_lastError = factory->EnumAdapters(0, &adapter); if(FAILED(m_lastError)) { throw Kiwi::Exception(L"D3D11Interface::Initialize", L"Failed to create graphics adapter"); return; } //enumerate the primary monitor m_lastError = adapter->EnumOutputs(0, &adapterOutput); if(FAILED(m_lastError)) { throw Kiwi::Exception(L"D3D11Interface::Initialize", L"Failed to enumerate primary monitor"); return; } //get the number of modes that fit the DXGI_FORMAT_R8G8B8A8_UNORM format m_lastError = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL); if(FAILED(m_lastError)) { throw Kiwi::Exception(L"D3D11Interface::Initialize", L"Failed to get display mode list"); return; } //create a list of all the display modes for the monitor/video card displayModeList = new DXGI_MODE_DESC[numModes]; //fill the display mode lists m_lastError = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); if(FAILED(m_lastError)) { throw Kiwi::Exception(L"D3D11Interface::Initialize", L"Failed to fill display mode list"); return; } //find the correct display mode for(unsigned int i = 0; i < numModes; i++) { if(displayModeList[i].Width == width && displayModeList[i].Height == height) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } //lastly, get the name of the video card and the amount of RAM m_lastError = adapter->GetDesc(&adapterDesc); if(FAILED(m_lastError)) { throw Kiwi::Exception(L"D3D11Interface::Initialize", L"Failed to get adapter info"); return; } //store video card RAM in megabytes m_videoCardInfo.totalRAM = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); //get the name of the video card m_videoCardInfo.name = adapterDesc.Description; delete [] displayModeList; displayModeList = 0; SAFE_RELEASE(adapterOutput); SAFE_RELEASE(adapter); SAFE_RELEASE(factory); //now initialize the swapchain/desc ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); swapChainDesc.BufferCount = 1; //single back buffer swapChainDesc.BufferDesc.Width = width; swapChainDesc.BufferDesc.Height = height; swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; //32-bit surface if(vsyncEnabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator; }else { swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; } //using the back buffer as a render target swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.OutputWindow = hwnd; //turn off multisampling swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; swapChainDesc.Windowed = !fullscreen; swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; //discard back buffer contents after presenting swapChainDesc.Flags = 0; //using DX 11 featureLevel = D3D_FEATURE_LEVEL_11_0; //create the swapchain, direct3d device, and d3d context m_lastError = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_DEBUG, &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext); if(FAILED(m_lastError)) { std::wstring error = Kiwi::GetD3DErrorString(m_lastError); throw Kiwi::Exception(L"D3D11Interface::Initialize", L"Failed to create device/swap chain ("+error+L")"); return; } //get the back buffer and attach it to the swap chain m_lastError = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&m_backBuffer); if(FAILED(m_lastError)) { throw Kiwi::Exception(L"D3D11Interface::Initialize", L"Failed to attach back buffer"); } //create render target view m_lastError = m_device->CreateRenderTargetView(m_backBuffer, NULL, &m_backBufferRenderTargetView); if(FAILED(m_lastError)) { throw Kiwi::Exception(L"D3D11Interface::Initialize", L"Failed to create back buffer render target view");; } //create depth/stencil buffer to allow proper rendering in 3d space and allow for effects ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); depthBufferDesc.Width = width; depthBufferDesc.Height = height; depthBufferDesc.MipLevels = 1; depthBufferDesc.ArraySize = 1; depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthBufferDesc.SampleDesc.Count = 1; depthBufferDesc.SampleDesc.Quality = 0; depthBufferDesc.Usage = D3D11_USAGE_DEFAULT; depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthBufferDesc.CPUAccessFlags = 0; depthBufferDesc.MiscFlags = 0; m_lastError = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_backBufferDepthBuffer); if(FAILED(m_lastError)) { throw Kiwi::Exception(L"D3D11Interface::Initialize", L"Failed to create back buffer depth stencil buffer");; } //now setup depth stencil to allow control of what type of depth test is done for each pixel ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc)); depthStencilDesc.DepthEnable = true; depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; depthStencilDesc.StencilEnable = true; depthStencilDesc.StencilReadMask = 0xFF; depthStencilDesc.StencilWriteMask = 0xFF; //for front-facing pixels depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; //for back facing pixels depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; m_lastError = m_device->CreateDepthStencilState(&depthStencilDesc, &m_backBufferDepthState); if(FAILED(m_lastError)) { throw Kiwi::Exception(L"D3D11Interface::Initialize", L"Failed to create back buffer depth stencil state");; } //set the depth stencil state m_deviceContext->OMSetDepthStencilState(m_backBufferDepthState, 1); //setup the depth stencil buffer so DX will use the buffer as a depth stencil texture ZeroMemory(&dsViewDesc, sizeof(dsViewDesc)); dsViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; dsViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; dsViewDesc.Texture2D.MipSlice = 0; m_lastError = m_device->CreateDepthStencilView(m_backBufferDepthBuffer, &dsViewDesc, &m_backBufferDepthView); if(FAILED(m_lastError)) { throw Kiwi::Exception(L"D3D11Interface::Initialize", L"Failed to create back buffer depth stencil view");; } //now bind the render target view and depth stencil buffer to the render pipeline m_deviceContext->OMSetRenderTargets(1, &m_backBufferRenderTargetView, m_backBufferDepthView); //by default, set the primitive type to triangle list m_deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); m_fullscreen = fullscreen; m_vSyncEnabled = vsyncEnabled; }
bool D3DApp::InitDirect3D() { UINT createDeviceFlags = 0; #if defined(DEBUG) || defined(_DEBUG) createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL featureLevel; HRESULT hr = D3D11CreateDevice( 0, md3dDriverType, 0, createDeviceFlags, 0, 0, D3D11_SDK_VERSION, &md3dDevice, &featureLevel, &md3dImmediateContext); if (FAILED(hr)) { LogPrint(L"D3D11CreateDevice Failed."); return FALSE; } if (featureLevel != D3D_FEATURE_LEVEL_11_0) { LogPrint(L"Direct3D Feature Level 11 unsupported!"); return FALSE; } HR(md3dDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_B8G8R8A8_UNORM, 4, &m4xMsaaQuality)); assert(m4xMsaaQuality > 0); DXGI_SWAP_CHAIN_DESC sd; sd.BufferDesc.Width = mClientWidth; sd.BufferDesc.Height = mClientHeight; sd.BufferDesc.RefreshRate.Numerator = 60; sd.BufferDesc.RefreshRate.Denominator = 1; sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; if (mEnable4xMsaa) { sd.SampleDesc.Count = 4; sd.SampleDesc.Quality = m4xMsaaQuality - 1; } else { sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; } sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.BufferCount = 1; sd.OutputWindow = mhMainWnd; sd.Windowed = TRUE; sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; sd.Flags = 0; IDXGIDevice*dxgiDevice = 0; HR(md3dDevice->QueryInterface(COMID_P(dxgiDevice))); IDXGIAdapter* dxgiAdapter = 0; HR(dxgiDevice->GetParent(COMID_P(dxgiAdapter))); IDXGIFactory* dxgiFactory = 0; HR(dxgiAdapter->GetParent(COMID_P(dxgiFactory))); HR(dxgiFactory->CreateSwapChain(md3dDevice, &sd, &mSwapChain)); ReleaseCom(dxgiDevice); ReleaseCom(dxgiAdapter); ReleaseCom(dxgiFactory); OnResize(); return true; }
bool D3D10App::initAPI(const DXGI_FORMAT backBufferFmt, const DXGI_FORMAT depthBufferFmt, const int samples, const uint flags){ backBufferFormat = backBufferFmt; depthBufferFormat = depthBufferFmt; msaaSamples = samples; // if (screen >= GetSystemMetrics(SM_CMONITORS)) screen = 0; IDXGIFactory *dxgiFactory; if (FAILED(CreateDXGIFactory(__uuidof(IDXGIFactory), (void **) &dxgiFactory))){ ErrorMsg("Couldn't create DXGIFactory"); return false; } IDXGIAdapter *dxgiAdapter; if (dxgiFactory->EnumAdapters(0, &dxgiAdapter) == DXGI_ERROR_NOT_FOUND){ ErrorMsg("No adapters found"); return false; } // DXGI_ADAPTER_DESC adapterDesc; // dxgiAdapter->GetDesc(&adapterDesc); IDXGIOutput *dxgiOutput; if (dxgiAdapter->EnumOutputs(0, &dxgiOutput) == DXGI_ERROR_NOT_FOUND){ ErrorMsg("No outputs found"); return false; } DXGI_OUTPUT_DESC oDesc; dxgiOutput->GetDesc(&oDesc); // Find a suitable fullscreen format int targetHz = 85; DXGI_RATIONAL fullScreenRefresh; int fsRefresh = 60; fullScreenRefresh.Numerator = fsRefresh; fullScreenRefresh.Denominator = 1; char str[128]; uint nModes = 0; dxgiOutput->GetDisplayModeList(backBufferFormat, 0, &nModes, NULL); DXGI_MODE_DESC *modes = new DXGI_MODE_DESC[nModes]; dxgiOutput->GetDisplayModeList(backBufferFormat, 0, &nModes, modes); resolution->clear(); for (uint i = 0; i < nModes; i++){ if (modes[i].Width >= 640 && modes[i].Height >= 480){ sprintf(str, "%dx%d", modes[i].Width, modes[i].Height); int index = resolution->addItemUnique(str); if (int(modes[i].Width) == fullscreenWidth && int(modes[i].Height) == fullscreenHeight){ int refresh = modes[i].RefreshRate.Numerator / modes[i].RefreshRate.Denominator; if (abs(refresh - targetHz) < abs(fsRefresh - targetHz)){ fsRefresh = refresh; fullScreenRefresh = modes[i].RefreshRate; } resolution->selectItem(index); } } } delete modes; sprintf(str, "%s (%dx%d)", getTitle(), width, height); DWORD wndFlags = 0; int x, y, w, h; if (fullscreen){ wndFlags |= WS_POPUP; x = y = 0; w = width; h = height; } else { wndFlags |= WS_OVERLAPPEDWINDOW; RECT wRect; wRect.left = 0; wRect.right = width; wRect.top = 0; wRect.bottom = height; AdjustWindowRect(&wRect, wndFlags, FALSE); MONITORINFO monInfo; monInfo.cbSize = sizeof(monInfo); GetMonitorInfo(oDesc.Monitor, &monInfo); w = min(wRect.right - wRect.left, monInfo.rcWork.right - monInfo.rcWork.left); h = min(wRect.bottom - wRect.top, monInfo.rcWork.bottom - monInfo.rcWork.top); x = (monInfo.rcWork.left + monInfo.rcWork.right - w) / 2; y = (monInfo.rcWork.top + monInfo.rcWork.bottom - h) / 2; } hwnd = CreateWindow("Humus", str, wndFlags, x, y, w, h, HWND_DESKTOP, NULL, hInstance, NULL); RECT rect; GetClientRect(hwnd, &rect); // Create device and swap chain DXGI_SWAP_CHAIN_DESC sd; memset(&sd, 0, sizeof(sd)); sd.BufferDesc.Width = rect.right; sd.BufferDesc.Height = rect.bottom; sd.BufferDesc.Format = backBufferFormat; sd.BufferDesc.RefreshRate = fullScreenRefresh; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.BufferCount = 1; sd.OutputWindow = hwnd; sd.Windowed = (BOOL) (!fullscreen); sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; DWORD deviceFlags = D3D10_CREATE_DEVICE_SINGLETHREADED; #ifdef _DEBUG deviceFlags |= D3D10_CREATE_DEVICE_DEBUG; #endif if (FAILED(D3D10CreateDevice(dxgiAdapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, deviceFlags, D3D10_SDK_VERSION, &device))){ ErrorMsg("Couldn't create D3D10 device"); return false; } while (msaaSamples > 0){ UINT nQuality; if (SUCCEEDED(device->CheckMultisampleQualityLevels(backBufferFormat, msaaSamples, &nQuality)) && nQuality > 0){ if ((flags & NO_SETTING_CHANGE) == 0) antiAliasSamples = msaaSamples; break; } else { msaaSamples -= 2; } } sd.SampleDesc.Count = msaaSamples; sd.SampleDesc.Quality = 0; if (FAILED(dxgiFactory->CreateSwapChain(device, &sd, &swapChain))){ ErrorMsg("Couldn't create swapchain"); return false; } // We'll handle Alt-Enter ourselves thank you very much ... dxgiFactory->MakeWindowAssociation(hwnd, DXGI_MWA_NO_WINDOW_CHANGES | DXGI_MWA_NO_ALT_ENTER); dxgiOutput->Release(); dxgiAdapter->Release(); dxgiFactory->Release(); if (!createBuffers()) return false; if (fullscreen){ captureMouse(!configDialog->isVisible()); } renderer = new Direct3D10Renderer(device); ((Direct3D10Renderer *) renderer)->setFrameBuffer(backBufferRTV, depthBufferDSV); antiAlias->selectItem(antiAliasSamples / 2); linearClamp = renderer->addSamplerState(LINEAR, CLAMP, CLAMP, CLAMP); defaultFont = renderer->addFont("../Textures/Fonts/Future.dds", "../Textures/Fonts/Future.font", linearClamp); blendSrcAlpha = renderer->addBlendState(SRC_ALPHA, ONE_MINUS_SRC_ALPHA); noDepthTest = renderer->addDepthState(false, false); noDepthWrite = renderer->addDepthState(true, false); cullNone = renderer->addRasterizerState(CULL_NONE); cullBack = renderer->addRasterizerState(CULL_BACK); cullFront = renderer->addRasterizerState(CULL_FRONT); return true; }
bool D3DClass::Initialise(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen, float screenDepth, float screenNear) { HRESULT result; IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* adapterOutput; unsigned int numModes, i, numerator, denominator, stringLength; DXGI_MODE_DESC* displayModeList; DXGI_ADAPTER_DESC adapterDesc; int error; DXGI_SWAP_CHAIN_DESC swapChainDesc; D3D_FEATURE_LEVEL featureLevel; ID3D11Texture2D* backBufferPtr; D3D11_TEXTURE2D_DESC depthBufferDesc; D3D11_DEPTH_STENCIL_DESC depthStencilDesc; D3D11_DEPTH_STENCIL_DESC depthDisabledStencilDesc; D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; D3D11_BLEND_DESC blendStateDescription; D3D11_RASTERIZER_DESC rasterDesc; float fieldOfView, screenAspect; // Store the vsync setting. m_vsync_enabled = vsync; // Create a DirectX graphics interface factory. result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if(FAILED(result)) { return false; } // Use the factory to create an adapter for the primary graphics interface (video card). result = factory->EnumAdapters(0, &adapter); if(FAILED(result)) { return false; } // Enumerate the primary adapter output (monitor). result = adapter->EnumOutputs(0, &adapterOutput); if(FAILED(result)) { return false; } // Get the number of modes that fit the DXGI_FORMAT_R8G8B8A8_UNORM display format for the adapter output (monitor). result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL); if(FAILED(result)) { return false; } // Create a list to hold all the possible display modes for this monitor/video card combination. displayModeList = new DXGI_MODE_DESC[numModes]; if(!displayModeList) { return false; } // Now fill the display mode list structures. result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); if(FAILED(result)) { return false; } // Now go through all the display modes and find the one that matches the screen width and height. // When a match is found store the numerator and denominator of the refresh rate for that monitor. for(i=0; i<numModes; i++) { if(displayModeList[i].Width == (unsigned int)screenWidth) { if(displayModeList[i].Height == (unsigned int)screenHeight) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } } // Get the adapter (video card) description. result = adapter->GetDesc(&adapterDesc); if(FAILED(result)) { return false; } // Store the dedicated video card memory in megabytes. m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); // Convert the name of the video card to a character array and store it. error = wcstombs_s(&stringLength, m_videoCardDescription, 128, adapterDesc.Description, 128); if(error != 0) { return false; } // Release the display mode list. delete [] displayModeList; displayModeList = 0; // Release the adapter output. adapterOutput->Release(); adapterOutput = 0; // Release the adapter. adapter->Release(); adapter = 0; // Release the factory. factory->Release(); factory = 0; // Initialise the swap chain description. ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); // Set to a single back buffer. swapChainDesc.BufferCount = 1; // Set the width and height of the back buffer. swapChainDesc.BufferDesc.Width = screenWidth; swapChainDesc.BufferDesc.Height = screenHeight; // Set regular 32-bit surface for the back buffer. swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // Set the refresh rate of the back buffer. if(m_vsync_enabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator; } else { swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; } // Set the usage of the back buffer. swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // Set the handle for the window to render to. swapChainDesc.OutputWindow = hwnd; // Turn multisampling off. swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; // Set to full screen or windowed mode. if(fullscreen) { swapChainDesc.Windowed = false; } else { swapChainDesc.Windowed = true; } // Set the scan line ordering and scaling to unspecified. swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; // Discard the back buffer contents after presenting. swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; // Don't set the advanced flags. swapChainDesc.Flags = 0; // Set the feature level to DirectX 11. featureLevel = D3D_FEATURE_LEVEL_11_0; // Create the swap chain, Direct3D device, and Direct3D device context. result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext); if(FAILED(result)) { return false; } // Get the pointer to the back buffer. result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr); if(FAILED(result)) { return false; } // Create the render target view with the back buffer pointer. result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView); if(FAILED(result)) { return false; } // Release pointer to the back buffer as we no longer need it. backBufferPtr->Release(); backBufferPtr = 0; // Initialise the description of the depth buffer. ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); // Set up the description of the depth buffer. depthBufferDesc.Width = screenWidth; depthBufferDesc.Height = screenHeight; depthBufferDesc.MipLevels = 1; depthBufferDesc.ArraySize = 1; depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthBufferDesc.SampleDesc.Count = 1; depthBufferDesc.SampleDesc.Quality = 0; depthBufferDesc.Usage = D3D11_USAGE_DEFAULT; depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthBufferDesc.CPUAccessFlags = 0; depthBufferDesc.MiscFlags = 0; // Create the texture for the depth buffer using the filled out description. result = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer); if(FAILED(result)) { return false; } // Initialise the description of the stencil state. ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc)); // Set up the description of the stencil state. depthStencilDesc.DepthEnable = true; depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; depthStencilDesc.StencilEnable = true; depthStencilDesc.StencilReadMask = 0xFF; depthStencilDesc.StencilWriteMask = 0xFF; // Stencil operations if pixel is front-facing. depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // Stencil operations if pixel is back-facing. depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // Create the depth stencil state. result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); if(FAILED(result)) { return false; } // Set the depth stencil state. m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1); // Initialise the depth stencil view. ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc)); // Set up the depth stencil view description. depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; // Create the depth stencil view. result = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView); if(FAILED(result)) { return false; } // Bind the render target view and depth stencil buffer to the output render pipeline. m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView); // Setup the raster description which will determine how and what polygons will be drawn. rasterDesc.AntialiasedLineEnable = false; rasterDesc.CullMode = D3D11_CULL_BACK; rasterDesc.DepthBias = 0; rasterDesc.DepthBiasClamp = 0.0f; rasterDesc.DepthClipEnable = true; rasterDesc.FillMode = D3D11_FILL_SOLID; rasterDesc.FrontCounterClockwise = false; rasterDesc.MultisampleEnable = false; rasterDesc.ScissorEnable = false; rasterDesc.SlopeScaledDepthBias = 0.0f; // Create the rasterizer state from the description we just filled out. result = m_device->CreateRasterizerState(&rasterDesc, &m_rasterState); if(FAILED(result)) { return false; } // Now set the rasterizer state. m_deviceContext->RSSetState(m_rasterState); // Setup the viewport for rendering. m_viewport.Width = (float)screenWidth; m_viewport.Height = (float)screenHeight; m_viewport.MinDepth = 0.0f; m_viewport.MaxDepth = 1.0f; m_viewport.TopLeftX = 0.0f; m_viewport.TopLeftY = 0.0f; // Create the viewport. m_deviceContext->RSSetViewports(1, &m_viewport); // Setup the projection matrix. fieldOfView = (float)D3DX_PI / 4.0f; screenAspect = (float)screenWidth / (float)screenHeight; // Create the projection matrix for 3D rendering. D3DXMatrixPerspectiveFovLH(&m_projectionMatrix, fieldOfView, screenAspect, screenNear, screenDepth); // Initialise the world matrix to the identity matrix. D3DXMatrixIdentity(&m_worldMatrix); // Create an orthographic projection matrix for 2D rendering. D3DXMatrixOrthoLH(&m_orthoMatrix, (float)screenWidth, (float)screenHeight, screenNear, screenDepth); // Clear the second depth stencil state before setting the parameters. ZeroMemory(&depthDisabledStencilDesc, sizeof(depthDisabledStencilDesc)); // Now create a second depth stencil state which turns off the Z buffer for 2D rendering. The only difference is // that DepthEnable is set to false, all other parameters are the same as the other depth stencil state. depthDisabledStencilDesc.DepthEnable = false; depthDisabledStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthDisabledStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; depthDisabledStencilDesc.StencilEnable = false; depthDisabledStencilDesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; depthDisabledStencilDesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; depthDisabledStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthDisabledStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; depthDisabledStencilDesc.BackFace = depthDisabledStencilDesc.FrontFace; // Create the state using the device. result = m_device->CreateDepthStencilState(&depthDisabledStencilDesc, &m_depthDisabledStencilState); if(FAILED(result)) { return false; } // Clear the blend state description. ZeroMemory(&blendStateDescription, sizeof(D3D11_BLEND_DESC)); // Create an alpha enabled blend state description. blendStateDescription.RenderTarget[0].BlendEnable = TRUE; //blendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; blendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; blendStateDescription.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; blendStateDescription.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; blendStateDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA; blendStateDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; blendStateDescription.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_SUBTRACT; blendStateDescription.RenderTarget[0].RenderTargetWriteMask = 0x0f; // Create the blend state using the description. result = m_device->CreateBlendState(&blendStateDescription, &m_alphaEnableBlendingState); if (FAILED(result)) { return false; } // Modify the description to create an alpha disabled blend state description. blendStateDescription.RenderTarget[0].BlendEnable = FALSE; // Create the blend state using the description. result = m_device->CreateBlendState(&blendStateDescription, &m_alphaDisableBlendingState); if (FAILED(result)) { return false; } return true; }
void BBWin8Game::CreateD3dDevice(){ CoreWindow ^window=CoreWindow::GetForCurrentThread(); _windowBounds=window->Bounds; _renderTargetSize.Width=DipsToPixels( _windowBounds.Width ); _renderTargetSize.Height=DipsToPixels( _windowBounds.Height ); int width=_renderTargetSize.Width; int height=_renderTargetSize.Height; UINT creationFlags=D3D11_CREATE_DEVICE_BGRA_SUPPORT; #ifdef _DEBUG creationFlags|=D3D11_CREATE_DEVICE_DEBUG; #endif #if WINDOWS_8 D3D_FEATURE_LEVEL featureLevels[]={ D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1 }; #elif WINDOWS_PHONE_8 D3D_FEATURE_LEVEL featureLevels[]={ D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3 }; #endif ID3D11Device *device; ID3D11DeviceContext *context; DXASS( D3D11CreateDevice( 0, D3D_DRIVER_TYPE_HARDWARE, 0, creationFlags, featureLevels, ARRAYSIZE(featureLevels), D3D11_SDK_VERSION, &device, &_featureLevel, &context ) ); DXASS( device->QueryInterface( __uuidof( ID3D11Device1 ),(void**)&_d3dDevice ) ); DXASS( context->QueryInterface( __uuidof( ID3D11DeviceContext1 ),(void**)&_d3dContext ) ); device->Release(); context->Release(); //create swap chain if( _swapChain ){ DXASS( _swapChain->ResizeBuffers( 2,width,height,DXGI_FORMAT_B8G8R8A8_UNORM,0 ) ); }else{ #if WINDOWS_8 DXGI_SWAP_CHAIN_DESC1 swapChainDesc={0}; swapChainDesc.Width=width; swapChainDesc.Height=height; swapChainDesc.Format=DXGI_FORMAT_B8G8R8A8_UNORM; swapChainDesc.Stereo=false; swapChainDesc.SampleDesc.Count=1; swapChainDesc.SampleDesc.Quality=0; swapChainDesc.BufferUsage=DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount=2; swapChainDesc.Scaling=DXGI_SCALING_NONE; swapChainDesc.SwapEffect=DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; swapChainDesc.Flags=0; #elif WINDOWS_PHONE_8 DXGI_SWAP_CHAIN_DESC1 swapChainDesc={0}; swapChainDesc.Width=width; swapChainDesc.Height=height; swapChainDesc.Format=DXGI_FORMAT_B8G8R8A8_UNORM; swapChainDesc.Stereo=false; swapChainDesc.SampleDesc.Count=1; swapChainDesc.SampleDesc.Quality=0; swapChainDesc.BufferUsage=DXGI_USAGE_RENDER_TARGET_OUTPUT; swapChainDesc.BufferCount=1; swapChainDesc.Scaling=DXGI_SCALING_STRETCH; swapChainDesc.SwapEffect=DXGI_SWAP_EFFECT_DISCARD; swapChainDesc.Flags=0; #endif IDXGIDevice1 *dxgiDevice; DXASS( _d3dDevice->QueryInterface( __uuidof( IDXGIDevice1 ),(void**)&dxgiDevice ) ); IDXGIAdapter *dxgiAdapter; DXASS( dxgiDevice->GetAdapter( &dxgiAdapter ) ); IDXGIFactory2 *dxgiFactory; DXASS( dxgiAdapter->GetParent( __uuidof( IDXGIFactory2 ),(void**)&dxgiFactory ) ); DXASS( dxgiFactory->CreateSwapChainForCoreWindow( _d3dDevice,(IUnknown*)window,&swapChainDesc,0,&_swapChain ) ); DXASS( dxgiDevice->SetMaximumFrameLatency( 1 ) ); dxgiFactory->Release(); dxgiAdapter->Release(); dxgiDevice->Release(); } // Create a render target view of the swap chain back buffer. // ID3D11Texture2D *backBuffer; DXASS( _swapChain->GetBuffer( 0,__uuidof( ID3D11Texture2D ),(void**)&backBuffer ) ); DXASS( _d3dDevice->CreateRenderTargetView( backBuffer,0,&_renderTargetView ) ); backBuffer->Release(); /* // Create a depth stencil view // D3D11_TEXTURE2D_DESC dsdesc; ZEROMEM( dsdesc ); dsdesc.Width=width; dsdesc.Height=height; dsdesc.MipLevels=1; dsdesc.ArraySize=1; dsdesc.Format=DXGI_FORMAT_D24_UNORM_S8_UINT; dsdesc.SampleDesc.Count=1; dsdesc.SampleDesc.Quality=0; dsdesc.Usage=D3D11_USAGE_DEFAULT; dsdesc.BindFlags=D3D11_BIND_DEPTH_STENCIL; dsdesc.CpuAccessFlags=0; dsdesc.MiscFlags=0; ID3D11Texture2D *depthStencil; DXASS( _d3dDevice->CreateTexture2D( &dsdesc,0,&depthStencil ) ); DXASS( _d3dDevice->CreateDepthStencilView( depthStencil,0,&_depthStencilView ) ); depthStencil->Release(); */ D3D11_VIEWPORT viewport={ 0,0,width,height,0,1 }; _d3dContext->RSSetViewports( 1,&viewport ); }
bool D3DClass::Initialize(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen, float screenDepth, float screenNear) { HRESULT result; IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* adapterOutput; unsigned int numModes, i, numerator, denominator, stringLength; DXGI_MODE_DESC* displayModeList; DXGI_ADAPTER_DESC adapterDesc; int error; DXGI_SWAP_CHAIN_DESC swapChainDesc; D3D_FEATURE_LEVEL featureLevel; ID3D11Texture2D* backBufferPtr; D3D11_TEXTURE2D_DESC depthBufferDesc; D3D11_DEPTH_STENCIL_DESC depthStencilDesc; D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; D3D11_RASTERIZER_DESC rasterDesc; D3D11_VIEWPORT viewport; float fieldOfView, screenAspect; // vsync(수직동기화) 설정을 저장합니다. m_vsync_enabled = vsync; // DirectX 그래픽 인터페이스 팩토리를 만듭니다. result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if (FAILED(result)) { return false; } // 팩토리 객체를 사용하여 첫번째 그래픽 카드 인터페이스에 대한 아답터를 만듭니다. result = factory->EnumAdapters(0, &adapter); if (FAILED(result)) { return false; } // 출력(모니터)에 대한 첫번째 아답터를 나열합니다. result = adapter->EnumOutputs(0, &adapterOutput); if (FAILED(result)) { return false; } // DXGI_FORMAT_R8G8B8A8_UNORM 모니터 출력 디스플레이 포맷에 맞는 모드의 개수를 구합니다. result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL); if (FAILED(result)) { return false; } // 가능한 모든 모니터와 그래픽카드 조합을 저장할 리스트를 생성합니다. displayModeList = new DXGI_MODE_DESC[numModes]; if (!displayModeList) { return false; } // 디스플레이 모드에 대한 리스트 구조를 채워넣습니다. result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); if (FAILED(result)) { return false; } // 이제 모든 디스플레이 모드에 대해 화면 너비/높이에 맞는 디스플레이 모드를 찾습니다. // 적합한 것을 찾으면 모니터의 새로고침 비율의 분모와 분자 값을 저장합니다. for (i = 0; i<numModes; i++) { if (displayModeList[i].Width == (unsigned int)screenWidth) { if (displayModeList[i].Height == (unsigned int)screenHeight) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } } // 아답터(그래픽카드)의 description을 가져옵니다. result = adapter->GetDesc(&adapterDesc); if (FAILED(result)) { return false; } // 현재 그래픽카드의 메모리 용량을 메가바이트 단위로 저장합니다. m_videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); // 그래픽카드의 이름을 char형 문자열 배열로 바꾼 뒤 저장합니다. error = wcstombs_s(&stringLength, m_videoCardDescription, 128, adapterDesc.Description, 128); if (error != 0) { return false; } // 디스플레이 모드 리스트의 할당을 해제합니다. delete[] displayModeList; displayModeList = 0; // 출력 아답터를 할당 해제합니다. adapterOutput->Release(); adapterOutput = 0; // 아답터를 할당 해제합니다. adapter->Release(); adapter = 0; // 팩토리 객체를 할당 해제합니다. factory->Release(); factory = 0; // 스왑 체인 description을 초기화합니다. ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); // 하나의 백버퍼만을 사용하도록 합니다. swapChainDesc.BufferCount = 1; // 백버퍼의 너비와 높이를 설정합니다. swapChainDesc.BufferDesc.Width = screenWidth; swapChainDesc.BufferDesc.Height = screenHeight; // 백퍼버로 일반적인 32bit의 서페이스를 지정합니다. swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // 백버퍼의 새로고침 비율을 설정합니다. if (m_vsync_enabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator; } else { swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; } // 백버퍼의 용도를 설정합니다. swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // 렌더링이 이루어질 윈도우의 핸들을 설정합니다. swapChainDesc.OutputWindow = hwnd; // 멀티샘플링을 끕니다. swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; // 윈도우 모드 또는 풀스크린 모드를 설정합니다. if (fullscreen) swapChainDesc.Windowed = false; else swapChainDesc.Windowed = true; // 스캔라인의 정렬과 스캔라이닝을 지정되지 않으므로 (unspecified) 설정합니다. swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; // 출력된 이후의 백버퍼의 내용을 버리도록 합니다. swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; // 추가 옵션 플래그를 사용하지 않습니다. swapChainDesc.Flags = 0; // 피쳐 레벨을 DirectX 11로 설정합니다. featureLevel = D3D_FEATURE_LEVEL_11_0; // 스왑 체인, Direct3D 디바이스, Direct3D 디바이스 컨텍스트를 생성합니다. result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext); if (FAILED(result)) return false; // 백버퍼의 포인터를 가져옵니다. result = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr); if (FAILED(result)) return false; // 백버퍼의 포인터로 렌더타겟 뷰를 생성합니다. result = m_device->CreateRenderTargetView(backBufferPtr, NULL, &m_renderTargetView); if (FAILED(result)) return false; // 백버퍼 포인터를 더이상 사용하지 않으므로 할당 해제합니다. backBufferPtr->Release(); backBufferPtr = 0; // 깊이 버퍼의 description을 초기화합니다. ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); // 깊이 버퍼의 description을 작성합니다. depthBufferDesc.Width = screenWidth; depthBufferDesc.Height = screenHeight; depthBufferDesc.MipLevels = 1; depthBufferDesc.ArraySize = 1; depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthBufferDesc.SampleDesc.Count = 1; depthBufferDesc.SampleDesc.Quality = 0; depthBufferDesc.Usage = D3D11_USAGE_DEFAULT; depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthBufferDesc.CPUAccessFlags = 0; depthBufferDesc.MiscFlags = 0; // description을 사용하여 깊이 버퍼의 텍스쳐를 생성합니다. result = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer); if (FAILED(result)) return false; // 스텐실 상태의 description을 초기화합니다. ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc)); // 스텐실 상태의 description을 작성합니다. depthStencilDesc.DepthEnable = true; depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; depthStencilDesc.StencilEnable = true; depthStencilDesc.StencilReadMask = 0xFF; depthStencilDesc.StencilWriteMask = 0xFF; // Stencil operations if pixel is front-facing. depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // Stencil operations if pixel is back-facing. depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // 깊이 - 스텐실 상태를 생성합니다. result = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); if (FAILED(result)) return false; // 깊이 - 스텐실 상태를 설정합니다. m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1); // 깊이 - 스텐실 뷰의 description을 초기화 합니다. ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc)); // 깊이 - 스텐실 부의 description을 작성합니다. depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; // 깊이 - 스텐실 뷰를 생성합니다. result = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView); if (FAILED(result)) return false; // 렌더타겟 뷰와 깊이 - 스텐실 버퍼를 각각 출력 파이프라인에 바인딩합니다. m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView); // 어떤 도형을 어떻게 그릴 것인지 결정하는 래스터화기 description을 작성합니다. rasterDesc.AntialiasedLineEnable = false; rasterDesc.CullMode = D3D11_CULL_BACK; rasterDesc.DepthBias = 0; rasterDesc.DepthBiasClamp = 0.0f; rasterDesc.DepthClipEnable = true; rasterDesc.FillMode = D3D11_FILL_SOLID; rasterDesc.FrontCounterClockwise = false; rasterDesc.MultisampleEnable = false; rasterDesc.ScissorEnable = false; rasterDesc.SlopeScaledDepthBias = 0.0f; // 작성한 description으로부터 래스터화기 상태를 생성합니다. result = m_device->CreateRasterizerState(&rasterDesc, &m_rasterState); if (FAILED(result)) return false; // 래스터화기 상태를 설정합니다. m_deviceContext->RSSetState(m_rasterState); // 렌더링을 위한 뷰포트를 설정합니다. viewport.Width = (float)screenWidth; viewport.Height = (float)screenHeight; viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; viewport.TopLeftX = 0.0f; viewport.TopLeftY = 0.0f; // 뷰포트를 생성합니다. m_deviceContext->RSSetViewports(1, &viewport); // 투영 행렬을 설정합니다. fieldOfView = (float)D3DX_PI / 4.0f; screenAspect = (float)screenWidth / (float)screenHeight; // 3D 렌더링을 위한 투영 행렬을 생성합니다. D3DXMatrixPerspectiveFovLH(&m_projectionMatrix, fieldOfView, screenAspect, screenNear, screenDepth); // 월드 행렬을 단위 행렬로 초기화 합니다. D3DXMatrixIdentity(&m_worldMatrix); // 2D 렌더링에 사용될 정사영 행렬을 생성합니다. D3DXMatrixOrthoLH(&m_orthoMatrix, (float)screenWidth, (float)screenHeight, screenNear, screenDepth); return true; }
//-------------------------------------------------------------------------------------- // Enumerate for each adapter all of the supported display modes, // device types, adapter formats, back buffer formats, window/full screen support, // depth stencil formats, multisampling types/qualities, and presentations intervals. // // For each combination of device type (HAL/REF), adapter format, back buffer format, and // IsWindowed it will call the app's ConfirmDevice callback. This allows the app // to reject or allow that combination based on its caps/etc. It also allows the // app to change the BehaviorFlags. The BehaviorFlags defaults non-pure HWVP // if supported otherwise it will default to SWVP, however the app can change this // through the ConfirmDevice callback. //-------------------------------------------------------------------------------------- HRESULT CD3D11Enumeration::Enumerate( LPDXUTCALLBACKISD3D11DEVICEACCEPTABLE IsD3D11DeviceAcceptableFunc, void* pIsD3D11DeviceAcceptableFuncUserContext ) { CDXUTPerfEventGenerator eventGenerator( DXUT_PERFEVENTCOLOR, L"DXUT D3D11 Enumeration" ); HRESULT hr; IDXGIFactory1* pFactory = DXUTGetDXGIFactory(); if( pFactory == NULL ) return E_FAIL; m_bHasEnumerated = true; m_IsD3D11DeviceAcceptableFunc = IsD3D11DeviceAcceptableFunc; m_pIsD3D11DeviceAcceptableFuncUserContext = pIsD3D11DeviceAcceptableFuncUserContext; ClearAdapterInfoList(); for( int index = 0; ; ++index ) { IDXGIAdapter* pAdapter = NULL; hr = pFactory->EnumAdapters( index, &pAdapter ); if( FAILED( hr ) ) // DXGIERR_NOT_FOUND is expected when the end of the list is hit break; CD3D11EnumAdapterInfo* pAdapterInfo = new CD3D11EnumAdapterInfo; if( !pAdapterInfo ) { SAFE_RELEASE( pAdapter ); return E_OUTOFMEMORY; } ZeroMemory( pAdapterInfo, sizeof( CD3D11EnumAdapterInfo ) ); pAdapterInfo->AdapterOrdinal = index; pAdapter->GetDesc( &pAdapterInfo->AdapterDesc ); pAdapterInfo->m_pAdapter = pAdapter; // Enumerate the device driver types on the adapter. hr = EnumerateDevices( pAdapterInfo ); if( FAILED( hr ) ) { delete pAdapterInfo; continue; } hr = EnumerateOutputs( pAdapterInfo ); if( FAILED( hr ) || pAdapterInfo->outputInfoList.GetSize() <= 0 ) { delete pAdapterInfo; continue; } // Get info for each devicecombo on this device if( FAILED( hr = EnumerateDeviceCombos( pFactory, pAdapterInfo ) ) ) { delete pAdapterInfo; continue; } hr = m_AdapterInfoList.Add( pAdapterInfo ); if( FAILED( hr ) ) { delete pAdapterInfo; return hr; } } // If we did not get an adapter then we should still enumerate WARP and Ref. if (m_AdapterInfoList.GetSize() == 0) { CD3D11EnumAdapterInfo* pAdapterInfo = new CD3D11EnumAdapterInfo; if( !pAdapterInfo ) { return E_OUTOFMEMORY; } ZeroMemory( pAdapterInfo, sizeof( CD3D11EnumAdapterInfo ) ); pAdapterInfo->bAdapterUnavailable = true; hr = EnumerateDevices( pAdapterInfo ); // Get info for each devicecombo on this device if( FAILED( hr = EnumerateDeviceCombosNoAdapter( pAdapterInfo ) ) ) { delete pAdapterInfo; } if (!FAILED(hr)) hr = m_AdapterInfoList.Add( pAdapterInfo ); } // // Check for 2 or more adapters with the same name. Append the name // with some instance number if that's the case to help distinguish // them. // bool bUniqueDesc = true; CD3D11EnumAdapterInfo* pAdapterInfo; for( int i = 0; i < m_AdapterInfoList.GetSize(); i++ ) { CD3D11EnumAdapterInfo* pAdapterInfo1 = m_AdapterInfoList.GetAt( i ); for( int j = i + 1; j < m_AdapterInfoList.GetSize(); j++ ) { CD3D11EnumAdapterInfo* pAdapterInfo2 = m_AdapterInfoList.GetAt( j ); if( wcsncmp( pAdapterInfo1->AdapterDesc.Description, pAdapterInfo2->AdapterDesc.Description, DXGI_MAX_DEVICE_IDENTIFIER_STRING ) == 0 ) { bUniqueDesc = false; break; } } if( !bUniqueDesc ) break; } for( int i = 0; i < m_AdapterInfoList.GetSize(); i++ ) { pAdapterInfo = m_AdapterInfoList.GetAt( i ); wcscpy_s( pAdapterInfo->szUniqueDescription, 100, pAdapterInfo->AdapterDesc.Description ); if( !bUniqueDesc ) { WCHAR sz[100]; swprintf_s( sz, 100, L" (#%d)", pAdapterInfo->AdapterOrdinal ); wcscat_s( pAdapterInfo->szUniqueDescription, DXGI_MAX_DEVICE_IDENTIFIER_STRING, sz ); } } return S_OK; }
bool D3DApp::InitDirect3D() { // Create the device and device context. UINT createDeviceFlags = 0; #if defined(DEBUG) || defined(_DEBUG) createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL featureLevel; HRESULT hr = D3D11CreateDevice( 0, // default adapter D3D_DRIVER_TYPE_HARDWARE,// D3D_DRIVER_TYPE_HARDWARE - 3D hardware acceleration for rendering 0, // no software driver createDeviceFlags, 0, 0, // default feature level array D3D11_SDK_VERSION, // This never changes &md3dDevice, // The now created device &featureLevel, // Greatest feature level supported &md3dImmediateContext); // The now created device context if( FAILED(hr) ) { MessageBox(0, L"D3D11CreateDevice Failed.", 0, 0); return false; } // This is the order that the feature levels are tried if( featureLevel == D3D_FEATURE_LEVEL_11_0 ) { printf("Using Direct3D Feature Level 11.0\n"); } else if( featureLevel == D3D_FEATURE_LEVEL_10_1 ) { printf("Using Direct3D Feature Level 10.1\n"); } else if( featureLevel == D3D_FEATURE_LEVEL_10_0 ) { printf("Using Direct3D Feature Level 10.0\n"); } else if( featureLevel == D3D_FEATURE_LEVEL_9_3 ) { printf("Using Direct3D Feature Level 9.3\n"); } else if( featureLevel == D3D_FEATURE_LEVEL_9_2 ) { printf("Using Direct3D Feature Level 9.2\n"); } else if( featureLevel == D3D_FEATURE_LEVEL_9_1 ) { printf("Using Direct3D Feature Level 9.1\n"); } // Check 4X MSAA quality support for our back buffer format. // All Direct3D 11 capable devices support 4X MSAA for all render // target formats, so we only need to check quality support. HR(md3dDevice->CheckMultisampleQualityLevels( DXGI_FORMAT_R8G8B8A8_UNORM, 4, &m4xMsaaQuality)); // If m4xMsaaQuality > 0 4x MSAA is supported //assert( m4xMsaaQuality > 0 ); // Fill out a DXGI_SWAP_CHAIN_DESC to describe our swap chain. DXGI_SWAP_CHAIN_DESC sd; sd.BufferDesc.Width = mClientWidth; sd.BufferDesc.Height = mClientHeight; sd.BufferDesc.RefreshRate.Numerator = 60; sd.BufferDesc.RefreshRate.Denominator = 1; sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; // Use 4X MSAA? if( mEnable4xMsaa ) { sd.SampleDesc.Count = 4; sd.SampleDesc.Quality = m4xMsaaQuality-1; } // No MSAA else { sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; } sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // Rendering to the back buffer sd.BufferCount = 1; // Number of back buffers sd.OutputWindow = mhMainWnd; // Handle to the window we are rendering to sd.Windowed = true; sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; // Let the driver choose the most efficient method sd.Flags = 0; // To correctly create the swap chain, we must use the IDXGIFactory that was // used to create the device. If we tried to use a different IDXGIFactory instance // (by calling CreateDXGIFactory), we get an error: "IDXGIFactory::CreateSwapChain: // This function is being called with a device from a different IDXGIFactory." IDXGIDevice* dxgiDevice = 0; HR(md3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice)); IDXGIAdapter* dxgiAdapter = 0; HR(dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&dxgiAdapter)); IDXGIFactory* dxgiFactory = 0; HR(dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgiFactory)); HR(dxgiFactory->CreateSwapChain(md3dDevice, &sd, &mSwapChain)); // Disables Alt + Enter to toggle between fullscreen and windowed mode //HR(dxgiFactory->MakeWindowAssociation(mhMainWnd, DXGI_MWA_NO_ALT_ENTER)); ReleaseCOM(dxgiDevice); ReleaseCOM(dxgiAdapter); ReleaseCOM(dxgiFactory); // The remaining steps that need to be carried out for d3d creation // also need to be executed every time the window is resized. So // just call the OnResize method here to avoid code duplication. OnResize(); return true; }
void DXRenderer::InitializeDX(int _screenWidth, int _screenHeight, bool _vsync, HWND _hwnd, bool _fullScreen, float _screenDepth, float _screenNear) { HRESULT result; IDXGIFactory* factory; IDXGIAdapter* adapter; IDXGIOutput* adapterOutput; unsigned int numModes, i, numerator = 60, denominator = 1, stringLength; DXGI_MODE_DESC* displayModeList; DXGI_ADAPTER_DESC adapterDesc; int error; DXGI_SWAP_CHAIN_DESC swapChainDesc; ID3D11Texture2D* backBufferPtr; D3D11_TEXTURE2D_DESC depthBufferDesc; D3D11_DEPTH_STENCIL_DESC depthStencilDesc; D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; D3D11_RASTERIZER_DESC rasterDesc; D3D11_VIEWPORT viewport; float fieldOfView, screenAspect; m_fScreenDepth = _screenDepth; m_fScreenNear = _screenNear; // Store the vsync setting. m_bVSyncEnabled = _vsync; // Create a DirectX graphics interface factory. result = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory); if (FAILED(result)) { //return false; std::cout << "Error creating DXGIFactory" << std::endl; } // Use the factory to create an adapter for the primary graphics interface (video card). result = factory->EnumAdapters(0, &adapter); if (FAILED(result)) { //return false; } // Enumerate the primary adapter output (monitor). result = adapter->EnumOutputs(0, &adapterOutput); if (FAILED(result)) { //return false; } // Get the number of modes that fit the DXGI_FORMAT_R8G8B8A8_UNORM display format for the adapter output (monitor). result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL); if (FAILED(result)) { //return false; } // Create a list to hold all the possible display modes for this monitor/video card combination. displayModeList = new DXGI_MODE_DESC[numModes]; if (!displayModeList) { //return false; } // Now fill the display mode list structures. result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList); if (FAILED(result)) { //return false; } // Now go through all the display modes and find the one that matches the screen width and height. // When a match is found store the numerator and denominator of the refresh rate for that monitor. for (i = 0; i<numModes; i++) { if (displayModeList[i].Width == (unsigned int)_screenWidth) { if (displayModeList[i].Height == (unsigned int)_screenHeight) { numerator = displayModeList[i].RefreshRate.Numerator; denominator = displayModeList[i].RefreshRate.Denominator; } } } // Get the adapter (video card) description. result = adapter->GetDesc(&adapterDesc); if (FAILED(result)) { //return false; } // Store the dedicated video card memory in megabytes. m_iVideoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024); // Convert the name of the video card to a character array and store it. error = wcstombs_s(&stringLength, m_sVideoCardDescription, 128, adapterDesc.Description, 128); if (error != 0) { //return false; } std::cout << "Video Card: " << m_sVideoCardDescription << std::endl; //Ora si possono liberare tutti gli oggetti e strutture create per ottenere le informazioni sulla scheda video e refresh rate // Release the display mode list. delete[] displayModeList; displayModeList = 0; // Release the adapter output. adapterOutput->Release(); adapterOutput = 0; // Release the adapter. adapter->Release(); adapter = 0; // Release the factory. factory->Release(); factory = 0; //Ora inizializziamo DirectX! //Initialize the swap chain description. ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); // Set to a single back buffer. swapChainDesc.BufferCount = 1; // Set the width and height of the back buffer. swapChainDesc.BufferDesc.Width = _screenWidth; swapChainDesc.BufferDesc.Height = _screenHeight; // Set regular 32-bit surface for the back buffer. swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // Set the refresh rate of the back buffer. if (m_bVSyncEnabled) { swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator; swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator; } else { swapChainDesc.BufferDesc.RefreshRate.Numerator = 60; swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; } // Set the usage of the back buffer. swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // Set the handle for the window to render to. swapChainDesc.OutputWindow = _hwnd; // Turn multisampling off. swapChainDesc.SampleDesc.Count = 1; swapChainDesc.SampleDesc.Quality = 0; // Set to full screen or windowed mode. if (_fullScreen) { swapChainDesc.Windowed = false; } else { swapChainDesc.Windowed = true; } //Proviamo senza questa roba avanzata // Set the scan line ordering and scaling to unspecified. swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; // Discard the back buffer contents after presenting. swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; // Don't set the advanced flags. swapChainDesc.Flags = 0; D3D_FEATURE_LEVEL featureLevel[] = { // TODO: Modify for supported Direct3D feature levels (see code below related to 11.1 fallback handling) D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2, D3D_FEATURE_LEVEL_9_1, }; D3D_DRIVER_TYPE driverTypes[] = { D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_REFERENCE, D3D_DRIVER_TYPE_SOFTWARE, }; UINT numDriverTypes = sizeof(driverTypes) / sizeof(driverTypes[0]); D3D_DRIVER_TYPE g_driverType; for (UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; ++driverTypeIndex) { // Prova ad inizializzare per i tipi di driver definiti g_driverType = driverTypes[driverTypeIndex]; //result = D3D11CreateDevice(nullptr, g_driverType, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, &m_device, nullptr, &m_deviceContext); result = D3D11CreateDeviceAndSwapChain(nullptr, g_driverType, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, &swapChainDesc, &m_dSwapChain, &m_dDevice, nullptr, &m_dDeviceContext); // Appena funziona esci if (SUCCEEDED(result)) break; } if (FAILED(result)) { //return false; std::cout << "Error creating SwapChain" << std::endl; } else std::cout << "DirectX SwapChain created successfully." << std::endl; //D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0; //Creiamo la swapchain, il device e il device context!! /* result = D3D11CreateDeviceAndSwapChain( NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext); if (FAILED(result)) { return false; } */ // Get the pointer to the back buffer. result = m_dSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr); if (FAILED(result)) { //return false; std::cout << "Error creating backbuffer" << std::endl; } // Create the render target view with the back buffer pointer. result = m_dDevice->CreateRenderTargetView(backBufferPtr, NULL, &m_dRenderTargetView); if (FAILED(result)) { //return false; std::cout << "Error creating Render Target View" << std::endl; } // Release pointer to the back buffer as we no longer need it. backBufferPtr->Release(); backBufferPtr = nullptr; // Initialize the description of the depth buffer. ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc)); // Set up the description of the depth buffer. depthBufferDesc.Width = _screenWidth; depthBufferDesc.Height = _screenHeight; depthBufferDesc.MipLevels = 1; depthBufferDesc.ArraySize = 1; depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthBufferDesc.SampleDesc.Count = 1; depthBufferDesc.SampleDesc.Quality = 0; depthBufferDesc.Usage = D3D11_USAGE_DEFAULT; depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; depthBufferDesc.CPUAccessFlags = 0; depthBufferDesc.MiscFlags = 0; // Create the texture for the depth buffer using the filled out description. result = m_dDevice->CreateTexture2D(&depthBufferDesc, NULL, &m_dDepthStencilBuffer); if (FAILED(result)) { //return false; } // Initialize the description of the stencil state. ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc)); // Set up the description of the stencil state. depthStencilDesc.DepthEnable = true; depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; depthStencilDesc.StencilEnable = true; depthStencilDesc.StencilReadMask = 0xFF; depthStencilDesc.StencilWriteMask = 0xFF; // Stencil operations if pixel is front-facing. depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // Stencil operations if pixel is back-facing. depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; // Create the depth stencil state. result = m_dDevice->CreateDepthStencilState(&depthStencilDesc, &m_dDepthStencilState); if (FAILED(result)) { //return false; std::cout << "Error creating Depth Stencil State" << std::endl; } // Set the depth stencil state. m_dDeviceContext->OMSetDepthStencilState(m_dDepthStencilState, 1); // Initailze the depth stencil view. ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc)); // Set up the depth stencil view description. depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; // Create the depth stencil view. result = m_dDevice->CreateDepthStencilView(m_dDepthStencilBuffer, &depthStencilViewDesc, &m_dDepthStencilView); if (FAILED(result)) { //return false; std::cout << "Error creating Depth Stencil View" << std::endl; } // Bind the render target view and depth stencil buffer to the output render pipeline. m_dDeviceContext->OMSetRenderTargets(1, &m_dRenderTargetView, m_dDepthStencilView); // Setup the raster description which will determine how and what polygons will be drawn. rasterDesc.AntialiasedLineEnable = false; rasterDesc.CullMode = D3D11_CULL_BACK; rasterDesc.DepthBias = 0; rasterDesc.DepthBiasClamp = 0.0f; rasterDesc.DepthClipEnable = true; rasterDesc.FillMode = D3D11_FILL_SOLID; rasterDesc.FrontCounterClockwise = false; rasterDesc.MultisampleEnable = false; rasterDesc.ScissorEnable = false; rasterDesc.SlopeScaledDepthBias = 0.0f; // Create the rasterizer state from the description we just filled out. result = m_dDevice->CreateRasterizerState(&rasterDesc, &m_dRasterState); if (FAILED(result)) { //return false; } // Now set the rasterizer state. m_dDeviceContext->RSSetState(m_dRasterState); // Setup the viewport for rendering. viewport.Width = (float)_screenWidth; viewport.Height = (float)_screenHeight; viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; viewport.TopLeftX = 0.0f; viewport.TopLeftY = 0.0f; // Create the viewport. m_dDeviceContext->RSSetViewports(1, &viewport); // Setup the projection matrix. fieldOfView = (float)DirectX::XM_PI / 4.0f; screenAspect = (float)_screenWidth / (float)_screenHeight; //Create constant buffer for the vertex shader D3D11_BUFFER_DESC cbDesc; ZeroMemory(&cbDesc, sizeof(D3D11_BUFFER_DESC)); cbDesc.Usage = D3D11_USAGE_DEFAULT; cbDesc.ByteWidth = sizeof(GFX::ConstantObject); cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; cbDesc.CPUAccessFlags = 0; cbDesc.MiscFlags = 0; D3D11_SAMPLER_DESC sampDesc; ZeroMemory(&sampDesc, sizeof(sampDesc)); sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; sampDesc.MinLOD = 0; sampDesc.MaxLOD = D3D11_FLOAT32_MAX; m_dDevice->CreateSamplerState(&sampDesc, &m_dSamplerState); m_dDevice->CreateBuffer(&cbDesc, NULL, &m_bConstObj); m_dDeviceContext->VSSetConstantBuffers(0, 1, &m_bConstObj); std::cout << "DirectX initialized successfully." << std::endl; }