Example #1
0
    void MFPlayer::init(const OTextureRef& pRenderTarget)
    {
        m_pRenderTarget = pRenderTarget;
        auto pRendererD3D11 = std::dynamic_pointer_cast<ORendererD3D11>(oRenderer);

        HRESULT ret;

        // Initialize M$ bullshit
        //ret = CoInitializeEx(NULL, COINIT_MULTITHREADED);
        //assert(ret == S_OK);
        ret = MFStartup(MF_VERSION);
        assert(ret == S_OK);

        // Create factory
        IMFMediaEngineClassFactory *pMediaEngineClassFactory = nullptr;
        ret = CoCreateInstance(CLSID_MFMediaEngineClassFactory, nullptr, CLSCTX_ALL, IID_PPV_ARGS(&pMediaEngineClassFactory));
        assert(ret == S_OK);

        // Create notify
        m_pPlayerNodify = new MFPlayerNotify(shared_from_this());

        // Create attributes
        IMFAttributes *pAttributes = nullptr;
        ret = MFCreateAttributes(&pAttributes, 1);
        assert(ret == S_OK);
        ret = pAttributes->SetUnknown(MF_MEDIA_ENGINE_CALLBACK, m_pPlayerNodify);
        assert(ret == S_OK);

        ID3D10Multithread *pMultithread = nullptr;
        ID3D11Device *pDevice = pRendererD3D11->getDevice();
        ret = pDevice->QueryInterface(IID_PPV_ARGS(&pMultithread));
        assert(ret == S_OK);
        pMultithread->SetMultithreadProtected(TRUE);
        pMultithread->Release();

        UINT resetToken = 0;
        ret = MFCreateDXGIDeviceManager(&resetToken, &m_pDXGIManager);
        assert(ret == S_OK);
        ret = m_pDXGIManager->ResetDevice(pRendererD3D11->getDevice(), resetToken);
        assert(ret == S_OK);
        ret = pAttributes->SetUnknown(MF_MEDIA_ENGINE_DXGI_MANAGER, m_pDXGIManager);
        assert(ret == S_OK);

        ret = pAttributes->SetUINT32(MF_MEDIA_ENGINE_VIDEO_OUTPUT_FORMAT, DXGI_FORMAT_R8G8B8A8_UNORM);
        assert(ret == S_OK);

        // Create player
        ret = pMediaEngineClassFactory->CreateInstance(MF_MEDIA_ENGINE_WAITFORSTABLE_STATE, pAttributes, &m_pMediaEngine);
        assert(ret == S_OK);

        // Release bullshits
        pAttributes->Release();
        pMediaEngineClassFactory->Release();
    }
HRESULT CreateDX11Device(_Out_ ID3D11Device** ppDevice, _Out_ ID3D11DeviceContext** ppDeviceContext, _Out_ D3D_FEATURE_LEVEL* pFeatureLevel )
{
    HRESULT hr = S_OK;
    static const D3D_FEATURE_LEVEL levels[] = {
        D3D_FEATURE_LEVEL_11_1,
        D3D_FEATURE_LEVEL_11_0,  
        D3D_FEATURE_LEVEL_10_1,
        D3D_FEATURE_LEVEL_10_0,
        D3D_FEATURE_LEVEL_9_3,
        D3D_FEATURE_LEVEL_9_2,
        D3D_FEATURE_LEVEL_9_1
    };

    
    hr = D3D11CreateDevice(
        nullptr,
        D3D_DRIVER_TYPE_HARDWARE,
        nullptr,
        D3D11_CREATE_DEVICE_VIDEO_SUPPORT,
        levels,
        ARRAYSIZE(levels),
        D3D11_SDK_VERSION,
        ppDevice,
        pFeatureLevel,
        ppDeviceContext
        );
    
    if(SUCCEEDED(hr))
    {
        ID3D10Multithread* pMultithread;
        hr =  ((*ppDevice)->QueryInterface(IID_PPV_ARGS(&pMultithread)));

        if(SUCCEEDED(hr))
        {
            pMultithread->SetMultithreadProtected(TRUE);
        }

        SafeRelease(&pMultithread);
        
    }

    return hr;
}
bool AngelCore::AngelSubSystem::RenderManager::CreateDevice()
{
	HRESULT hr;

	hr = CreateDXGIFactory(__uuidof(IDXGIFactory2), (void**)(&this->m_dxgiFactory));

	AngelSubSystemResources::GraphicDeviceResources::GetDXGIFactory() = this->m_dxgiFactory;
	if (FAILED(hr))
	{
		AngelCore::AngelSubSystem::AngelLog::WriteErrorMessage("Failed Creating DXGIFactory");
		return false;
	}

	AngelCore::AngelSubSystem::AngelLog::WriteLogMessage("++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
	AngelCore::AngelSubSystem::AngelLog::WriteLogMessage("++++++++++++ Graphics devices Info Started +++++++++++++");

	Microsoft::WRL::ComPtr<IDXGIAdapter> _adapter = nullptr;
	for (int i = 0; DXGI_ERROR_NOT_FOUND != this->m_dxgiFactory->EnumAdapters(i, &_adapter); ++i)
	{
		DXGI_ADAPTER_DESC adapterDesc = { 0 };
		auto hr = _adapter->GetDesc(&adapterDesc);

		if (hr != S_OK)
		{
			AngelCore::AngelSubSystem::AngelLog::WriteErrorMessage("Failed Getting Graphic Adaptor");
		}

		std::wstring adaptorName = adapterDesc.Description;
		std::string sAdaptorName(adaptorName.begin(), adaptorName.end());
		AngelCore::AngelSubSystem::AngelLog::WriteLogMessage("++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
		AngelCore::AngelSubSystem::AngelLog::WriteLogMessage(std::string("DeviceId : " + std::to_string(adapterDesc.DeviceId)).c_str());
		AngelCore::AngelSubSystem::AngelLog::WriteLogMessage(std::string("DedicatedSystemMemory : " + std::to_string(adapterDesc.DedicatedSystemMemory)).c_str());
		AngelCore::AngelSubSystem::AngelLog::WriteLogMessage(std::string("DedicatedVideoMemory : " + std::to_string(adapterDesc.DedicatedVideoMemory)).c_str());
		AngelCore::AngelSubSystem::AngelLog::WriteLogMessage(std::string("VideoCard : " + sAdaptorName).c_str());
		AngelCore::AngelSubSystem::AngelLog::WriteLogMessage(std::string("VendorId : " + std::to_string(adapterDesc.VendorId)).c_str());
		AngelCore::AngelSubSystem::AngelLog::WriteLogMessage(std::string("SubSysId : " + std::to_string(adapterDesc.SubSysId)).c_str());

		if (adapterDesc.DeviceId == 140)
		{
			AngelCore::AngelSubSystem::AngelLog::WriteLogMessage("Microsoft Basic Render Driver skipped");
			AngelCore::AngelSubSystem::AngelLog::WriteLogMessage("Finished Graphic Device.\n");
			AngelCore::AngelSubSystem::AngelLog::WriteLogMessage("++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n");
		}
		else
		{

			AngelSubSystemResources::GraphicDeviceResources::GetDXGIAdaptor() = _adapter;
			Microsoft::WRL::ComPtr<ID3D11Device>  device11;
			Microsoft::WRL::ComPtr<ID3D11DeviceContext> deviceContext11;


			UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;

#if defined(DEBUG) | defined(_DEBUG)
			creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

			D3D_FEATURE_LEVEL featureLevels[] =
			{
				D3D_FEATURE_LEVEL_11_1,
				D3D_FEATURE_LEVEL_11_0,
				D3D_FEATURE_LEVEL_10_1,
				D3D_FEATURE_LEVEL_10_0,
				D3D_FEATURE_LEVEL_9_3,
				D3D_FEATURE_LEVEL_9_2,
				D3D_FEATURE_LEVEL_9_1
			};

			HR(D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, creationFlags,
				featureLevels, ARRAYSIZE(featureLevels), D3D11_SDK_VERSION, &device11, &this->m_suppurtedFeatureLevel,
				&deviceContext11));

			AngelSubSystemResources::GraphicDeviceResources::SetSupportedFeatureLevel(this->m_suppurtedFeatureLevel);

			switch (this->m_suppurtedFeatureLevel)
			{
			case D3D_FEATURE_LEVEL_10_0:
				AngelCore::AngelSubSystem::AngelLog::WriteLogMessage("Feature Level Supporeted 10_0");
				break;
			case D3D_FEATURE_LEVEL_10_1:
				AngelCore::AngelSubSystem::AngelLog::WriteLogMessage("Feature Level Supporeted 10_1");
				break;
			case D3D_FEATURE_LEVEL_11_0:
				AngelCore::AngelSubSystem::AngelLog::WriteLogMessage("Feature Level Supporeted 11_0");
				break;
			case D3D_FEATURE_LEVEL_11_1:
				AngelCore::AngelSubSystem::AngelLog::WriteLogMessage("Feature Level Supporeted 11_1");
				break;
			case D3D_FEATURE_LEVEL_9_1:
				AngelCore::AngelSubSystem::AngelLog::WriteLogMessage("Feature Level Supporeted 9_1");
				break;
			case D3D_FEATURE_LEVEL_9_2:
				AngelCore::AngelSubSystem::AngelLog::WriteLogMessage("Feature Level Supporeted 9_2");
				break;
			case D3D_FEATURE_LEVEL_9_3:
				AngelCore::AngelSubSystem::AngelLog::WriteLogMessage("Feature Level Supporeted 9_3");
				break;
			}


			HR(device11.As(&AngelSubSystemResources::GraphicDeviceResources::Device));
			HR(deviceContext11.As(&AngelSubSystemResources::GraphicDeviceResources::DeviceContext));

			COM_RELEASE(device11);
			COM_RELEASE(deviceContext11);
			ID3D10Multithread *multiThread;
			HR(AngelSubSystemResources::GraphicDeviceResources::Device.Get()->
				QueryInterface(__uuidof(ID3D10Multithread),(LPVOID*)&multiThread));

			multiThread->SetMultithreadProtected(true);
			
			UINT sampleLevel = 0;
			UINT sampleCount = AngelSubSystemResources::GraphicDeviceResources::GetSampleCount(); // You set this
			HR(AngelSubSystemResources::GraphicDeviceResources::Device->
				CheckMultisampleQualityLevels(DXGI_FORMAT_B8G8R8A8_UNORM
				, sampleCount, &sampleLevel));

			DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 };

			swapChainDesc.Width = AngelCore::AngelSubSystemResources::WindowProperties::GetWidth(); // Match the size of the window.
			swapChainDesc.Height = AngelCore::AngelSubSystemResources::WindowProperties::GetHeight();
			swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // This is the most common swap chain format.
			swapChainDesc.Stereo = m_dxgiFactory->IsWindowedStereoEnabled();;
			swapChainDesc.SampleDesc.Count = sampleCount; // Don't use multi-sampling.
			swapChainDesc.SampleDesc.Quality = sampleLevel - 1;
			swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
			swapChainDesc.BufferCount = 2; // Use double-buffering to minimize latency.
			swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT::DXGI_SWAP_EFFECT_DISCARD; // All Windows Store apps must use this SwapEffect.
			swapChainDesc.Flags = 0;
			swapChainDesc.Scaling = DXGI_SCALING::DXGI_SCALING_STRETCH;
			swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;

			DXGI_SWAP_CHAIN_FULLSCREEN_DESC fullscreen;
			fullscreen.RefreshRate.Numerator = 0;
			fullscreen.RefreshRate.Denominator = 1;
			fullscreen.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
			fullscreen.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE;

			HR(this->m_dxgiFactory->CreateSwapChainForHwnd
				(AngelCore::AngelSubSystemResources::GraphicDeviceResources::Device.Get()
					, AngelCore::AngelSubSystemResources::WindowProperties::GetHWND(),
					&swapChainDesc
					,&fullscreen,
					nullptr,
					&AngelCore::AngelSubSystemResources::GraphicDeviceResources::SwapChain));

			Microsoft::WRL::ComPtr<ID3D11Texture2D> backBuffer;

			HR(AngelCore::AngelSubSystemResources::GraphicDeviceResources::SwapChain->
				GetBuffer(0, IID_PPV_ARGS(&backBuffer)));

			HR(AngelCore::AngelSubSystemResources::GraphicDeviceResources::Device->
				CreateRenderTargetView(backBuffer.Get()
				, nullptr
				,
				&AngelCore::AngelSubSystemResources::GraphicDeviceResources::RenderTargetView));

			COM_RELEASE(backBuffer);

			AngelCore::AngelSubSystem::AngelLog::WriteLogMessage("Finished Graphic Device.\n");
			AngelCore::AngelSubSystem::AngelLog::WriteLogMessage("++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n");

			Microsoft::WRL::ComPtr<ID3D11Texture2D> dephtTexture;
			D3D11_TEXTURE2D_DESC desc;
			desc.ArraySize = 1;
			desc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
			desc.CPUAccessFlags = 0;
			desc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
			desc.Height = AngelSubSystemResources::WindowProperties::GetHeight();
			desc.MipLevels = 1;
			desc.MiscFlags = 0;
			desc.SampleDesc.Count = sampleCount;
			desc.SampleDesc.Quality = sampleLevel-1;
			desc.Usage = D3D11_USAGE_DEFAULT;
			desc.Width = AngelSubSystemResources::WindowProperties::GetWidth();

			HR(AngelSubSystemResources::GraphicDeviceResources::Device->CreateTexture2D
				(&desc, nullptr, dephtTexture.GetAddressOf()));

			HR(AngelCore::AngelSubSystemResources::GraphicDeviceResources::Device->CreateDepthStencilView(dephtTexture.Get(),
				nullptr, AngelSubSystemResources::GraphicDeviceResources::DepthStencilView.GetAddressOf()));

			COM_RELEASE(dephtTexture);

			D3D11_VIEWPORT view;
			view.Height = static_cast<FLOAT>(AngelSubSystemResources::WindowProperties::GetHeight());
			view.Width = static_cast<FLOAT>(AngelSubSystemResources::WindowProperties::GetWidth());
			view.MaxDepth = 1.0f;
			view.MinDepth = 0.0f;
			view.TopLeftX = 0.0f;
			view.TopLeftY = 0.0f;

			AngelSubSystemResources::GraphicDeviceResources::DeviceContext->RSSetViewports(1, &view);

		}
	}

	AngelCore::AngelSubSystem::AngelLog::WriteLogMessage("++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
	AngelCore::AngelSubSystem::AngelLog::WriteLogMessage("+++++++++++ Graphics devices Info Finished +++++++++++++");
	AngelCore::AngelSubSystem::AngelLog::WriteLogMessage("++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n");


	Texture2D::CreateSampler(
		D3D11_FILTER_ANISOTROPIC,
		D3D11_TEXTURE_ADDRESS_WRAP
		, D3D11_TEXTURE_ADDRESS_WRAP
		, D3D11_TEXTURE_ADDRESS_WRAP, 
		D3D11_COMPARISON_NEVER);

	Texture2D::CreateSampler(D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR,
		D3D11_TEXTURE_ADDRESS_CLAMP
		, D3D11_TEXTURE_ADDRESS_CLAMP
		,D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_COMPARISON_NEVER);

	Texture2D::CreateSampler(D3D11_FILTER_ANISOTROPIC,
		D3D11_TEXTURE_ADDRESS_WRAP,
		D3D11_TEXTURE_ADDRESS_WRAP,
		D3D11_TEXTURE_ADDRESS_WRAP, D3D11_COMPARISON_ALWAYS);

	Texture2D::CreateSampler(D3D11_FILTER_MIN_MAG_MIP_LINEAR,
		D3D11_TEXTURE_ADDRESS_WRAP,
		D3D11_TEXTURE_ADDRESS_WRAP,
		D3D11_TEXTURE_ADDRESS_WRAP, D3D11_COMPARISON_NEVER);

	Texture2D::CreateSampler(D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR, 
		D3D11_TEXTURE_ADDRESS_CLAMP
		, D3D11_TEXTURE_ADDRESS_CLAMP,
		D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_COMPARISON_LESS);

	D3D11_RASTERIZER_DESC SolidDesc;
	ZeroMemory(&SolidDesc, sizeof(D3D11_RASTERIZER_DESC));
	SolidDesc.FillMode = D3D11_FILL_SOLID;
	SolidDesc.CullMode = D3D11_CULL_NONE;
	//SolidDesc.FrontCounterClockwise = false;
	//SolidDesc.DepthClipEnable = true;
	//SolidDesc.AntialiasedLineEnable = false;
	//SolidDesc.MultisampleEnable = true;

	HR(AngelCore::AngelSubSystemResources::GraphicDeviceResources::Device->CreateRasterizerState(&SolidDesc,
		AngelSubSystemResources::GraphicDeviceResources::SolidRasterizer.GetAddressOf()));

	D3D11_RASTERIZER_DESC wireFrameDesc;
	ZeroMemory(&wireFrameDesc, sizeof(D3D11_RASTERIZER_DESC));
	wireFrameDesc.FillMode = D3D11_FILL_WIREFRAME;
	wireFrameDesc.CullMode = D3D11_CULL_NONE;
	//wireFrameDesc.FrontCounterClockwise = false;
	//wireFrameDesc.DepthClipEnable = true;
	//wireFrameDesc.AntialiasedLineEnable = false;
	//wireFrameDesc.MultisampleEnable = true;

	HR(AngelCore::AngelSubSystemResources::GraphicDeviceResources::Device->CreateRasterizerState(&wireFrameDesc,
		AngelSubSystemResources::GraphicDeviceResources::WireFrameRasterizer.GetAddressOf()));
	D3D11_BLEND_DESC blendStateDescription;
	ZeroMemory(&blendStateDescription, sizeof(D3D11_BLEND_DESC));
	blendStateDescription.RenderTarget[0].BlendEnable = TRUE;
	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_ONE;
	blendStateDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
	blendStateDescription.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
	blendStateDescription.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;

	HR(AngelSubSystemResources::GraphicDeviceResources::Device->CreateBlendState(
		&blendStateDescription,
		AngelSubSystemResources::GraphicDeviceResources::TransparentBlending.GetAddressOf()));

	ZeroMemory(&blendStateDescription, sizeof(D3D11_BLEND_DESC));
	blendStateDescription.RenderTarget[0].BlendEnable = TRUE;
	blendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE;
	blendStateDescription.RenderTarget[0].DestBlend = D3D11_BLEND_ONE;
	blendStateDescription.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
	blendStateDescription.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
	blendStateDescription.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
	blendStateDescription.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
	blendStateDescription.RenderTarget[0].RenderTargetWriteMask = 0x0f;

	HR(AngelSubSystemResources::GraphicDeviceResources::Device->CreateBlendState(
		&blendStateDescription,
		AngelSubSystemResources::GraphicDeviceResources::AdditiveBlending.GetAddressOf()));

	D3D11_DEPTH_STENCIL_DESC DSDesc;
	DSDesc.DepthEnable = 1;
	DSDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK::D3D11_DEPTH_WRITE_MASK_ZERO;
	DSDesc.DepthFunc = D3D11_COMPARISON_FUNC::D3D11_COMPARISON_LESS;
	DSDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP::D3D11_STENCIL_OP_ZERO;
	DSDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP::D3D11_STENCIL_OP_ZERO;
	DSDesc.BackFace.StencilFunc = D3D11_COMPARISON_NEVER;
	DSDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP::D3D11_STENCIL_OP_ZERO;
	DSDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP::D3D11_STENCIL_OP_ZERO;
	DSDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP::D3D11_STENCIL_OP_ZERO;
	DSDesc.FrontFace.StencilFunc = D3D11_COMPARISON_NEVER;
	DSDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP::D3D11_STENCIL_OP_ZERO;
	DSDesc.StencilEnable = false;
	DSDesc.StencilReadMask = 0;
	DSDesc.StencilWriteMask = 0;

	HR(AngelSubSystemResources::GraphicDeviceResources::Device->CreateDepthStencilState(
		&DSDesc,
		AngelSubSystemResources::GraphicDeviceResources::DisableDepth.GetAddressOf()));
	return true;
}
Example #4
0
bool RenderCore::Init(int screenWidth, int screenHeight, HWND hWnd)
{
	HRESULT hr;
		
	IDXGIAdapter1 *adapter;
	IDXGIOutput *adapterOutput;
	IDXGIOutput1 *adapterOutput1;

	DXGI_ADAPTER_DESC adapterDesc;	
	DXGI_MODE_DESC *displayModeList;
	DXGI_SWAP_CHAIN_DESC swapChainDesc;

	ID3D11Texture2D *pBackBuffer;

	D3D11_TEXTURE2D_DESC depthBufferDesc;
	D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
	D3D11_DEPTH_STENCIL_DESC depthDisabledStencilDesc;
	D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;
	D3D11_RASTERIZER_DESC rasterDesc;	

	uint32_t numModes, fpsNumerator, fpsDenominator;
	size_t stringLength;
	int error;
	float fov, aspect;
		
	if (!EnumerateDisplayAdapters(&g_DXGIAdapters)) {
		return false;
	}
	adapter = g_DXGIAdapters.at(0);

	hr = adapter->EnumOutputs(0, &adapterOutput);
	if (FAILED(hr)) {
		return false;
	}
	
	// desktop duplication stuff
	hr = adapterOutput->QueryInterface(&adapterOutput1);
	
	hr = adapterOutput1->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, nullptr);
	if (FAILED(hr)) {
		return false;
	}

	displayModeList = new DXGI_MODE_DESC[numModes];
	if (!displayModeList) {
		return false;
	}

	hr = adapterOutput1->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList);
	if (FAILED(hr)) {
		return false;
	}
	
	for (UINT i = 0; i < numModes; i++) {
		if (displayModeList[i].Width == (unsigned int)screenWidth) {
			if (displayModeList[i].Height == (unsigned int)screenHeight) {
				fpsNumerator = displayModeList[i].RefreshRate.Numerator;
				fpsDenominator = displayModeList[i].RefreshRate.Denominator;
			}
		}
	}

	hr = adapter->GetDesc(&adapterDesc);
	if (FAILED(hr)) {
		return false;
	}
		
	// retrieve video adapter memory and name
	m_VideoMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024);	
	
	error = wcstombs_s(&stringLength, m_VideoCardDesc, 128, adapterDesc.Description, 128);
	
	if (error != 0) {
		return false;
	}
	DebugOut("Found graphics adapter: %s (%dMB VRAM)\n", m_VideoCardDesc, m_VideoMemory);

	delete[] displayModeList;
	displayModeList = nullptr;

	adapterOutput->Release();
	adapter->Release();
	
	// set single back buffer
	ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
	swapChainDesc.BufferCount = 1;
	swapChainDesc.BufferDesc.Width = screenWidth;
	swapChainDesc.BufferDesc.Height = screenHeight;
	swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
	swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
	swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	swapChainDesc.OutputWindow = hWnd;
	swapChainDesc.SampleDesc.Count = 1;
	swapChainDesc.SampleDesc.Quality = 0;
	swapChainDesc.Windowed = true;
	//swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
	//swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
	//swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
	//swapChainDesc.Flags = 0;

	// create swap chain, direct3d device, and d3d context	
	uint32_t deviceFlags = 0;
#define D3D_DEVICE_DEBUG
#ifdef D3D_DEVICE_DEBUG
	deviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

	D3D_FEATURE_LEVEL featureLevels[] = {
		D3D_FEATURE_LEVEL_11_1,
		D3D_FEATURE_LEVEL_11_0,
		D3D_FEATURE_LEVEL_10_1,
		D3D_FEATURE_LEVEL_10_0,
	};
	uint32_t numFeatureLevels = ARRAYSIZE(featureLevels);

	hr = D3D11CreateDeviceAndSwapChain(		nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, deviceFlags, featureLevels, numFeatureLevels,
											D3D11_SDK_VERSION, &swapChainDesc, &m_SwapChain, &m_d3d11Device, nullptr, &m_d3d11DeviceContext);
	if (FAILED(hr)) { 
		DebugOut("D3D11CreateDeviceAndSwapChain failed!\n");
		return false;
	}

	// enable multithreaded device context protection
	ID3D10Multithread *contextMT = nullptr;
	m_d3d11DeviceContext->QueryInterface(&contextMT);

	if (contextMT) {
		contextMT->SetMultithreadProtected(true);
		contextMT->Release();
	}
	else {
		DebugOut("Fatal error! ID3D10Multithread::SetMultithreadProtected for D3D11 device context failed!\n");
		return false;
	}

	// get pointer to the back buffer
	hr = m_SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID *)&pBackBuffer);
	if (FAILED(hr)) {
		DebugOut("IDXGISwapChain::GetBuffer failed!\n");
		return false;
	}

	// create render target view from back buffer
	hr = m_d3d11Device->CreateRenderTargetView(pBackBuffer, nullptr, &m_d3d11RenderTargetView);
	if (FAILED(hr)) {
		DebugOut("ID3D11Device::CreateRenderTargetView failed!\n");
		return false;
	}
	pBackBuffer->Release();

	// set up depth buffer description
	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;

	// create texture for depth buffer
	hr = m_d3d11Device->CreateTexture2D(&depthBufferDesc, nullptr, &m_d3d11DepthStencilBuffer);
	if (FAILED(hr)) {
		DebugOut("ID3D11Device::CreateTexture2D failed! Could not create texture for depth buffer.\n");
		return false;
	}

	// set up description of stencil state
	ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc));	
	depthStencilDesc.DepthEnable = true; // z-buffer enabled
	depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
	depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;

	depthStencilDesc.StencilEnable = true;
	depthStencilDesc.StencilReadMask = 0xFF;
	depthStencilDesc.StencilWriteMask = 0xFF;

	// Stencil operations if pixel is front-facing.
	depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
	depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
	depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
	depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

	// Stencil operations if pixel is back-facing.
	depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
	depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
	depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
	depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

	// create depth stencil state
	hr = m_d3d11Device->CreateDepthStencilState(&depthStencilDesc, &m_d3d11DepthStencilState);
	if (FAILED(hr)) {
		DebugOut("ID3D11Device::CreateDepthStencilState failed!\n");
		return false;
	}

	// Now create a second depth stencil state which turns off the Z buffer for 2D rendering.  The only difference is 
	// that DepthEnable is set to false, all other parameters are the same as the other depth stencil state.
	depthDisabledStencilDesc.DepthEnable = false;
	depthDisabledStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
	depthDisabledStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;
	depthDisabledStencilDesc.StencilEnable = true;
	depthDisabledStencilDesc.StencilReadMask = 0xFF;
	depthDisabledStencilDesc.StencilWriteMask = 0xFF;
	depthDisabledStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
	depthDisabledStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
	depthDisabledStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
	depthDisabledStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
	depthDisabledStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
	depthDisabledStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
	depthDisabledStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
	depthDisabledStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

	// Create the state using the device.
	hr = m_d3d11Device->CreateDepthStencilState(&depthDisabledStencilDesc, &m_d3d11DepthStencilDisabledState);
	if (FAILED(hr))
	{
		return false;
	}

	// disable the Z-Buffer
	ZBufferState(0);

	// set up depth stencil view description
	ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc));	
	depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
	depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
	depthStencilViewDesc.Texture2D.MipSlice = 0;

	// create depth stencil view
	hr = m_d3d11Device->CreateDepthStencilView(m_d3d11DepthStencilBuffer, &depthStencilViewDesc, &m_d3d11DepthStencilView);
	if (FAILED(hr)) {
		DebugOut("ID3D11Device::CreateDepthStencilView failed!\n");
		return false;
	}

	// bind render target view and depth stencil buffer to the output render pipeline
	m_d3d11DeviceContext->OMSetRenderTargets(1, &m_d3d11RenderTargetView, m_d3d11DepthStencilView);

	// set up rasterizer description	
	rasterDesc.AntialiasedLineEnable = false;
	rasterDesc.CullMode = D3D11_CULL_NONE;
	rasterDesc.DepthBias = 0;
	rasterDesc.DepthBiasClamp = 0.0f;
	rasterDesc.DepthClipEnable = false;
	rasterDesc.FillMode = D3D11_FILL_SOLID;
	rasterDesc.FrontCounterClockwise = false;
	rasterDesc.MultisampleEnable = false;
	rasterDesc.ScissorEnable = false;
	rasterDesc.SlopeScaledDepthBias = 0.0f;

	// create the rasterizer
	hr = m_d3d11Device->CreateRasterizerState(&rasterDesc, &m_d3d11RasterState);
	if (FAILED(hr)) {
		DebugOut("ID3D11Device::CreateRasterizerState failed!");
		return false;
	}
	
	m_d3d11DeviceContext->RSSetState(m_d3d11RasterState);

	// set up viewport for rendering
	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;

	// create the viewport
	m_d3d11DeviceContext->RSSetViewports(1, &viewport);
		
	fov = (float)PI / 4.0f;
	aspect = (float)screenWidth / (float)screenHeight;
		
	m_ProjectionMatrix = DirectX::XMMatrixPerspectiveFovLH(fov, aspect, SCREEN_NEAR, SCREEN_DEPTH);
	m_WorldMatrix = DirectX::XMMatrixIdentity();
	m_OrthoMatrix = DirectX::XMMatrixOrthographicLH((float)screenWidth, (float)screenHeight, SCREEN_NEAR, SCREEN_DEPTH);

	// Scene is a textured quad to draw on
	g_Scene = new Scene(GetDevice(), GetDeviceContext(), screenWidth, screenHeight);
	//g_Scene2 = new Scene(GetDevice(), GetDeviceContext(), screenWidth, screenHeight);	

	// new DXGI Desktop Duplication object
	g_DesktopDuplication = new DXGIDuplication();
	if (!g_DesktopDuplication->Init(0, 0, &g_DXGIAdapters, GetDevice())) { DebugOut("Failed to init DXGI Desktop Duplication API!\n"); return false; }
	
	//g_DesktopDuplication2 = new DXGIDuplication();
	//if (!g_DesktopDuplication2->Init(0, 1, &g_DXGIAdapters, GetDevice())) { DebugOut("Failed to init DXGI Desktop Duplication API for Adapter 1/Output 2!\n"); return false; }

	// initialize Media Foundation
	g_MFEncoder = new MF_H264_Encoder(m_d3d11Device, m_d3d11DeviceContext);
	if (!g_MFEncoder->Init()) { DebugOut("Failed to init Media Foundation H.264 Encoder!\n"); return false; }

	return true;
};
Example #5
0
STDMETHODIMP CDecD3D11::CreateD3D11Device(UINT nDeviceIndex, ID3D11Device **ppDevice, DXGI_ADAPTER_DESC *pDesc)
{
  ID3D11Device *pD3D11Device = nullptr;

  // create DXGI factory
  IDXGIAdapter *pDXGIAdapter = nullptr;
  IDXGIFactory1 *pDXGIFactory = nullptr;
  HRESULT hr = dx.mCreateDXGIFactory1(IID_IDXGIFactory1, (void **)&pDXGIFactory);
  if (FAILED(hr))
  {
    DbgLog((LOG_ERROR, 10, L"-> DXGIFactory creation failed"));
    goto fail;
  }

  // find the adapter
enum_adapter:
  hr = pDXGIFactory->EnumAdapters(nDeviceIndex, &pDXGIAdapter);
  if (FAILED(hr))
  {
    if (nDeviceIndex != 0)
    {
      DbgLog((LOG_ERROR, 10, L"-> Requested DXGI device %d not available, falling back to default", nDeviceIndex));
      nDeviceIndex = 0;
      hr = pDXGIFactory->EnumAdapters(0, &pDXGIAdapter);
    }

    if (FAILED(hr))
    {
      DbgLog((LOG_ERROR, 10, L"-> Failed to enumerate a valid DXGI device"));
      goto fail;
    }
  }

  // Create a device with video support, and BGRA support for Direct2D interoperability (drawing UI, etc)
  UINT nCreationFlags = D3D11_CREATE_DEVICE_VIDEO_SUPPORT | D3D11_CREATE_DEVICE_BGRA_SUPPORT;

  D3D_FEATURE_LEVEL d3dFeatureLevel;
  hr = dx.mD3D11CreateDevice(pDXGIAdapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, nCreationFlags, s_D3D11Levels, countof(s_D3D11Levels), D3D11_SDK_VERSION, &pD3D11Device, &d3dFeatureLevel, nullptr);
  if (FAILED(hr))
  {
    if (nDeviceIndex != 0)
    {
      DbgLog((LOG_ERROR, 10, L"-> Failed to create a D3D11 device with video support on requested device %d, re-trying with default", nDeviceIndex));
      SafeRelease(&pDXGIAdapter);
      nDeviceIndex = 0;
      goto enum_adapter;
    }

    DbgLog((LOG_ERROR, 10, L"-> Failed to create a D3D11 device with video support"));
    goto fail;
  }

  DbgLog((LOG_TRACE, 10, L"-> Created D3D11 device with feature level %d.%d", d3dFeatureLevel >> 12, (d3dFeatureLevel >> 8) & 0xF));

  // enable multithreaded protection
  ID3D10Multithread *pMultithread = nullptr;
  hr = pD3D11Device->QueryInterface(&pMultithread);
  if (SUCCEEDED(hr)) {
    pMultithread->SetMultithreadProtected(TRUE);
    SafeRelease(&pMultithread);
  }

  // store adapter info
  if (pDesc)
  {
    ZeroMemory(pDesc, sizeof(*pDesc));
    pDXGIAdapter->GetDesc(pDesc);
  }

  // return device
  *ppDevice = pD3D11Device;

fail:
  SafeRelease(&pDXGIFactory);
  SafeRelease(&pDXGIAdapter);
  return hr;
}