void DesktopDuplication::init() { IDXGIFactory1* dxgiFactory = nullptr; CHECKED(hr, CreateDXGIFactory1(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&dxgiFactory))); IDXGIAdapter1* dxgiAdapter = nullptr; CHECKED(hr, dxgiFactory->EnumAdapters1(adapter, &dxgiAdapter)); dxgiFactory->Release(); CHECKED(hr, D3D11CreateDevice(dxgiAdapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, NULL, NULL, NULL, D3D11_SDK_VERSION, &d3dDevice, NULL, &d3dContext)); IDXGIOutput* dxgiOutput = nullptr; CHECKED(hr, dxgiAdapter->EnumOutputs(output, &dxgiOutput)); dxgiAdapter->Release(); IDXGIOutput1* dxgiOutput1 = nullptr; CHECKED(hr, dxgiOutput->QueryInterface(__uuidof(dxgiOutput1), reinterpret_cast<void**>(&dxgiOutput1))); dxgiOutput->Release(); IDXGIDevice* dxgiDevice = nullptr; CHECKED(hr, d3dDevice->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice))); CHECKED(hr, dxgiOutput1->DuplicateOutput(dxgiDevice, &outputDuplication)); dxgiOutput1->Release(); dxgiDevice->Release(); }
static IDXGIFactory *GetDXGIFactoryFromDevice(ID3D11Device *device) { IDXGIDevice *dxgiDevice = nullptr; HRESULT result = device->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void **>(&dxgiDevice)); if (FAILED(result)) { return nullptr; } IDXGIAdapter *dxgiAdapter = nullptr; result = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void **>(&dxgiAdapter)); SafeRelease(dxgiDevice); if (FAILED(result)) { return nullptr; } IDXGIFactory *dxgiFactory = nullptr; result = dxgiAdapter->GetParent(__uuidof(IDXGIFactory), reinterpret_cast<void **>(&dxgiFactory)); SafeRelease(dxgiAdapter); if (FAILED(result)) { return nullptr; } return dxgiFactory; }
bool DX11Engine::CreateSwapChain(HWND handle, UINT xSize, UINT ySize) { mXsize = xSize; mYSize = ySize; IDXGIDevice* dxgiDevice = nullptr; HRESULT hr = m_pDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice); if (hr != S_OK) { return false; } IDXGIAdapter* dxgiAdapter = nullptr; hr = dxgiDevice->GetAdapter(&dxgiAdapter); if (hr != S_OK) { return false; } IDXGIFactory1* dxgiFactory1 = nullptr; hr = dxgiAdapter->GetParent(__uuidof(IDXGIFactory1), (void**)&dxgiFactory1); if (hr != S_OK) { return false; } DXGI_SWAP_CHAIN_DESC desc; desc.BufferDesc.Width = xSize; desc.BufferDesc.Height = ySize; desc.BufferDesc.RefreshRate.Numerator = 0; desc.BufferDesc.RefreshRate.Denominator = 1; desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.BufferUsage = DXGI_USAGE_BACK_BUFFER | DXGI_USAGE_RENDER_TARGET_OUTPUT; desc.BufferCount = 2; desc.OutputWindow = handle; desc.Windowed = TRUE; desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; desc.Flags = 0; hr = dxgiFactory1->CreateSwapChain(dxgiDevice, &desc, &m_pSwapChain); if (hr != S_OK) { return false; } dxgiDevice->Release(); dxgiAdapter->Release(); dxgiFactory1->Release(); return true; }
UINT D3D10System::GetNumOutputs() { UINT count = 0; IDXGIDevice *device; if(SUCCEEDED(d3d->QueryInterface(__uuidof(IDXGIDevice), (void**)&device))) { IDXGIAdapter *adapter; if(SUCCEEDED(device->GetAdapter(&adapter))) { IDXGIOutput *outputInterface; while(SUCCEEDED(adapter->EnumOutputs(count, &outputInterface))) { count++; outputInterface->Release(); } adapter->Release(); } device->Release(); } return count; }
static string getGPUName( IUnknown* pDevice ) { string sRet = ""; IDXGIDevice* pDXGIDevice = NULL; pDevice->QueryInterface( __uuidof( IDXGIDevice ), ( void** )&pDXGIDevice ); if ( pDXGIDevice ) { IDXGIAdapter* pDXGIAdapter = NULL; pDXGIDevice->GetAdapter( &pDXGIAdapter ); if ( pDXGIAdapter ) { DXGI_ADAPTER_DESC adapterDesc; pDXGIAdapter->GetDesc( &adapterDesc ); sRet = PluginManager::UTF82ACP( PluginManager::UCS22UTF8( adapterDesc.Description ) ); SAFE_RELEASE( pDXGIAdapter ); } SAFE_RELEASE( pDXGIDevice ); } return sRet; }
void D3D11RenderWindow::_createSwapChain() { // Fill out a DXGI_SWAP_CHAIN_DESC to describe our swap chain. DXGI_SWAP_CHAIN_DESC sd; sd.BufferDesc.Width = mWidth; sd.BufferDesc.Height = mHeight; 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; sd.BufferCount = 2; sd.OutputWindow = mhMainWnd; sd.Windowed = true; sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; 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)); 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. _updateSwapChain(); }
bool CDuplicateOutputDx11::CreateOutputDuplicator() { SAFE_RELEASE(m_pOutputDuplication); HRESULT hRes = S_OK; IDXGIDevice* pDxgiDevice = nullptr; hRes = m_pDevice->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&pDxgiDevice)); if (!SUCCEEDED(hRes)) { DOLOG("m_pDevice->QueryInterface failed!"); return false; } IDXGIAdapter* pDxgiAdapter = nullptr; hRes = pDxgiDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&pDxgiAdapter)); SAFE_RELEASE(pDxgiDevice); if (!SUCCEEDED(hRes)) { DOLOG("pDxgiDevice->GetParent failed!"); return false; } DXGI_ADAPTER_DESC descAdapter; pDxgiAdapter->GetDesc(&descAdapter); // Get output IDXGIOutput* pDxgiOutput = nullptr; hRes = pDxgiAdapter->EnumOutputs(0, &pDxgiOutput); SAFE_RELEASE(pDxgiAdapter); if (!SUCCEEDED(hRes)) { DOLOG("pDxgiAdapter->EnumOutputs failed!"); return false; } // Get output1 IDXGIOutput1* pDxgiOutput1 = nullptr; hRes = pDxgiOutput->QueryInterface(__uuidof(IDXGIOutput1), reinterpret_cast<void**>(&pDxgiOutput1)); SAFE_RELEASE(pDxgiOutput); if (!SUCCEEDED(hRes)) { DOLOG("pDxgiOutput->QueryInterface failed!"); return false; } // Get duplicate hRes = pDxgiOutput1->DuplicateOutput(m_pDevice, &m_pOutputDuplication); SAFE_RELEASE(pDxgiOutput1); if (!SUCCEEDED(hRes)) { DOLOG("pDxgiOutput1->DuplicateOutput"); return false; } return true; }
void D3DContext::InitD3D(HWND hWnd) { m_MSAAEnabled = true; HRESULT hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, m_DebugLayerEnabled ? D3D11_CREATE_DEVICE_DEBUG : D3D11_CREATE_DEVICE_SINGLETHREADED, NULL, NULL, D3D11_SDK_VERSION, &dev, &m_D3DFeatureLevel, &devcon); dev->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, 4, &m_MSAAQuality); // assert(m_MSAAQuality > 0); DXGI_SWAP_CHAIN_DESC scd; ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC)); scd.BufferDesc.Width = m_Properties.width; scd.BufferDesc.Height = m_Properties.height; scd.BufferDesc.RefreshRate.Numerator = 60; scd.BufferDesc.RefreshRate.Denominator = 1; scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; scd.SampleDesc.Count = m_MSAAEnabled ? 4 : 1; scd.SampleDesc.Quality = m_MSAAEnabled ? (m_MSAAQuality - 1) : 0; scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; scd.BufferCount = 3; scd.OutputWindow = hWnd; scd.Windowed = !m_Properties.fullscreen; scd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; scd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; IDXGIDevice* dxgiDevice = 0; IDXGIAdapter* dxgiAdapter = 0; IDXGIFactory* dxgiFactory = 0; dev->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice); dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&dxgiAdapter); dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgiFactory); dxgiFactory->CreateSwapChain(dev, &scd, &swapchain); dxgiFactory->Release(); dxgiAdapter->Release(); dxgiDevice->Release(); if (m_DebugLayerEnabled) { dev->QueryInterface(__uuidof(ID3D11Debug), reinterpret_cast<void**>(&m_DebugLayer)); m_DebugLayer->ReportLiveDeviceObjects(D3D11_RLDO_SUMMARY); ID3D11InfoQueue* infoQueue; dev->QueryInterface(__uuidof(ID3D11InfoQueue), reinterpret_cast<void**>(&infoQueue)); D3D11_MESSAGE_ID hide[] = { D3D11_MESSAGE_ID_DEVICE_DRAW_SAMPLER_NOT_SET }; D3D11_INFO_QUEUE_FILTER filter; memset(&filter, 0, sizeof(filter)); filter.DenyList.NumIDs = 1; filter.DenyList.pIDList = hide; infoQueue->AddStorageFilterEntries(&filter); } Resize(); }
bool TRenderDevice::CreateSwapChain(){ IDXGIDevice* device; if (FAILED(Device->QueryInterface(__uuidof(IDXGIDevice), (void**) &device))){ MessageBox(0,L"获取设备接口失败",0,0); return false; } IDXGIAdapter* adapter; if (FAILED(device->GetParent(__uuidof(IDXGIAdapter), (void**) &adapter))){ MessageBox(0,L"获取适配器接口失败",0,0); return false; } IDXGIFactory* factory; if (FAILED(adapter->GetParent(__uuidof(IDXGIFactory), (void**) &factory))){ MessageBox(0,L"获取Factory接口失败",0,0); return false; } DXGI_SWAP_CHAIN_DESC sd; sd.BufferDesc.Width = RenderSize->GetRenderWidth(); sd.BufferDesc.Height = RenderSize->GetRenderHeight(); 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 (MsaaQuality>0){ sd.SampleDesc.Count = MsaaQuality; sd.SampleDesc.Quality = MsaaQuality - 1; }else{ sd.SampleDesc.Count=1; sd.SampleDesc.Quality=0; } sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.BufferCount = 1; sd.OutputWindow = RenderWindow->GetHWnd(); sd.Windowed = true; sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; sd.Flags = 0; if (FAILED(factory->CreateSwapChain(Device, &sd, &SwapChain))){ MessageBox(0,L"创建SwapChain失败",0,0); return false; } device->Release(); adapter->Release(); factory->Release(); return true; }
IDXGIAdapter* GetDXGIAdapterFromD3D11Device(ID3D11Device* device) { IDXGIDevice* dxgiDevice = NULL; CHECK_HR(device->QueryInterface(&dxgiDevice)); IDXGIAdapter* dxgiAdapter = NULL; CHECK_HR(dxgiDevice->GetAdapter(&dxgiAdapter)); SafeRelease(dxgiDevice); return dxgiAdapter; }
//************************************************************************************************* // Create the swap chain for the device //************************************************************************************************* SBOOL RenderContext::createSwapChain(HWND clientWindow, SUINT clientWidth, SUINT clientHeight) { // Fill out DXGI swap chain description DXGI_SWAP_CHAIN_DESC sd; sd.BufferDesc.Width = clientWidth; sd.BufferDesc.Height = clientHeight; 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(_4xMsaaEnabled) { sd.SampleDesc.Count = 4; sd.SampleDesc.Quality = _4xMsaaQuality - 1; } // No Msaa else { sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; } sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.BufferCount = 1; sd.OutputWindow = clientWindow; sd.Windowed = true; sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; sd.Flags = 0; // Generate an IDXGI factory to properly initialize the swap chain IDXGIDevice* dxgiDevice = 0; HR(_d3dDevice->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(_d3dDevice, &sd, &_swapChain)); ReleaseCOM(dxgiDevice); ReleaseCOM(dxgiAdapter); ReleaseCOM(dxgiFactory); return true; }
std::shared_ptr<SwapChain> Device::createSwapChain(const Window& window) { std::shared_ptr<SwapChain> swapChain; IDXGIDevice* dxgiDevice = nullptr; if (SUCCEEDED(m_device->QueryInterface<IDXGIDevice>(&dxgiDevice))) { IDXGIAdapter* adapter = nullptr; if (SUCCEEDED(dxgiDevice->GetAdapter(&adapter))) { IDXGIFactory* dxgiFactory = nullptr; if (SUCCEEDED(adapter->GetParent(__uuidof(IDXGIFactory), reinterpret_cast<void**>(&dxgiFactory)))) { DXGI_SWAP_CHAIN_DESC sd; ZeroMemory(&sd, sizeof(sd)); sd.BufferCount = 1; sd.BufferDesc.Width = window.getWidth(); sd.BufferDesc.Height = window.getHeight(); sd.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; sd.BufferDesc.RefreshRate.Numerator = 0; sd.BufferDesc.RefreshRate.Denominator = 1; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; sd.OutputWindow = window.getPlatformData()->getHandle(); sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.Windowed = TRUE; IDXGISwapChain* nativeSwapChain = nullptr; if (SUCCEEDED(dxgiFactory->CreateSwapChain(m_device, &sd, &nativeSwapChain))) { ID3D11Texture2D* backBufferTexture = nullptr; if (SUCCEEDED(nativeSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&backBufferTexture)))) { auto texture = std::make_shared<Texture2d>(backBufferTexture); auto backBufferRenderCommandEncoder = createRenderCommandEncoder(1, &texture, nullptr, false); swapChain = std::make_shared<SwapChain>(nativeSwapChain, backBufferRenderCommandEncoder); } dxgiFactory->Release(); } adapter->Release(); } } dxgiDevice->Release(); } return swapChain; }
// Callers must Release the DXGIAdapter after use or risk mem-leak static bool GetDXGIAdapter(__out IDXGIAdapter **DXGIAdapter) { ID3D10Device1 *D2D10Device; IDXGIDevice *DXGIDevice; bool result = false; if (D2D10Device = mozilla::gfx::Factory::GetDirect3D10Device()) { if (D2D10Device->QueryInterface(__uuidof(IDXGIDevice), (void **)&DXGIDevice) == S_OK) { result = (DXGIDevice->GetAdapter(DXGIAdapter) == S_OK); DXGIDevice->Release(); } } return result; }
inline void DisableDXGIWindowChanges(IUnknown* device, HWND window) { IDXGIDevice * pDXGIDevice; ThrowIfFailed(device->QueryInterface(IID_PPV_ARGS(&pDXGIDevice))); IDXGIAdapter * pDXGIAdapter; ThrowIfFailed(pDXGIDevice->GetParent(IID_PPV_ARGS(&pDXGIAdapter))); IDXGIFactory * pIDXGIFactory; ThrowIfFailed(pDXGIAdapter->GetParent(IID_PPV_ARGS(&pIDXGIFactory))); ThrowIfFailed(pIDXGIFactory->MakeWindowAssociation(window, DXGI_MWA_NO_WINDOW_CHANGES | DXGI_MWA_NO_ALT_ENTER)); pIDXGIFactory->Release(); pDXGIAdapter->Release(); pDXGIDevice->Release(); }
static IDXGIFactory* FactoryFromDevice(ID3D11Device *device) { assert(device); IDXGIDevice *dxgiDevice = nullptr; DEBUG_HR(device->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice))); IDXGIAdapter *dxgiAdapter = nullptr; DEBUG_HR(dxgiDevice->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&dxgiAdapter))); IDXGIFactory *dxgiFactory = nullptr; DEBUG_HR(dxgiAdapter->GetParent(__uuidof(IDXGIFactory), reinterpret_cast<void**>(&dxgiFactory))); ReleaseCom(dxgiAdapter); ReleaseCom(dxgiDevice); return dxgiFactory; }
//======================================================================== // For specified ID3D10Device returns IDXGIFactory used to create it //======================================================================== IDXGIFactory *getDeviceFactory(ID3D10Device *device) { IDXGIDevice *dxgiDevice = 0; IDXGIAdapter *dxgiAdapter = 0; IDXGIFactory *dxgiFactory = 0; if (SUCCEEDED( device->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice) )) { if (SUCCEEDED( dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&dxgiAdapter) )) { dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgiFactory); dxgiAdapter->Release(); } dxgiDevice->Release(); } return dxgiFactory; }
bool Renderer::CreateSwapChain() { // Determine buffer size RECT rect; GetClientRect(hwnd,&rect); // Create swap chain DXGI_SWAP_CHAIN_DESC SwapChainDesc; SwapChainDesc.BufferCount = 1; SwapChainDesc.BufferDesc.Width = rect.right - rect.left; SwapChainDesc.BufferDesc.Height = rect.bottom - rect.top; SwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; SwapChainDesc.BufferDesc.RefreshRate.Numerator = 60; SwapChainDesc.BufferDesc.RefreshRate.Denominator = 1; // 60/1 = 60 Hz SwapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; SwapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; SwapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; SwapChainDesc.OutputWindow = hwnd; SwapChainDesc.SampleDesc.Count = 1; SwapChainDesc.SampleDesc.Quality = 0; // no AA SwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; SwapChainDesc.Windowed = true; // Obtain DXGI factory that was used to create the device // ??? IDXGIDevice* DXGIDevice; D3DDevice->QueryInterface(__uuidof(IDXGIDevice),(void**)&DXGIDevice); IDXGIAdapter* DXGIAdapter; DXGIDevice->GetParent(__uuidof(IDXGIAdapter),(void**)&DXGIAdapter); IDXGIFactory* DXGIFactory; DXGIAdapter->GetParent(__uuidof(IDXGIFactory),(void**)&DXGIFactory); // Use it if(DXGIFactory->CreateSwapChain(D3DDevice,&SwapChainDesc,&SwapChain) != S_OK) { MessageBox(hwnd,"Error creating swap chain","Error",MB_OK); return false; } // Release unused stuff DXGIDevice->Release(); DXGIAdapter->Release(); DXGIFactory->Release(); return true; }
Bool CImplDirectXGraphicsManager::Initialize( CGraphicsManager& manager ) { m_PublicInterface = &manager; UInt32 flags = 0; IDXGIAdapter* selectedAdapter = NULL; D3D10_DRIVER_TYPE driverType = D3D10_DRIVER_TYPE_HARDWARE; #ifdef SETUP_CONFIG_DEBUG flags = D3D10_CREATE_DEVICE_DEBUG; #endif AssertDXCall( D3D10CreateDevice( selectedAdapter, driverType, NULL, flags, D3D10_SDK_VERSION, &m_Device ) ); #ifdef SETUP_CONFIG_DEBUG IDXGIDevice * pDXGIDevice; IDXGIAdapter * pDXGIAdapter; AssertDXCall( m_Device->QueryInterface(__uuidof(IDXGIDevice), (void **)&pDXGIDevice) ); AssertDXCall( pDXGIDevice->GetParent(__uuidof(IDXGIAdapter), (void **)&pDXGIAdapter) ); DXGI_ADAPTER_DESC desc; pDXGIAdapter->GetDesc( &desc ); Char description[256]; WStringToString( desc.Description, description, 256 ); DebugLogInfo("-----------------------------"); DebugLogInfo("Description: %s", description ); DebugLogInfo("DedicatedVideoMemory: %f mo", desc.DedicatedVideoMemory / 1024.0f / 1024.0f ); DebugLogInfo("DedicatedSystemMemory: %f mo", desc.DedicatedSystemMemory / 1024.0f / 1024.0f ); DebugLogInfo("SharedSystemMemory: %f mo", desc.SharedSystemMemory / 1024.0f / 1024.0f ); DebugLogInfo("-----------------------------"); #endif return TRUE; }
bool Direct3D::Initialize(HWND* hWnd) { mcWidth = &Settings->GetData()->mWidth; mcHeight = &Settings->GetData()->mHeight; UINT createDeviceFlags = 0; #if defined(_DEBUG) | (DEBUG) createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL featureLevel; if( FAILED ( D3D11CreateDevice( nullptr, mDriverType, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, &mDevice, &featureLevel, &mDevCon))) { cout << "D3D11CreateDevice failed." << endl; return false; } if(featureLevel != D3D_FEATURE_LEVEL_11_0) { cout << "Direct3D feature level 11 unsupported." << endl; return false; } mDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, 4, &m4xMSAAQuality); assert(m4xMSAAQuality > 0); DXGI_SWAP_CHAIN_DESC sd = {}; sd.BufferDesc.Width = *mcWidth; sd.BufferDesc.Height = *mcHeight; 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; // Use back buffer as render target sd.BufferCount = 1; // Number of back buffers to use in swap chain sd.OutputWindow = *hWnd; // Specify window we render into sd.Windowed = !Settings->GetData()->mIsFullscreen; // Windowed mode or full-screen mode sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; // Let display driver select most efficient presentation method sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; IDXGIDevice* dxgiDevice = nullptr; mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice); IDXGIAdapter* dxgiAdapter = nullptr; dxgiDevice->GetParent(__uuidof(IDXGIAdapter),(void**)&dxgiAdapter); IDXGIFactory* dxgiFactory = nullptr; dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgiFactory); dxgiFactory->CreateSwapChain(mDevice, &sd, &mSwapChain); SafeRelease(dxgiDevice); SafeRelease(dxgiAdapter); SafeRelease(dxgiFactory); this->OnResize(); return true; }
//-------------------------------------------------------------------------------------- // Render a frame //-------------------------------------------------------------------------------------- void Render() { // Clear the back buffer //float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f }; // red,green,blue,alpha //make sure the texture changes the whole time g_ClearColor[0] = ( g_ClearColor[0] + 0.0010f ); if (g_ClearColor[0] >= 1) g_ClearColor[0] -= 1.0f; g_ClearColor[1] = ( g_ClearColor[1] + 0.0009f ); if (g_ClearColor[1] >= 1) g_ClearColor[1] -= 1.0f; g_ClearColor[2] = ( g_ClearColor[2] + 0.0008f ); if (g_ClearColor[2] >= 1) g_ClearColor[2] -= 1.0f; /////////////////////////////////////////////////////////////////////////////////////////// //// COPY THE BACKBUFFER TO OUR (global) SHARED TEXTURE /////////////////////////////////////////////////////////////////////////////////////////// ID3D11Texture2D* pSourceBuffer; //will be used to copy the backbuffer to our sharedTexture ////g_pImmediateContext-> ////g_pSwapChain-> g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pSourceBuffer); //if ( g_pSharedTexture == NULL && pSourceBuffer != NULL ) { // //IDirect3D9Ex_CreateDevice(p,a, b ,c,d,e,f); // D3D11_TEXTURE2D_DESC td; pSourceBuffer->GetDesc(&td); //make it a shared texture, so add a flag td.MiscFlags |= D3D11_RESOURCE_MISC_SHARED; td.MipLevels = 1; td.Usage = D3D11_USAGE_DEFAULT; td.ArraySize = 1; td.BindFlags = 0; //D3D11_BIND_RENDER_TARGET; td.Format = DXGI_FORMAT_B8G8R8A8_UNORM; //DXGI_FORMAT_R8G8B8A8_UNORM; //CD3D11_TEXTURE2D_DESC td2 = new CD3D11_TEXTURE2D_DESC(...); // I think we should create a D3D9ex shared texture and share that. Using the same handle we should open our D3D11 copy ourselves... // Some hints here http://xboxforums.create.msdn.com/forums/t/103939.aspx if (g_pSharedTexture == NULL) { //Ideally end up with 1 simple function somewhat like this: CreateD3D10SharedTexture(pSourceBuffer, g_pd3dDevice, &g_pSharedTexture); #define USE_DLL true #define USE_FUNCTION true //only relevant if USE_DLL = false HANDLE d3d9exShareHandle = NULL; PDIRECT3DTEXTURE9 pD3D9Texture = NULL; D3DFORMAT format = D3DFMT_A32B32G32R32F; //D3DFMT_A8R8G8B8; //D3DFMT_X8R8G8B8; if ( USE_DLL ) { PDIRECT3DTEXTURE9 pD3D9Texture = NULL; //unsigned __int32 sharedTextureHandleInt; HRESULT hr = CreateDX9ExTexture( td.Width, td.Height, D3DUSAGE_RENDERTARGET, format, &pD3D9Texture, &d3d9exShareHandle ); //d3d9exShareHandle = (HANDLE)sharedTextureHandleInt; } else if ( ! USE_FUNCTION ) { IDirect3D9Ex * pDirect3D9Ex; IDirect3DDevice9 * pDeviceD3D9; IDirect3DDevice9Ex * pDeviceD3D9ex; ID3D10Device1 * pDeviceD3D10_1; //Get adapter of the current D3D11 device. Our D3D10 will run on the same adapter. IDXGIDevice* pDXGIDevice; IDXGIAdapter* pAdapter; g_pd3dDevice->QueryInterface<IDXGIDevice>(&pDXGIDevice); //g_pd3dDevice->QueryInterface<IDirect3DDevice9Ex>(&pDeviceD3D9ex); pDXGIDevice->GetAdapter(&pAdapter); pDXGIDevice->Release(); //////// If we add the lib-file to the linker there is no need to load this dll dynamically /////////////////////////////////////////////////////////////////////////////////////////// ////Get address of the function D3D10CreateDevice1 dynamically. ////Load D3D10.DLL ////HMODULE m_hD3D9 = LoadLibrary(L"d3d9.dll"); //HMODULE m_hD3D10 = LoadLibrary(L"d3d10_1.dll"); //typedef HRESULT (WINAPI* FN_D3D10CreateDevice1)(IDXGIAdapter *pAdapter, D3D10_DRIVER_TYPE DriverType, HMODULE Software, // UINT Flags, D3D10_FEATURE_LEVEL1 HardwareLevel, UINT SDKVersion, ID3D10Device1 **ppDevice ); //FN_D3D10CreateDevice1 fnCreate = (FN_D3D10CreateDevice1)GetProcAddress(m_hD3D10, "D3D10CreateDevice1"); ////Call D3D10CreateDevice1 dynamically. //fnCreate( pAdapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, D3D10_CREATE_DEVICE_BGRA_SUPPORT | D3D10_CREATE_DEVICE_DEBUG, // D3D10_FEATURE_LEVEL_10_1, D3D10_1_SDK_VERSION, &pDeviceD3D10_1); D3D10CreateDevice1(pAdapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, D3D10_CREATE_DEVICE_BGRA_SUPPORT | D3D10_CREATE_DEVICE_DEBUG, D3D10_FEATURE_LEVEL_10_1, D3D10_1_SDK_VERSION, &pDeviceD3D10_1); //Now we have a D3D10 device: m_pInterD3D10 (which means the Intermediate Direct3D10 device). //Now let’s share it with D3D11. Do this on your Swapchain Resizing event. (Because size of the Render Target changes): D3DPRESENT_PARAMETERS present_parameters = {0}; //IDirect3DDevice9Ex *device; //D3DDISPLAYMODEEX mode; //, *m; // WE DON'T NEED A SEPARATE WINDOW TO CREATE OUR D3D9ex device !!! ////////////////////////////////////////////////////////////////// // Create window //RECT rc = { 0, 0, 640, 480 }; //AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE ); //if (g_hWnd_D3D9Ex == NULL) { // g_hWnd_D3D9Ex = CreateWindow( L"TutorialWindowClass", L"D3D9Ex window - Direct3D 11 Tutorial 2: Rendering a Triangle", // WS_OVERLAPPEDWINDOW, // CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, g_hInst, // NULL ); // ShowWindow( g_hWnd_D3D9Ex, SW_SHOWNA ); //} ZeroMemory( &present_parameters, sizeof(present_parameters) ); present_parameters.Windowed = true; present_parameters.hDeviceWindow = NULL; //g_hWnd; //g_hWnd_D3D9Ex; present_parameters.SwapEffect = D3DSWAPEFFECT_COPY; present_parameters.BackBufferWidth = td.Width; present_parameters.BackBufferHeight = td.Height; present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8; present_parameters.EnableAutoDepthStencil = FALSE; present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8; present_parameters.BackBufferCount = 1; //present_parameters.Flags = 0; //present_parameters.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; //mode.Size = sizeof(mode); //mode.Width = td.Width; //mode.Height = td.Height; //mode.RefreshRate = 0; //mode.Format = D3DFMT_A8R8G8B8; //mode.ScanLineOrdering = D3DSCANLINEORDERING_UNKNOWN; ////Create a D3D10.1 render target texture and share it with our D3D11. //D3D10_TEXTURE2D_DESC tDesc; //tDesc.Width = td.Width; //tDesc.Height = td.Height; //tDesc.MipLevels = 1; //tDesc.ArraySize = 1; //tDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; //DXGI_FORMAT_R8G8B8A8_UNORM; //tDesc.SampleDesc.Count = 1; //tDesc.SampleDesc.Quality = 0; //tDesc.Usage = D3D10_USAGE_DEFAULT; ////EVEN IF YOU WON'T USE AS SHADER RESOURCE, SET THIS BIND FLAGS: //tDesc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE; //tDesc.CPUAccessFlags = 0; //tDesc.MiscFlags = D3D10_RESOURCE_MISC_SHARED;// Direct3DCreate9Ex( D3D_SDK_VERSION, //_Out_ &pDirect3D9Ex); HRESULT hr; //This works D3DDISPLAYMODE d3ddm = {0}; pDirect3D9Ex->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ); //This doesn't work D3DDISPLAYMODEEX d3ddmex; d3ddmex.Size = sizeof(d3ddmex); d3ddmex.Width = d3ddm.Width; d3ddmex.Height = d3ddm.Height; d3ddmex.Format = d3ddm.Format; d3ddmex.ScanLineOrdering = D3DSCANLINEORDERING_UNKNOWN; //D3DDISPLAYROTATION d3ddrot; //if( S_OK != ( hr = pDirect3D9Ex->GetAdapterDisplayModeEx( D3DADAPTER_DEFAULT, &d3ddmex, &d3ddrot ) ) ) //{ // // TO DO: Respond to failure of GetAdapterDisplayMode // return; //} if ( S_OK != ( hr = pDirect3D9Ex->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3ddm.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D16 ) ) ) { if( hr == D3DERR_NOTAVAILABLE ) // POTENTIAL PROBLEM: We need at least a 16-bit z-buffer! return; } // Do we support hardware vertex processing? if so, use it. // If not, downgrade to software. D3DCAPS9 d3dCaps; if( S_OK != pDirect3D9Ex->GetDeviceCaps( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &d3dCaps ) ) { // TO DO: Respond to failure of GetDeviceCaps return; } DWORD dwBehaviorFlags = 0; if( d3dCaps.VertexProcessingCaps != 0 ) dwBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING; else dwBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING; DWORD d3d9ex_usage = D3DUSAGE_RENDERTARGET | D3DUSAGE_NONSECURE | (dwBehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING ? 0 : D3DUSAGE_SOFTWAREPROCESSING); //HRESULT createDeviceHR = pDirect3D9Ex->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd_D3D9Ex, dwBehaviorFlags, &present_parameters, &pDeviceD3D9); //if (createDeviceHR == S_OK) { // hr = pDeviceD3D9->CreateTexture(td.Width, td.Height, 1 // , D3DUSAGE_RENDERTARGET //| D3DUSAGE_SOFTWAREPROCESSING // , D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pD3D9Texture, &d3d9exShareHandle); // if ( pD3D9Texture == NULL ) { // Sleep(1000); // } //} //else if (D3DERR_DEVICELOST == createDeviceHR) // Sleep(1000); //else if (D3DERR_INVALIDCALL == createDeviceHR) // Sleep(1000); //else if (D3DERR_WRONGTEXTUREFORMAT == createDeviceHR) // Sleep(1000); HRESULT createDeviceExHR = pDirect3D9Ex->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd_D3D9Ex, dwBehaviorFlags, &present_parameters, NULL, &pDeviceD3D9ex); if (createDeviceExHR == S_OK) { hr = pDeviceD3D9ex->CreateTexture(td.Width, td.Height, 1, d3d9ex_usage, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pD3D9Texture, &d3d9exShareHandle); } else if (D3DERR_DEVICELOST == createDeviceExHR) Sleep(1000); else if (D3DERR_INVALIDCALL == createDeviceExHR) Sleep(1000); else if (D3DERR_WRONGTEXTUREFORMAT == createDeviceExHR) Sleep(1000); ////Create the RT texture on D3D10 //ID3D10Texture2D * pD3D10Texture; //pDeviceD3D10_1->CreateTexture2D( &tDesc, NULL, &pD3D10Texture); ////Get DXGI Resource and retrieve the sharing handle. //IDXGISurface * pDXGISurf; //IDXGIResource * pDXGIRes; //HANDLE d3d10ShareHandle; //pD3D10Texture->QueryInterface<IDXGISurface>(&pDXGISurf); //pDXGISurf->QueryInterface<IDXGIResource>(&pDXGIRes); //pDXGIRes->GetSharedHandle( &d3d9exShareHandle ); //pDXGIRes->Release(); //pDXGISurf->Release(); } else { //IF USE_FUNCTION //DWORD usage = D3DUSAGE_RENDERTARGET; PDIRECT3DTEXTURE9 pD3D9Texture = NULL; HRESULT hr = MyCreateDX9ExTexture(td.Width, td.Height, format /*D3DFMT_A8R8G8B8*/, D3DUSAGE_RENDERTARGET, &pD3D9Texture, &d3d9exShareHandle); } if (d3d9exShareHandle != NULL) { ////Call D3D 11 to open shared resource (m_pDevice is the D3D11 device). ID3D11Resource * pD3D11Res; //ID3D11Texture2D * m_pInterRTD3D11; g_pd3dDevice->OpenSharedResource(d3d9exShareHandle, __uuidof(ID3D11Resource), (void**)&pD3D11Res); pD3D11Res->QueryInterface<ID3D11Texture2D>(&g_pSharedTexture); pD3D11Res->Release(); g_pImmediateContext->CopyResource(g_pSharedTexture, pSourceBuffer); ShareD3DTexture(g_hWyphonPartner, d3d9exShareHandle, td.Width, td.Height, format, D3DUSAGE_RENDERTARGET, TEXT("screen output")); //SimpleVertex vertices[] = //{ // { XMFLOAT3( -1.0f, 1.0f, -1.0f ), XMFLOAT2( 1.0f, 0.0f ) }, // { XMFLOAT3( 1.0f, 1.0f, -1.0f ), XMFLOAT2( 0.0f, 0.0f ) }, // { XMFLOAT3( 1.0f, 1.0f, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) }, // { XMFLOAT3( -1.0f, 1.0f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) }, //}; } else { Sleep(1000); } } //if ( g_pSharedTexture == NULL ) { //Render to SCREEN g_pImmediateContext->OMSetRenderTargets( 1, &g_pRenderTargetView, NULL ); g_pImmediateContext->ClearRenderTargetView( g_pRenderTargetView, g_ClearColor ); // Render a triangle g_pImmediateContext->VSSetShader( g_pVertexShader, NULL, 0 ); g_pImmediateContext->PSSetShader( g_pPixelShader, NULL, 0 ); g_pImmediateContext->Draw( 3, 0 ); // Present the information rendered to the back buffer to the front buffer (the screen) g_pSwapChain->Present( 0, 0 ); //} if ( g_pSharedTexture != NULL ) { //Render to TEXTURE // If screen and shared texture have the same format, we could CopyResource the backbuffer to the texture ///////////////////////////////////////////////////////////////////////////////////////////////////////// //g_pImmediateContext->CopyResource(g_pSharedTexture, pSourceBuffer); // Otherwise, we need to setup the texture as the rendertarget, and render the scene again ////////////////////////////////////////////////////////////////////////////////////////// //g_pImmediateContext->Flush(); HRESULT result; D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc; D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc; ID3D11RenderTargetView* m_renderTargetView = NULL; ID3D11ShaderResourceView* m_shaderResourceView = NULL; // Setup the description of the render target view. D3D11_TEXTURE2D_DESC textureDesc; g_pSharedTexture->GetDesc(&textureDesc); renderTargetViewDesc.Format = textureDesc.Format; renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; renderTargetViewDesc.Texture2D.MipSlice = 0; // Create the render target view. result = g_pd3dDevice->CreateRenderTargetView(g_pSharedTexture, &renderTargetViewDesc, &m_renderTargetView); if(FAILED(result)) { } else { // Setup the description of the shader resource view. shaderResourceViewDesc.Format = textureDesc.Format; shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; shaderResourceViewDesc.Texture2D.MostDetailedMip = 0; shaderResourceViewDesc.Texture2D.MipLevels = 1; // Create the shader resource view. //result = g_pd3dDevice->CreateShaderResourceView(g_pSharedTexture, &shaderResourceViewDesc, &m_shaderResourceView); //if(FAILED(result)) //{ //} //else { //ID3D11DepthStencilView* m_depthStencilView; g_pImmediateContext->OMSetRenderTargets( 1, &m_renderTargetView, NULL ); g_pImmediateContext->ClearRenderTargetView( m_renderTargetView, g_ClearColor ); // Render a triangle g_pImmediateContext->VSSetShader( g_pVertexShader, NULL, 0 ); g_pImmediateContext->PSSetShader( g_pPixelShader, NULL, 0 ); g_pImmediateContext->Draw( 3, 0 ); //g_pImmediateContext->Flush(); // Present the information rendered to the back buffer to the front buffer (the screen) //g_pSwapChain->Present( 0, 0 ); //cleanup if ( m_shaderResourceView != NULL ) m_shaderResourceView->Release(); if ( m_renderTargetView != NULL ) m_renderTargetView->Release(); //} } /* Something similar in D3D9Ex //set new render target g_pd3dDevice->SetRenderTarget(0,pRenderSurface); //clear texture g_App.GetDevice()->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(100,100,100), 1.0f, 0); g_App.GetDevice()->BeginScene(); g_App.GetDevice()->SetTexture(0,pPyramideTexture); D3DXMatrixRotationY(&matRotationY,fRotation); D3DXMatrixTranslation(&matTranslation,0.0f,0.0f,5.0f); g_App.GetDevice()->SetTransform(D3DTS_WORLD, &(matRotationY * matTranslation)); //set projection matrix g_App.GetDevice()->SetTransform(D3DTS_PROJECTION,&matProjection); g_App.GetDevice()->SetStreamSource(0,pTriangleVB,0,sizeof(D3DVERTEX)); g_App.GetDevice()->DrawPrimitive(D3DPT_TRIANGLELIST,0,4); g_App.GetDevice()->EndScene(); */ } Sleep(10); // ID3D11Texture2D* pSurface; // HRESULT hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), reinterpret_cast< void** >( &pSurface ) ); // if( pSurface ) // { // //ft: added m_dpi myself // int m_dpi = 96; // // const int width = static_cast<int>(m_window->Bounds.Width * m_dpi / 96.0f); // const int height = static_cast<int>(m_window->Bounds.Height * m_dpi / 96.0f); // unsigned int size = width * height; // if( m_captureData ) // { // freeFramebufferData( m_captureData ); // } // m_captureData = new unsigned char[ width * height * 4 ]; // // ID3D11Texture2D* pNewTexture = NULL; // // D3D11_TEXTURE2D_DESC description; // pSurface->GetDesc( &description ); // description.BindFlags = 0; // description.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; // description.Usage = D3D11_USAGE_STAGING; // // HRESULT hr = m_d3dDevice->CreateTexture2D( &description, NULL, &pNewTexture ); // if ( pNewTexture ) // { // m_d3dContext->CopyResource( pNewTexture, pSurface ); // D3D11_MAPPED_SUBRESOURCE resource; // unsigned int subresource = D3D11CalcSubresource( 0, 0, 0 ); // HRESULT hr = m_d3dContext->Map( pNewTexture, subresource, D3D11_MAP_READ_WRITE, 0, &resource ); // //resource.pData; // TEXTURE DATA IS HERE // // const int pitch = width << 2; // const unsigned char* source = static_cast< const unsigned char* >( resource.pData ); // unsigned char* dest = m_captureData; // for( int i = 0; i < height; ++i ) // { // memcpy( dest, source, width * 4 ); // source += pitch; // dest += pitch; // } // // m_captureSize = size; // m_captureWidth = width; // m_captureHeight = height; // // return; // } // // freeFramebufferData( m_captureData ); // } }
// 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; }
//-------------------------------------------------------------------------------------- // 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 = {}; 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 = {}; 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; 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; }
// ´ÙÀÌ·ºÆ® °´Ã¼ ÃʱâÈ // - °¢Á¾±â´ÉÀ» Áö¿øÇϴ°¡ üũÇÏ°í(´ÙÁß »ùÇøµ µî), ½º¿ÒüÀÎ, ÄÄ °´Ã¼ µîÀ» »ý¼º, Á¦°ÅÇÑ´Ù. bool cInitD3D::InitDirect3D() { // µð¹ÙÀ̽º, µð¹ÙÀ̽º ÄÁÅؽºÆ® »ý¼º UINT createDeviceFlags = 0; #if defined(DEBUG) || defined(_DEBUG) createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL featureLevel; HRESULT hr = D3D11CreateDevice( 0, // default adapter md3dDriverType, 0, // no software device createDeviceFlags, 0, 0, // default feature level array D3D11_SDK_VERSION, &md3dDevice, &featureLevel, &md3dImmediateContext); 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; } // ¹é¹öÆÛ¿¡ 4X MSAA Ç°Áú Áö¿øÀ» È®ÀÎ HR(md3dDevice->CheckMultisampleQualityLevels( DXGI_FORMAT_R8G8B8A8_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; // ´ÙÁß »ùÇøµ À¯¹« (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; sd.BufferCount = 1; sd.OutputWindow = mhMainWnd; sd.Windowed = true; sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; sd.Flags = 0; // µð¹ÙÀ̽º »ý¼º 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)); // ÄÄ °´Ã¼ »èÁ¦ ReleaseCOM(dxgiDevice); ReleaseCOM(dxgiAdapter); ReleaseCOM(dxgiFactory); // â Å©±â Á¶Àý (ÄÚµå Áߺ¹ ÇÇÇϱâ À§ÇØ »ç¿ë) OnResize(); return true; }
void DirectXController::Initialize( void ) { WindowController::Get()->Initialize(); WindowController::Get()->OpenWindow(); driverType = D3D_DRIVER_TYPE_HARDWARE; enable4xMsaa = false; msaa4xQuality = 0; device.dx = nullptr; deviceContext.dx = nullptr; swapChain = nullptr; depthStencilBuffer = nullptr; renderTargetView = nullptr; depthStencilView = nullptr; ZeroMemory( &viewport, sizeof(D3D11_VIEWPORT) ); UINT createDeviceFlags = 0; #if defined(_DEBUG) || defined(DEBUG) createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL requiredFeatureLevel = D3D_FEATURE_LEVEL_11_0; D3D_FEATURE_LEVEL featureLevel; HRESULT hResult = D3D11CreateDevice( NULL, // Adapter driverType, // Driver Type NULL, // Software createDeviceFlags, // Flags &requiredFeatureLevel, // Feature levels 1, // num Feature levels D3D11_SDK_VERSION, // SDK Version &device.dx, // Device &featureLevel, // Feature Level &deviceContext.dx ); // Device Context // Handle any device creation or DirectX version errors if( FAILED(hResult) ) { MessageBox(NULL, L"D3D11CreateDevice Failed", NULL, NULL); //return false; } if( featureLevel != requiredFeatureLevel ) { MessageBox(NULL, L"Direct3D Feature Level 11 unsupported", NULL, NULL); //return false; } // Check for 4X MSAA quality support HR(device.dx->CheckMultisampleQualityLevels( DXGI_FORMAT_R8G8B8A8_UNORM, 4, &msaa4xQuality)); //assert( msaa4xQuality > 0 ); // Potential problem if quality is 0 // set up swap chain DXGI_SWAP_CHAIN_DESC swapChainDesc; ZeroMemory(&swapChainDesc, sizeof(swapChainDesc) ); swapChainDesc.BufferCount = 1; swapChainDesc.BufferDesc.Width = WindowController::Get()->GetWidth();//windowWidth; swapChainDesc.BufferDesc.Height = WindowController::Get()->GetHeight();//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.OutputWindow = Win32Controller::Get()->GetHWnd();//hMainWnd; swapChainDesc.Windowed = true; 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.dx->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.dx, &swapChainDesc, &swapChain)); ReleaseCOMobjMacro(dxgiDevice); ReleaseCOMobjMacro(dxgiAdapter); ReleaseCOMobjMacro(dxgiFactory); // The remaining steps also need to happen each time the window // is resized, so just run the OnResize method Resize(); }
bool CreateDevice( _Outptr_ ID3D11Device** pDevice ) { if ( !pDevice ) return false; *pDevice = nullptr; typedef HRESULT (WINAPI * LPD3D11CREATEDEVICE)( IDXGIAdapter*, D3D_DRIVER_TYPE, HMODULE, UINT32, D3D_FEATURE_LEVEL*, UINT, UINT32, ID3D11Device**, D3D_FEATURE_LEVEL*, ID3D11DeviceContext** ); static LPD3D11CREATEDEVICE s_DynamicD3D11CreateDevice = nullptr; if ( !s_DynamicD3D11CreateDevice ) { HMODULE hModD3D11 = LoadLibrary( L"d3d11.dll" ); if ( !hModD3D11 ) return false; s_DynamicD3D11CreateDevice = ( LPD3D11CREATEDEVICE )GetProcAddress( hModD3D11, "D3D11CreateDevice" ); if ( !s_DynamicD3D11CreateDevice ) return false; } D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, }; UINT createDeviceFlags = 0; #ifdef _DEBUG createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL fl; HRESULT hr = s_DynamicD3D11CreateDevice( nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, createDeviceFlags, featureLevels, _countof(featureLevels), D3D11_SDK_VERSION, pDevice, &fl, nullptr ); if ( SUCCEEDED(hr) ) { if ( fl < D3D_FEATURE_LEVEL_11_0 ) { D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS hwopts; hr = (*pDevice)->CheckFeatureSupport( D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, &hwopts, sizeof(hwopts) ); if ( FAILED(hr) ) memset( &hwopts, 0, sizeof(hwopts) ); if ( !hwopts.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x ) { if ( *pDevice ) { (*pDevice)->Release(); *pDevice = nullptr; } hr = HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED ); } } } if ( SUCCEEDED(hr) ) { IDXGIDevice* dxgiDevice = nullptr; hr = (*pDevice)->QueryInterface( __uuidof( IDXGIDevice ), reinterpret_cast< void** >( &dxgiDevice ) ); if ( SUCCEEDED(hr) ) { IDXGIAdapter* pAdapter = nullptr; hr = dxgiDevice->GetAdapter( &pAdapter ); if ( SUCCEEDED(hr) ) { DXGI_ADAPTER_DESC desc; hr = pAdapter->GetDesc( &desc ); if ( SUCCEEDED(hr) ) { wprintf( L"\n[Using DirectCompute on \"%s\"]\n", desc.Description ); } pAdapter->Release(); } dxgiDevice->Release(); } return true; } else return false; }
bool D3DApp::InitDirect3D() { /* ----------------------------------------- Create the D3D11 Device and DeviceContext ----------------------------------------- */ /* ----------------------- //? D3D11CreateDevice Notes ----------------------- //! Function Signature HRESULT result = D3D11CreateDevice( pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, ppDevice, pFeatureLevel, ppImmediateContext ); //! Parameter Descriptions // The display adapter we want the created device to represent // Notes: Specifying "null" indicates the primary display adapter. //! IDXGIAdapter* pAdapter; // Type of driver our device will represent // Notes: In general, this should always be D3D_DRIVER_TYPE_HARDWARE, unless you need a reference, software, or WARP device. //! D3D_DRIVER_TYPE DriverType; // Software Driver // Notes: This is "null" if using a hardware driver. //! HMODULE Software; // (Optional) Device creation flags // Ex: D3D11_CREATE_DEVICE_DEBUG - Enables the Debug Layer, Direct3D will send debug messages to the VC++ output window. // Ex: D3D11_CREATE_DEVICE_SINGLETHREADED - Improves performance if you guarantee that Direct3D will not be called from multiple threads. //! UINT Flags; // Array of D3D feature levels // Notes: The order indicates the order in which to check for feature level support. // Specifying "null" indicates to choose the greatest feature level supported. //! const D3D_FEATURE_LEVEL* pFeatureLevels; // Size of pFeatureLevels array. // Notes: Specify "0" if you specified "null" for pFeatureLevels. //! UINT FeatureLevels; // Direct3D SDK Version // Notes: While studying this book, always use D3D11_SDK_VERSION. //! UINT SDKVersion; // Returns: Pointer to the device which this function will create //! ID3D11Device** ppDevice; // Returns: The first (highest) supported feature level from pFeatureLevels //! D3D_FEATURE_LEVEL* pFeatureLevel; // Returns: The created device context //! ID3D11DeviceContext** ppImmediateContext; */ UINT CreateDeviceFlags = 0; #if defined(DEBUG) || defined(_DEBUG) CreateDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif D3D_FEATURE_LEVEL FeatureLevel; HRESULT CreateDeviceResult = D3D11CreateDevice( nullptr, mD3DDriverType, nullptr, CreateDeviceFlags, nullptr, 0, D3D11_SDK_VERSION, &mDevice, &FeatureLevel, &mImmediateContext ); if (FAILED(CreateDeviceResult)) { 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 Level Support ----------------------------------- */ HR(mDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, 4, &mMultisampleQuality)); assert(mMultisampleQuality > 0); /* ---------------------------------------------- Describe the characteristics of the swap chain ---------------------------------------------- */ /* -------------------------- //? DXGI_SWAP_CHAIN_DESC Notes -------------------------- //! Structure Signature typedef struct DXGI_SWAP_CHAIN_DESC { DXGI_MODE_DESC BufferDesc; DXGI_SAMPLE_DESC SampleDesc; DXGI_USAGE BufferUsage; UINT BufferCount; HWND OutputWindow; BOOL Windowed; DXGI_SWAP_EFFECT SwapEffect; UINT Flags; } DXGI_SWAP_CHAIN_DESC; //! Member Descriptions // Properties of the back buffer // Notes: The main properties that concern us are the width, height, and pixel format. //! DXGI_MODE_DESC BufferDesc; // Number of multisamples and quality level //! DXGI_SAMPLE_DESC SampleDesc; // Usage of the back buffer // Notes: Specify DXGI_USAGE_RENDER_TARGET_OUTPUT to indicate that the back buffer will be used for rendering. //! DXGI_USAGE BufferUsage; // Number of back buffers in the swap chain // Notes: Use "1" to allocate one back buffer (double buffering) //! UINT BufferCount; // Handle to the window we are rendering to //! HWND OutputWindow; // Notes: "true" indicates windowed-mode, "false" indicates full-screen mode //! BOOL Windowed; // Notes: Specify DXGI_SWAP_EFFECT_DISCARD to let the display driver select the most efficient presentation method //! DXGI_SWAP_EFFECT SwapEffect; // (Optional) flags // Notes: If you use DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH, then when you switch to full-screen mode, the application // will select a display mode that best matches the current back buffer settings. //! UINT Flags; */ DXGI_SWAP_CHAIN_DESC SwapChainDesc; /* -------------------------- //? DXGI_DESC_MODE Notes -------------------------- //! Structure Signature typedef struct DXGI_MODE_DESC { UINT Width; UINT Height; DXGI_RATIONAL RefreshRate; DXGI_FORMAT Format; DXGI_MODE_SCANLINE_ORDER ScanlineOrdering; DXGI_MODE_SCALING Scaling; } DXGI_MODE_DESC; //! Member Descriptions // Window resolution width //! UINT Width; // Window resolution height //! UINT Height; // Refresh rate defined in Hz (Numerator and Denominator) //! DXGI_RATIONAL RefreshRate; // Display format //! DXGI_FORMAT Format; // Scanline Drawing Mode //! DXGI_MODE_SCANLINE_ORDER ScanlineOrdering; // Scaling Mode // Notes: Indicates how an image is stretched to fit the screen resolution. //! DXGI_MODE_SCALING Scaling; */ DXGI_MODE_DESC BackBufferDesc; BackBufferDesc.Width = 800; BackBufferDesc.Height = 600; // Most monitors cannot output more than 24-bit color, so extra precision would be wasted // Even though the monitor cannot output the 8-bit alpha, those bits can be used for other things like effects BackBufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; BackBufferDesc.RefreshRate.Numerator = 60; BackBufferDesc.RefreshRate.Denominator = 1; BackBufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; BackBufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; SwapChainDesc.BufferDesc = BackBufferDesc; if (mEnableMultisample) { SwapChainDesc.SampleDesc.Count = 4; SwapChainDesc.SampleDesc.Quality = mMultisampleQuality - 1; } else { SwapChainDesc.SampleDesc.Count = 1; SwapChainDesc.SampleDesc.Quality = 0; } SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; SwapChainDesc.BufferCount = 1; SwapChainDesc.OutputWindow = mMainWindow; SwapChainDesc.Windowed = true; SwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; SwapChainDesc.Flags = 0; /* --------------------- Create the swap chain --------------------- */ IDXGIDevice* dxgiDevice = 0; mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice); IDXGIAdapter* dxgiAdapter = 0; dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&dxgiAdapter); IDXGIFactory* dxgiFactory = 0; dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgiFactory); dxgiFactory->CreateSwapChain(mDevice, &SwapChainDesc, &mSwapChain); ReleaseCOM(dxgiDevice); ReleaseCOM(dxgiAdapter); ReleaseCOM(dxgiFactory); OnResize(); return true; }
bool D3DClass::Initialize(int screenWidth, int screenHeight, bool vsync, HWND hwnd, bool fullscreen, float screenDepth, float screenNear){ HRESULT hr; float fov, screenAspect; m_vsync_enabled = vsync; m_featureLevel = D3D_FEATURE_LEVEL_11_0; 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 (int driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++){ m_driverType = driverTypes[driverTypeIndex]; hr = D3D11CreateDevice(NULL, m_driverType, NULL, 0, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &m_device, &m_featureLevel, &m_deviceContext); if (hr == E_INVALIDARG){ hr = D3D11CreateDevice(NULL, m_driverType, NULL, 0, &featureLevels[1], numFeatureLevels - 1, D3D11_SDK_VERSION, &m_device, &m_featureLevel, &m_deviceContext); } if (SUCCEEDED(hr)){ break; } } if (FAILED(hr)){ return false; } IDXGIFactory1* factory = 0; IDXGIDevice* device = 0; hr = m_device->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&device)); if (SUCCEEDED(hr)){ IDXGIAdapter* adapter = 0; hr = device->GetAdapter(&adapter); if (SUCCEEDED(hr)){ hr = adapter->GetParent(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&factory)); adapter->Release(); } device->Release(); } if (FAILED(hr)){ return false; } IDXGIFactory2* factory2 = 0; hr = factory->QueryInterface(__uuidof(IDXGIFactory2), reinterpret_cast<void**>(&factory2)); if (factory2){ hr = m_device->QueryInterface(__uuidof(ID3D11Device1), reinterpret_cast<void**>(&m_device1)); if (SUCCEEDED(hr)){ (void)m_deviceContext->QueryInterface(__uuidof(ID3D11DeviceContext1), reinterpret_cast<void**>(&m_deviceContext1)); } DXGI_SWAP_CHAIN_DESC1 sd; ZeroMemory(&sd, sizeof(sd)); sd.Width = screenWidth; sd.Height = screenHeight; 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 = factory2->CreateSwapChainForHwnd(m_device, hwnd, &sd, NULL, NULL, &m_swapChain1); if (SUCCEEDED(hr)){ m_swapChain = NULL; hr = m_swapChain1->QueryInterface(__uuidof(IDXGISwapChain), reinterpret_cast<void**>(&m_swapChain)); } factory2->Release(); } else{ DXGI_SWAP_CHAIN_DESC sd; ZeroMemory(&sd, sizeof(sd)); sd.BufferCount = 1; sd.BufferDesc.Width = screenWidth; sd.BufferDesc.Height = screenHeight; 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 = hwnd; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.Windowed = TRUE; hr = factory->CreateSwapChain(m_device, &sd, &m_swapChain); } factory->MakeWindowAssociation(hwnd, DXGI_MWA_NO_ALT_ENTER); factory->Release(); if (FAILED(hr)){ return false; } ID3D11Texture2D* backBuffer = 0; hr = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&backBuffer)); if (FAILED(hr)){ return false; } hr = m_device->CreateRenderTargetView(backBuffer, NULL, &m_renderTargetView); backBuffer->Release(); if (FAILED(hr)){ return false; } m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, NULL); 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; hr = m_device->CreateTexture2D(&depthBufferDesc, NULL, &m_depthStencilBuffer); if (FAILED(hr)){ return false; } D3D11_DEPTH_STENCIL_DESC depthStencilDesc; 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; 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; 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; hr = m_device->CreateDepthStencilState(&depthStencilDesc, &m_depthStencilState); if (FAILED(hr)){ return false; } m_deviceContext->OMSetDepthStencilState(m_depthStencilState, 1); D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc; ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc)); depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; depthStencilViewDesc.Texture2D.MipSlice = 0; hr = m_device->CreateDepthStencilView(m_depthStencilBuffer, &depthStencilViewDesc, &m_depthStencilView); if (FAILED(hr)){ return false; } m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthStencilView); 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; hr = m_device->CreateRasterizerState(&rasterDesc, &m_rasterState); if (FAILED(hr)){ return false; } m_deviceContext->RSSetState(m_rasterState); D3D11_VIEWPORT viewport; 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); fov = XM_PI / 4.0f; screenAspect = (float)screenWidth / (float)screenHeight; m_projectionMatrix = XMMatrixPerspectiveFovLH(fov, screenAspect, screenNear, screenDepth); m_worldMatrix = XMMatrixIdentity(); m_orthoMatrix = XMMatrixOrthographicLH((float)screenWidth, (float)screenHeight, screenNear, screenDepth); D3D11_DEPTH_STENCIL_DESC depthDisabledStencilDesc; ZeroMemory(&depthDisabledStencilDesc, sizeof(depthDisabledStencilDesc)); 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; hr = m_device->CreateDepthStencilState(&depthDisabledStencilDesc, &m_depthDisabledStencilState); if (FAILED(hr)){ return false; } D3D11_BLEND_DESC blendStateDescription; ZeroMemory(&blendStateDescription, sizeof(D3D11_BLEND_DESC)); blendStateDescription.RenderTarget[0].BlendEnable = TRUE; blendStateDescription.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; 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_INV_DEST_ALPHA; blendStateDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; // blendStateDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE; blendStateDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; blendStateDescription.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; blendStateDescription.RenderTarget[0].RenderTargetWriteMask = 0x0f; hr = m_device->CreateBlendState(&blendStateDescription, &m_alphaEnableBlendingState); if (FAILED(hr)){ return false; } blendStateDescription.RenderTarget[0].BlendEnable = FALSE; hr = m_device->CreateBlendState(&blendStateDescription, &m_alphaDisableBlendingState); if (FAILED(hr)){ return false; } return true; }
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 md3dDriverType, 0, // no software device createDeviceFlags, 0, 0, // default feature level array D3D11_SDK_VERSION, &md3dDevice, &featureLevel, &md3dImmediateContext); 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(md3dDevice->CheckMultisampleQualityLevels( DXGI_FORMAT_R8G8B8A8_UNORM, 4, &m4xMsaaQuality)); assert( m4xMsaaQuality > 0 ); // Fill out a DXGI_SWAP_CHAIN_DESC to describe our swap chain. DXGI_SWAP_CHAIN_DESC sd; ZeroMemory(&sd, sizeof(DXGI_SWAP_CHAIN_DESC)); sd.BufferDesc.Width = mClientWidth; sd.BufferDesc.Height = mClientHeight; sd.Windowed = true; sd.BufferDesc.RefreshRate.Numerator = m_MonitorNumerator; sd.BufferDesc.RefreshRate.Denominator = m_MonitorDenumerator; 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; sd.BufferCount = 1; sd.OutputWindow = mhMainWnd; sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; 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)); //Disable Alt-Enter Sequence 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(); if (mFullScreen){ mSwapChain->SetFullscreenState(true, NULL); } return true; }
//-------------------------------------------------------------------------------------- // 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; 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 ); // Compile the vertex shader ID3DBlob* pVSBlob = nullptr; hr = CompileShaderFromFile( L"Tutorial02.fx", "VS", "vs_4_0", &pVSBlob ); if( FAILED( hr ) ) { MessageBox( nullptr, "The FX file cannot be compiled. Please run this executable from the directory that contains the FX file.", "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 }, }; 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"Tutorial02.fx", "PS", "ps_4_0", &pPSBlob ); if( FAILED( hr ) ) { MessageBox( nullptr, "The FX file cannot be compiled. Please run this executable from the directory that contains the FX file.", "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( 0.0f, 0.5f, 0.5f ), XMFLOAT3( 0.5f, -0.5f, 0.5f ), XMFLOAT3( -0.5f, -0.5f, 0.5f ), }; D3D11_BUFFER_DESC bd; ZeroMemory( &bd, sizeof(bd) ); bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof( SimpleVertex ) * 3; 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 ); // Set primitive topology g_pImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); return S_OK; }
bool D3D11Context::Init(HINSTANCE hInst, HWND wnd, std::string *error_message) { hWnd_ = wnd; LoadD3D11Error result = LoadD3D11(); HRESULT hr = E_FAIL; std::vector<std::string> adapterNames; std::string chosenAdapterName; if (result == LoadD3D11Error::SUCCESS) { std::vector<IDXGIAdapter *> adapters; int chosenAdapter = 0; IDXGIFactory * pFactory = nullptr; ptr_CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&pFactory); IDXGIAdapter *pAdapter; for (UINT i = 0; pFactory->EnumAdapters(i, &pAdapter) != DXGI_ERROR_NOT_FOUND; i++) { adapters.push_back(pAdapter); DXGI_ADAPTER_DESC desc; pAdapter->GetDesc(&desc); std::string str = ConvertWStringToUTF8(desc.Description); adapterNames.push_back(str); if (str == g_Config.sD3D11Device) { chosenAdapter = i; } } chosenAdapterName = adapterNames[chosenAdapter]; hr = CreateTheDevice(adapters[chosenAdapter]); for (int i = 0; i < (int)adapters.size(); i++) { adapters[i]->Release(); } } if (FAILED(hr)) { const char *defaultError = "Your GPU does not appear to support Direct3D 11.\n\nWould you like to try again using Direct3D 9 instead?"; I18NCategory *err = GetI18NCategory("Error"); std::wstring error; if (result == LoadD3D11Error::FAIL_NO_COMPILER) { error = ConvertUTF8ToWString(err->T("D3D11CompilerMissing", "D3DCompiler_47.dll not found. Please install. Or press Yes to try again using Direct3D9 instead.")); } else if (result == LoadD3D11Error::FAIL_NO_D3D11) { error = ConvertUTF8ToWString(err->T("D3D11Missing", "Your operating system version does not include D3D11. Please run Windows Update.\n\nPress Yes to try again using Direct3D9 instead.")); } error = ConvertUTF8ToWString(err->T("D3D11NotSupported", defaultError)); std::wstring title = ConvertUTF8ToWString(err->T("D3D11InitializationError", "Direct3D 11 initialization error")); bool yes = IDYES == MessageBox(hWnd_, error.c_str(), title.c_str(), MB_ICONERROR | MB_YESNO); if (yes) { // Change the config to D3D9 and restart. g_Config.iGPUBackend = (int)GPUBackend::DIRECT3D9; g_Config.sFailedGPUBackends.clear(); g_Config.Save("save_d3d9_fallback"); W32Util::ExitAndRestart(); } return false; } if (FAILED(device_->QueryInterface(__uuidof (ID3D11Device1), (void **)&device1_))) { device1_ = nullptr; } if (FAILED(context_->QueryInterface(__uuidof (ID3D11DeviceContext1), (void **)&context1_))) { context1_ = nullptr; } #ifdef _DEBUG if (SUCCEEDED(device_->QueryInterface(__uuidof(ID3D11Debug), (void**)&d3dDebug_))) { if (SUCCEEDED(d3dDebug_->QueryInterface(__uuidof(ID3D11InfoQueue), (void**)&d3dInfoQueue_))) { d3dInfoQueue_->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true); d3dInfoQueue_->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true); d3dInfoQueue_->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_WARNING, true); } } #endif draw_ = Draw::T3DCreateD3D11Context(device_, context_, device1_, context1_, featureLevel_, hWnd_, adapterNames); SetGPUBackend(GPUBackend::DIRECT3D11, chosenAdapterName); bool success = draw_->CreatePresets(); // If we can run D3D11, there's a compiler installed. I think. _assert_msg_(G3D, success, "Failed to compile preset shaders"); int width; int height; GetRes(hWnd_, width, height); // Obtain DXGI factory from device (since we used nullptr for pAdapter above) IDXGIFactory1* dxgiFactory = nullptr; IDXGIDevice* dxgiDevice = nullptr; IDXGIAdapter* adapter = nullptr; hr = device_->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice)); if (SUCCEEDED(hr)) { hr = dxgiDevice->GetAdapter(&adapter); if (SUCCEEDED(hr)) { hr = adapter->GetParent(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&dxgiFactory)); DXGI_ADAPTER_DESC desc; adapter->GetDesc(&desc); adapter->Release(); } dxgiDevice->Release(); } // 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 = hWnd_; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.Windowed = TRUE; hr = dxgiFactory->CreateSwapChain(device_, &sd, &swapChain_); dxgiFactory->MakeWindowAssociation(hWnd_, DXGI_MWA_NO_ALT_ENTER); dxgiFactory->Release(); GotBackbuffer(); return true; }