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; }
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; }
IDXGIAdapter* GetDXGIAdapterFromD3D11Device(ID3D11Device* device) { IDXGIDevice* dxgiDevice = NULL; CHECK_HR(device->QueryInterface(&dxgiDevice)); IDXGIAdapter* dxgiAdapter = NULL; CHECK_HR(dxgiDevice->GetAdapter(&dxgiAdapter)); SafeRelease(dxgiDevice); return dxgiAdapter; }
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; }
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 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 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; }
void RenderContext::Init(pWindow inWindow) { CleanUp(); HWND hWnd = inWindow->mHWnd; D3D_DRIVER_TYPE driver_type = D3D_DRIVER_TYPE_NULL; D3D_FEATURE_LEVEL feature_level = D3D_FEATURE_LEVEL_11_0; HRESULT hr = S_OK; RECT rc; GetClientRect(hWnd, &rc); mWidth = rc.right - rc.left; mHeight = rc.bottom - rc.top; UINT createDeviceFlags = 0; #ifdef _DEBUG createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; createDeviceFlags |= D3D11_CREATE_DEVICE_DISABLE_GPU_TIMEOUT; #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++) { driver_type = driverTypes[driverTypeIndex]; hr = D3D11CreateDevice(nullptr, driver_type, nullptr, createDeviceFlags, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &mD3DDevice, &feature_level, &mImmediateContext); if (hr == E_INVALIDARG) { hr = D3D11CreateDevice(nullptr, driver_type, nullptr, createDeviceFlags, &featureLevels[1], numFeatureLevels - 1, D3D11_SDK_VERSION, &mD3DDevice, &feature_level, &mImmediateContext); } if (SUCCEEDED(hr)) break; } if (FAILED(hr)) { exit(hr); } // Obtain DXGI factory from device (since we used nullptr for pAdapter above) IDXGIFactory1* dxgiFactory = nullptr; { IDXGIDevice* dxgiDevice = nullptr; hr = mD3DDevice->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)) { exit(hr); } // Create swap chain IDXGIFactory2* dxgiFactory2 = nullptr; hr = dxgiFactory->QueryInterface(__uuidof(IDXGIFactory2), reinterpret_cast<void**>(&dxgiFactory2)); if (dxgiFactory2) { // DirectX 11.1 or later hr = mD3DDevice->QueryInterface(__uuidof(ID3D11Device1), reinterpret_cast<void**>(&mD3DDevice1)); if (SUCCEEDED(hr)) { (void)mImmediateContext->QueryInterface(__uuidof(ID3D11DeviceContext1), reinterpret_cast<void**>(&mImmediateContext1)); } DXGI_SWAP_CHAIN_DESC1 sd; ZeroMemory(&sd, sizeof(sd)); sd.Width = mWidth; sd.Height = mHeight; sd.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_UNORDERED_ACCESS; sd.BufferCount = 1; hr = dxgiFactory2->CreateSwapChainForHwnd(mD3DDevice, hWnd, &sd, nullptr, nullptr, &mSwapChain1); if (SUCCEEDED(hr)) { hr = mSwapChain1->QueryInterface(__uuidof(IDXGISwapChain), reinterpret_cast<void**>(&mSwapChain)); } dxgiFactory2->Release(); } else { // DirectX 11.0 systems DXGI_SWAP_CHAIN_DESC sd; ZeroMemory(&sd, sizeof(sd)); sd.BufferCount = 1; sd.BufferDesc.Width = mWidth; sd.BufferDesc.Height = mHeight; sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; sd.BufferDesc.RefreshRate.Numerator = 60; sd.BufferDesc.RefreshRate.Denominator = 1; sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_UNORDERED_ACCESS; sd.OutputWindow = hWnd; sd.SampleDesc.Count = 1; sd.SampleDesc.Quality = 0; sd.Windowed = TRUE; hr = dxgiFactory->CreateSwapChain(mD3DDevice, &sd, &mSwapChain); } // Note this tutorial doesn't handle full-screen swapchains so we block the ALT+ENTER shortcut dxgiFactory->MakeWindowAssociation(hWnd, DXGI_MWA_NO_ALT_ENTER); dxgiFactory->Release(); if (FAILED(hr)) { exit(hr); } // Create a render target view ID3D11Texture2D* pBackBuffer = nullptr; hr = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&pBackBuffer)); if (FAILED(hr)) { exit(hr); } mBackBuffer = MAKE_NEW(Texture); mBackBuffer->Init(pBackBuffer); mOutputRenderTarget = MAKE_NEW(RenderTarget); mOutputRenderTarget->Init(mBackBuffer); // setup rasterizer SetRasterizerState(FILL_SOLID, CULL_BACK, true, 0, 0.0f, 0.0f, true, false, false, false); D3D11_DEPTH_STENCIL_DESC dsDesc; dsDesc.DepthEnable = true; dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; dsDesc.DepthFunc = D3D11_COMPARISON_LESS; dsDesc.StencilEnable = false; dsDesc.StencilReadMask = 0xFF; dsDesc.StencilWriteMask = 0xFF; 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 ID3D11DepthStencilState * pDSState; mD3DDevice->CreateDepthStencilState(&dsDesc, &pDSState); mImmediateContext->OMSetDepthStencilState(pDSState, 1); // Setup the viewport SetViewport(int2(mWidth, mHeight), 0.0f, 1.0f, int2(0, 0)); hr = mImmediateContext->QueryInterface(__uuidof(mAnnotation), reinterpret_cast<void**>(&mAnnotation)); if (FAILED(hr)) { exit(hr); } mInitialized = true; }
//-------------------------------------------------------------------------- int CGraphicsLayer::CreateDeviceAndSwapChain() { HRESULT r=0; //adapter m_D3D11Adapter = NULL; //HRESULT hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)(&m_DXGIFactory) ); //hr=m_DXGIFactory->MakeWindowAssociation( NULL, 0 ); //device parameters DXGI_SWAP_CHAIN_DESC swapDesc; ZeroMemory(&swapDesc,sizeof(swapDesc)); //one back buffer swapDesc.BufferCount=1; //width and height of back buffer swapDesc.BufferDesc.Width=m_rcScreenRect.right; swapDesc.BufferDesc.Height=m_rcScreenRect.bottom; swapDesc.BufferDesc.Format=DXGI_FORMAT_R8G8B8A8_UNORM; //60hz refresh swapDesc.BufferDesc.RefreshRate.Numerator=60; swapDesc.BufferDesc.RefreshRate.Denominator=1; swapDesc.BufferUsage=DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_UNORDERED_ACCESS; swapDesc.OutputWindow=m_hWnd; swapDesc.SampleDesc.Count=1; swapDesc.SampleDesc.Quality=0; swapDesc.Windowed=TRUE; D3D_FEATURE_LEVEL FeatureLevel = D3D_FEATURE_LEVEL_11_0; D3D_FEATURE_LEVEL FeatureLevels[] = { 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 NumFeatureLevels = ARRAYSIZE( FeatureLevels ); //use ref //FeatureLevels[0] = D3D_FEATURE_LEVEL_11_0; // NumFeatureLevels = 1; if(D3D11CreateDeviceAndSwapChain( m_D3D11Adapter, D3D_DRIVER_TYPE_HARDWARE, //D3D_DRIVER_TYPE_REFERENCE, ( HMODULE )0, D3D11_CREATE_DEVICE_DEBUG, FeatureLevels, NumFeatureLevels, D3D11_SDK_VERSION, &swapDesc, &m_pSwapChain, &m_pDevice, &FeatureLevel, &m_pDeviceContext )!=S_OK) { MessageBox(m_hWnd, TEXT("Failed Create Device"), TEXT("Init Failure"), MB_OK | MB_ICONERROR); } IDXGIDevice* pDXGIDev = NULL; r = m_pDevice->QueryInterface( __uuidof( IDXGIDevice ), ( LPVOID* )&pDXGIDev ); if( SUCCEEDED( r ) && pDXGIDev ) { pDXGIDev->GetAdapter( &m_D3D11Adapter ); } //GET BACK BUFFER if(m_pSwapChain->GetBuffer(0,__uuidof(ID3D11Texture2D),(LPVOID*)&m_pBackBuffer)!=S_OK){return 1;} if(m_pDevice->CreateRenderTargetView(m_pBackBuffer,NULL,&m_pRenderTargetView)!=S_OK){return 1;} return 0; }
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; }
//-------------------------------------------------------------------------------------- // 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; }
//-------------------------------------------------------------------------------------- // 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; }
//-------------------------------------------------------------------------------------- // 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"Tutorial07.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 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_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"Tutorial07.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 ), 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 ) }, { XMFLOAT3( -1.0f, -1.0f, -1.0f ), XMFLOAT2( 0.0f, 0.0f ) }, { XMFLOAT3( 1.0f, -1.0f, -1.0f ), XMFLOAT2( 1.0f, 0.0f ) }, { XMFLOAT3( 1.0f, -1.0f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) }, { XMFLOAT3( -1.0f, -1.0f, 1.0f ), XMFLOAT2( 0.0f, 1.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 ) }, { 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( 1.0f, 1.0f ) }, { XMFLOAT3( 1.0f, -1.0f, -1.0f ), XMFLOAT2( 0.0f, 1.0f ) }, { XMFLOAT3( 1.0f, 1.0f, -1.0f ), XMFLOAT2( 0.0f, 0.0f ) }, { XMFLOAT3( 1.0f, 1.0f, 1.0f ), XMFLOAT2( 1.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 ) }, { 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( 1.0f, 1.0f ) }, { XMFLOAT3( 1.0f, -1.0f, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) }, { XMFLOAT3( 1.0f, 1.0f, 1.0f ), XMFLOAT2( 0.0f, 0.0f ) }, { XMFLOAT3( -1.0f, 1.0f, 1.0f ), XMFLOAT2( 1.0f, 0.0f ) }, }; D3D11_BUFFER_DESC bd; ZeroMemory( &bd, sizeof(bd) ); bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof( SimpleVertex ) * 24; 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 // Create vertex buffer WORD indices[] = { 3,1,0, 2,1,3, 6,4,5, 7,4,6, 11,9,8, 10,9,11, 14,12,13, 15,12,14, 19,17,16, 18,17,19, 22,20,21, 23,20,22 }; bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof( WORD ) * 36; 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 buffers bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof(CBNeverChanges); bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; bd.CPUAccessFlags = 0; hr = g_pd3dDevice->CreateBuffer( &bd, nullptr, &g_pCBNeverChanges ); if( FAILED( hr ) ) return hr; bd.ByteWidth = sizeof(CBChangeOnResize); hr = g_pd3dDevice->CreateBuffer( &bd, nullptr, &g_pCBChangeOnResize ); if( FAILED( hr ) ) return hr; bd.ByteWidth = sizeof(CBChangesEveryFrame); hr = g_pd3dDevice->CreateBuffer( &bd, nullptr, &g_pCBChangesEveryFrame ); if( FAILED( hr ) ) return hr; // Load the Texture hr = CreateDDSTextureFromFile( g_pd3dDevice, L"seafloor.dds", nullptr, &g_pTextureRV ); if( FAILED( hr ) ) return hr; // Create the sample state 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; hr = g_pd3dDevice->CreateSamplerState( &sampDesc, &g_pSamplerLinear ); if( FAILED( hr ) ) return hr; // Initialize the world matrices g_World = XMMatrixIdentity(); // Initialize the view matrix XMVECTOR Eye = XMVectorSet( 0.0f, 3.0f, -6.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 ); CBNeverChanges cbNeverChanges; cbNeverChanges.mView = XMMatrixTranspose( g_View ); g_pImmediateContext->UpdateSubresource( g_pCBNeverChanges, 0, nullptr, &cbNeverChanges, 0, 0 ); // Initialize the projection matrix g_Projection = XMMatrixPerspectiveFovLH( XM_PIDIV4, width / (FLOAT)height, 0.01f, 100.0f ); CBChangeOnResize cbChangesOnResize; cbChangesOnResize.mProjection = XMMatrixTranspose( g_Projection ); g_pImmediateContext->UpdateSubresource( g_pCBChangeOnResize, 0, nullptr, &cbChangesOnResize, 0, 0 ); #ifdef USE_OPENVR // OpenVR. // Loading the SteamVR Runtime vr::EVRInitError eError = vr::VRInitError_None; openvr_system_ = vr::VR_Init(&eError, vr::VRApplication_Scene); if (eError != vr::VRInitError_None) { openvr_system_ = nullptr; ShowMessageBoxAndExit("Unable to init VR runtime: %s", vr::VR_GetVRInitErrorAsEnglishDescription(eError)); } if (!vr::VRCompositor()) { ShowMessageBoxAndExit("Failed to obtain compositor."); } #endif return S_OK; }
//-------------------------------------------------------------------------------------- // 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 ); // } }
//[-------------------------------------------------------] //[ Public methods ] //[-------------------------------------------------------] 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 DXGI factory instance IDXGIFactory1 *dxgiFactory1 = nullptr; { IDXGIDevice *dxgiDevice = nullptr; IDXGIAdapter *dxgiAdapter = nullptr; d3d11Device->QueryInterface(IID_PPV_ARGS(&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 = {}; 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); // 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); // Release our DXGI factory dxgiFactory1->Release(); // 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 }
//-------------------------------------------------------------------------------------- // 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; }
//-------------------------------------------------------------------------------------- // Create any D3D11 resources that aren't dependant on the back buffer //-------------------------------------------------------------------------------------- HRESULT CALLBACK OnD3D11CreateDevice( ID3D11Device* pd3dDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ) { DXUT_SetDebugName( pd3dDevice, "Main Device" ); HRESULT hr; ID3D11DeviceContext* pd3dImmediateContext = DXUTGetD3D11DeviceContext(); V_RETURN( g_DialogResourceManager.OnD3D11CreateDevice( pd3dDevice, pd3dImmediateContext ) ); V_RETURN( g_SettingsDlg.OnD3D11CreateDevice( pd3dDevice ) ); g_pTxtHelper = new CDXUTTextHelper( pd3dDevice, pd3dImmediateContext, &g_DialogResourceManager, 15 ); IDXGIDevice* pDXGIDevice; hr = pd3dDevice->QueryInterface( __uuidof(IDXGIDevice), (VOID**)&pDXGIDevice ); if( SUCCEEDED(hr) ) { IDXGIAdapter* pAdapter; hr = pDXGIDevice->GetAdapter( &pAdapter ); if( SUCCEEDED(hr) ) { DXGI_ADAPTER_DESC AdapterDesc; pAdapter->GetDesc( &AdapterDesc ); SetAdapterInfoForShaderCompilation( AdapterDesc.Description ); SAFE_RELEASE( pAdapter ); } SAFE_RELEASE( pDXGIDevice ); } ID3D10Blob* pVSBlob = NULL; g_pVSTransform = CompileVertexShader( pd3dDevice, L"SceneRender.hlsl", "VSTransform", &pVSBlob ); g_pPSSceneRender = CompilePixelShader( pd3dDevice, L"SceneRender.hlsl", "PSSceneRender" ); g_pPSSceneRenderArray = CompilePixelShader( pd3dDevice, L"SceneRender.hlsl", "PSSceneRenderArray" ); g_pPSSceneRenderQuilt = CompilePixelShader( pd3dDevice, L"SceneRender.hlsl", "PSSceneRenderQuilt" ); // Create a layout for the object data const D3D11_INPUT_ELEMENT_DESC layout[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; V_RETURN( pd3dDevice->CreateInputLayout( layout, ARRAYSIZE( layout ), pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &g_pDefaultInputLayout ) ); // No longer need the shader blobs SAFE_RELEASE( pVSBlob ); // Create state objects D3D11_SAMPLER_DESC samDesc; ZeroMemory( &samDesc, sizeof(samDesc) ); samDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; samDesc.AddressU = samDesc.AddressV = samDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; samDesc.MaxAnisotropy = 1; samDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; samDesc.MaxLOD = D3D11_FLOAT32_MAX; V_RETURN( pd3dDevice->CreateSamplerState( &samDesc, &g_pSamLinear ) ); DXUT_SetDebugName( g_pSamLinear, "Linear" ); D3D11_BLEND_DESC BlendDesc; ZeroMemory( &BlendDesc, sizeof( D3D11_BLEND_DESC ) ); BlendDesc.RenderTarget[0].BlendEnable = FALSE; BlendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; BlendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; BlendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; BlendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA; BlendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; BlendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; BlendDesc.RenderTarget[0].RenderTargetWriteMask = D3D10_COLOR_WRITE_ENABLE_ALL; hr = pd3dDevice->CreateBlendState( &BlendDesc, &g_pBlendState ); ASSERT( SUCCEEDED(hr) ); D3D11_DEPTH_STENCIL_DESC DSDesc; ZeroMemory( &DSDesc, sizeof(D3D11_DEPTH_STENCIL_DESC) ); DSDesc.DepthEnable = FALSE; DSDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; DSDesc.DepthFunc = D3D11_COMPARISON_LESS; DSDesc.StencilEnable = FALSE; DSDesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; DSDesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; hr = pd3dDevice->CreateDepthStencilState( &DSDesc, &g_pDepthStencilState ); ASSERT( SUCCEEDED(hr) ); D3D11_RASTERIZER_DESC RSDesc; ZeroMemory( &RSDesc, sizeof(RSDesc) ); RSDesc.AntialiasedLineEnable = FALSE; RSDesc.CullMode = D3D11_CULL_BACK; RSDesc.DepthBias = 0; RSDesc.DepthBiasClamp = 0.0f; RSDesc.DepthClipEnable = TRUE; RSDesc.FillMode = D3D11_FILL_SOLID; RSDesc.FrontCounterClockwise = FALSE; RSDesc.MultisampleEnable = TRUE; RSDesc.ScissorEnable = FALSE; RSDesc.SlopeScaledDepthBias = 0.0f; hr = pd3dDevice->CreateRasterizerState( &RSDesc, &g_pRasterizerState ); ASSERT( SUCCEEDED(hr) ); g_pcbVSPerObject11 = CreateConstantBuffer( pd3dDevice, sizeof(CB_VS_PER_OBJECT) ); DXUT_SetDebugName( g_pcbVSPerObject11, "CB_VS_PER_OBJECT" ); // Create other render resources here D3D11_TILED_EMULATION_PARAMETERS EmulationParams; EmulationParams.DefaultPhysicalTileFormat = DXGI_FORMAT_R8G8B8A8_UNORM; EmulationParams.MaxPhysicalTileCount = 1000; D3D11CreateTiledResourceDevice( pd3dDevice, pd3dImmediateContext, &EmulationParams, &g_pd3dDeviceEx ); g_pd3dDeviceEx->CreateTilePool( &g_pTilePool ); g_pTitleResidencyManager = new TitleResidencyManager( pd3dDevice, pd3dImmediateContext, 1, EmulationParams.MaxPhysicalTileCount, g_pTilePool ); ResidencySampleRender::Initialize( pd3dDevice ); g_PageDebugRender.Initialize( pd3dDevice ); CreateSceneGeometry( pd3dDevice ); // Setup the camera's view parameters XMMATRIX matProjection = XMMatrixPerspectiveFovLH( XM_PIDIV4, (FLOAT)pBackBufferSurfaceDesc->Width / (FLOAT)pBackBufferSurfaceDesc->Height, 0.001f, 100.0f ); XMStoreFloat4x4A( &g_matProjection, matProjection ); UpdateViewMatrix(); g_pTitleResidencyManager->StartThreads(); return S_OK; }