Example #1
0
int main(int argc, char** argv)
{
	IDXGIFactory1* factory = 0;
	CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&factory);

	IDXGIAdapter* adapter = NULL;
	for (unsigned int index = 0; SUCCEEDED(factory->EnumAdapters(index, &adapter)); ++index)
	{
		DXGI_ADAPTER_DESC ad = {};
		adapter->GetDesc(&ad);

		if (ad.VendorId == 0x1414 && ad.DeviceId == 0x8c)
			continue; // Skip Microsoft Basic Render Driver

		printf("// GPU %d: %S (Vendor %04x Device %04x)\n", index, ad.Description, ad.VendorId, ad.DeviceId);

		if (argc == 1)
		{
			testCache(adapter);
		}
		else if (argc > 1 && strcmp(argv[1], "--") == 0)
		{
			testCacheSequence(adapter, argc, argv);
		}
		else
		{
			testCacheMeshes(adapter, argc, argv);
		}
	}
}
Example #2
0
STDMETHODIMP CDecD3D11::GetHWAccelDeviceInfo(DWORD dwIndex, BSTR *pstrDeviceName, DWORD *dwDeviceIdentifier)
{
  IDXGIAdapter *pDXGIAdapter = nullptr;
  IDXGIFactory1 *pDXGIFactory = nullptr;

  HRESULT hr = dx.mCreateDXGIFactory1(IID_IDXGIFactory1, (void **)&pDXGIFactory);
  if (FAILED(hr))
    goto fail;

  hr = pDXGIFactory->EnumAdapters(dwIndex, &pDXGIAdapter);
  if (FAILED(hr))
    goto fail;

  DXGI_ADAPTER_DESC desc;
  pDXGIAdapter->GetDesc(&desc);

  // stop when we hit the MS software device
  if (desc.VendorId == 0x1414 && desc.DeviceId == 0x8c)
  {
    hr = E_INVALIDARG;
    goto fail;
  }

  if (pstrDeviceName)
    *pstrDeviceName = SysAllocString(desc.Description);

  if (dwDeviceIdentifier)
    *dwDeviceIdentifier = desc.DeviceId;

fail:
  SafeRelease(&pDXGIFactory);
  SafeRelease(&pDXGIAdapter);
  return hr;
}
Example #3
0
void DesktopDuplication::init()
{
	IDXGIFactory1* dxgiFactory = nullptr;
	CHECKED(hr, CreateDXGIFactory1(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&dxgiFactory)));

	IDXGIAdapter1* dxgiAdapter = nullptr;
	CHECKED(hr, dxgiFactory->EnumAdapters1(adapter, &dxgiAdapter));
	dxgiFactory->Release();

	CHECKED(hr, D3D11CreateDevice(dxgiAdapter,
		D3D_DRIVER_TYPE_UNKNOWN,
		NULL,
		NULL,
		NULL,
		NULL,
		D3D11_SDK_VERSION,
		&d3dDevice,
		NULL,
		&d3dContext));

	IDXGIOutput* dxgiOutput = nullptr;
	CHECKED(hr, dxgiAdapter->EnumOutputs(output, &dxgiOutput));
	dxgiAdapter->Release();

	IDXGIOutput1* dxgiOutput1 = nullptr;
	CHECKED(hr, dxgiOutput->QueryInterface(__uuidof(dxgiOutput1), reinterpret_cast<void**>(&dxgiOutput1)));
	dxgiOutput->Release();

	IDXGIDevice* dxgiDevice = nullptr;
	CHECKED(hr, d3dDevice->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>(&dxgiDevice)));

	CHECKED(hr, dxgiOutput1->DuplicateOutput(dxgiDevice, &outputDuplication));
	dxgiOutput1->Release();
	dxgiDevice->Release();
}
Example #4
0
STDMETHODIMP_(DWORD) CDecD3D11::GetHWAccelNumDevices()
{
  DWORD nDevices = 0;
  UINT i = 0;
  IDXGIAdapter *pDXGIAdapter = nullptr;
  IDXGIFactory1 *pDXGIFactory = nullptr;

  HRESULT hr = dx.mCreateDXGIFactory1(IID_IDXGIFactory1, (void **)&pDXGIFactory);
  if (FAILED(hr))
    goto fail;

  DXGI_ADAPTER_DESC desc;
  while (SUCCEEDED(pDXGIFactory->EnumAdapters(i, &pDXGIAdapter)))
  {
    pDXGIAdapter->GetDesc(&desc);
    SafeRelease(&pDXGIAdapter);

    // stop when we hit the MS software device
    if (desc.VendorId == 0x1414 && desc.DeviceId == 0x8c)
      break;

    i++;
  }

  nDevices = i;

fail:
  SafeRelease(&pDXGIFactory);
  return nDevices;
}
D3D11CanvasWindowGraphicsPtr D3D11CanvasWindowGraphics::Create(
	HWND hWnd, D3D11DriverPtr driver, CameraPtr camera)
{
	D3D11CanvasWindowGraphicsPtr p(new D3D11CanvasWindowGraphics);

	p->m_hWnd = hWnd;
	p->m_driver = driver;
	p->m_camera = camera;

	ID3D11Device* pDevice = p->m_driver->GetD3D11Device();
	IDXGIFactory1* pDXGIFactory = p->m_driver->GetDXGIFactory();
	IDWriteFactory* pDWriteFactory = p->m_driver->GetDWriteFactory();

	// Create text format

	CHECK_HR(pDWriteFactory->CreateTextFormat(
		L"Calibri", NULL, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL,
		DWRITE_FONT_STRETCH_NORMAL, 24.0f, L"en-US", p->m_textFormat.Receive()));

	// Create swap chain

	DXGI_SWAP_CHAIN_DESC scd = { 0 };
	scd.BufferDesc.Format = BACKBUFFER_FORMAT;
	scd.SampleDesc.Count = 1;
	scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	scd.BufferCount = 1;
	scd.OutputWindow = hWnd;
	scd.Windowed = TRUE;
	CHECK_HR(pDXGIFactory->CreateSwapChain(pDevice, &scd, p->m_swapChain.Receive()));

	p->CreateSwapChainResources();

	return p;
}
Example #6
0
//----------------------------------------------------------------------------
void DXGIAdapter::Enumerate(std::vector<DXGIAdapter>& adapters)
{
    adapters.clear();

    IDXGIFactory1* factory = nullptr;
    HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1),
        (void**)&factory);
    CHECK_HR_RETURN_NONE("Unexpected error");

    if (factory)
    {
        for (UINT i = 0; /**/; ++i)
        {
            IDXGIAdapter1* adapter = nullptr;
            hr = factory->EnumAdapters1(i, &adapter);
            if (hr != DXGI_ERROR_NOT_FOUND)
            {
                adapters.push_back(DXGIAdapter(adapter));
            }
            else
            {
                break;
            }
        }

        SafeRelease(factory);
    }
}
bool CDuplicateOutputDx11::GetSpecificAdapter(int idAdapter, IDXGIAdapter** pAdapter)
{
	HRESULT err = S_OK;

	if (!pAdapter)
	{
		return false;
	}

	REFIID iidVal = __uuidof(IDXGIFactory1);
	UINT adapterID = 0;	// adapter index
	IDXGIFactory1* pFactory = NULL;
	if (FAILED(err = CreateDXGIFactory1(iidVal, (void**)&pFactory)))
	{
		return 	false;
	}
	UINT i = 0;
	UINT adapterDeviceID = idAdapter;		// if device id equal zero, use the first device

	DXGI_ADAPTER_DESC dxgiDesc;
	IDXGIAdapter1 *giAdapter = NULL;
	if (pFactory->EnumAdapters1(i, &giAdapter) != S_OK)
	{
		return false;
	}
	if (pFactory)pFactory->Release();
	*pAdapter = giAdapter;
	return true;
}
Example #8
0
void GetDisplayDevices(DeviceOutputs &deviceList)
{
    HRESULT err;

    deviceList.ClearData();

#ifdef USE_DXGI1_2
    REFIID iidVal = OSGetVersion() >= 8 ? __uuidof(IDXGIFactory2) : __uuidof(IDXGIFactory1);
#else
    REFIIF iidVal = __uuidof(IDXGIFactory1);
#endif

    IDXGIFactory1 *factory;
    if(SUCCEEDED(err = CreateDXGIFactory1(iidVal, (void**)&factory)))
    {
        UINT i=0;
        IDXGIAdapter1 *giAdapter;

        while(factory->EnumAdapters1(i++, &giAdapter) == S_OK)
        {
            Log(TEXT("------------------------------------------"));

            DXGI_ADAPTER_DESC adapterDesc;
            if(SUCCEEDED(err = giAdapter->GetDesc(&adapterDesc)))
            {
                if (adapterDesc.DedicatedVideoMemory != 0) {
                    DeviceOutputData &deviceData = *deviceList.devices.CreateNew();
                    deviceData.strDevice = adapterDesc.Description;

                    UINT j=0;
                    IDXGIOutput *giOutput;
                    while(giAdapter->EnumOutputs(j++, &giOutput) == S_OK)
                    {
                        DXGI_OUTPUT_DESC outputDesc;
                        if(SUCCEEDED(giOutput->GetDesc(&outputDesc)))
                        {
                            if(outputDesc.AttachedToDesktop)
                            {
                                deviceData.monitorNameList << outputDesc.DeviceName;

                                MonitorInfo &monitorInfo = *deviceData.monitors.CreateNew();
                                monitorInfo.hMonitor = outputDesc.Monitor;
                                mcpy(&monitorInfo.rect, &outputDesc.DesktopCoordinates, sizeof(RECT));
                            }
                        }

                        giOutput->Release();
                    }
                }
            }
            else
                AppWarning(TEXT("Could not query adapter %u"), i);

            giAdapter->Release();
        }

        factory->Release();
    }
}
Example #9
0
HRESULT WINAPI HookDXGIFactory(REFIID riid, void **ppFactory)
{
	// We need shared texture support for OpenVR, so force DXGI 1.0 games to use DXGI 1.1
	IDXGIFactory1* pDXGIFactory;
	HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void **)&pDXGIFactory);
	if (FAILED(hr))
		return hr;
	return pDXGIFactory->QueryInterface(riid, ppFactory);
}
Example #10
0
/// This function is called by the Mumble client in Mumble's scope
/// mainly to extract the offsets of various functions in the IDXGISwapChain
/// and IDXGIObject interfaces that need to be hooked in target
/// applications. The data is stored in the dxgi shared memory structure.
extern "C" __declspec(dllexport) void __cdecl PrepareDXGI() {
	if (! dxgi)
		return;

	ods("DXGI: Preparing static data for DXGI Injection");

	dxgi->wcFileName[0] = 0;
	dxgi->offsetPresent = 0;
	dxgi->offsetResize = 0;

	// Make sure this is Vista or greater as quite a number of <=WinXP users have fake DX10 libs installed
	OSVERSIONINFOEXW ovi;
	memset(&ovi, 0, sizeof(ovi));
	ovi.dwOSVersionInfoSize = sizeof(ovi);
	GetVersionExW(reinterpret_cast<OSVERSIONINFOW *>(&ovi));
	if (ovi.dwMajorVersion < 6 || (ovi.dwMajorVersion == 6 && ovi.dwBuildNumber < 6001)) {
		ods("DXGI: No DXGI pre-Vista - skipping prepare");
		return;
	}

	HMODULE hDXGI = LoadLibrary("DXGI.DLL");

	if (hDXGI != NULL) {
		GetModuleFileNameW(hDXGI, dxgi->wcFileName, ARRAY_NUM_ELEMENTS(dxgi->wcFileName));

		CreateDXGIFactory1Type pCreateDXGIFactory1 = reinterpret_cast<CreateDXGIFactory1Type>(GetProcAddress(hDXGI, "CreateDXGIFactory1"));
		ods("DXGI: Got CreateDXGIFactory1 at %p", pCreateDXGIFactory1);
		if (pCreateDXGIFactory1) {
			IDXGIFactory1 * pFactory;
			HRESULT hr = pCreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)(&pFactory));
			if (FAILED(hr))
				ods("DXGI: Call to pCreateDXGIFactory1 failed!");
			if (pFactory) {
				IDXGIAdapter1 *pAdapter = NULL;
				pFactory->EnumAdapters1(0, &pAdapter);

				/// Offsets have to be identified and initialized only once.
				bool initializeDXGIData = !dxgi->offsetPresent && !dxgi->offsetResize;
				PrepareDXGI10(pAdapter, initializeDXGIData);
				initializeDXGIData = !dxgi->offsetPresent && !dxgi->offsetResize;
				PrepareDXGI11(pAdapter, initializeDXGIData);

				pFactory->Release();
			} else {
				FreeLibrary(hDXGI);
			}
		} else {
			FreeLibrary(hDXGI);
		}
	} else {
		FreeLibrary(hDXGI);
	}
}
Example #11
0
void LogVideoCardStats()
{
    HRESULT err;

#ifdef USE_DXGI1_2
    REFIID iidVal = OSGetVersion() >= 8 ? __uuidof(IDXGIFactory2) : __uuidof(IDXGIFactory1);
#else
    REFIIF iidVal = __uuidof(IDXGIFactory1);
#endif

    IDXGIFactory1 *factory;
    if(SUCCEEDED(err = CreateDXGIFactory1(iidVal, (void**)&factory)))
    {
        UINT i=0;
        IDXGIAdapter1 *giAdapter;

        while(factory->EnumAdapters1(i++, &giAdapter) == S_OK)
        {
            DXGI_ADAPTER_DESC adapterDesc;
            if(SUCCEEDED(err = giAdapter->GetDesc(&adapterDesc)))
            {
                if (!(adapterDesc.VendorId == 0x1414 && adapterDesc.DeviceId == 0x8c)) { // Ignore Microsoft Basic Render Driver
                    Log(TEXT("------------------------------------------"));
                    Log(TEXT("Adapter %u"), i);
                    Log(TEXT("  Video Adapter: %s"), adapterDesc.Description);
                    Log(TEXT("  Video Adapter Dedicated Video Memory: %u"), adapterDesc.DedicatedVideoMemory);
                    Log(TEXT("  Video Adapter Shared System Memory: %u"), adapterDesc.SharedSystemMemory);

                    UINT j = 0;
                    IDXGIOutput *output;
                    while(SUCCEEDED(giAdapter->EnumOutputs(j++, &output)))
                    {
                        DXGI_OUTPUT_DESC desc;
                        if(SUCCEEDED(output->GetDesc(&desc)))
                            Log(TEXT("  Video Adapter Output %u: pos={%d, %d}, size={%d, %d}, attached=%s"), j,
                                desc.DesktopCoordinates.left, desc.DesktopCoordinates.top,
                                desc.DesktopCoordinates.right-desc.DesktopCoordinates.left, desc.DesktopCoordinates.bottom-desc.DesktopCoordinates.top,
                                desc.AttachedToDesktop ? L"true" : L"false");
                        output->Release();
                    }
                }
            }
            else
                AppWarning(TEXT("Could not query adapter %u"), i);

            giAdapter->Release();
        }

        factory->Release();
    }
}
Example #12
0
	IDXGIAdapter1	*D3D11Renderer::GetPrimaryAdaptor()
	{
		IDXGIFactory1	*factory = 0;

		if (CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void **)&factory) == S_OK)
		{
			IDXGIAdapter1	*adapter = 0;
				
			factory->EnumAdapters1(0, &adapter);
			memory::SafeRelease(&factory);
			memory::SafeRelease(&adapter);
			return adapter;
		}
		memory::SafeRelease(&factory);
		return 0;
	}
Example #13
0
	void	D3D11Renderer::EnumerateDisplayModes()
	{
		IDXGIFactory1	*factory = 0;

		if (CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void **)&factory) == S_OK)
		{
			IDXGIAdapter1	*adapter = 0;
			for (UINT i = 0; factory->EnumAdapters1(i, &adapter) != DXGI_ERROR_NOT_FOUND; i++)
			{
				DXGI_ADAPTER_DESC1 ad;
				adapter->GetDesc1(&ad);

				char description[128];
				size_t n;
				wcstombs_s(&n, description, ad.Description, 128);

				ATOM_LOG("-------------------------------------------------------------------------------\n");
				ATOM_LOG("[info]: adapter[%d]: %s\n", i, description);
				ATOM_LOG("[info]: - revision: %d\n", i, ad.Revision);
				ATOM_LOG("[info]: - video memory: %d\n", i, ad.DedicatedVideoMemory / 1024 / 1024);
				ATOM_LOG("[info]: - system memory: %d\n", i, ad.DedicatedSystemMemory / 1024 / 1024);
				ATOM_LOG("[info]: - shared system memory: %d\n", i, ad.SharedSystemMemory / 1024 / 1024);

				IDXGIOutput	*output = 0;
				for (UINT j = 0; adapter->EnumOutputs(j, &output) != DXGI_ERROR_NOT_FOUND; j++)
				{
					UINT			modesCount;
					DXGI_FORMAT		format = g_settings.format;

					output->GetDisplayModeList(format, 0, &modesCount, 0);
					DXGI_MODE_DESC	*modeDescs = new DXGI_MODE_DESC[modesCount];
					output->GetDisplayModeList(format, 0, &modesCount, modeDescs);

					ATOM_LOG("[info]: - output %d display modes(%d)\n", j, modesCount);
					for (UINT k = 0; k < modesCount; k++)
					{
						ATOM_LOG("[info]: -- mode[%d]: %d * %d", k, modeDescs[k].Width, modeDescs[k].Height);
						ATOM_LOG(", refresh rate: %d/%d\n", modeDescs[i].RefreshRate.Numerator, modeDescs[i].RefreshRate.Denominator);
					}
					delete[] modeDescs;
					memory::SafeRelease(&output);
				}
				memory::SafeRelease(&adapter);
			}
		}
		memory::SafeRelease(&factory);
	}
Example #14
0
std::vector<IDXGIAdapter*> EnumerateDXGIAdapters() {
  IDXGIAdapter * adaptor; 
  std::vector <IDXGIAdapter*> adaptors; 
  IDXGIFactory1* factory = NULL; 

  // Create a DXGIFactory object.
  if(FAILED(CreateDXGIFactory1(__uuidof(IDXGIFactory1) ,(void**)&factory))) {
    return adaptors;
  }

  for (auto i = 0; factory->EnumAdapters(i, &adaptor) != DXGI_ERROR_NOT_FOUND; ++i)  {
    adaptors.push_back(adaptor); 
  } 

  SafeRelease(&factory);

  return adaptors;
}
Example #15
0
	DXGI_RATIONAL	D3D11Renderer::GetDefaultRefreshRate()
	{
		DXGI_RATIONAL	refreshRate = {59, 1};
		IDXGIFactory1	*factory = 0;

		if (CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void **)&factory) == S_OK)
		{
			IDXGIAdapter1	*adapter = 0;
			for (UINT i = 0; factory->EnumAdapters1(i, &adapter) != DXGI_ERROR_NOT_FOUND; i++)
			{
				DXGI_ADAPTER_DESC1 ad;
				IDXGIOutput	*output = 0;

				adapter->GetDesc1(&ad);
				for (UINT j = 0; adapter->EnumOutputs(j, &output) != DXGI_ERROR_NOT_FOUND; j++)
				{
					UINT			modesCount;
					DXGI_FORMAT		format = g_settings.format;

					output->GetDisplayModeList(format, 0, &modesCount, 0);
					DXGI_MODE_DESC	*modeDescs = new DXGI_MODE_DESC[modesCount];
					output->GetDisplayModeList(format, 0, &modesCount, modeDescs);
					for (UINT k = 0; k < modesCount; k++)
					{
						if (modeDescs[k].Width == (UINT)g_settings.width &&
							modeDescs[k].Height == (UINT)g_settings.height)
						{
							refreshRate = modeDescs[i].RefreshRate;
							delete[] modeDescs;
							memory::SafeRelease(&output);
							memory::SafeRelease(&adapter);
							memory::SafeRelease(&factory);
							return refreshRate;
						}
					}
					delete[] modeDescs;
					memory::SafeRelease(&output);
				}
				memory::SafeRelease(&adapter);
			}
		}
		memory::SafeRelease(&factory);
		return refreshRate;
	}
void RenderContext::init(s32 width, s32 height, s32 refresh_rate, PlatformWindow *window) {
	pp = (PlatformPacket *)malloc(sizeof(PlatformPacket));
	memset(pp, 0, sizeof(PlatformPacket));
	DXGI_MODE_DESC buffer_desc = {0};
	buffer_desc.Width = width;
	buffer_desc.Height = height;
	buffer_desc.RefreshRate.Numerator = refresh_rate;
	buffer_desc.RefreshRate.Denominator = 1;
	buffer_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	buffer_desc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
	buffer_desc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED  ;
	
	SDL_SysWMinfo win32_info = {0};
	SDL_GetWindowWMInfo((SDL_Window *)window->handle, &win32_info);
	
	DXGI_SWAP_CHAIN_DESC swap_chain_desc = {0};
	swap_chain_desc.BufferDesc = buffer_desc;
	swap_chain_desc.SampleDesc.Count =  1;
	swap_chain_desc.SampleDesc.Quality =  0;
	swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	swap_chain_desc.BufferCount = 1; // NOTE(nathan): double buffering
	swap_chain_desc.OutputWindow = win32_info.info.win.window;
	swap_chain_desc.Windowed = true;
	swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
	swap_chain_desc.Flags = D3D11_CREATE_DEVICE_DEBUG; // NOTE(nathan): possible DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
	
	HRESULT error = D3D11CreateDeviceAndSwapChain(0, D3D_DRIVER_TYPE_HARDWARE, 0, 0, 0, 0, D3D11_SDK_VERSION, 
														  &swap_chain_desc, &pp->swap_chain, &pp->device, 0, &pp->device_context);
	
	
	// NOTE(nathan): disable alt-enter fullscreen
	IDXGIFactory1 *factory = 0;
	if(SUCCEEDED(pp->swap_chain->GetParent(__uuidof(IDXGIFactory1), (void **)&factory))) {
		factory->MakeWindowAssociation(win32_info.info.win.window, DXGI_MWA_NO_ALT_ENTER|DXGI_MWA_NO_PRINT_SCREEN );
		factory->Release();
	}
	
	resizeBuffer(width, height);
	
	error = pp->device->QueryInterface(IID_PPV_ARGS(&pp->debug_interface));
}
Example #17
0
bool RenderCore::EnumerateDisplayAdapters(std::vector<IDXGIAdapter1 *> *dxgiAdapters)
{
	IDXGIAdapter1 *pAdapter;
	IDXGIFactory1 *pFactory = nullptr;
	HRESULT hr;

	hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&pFactory);
	if (FAILED(hr)) {
		return false;
	}
	
	for (UINT i = 0; pFactory->EnumAdapters1(i, &pAdapter) != DXGI_ERROR_NOT_FOUND; ++i) {
		dxgiAdapters->push_back(pAdapter);
		//m_VideoAdapterList.push_back(pAdapter);
	}

	if (pFactory) {
		pFactory->Release();
	}

	return true;
};
Example #18
0
bool DeviceDirect3D::getAdapterHandle(std::vector<IDXGIAdapter1*>* adapters)
{
	HRESULT hr;

	//Create DXGI factory
	IDXGIFactory1* dxgiFactory;
	hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)(&dxgiFactory));
	if(FAILED(hr))
	{
		LOGERROR(hr, "CreateDXGIFactory1");
		return false;
	}

	//Get all the adapters
	UINT i = 0;
	IDXGIAdapter1* pAdapter = nullptr;
	while(dxgiFactory->EnumAdapters1(i, &pAdapter) != DXGI_ERROR_NOT_FOUND)
	{ 
		adapters->push_back(pAdapter);

		DXGI_ADAPTER_DESC1 desc;
		pAdapter->GetDesc1(&desc);
		std::wstring descriptionw(desc.Description);
		std::string description(descriptionw.begin(), descriptionw.end());
		Logger() << "Adapter found: (" << i << ") " << description;

		++i;
	}
	dxgiFactory->Release();

	if(adapters->empty())
	{
		LOGFUNCERROR("Your graphics card does not appear to support DirectX 10 or later");
		return false;
	}

	return true;
}
Example #19
0
void LogVideoCardStats()
{
    HRESULT err;

#ifdef USE_DXGI1_2
    REFIID iidVal = OSGetVersion() >= 8 ? __uuidof(IDXGIFactory2) : __uuidof(IDXGIFactory1);
#else
    REFIIF iidVal = __uuidof(IDXGIFactory1);
#endif

    IDXGIFactory1 *factory;
    if(SUCCEEDED(err = CreateDXGIFactory1(iidVal, (void**)&factory)))
    {
        UINT i=0;
        IDXGIAdapter1 *giAdapter;

        while(factory->EnumAdapters1(i++, &giAdapter) == S_OK)
        {
            DXGI_ADAPTER_DESC adapterDesc;
            if(SUCCEEDED(err = giAdapter->GetDesc(&adapterDesc)))
            {
                if (adapterDesc.DedicatedVideoMemory > 0) {
                    Log(TEXT("------------------------------------------"));
                    Log(TEXT("Adapter %u"), i);
                    Log(TEXT("  Video Adapter: %s"), adapterDesc.Description);
                    Log(TEXT("  Video Adapter Dedicated Video Memory: %u"), adapterDesc.DedicatedVideoMemory);
                    Log(TEXT("  Video Adapter Shared System Memory: %u"), adapterDesc.SharedSystemMemory);
                }
            }
            else
                AppWarning(TEXT("Could not query adapter %u"), i);

            giAdapter->Release();
        }

        factory->Release();
    }
}
Example #20
0
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;
}
Example #21
0
//--------------------------------------------------------------------------------------
// 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;
}
Example #22
0
  bool InitDirect3D(RENDERER_SETTINGS * pSetup) 
  {
    DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM;

    DXGI_SWAP_CHAIN_DESC desc;
    ZeroMemory(&desc, sizeof(DXGI_SWAP_CHAIN_DESC));
    desc.BufferCount = 1;
    desc.BufferDesc.Width = pSetup->nWidth;
    desc.BufferDesc.Height = pSetup->nHeight;
    desc.BufferDesc.Format = format;
    if (pSetup->bVsync)
    {
      bVsync = true;
      IDXGIFactory1 * pFactory = NULL;
      HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&pFactory);
      if (pFactory)
      {
        IDXGIAdapter1 * pAdapter = NULL;
        pFactory->EnumAdapters1( 0, &pAdapter );
        if (pAdapter)
        {
          IDXGIOutput * pOutput = NULL;
          pAdapter->EnumOutputs( 0, &pOutput );
          if (pOutput)
          {
            unsigned int nModeCount = 0;
            pOutput->GetDisplayModeList( format, DXGI_ENUM_MODES_INTERLACED | DXGI_ENUM_MODES_SCALING, &nModeCount, NULL);

            DXGI_MODE_DESC * pModes = new DXGI_MODE_DESC[ nModeCount ];
            pOutput->GetDisplayModeList( format, DXGI_ENUM_MODES_INTERLACED | DXGI_ENUM_MODES_SCALING, &nModeCount, pModes);

            for (int i=0; i<nModeCount; i++)
            {
              if (pModes[i].Width == pSetup->nWidth && pModes[i].Height == pSetup->nHeight)
              {
                desc.BufferDesc = pModes[i];
                break;
              }
            }
            delete[] pModes;

            pOutput->Release();
          }

          pAdapter->Release();
        }

        pFactory->Release();
      }
    }
    desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    desc.OutputWindow = hWnd;
    desc.SampleDesc.Count = 1;
    desc.Windowed = pSetup->windowMode != RENDERER_WINDOWMODE_FULLSCREEN;

    DWORD deviceCreationFlags = 0;
#ifdef _DEBUG
    //deviceCreationFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

    if (D3D11CreateDeviceAndSwapChain(
      NULL,
      D3D_DRIVER_TYPE_HARDWARE,
      NULL,
      deviceCreationFlags,
      NULL,
      NULL,
      D3D11_SDK_VERSION,
      &desc,
      &pSwapChain,
      &pDevice,
      NULL,
      &pContext) != S_OK)
    {
      printf("[Renderer] D3D11CreateDeviceAndSwapChain failed\n");
      return false;
    }

    pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&pBackBuffer);

    pDevice->CreateRenderTargetView(pBackBuffer, NULL, &pRenderTarget);
    pBackBuffer->Release();

    pContext->OMSetRenderTargets(1, &pRenderTarget, NULL);

    // create staging texture for frame grabbing

    D3D11_TEXTURE2D_DESC description;
    pBackBuffer->GetDesc( &description );
    description.BindFlags = 0;
    description.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
    description.Usage = D3D11_USAGE_STAGING;

    HRESULT hr = pDevice->CreateTexture2D( &description, NULL, &pFrameGrabTexture );

    return true;
  }
Example #23
0
HRESULT InitDevice()
{
	// Create swap chain
	{
		// Create DXGI factory to enumerate adapters
		IDXGIFactory1 *pDXGIFactory;

		HRESULT hResult = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&pDXGIFactory);
		assert(SUCCEEDED(hResult));

		// Use the first adapter
		IDXGIAdapter1 *pAdapter;

		hResult = pDXGIFactory->EnumAdapters1(0, &pAdapter);
		assert(SUCCEEDED(hResult));

		pDXGIFactory->Release();

		// Create D3D11 device and swapchain
		DXGI_SWAP_CHAIN_DESC scd = {0};
		ZeroMemory(&scd, sizeof(scd));
		scd.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
		scd.SampleDesc.Count = 1;
		scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
		scd.BufferCount = 1;
		scd.OutputWindow = hWnd;
		scd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
		scd.Windowed = TRUE;

		hResult = D3D11CreateDeviceAndSwapChain(
			pAdapter,
			D3D_DRIVER_TYPE_UNKNOWN,
			NULL,
			D3D11_CREATE_DEVICE_DEBUG |
			D3D11_CREATE_DEVICE_BGRA_SUPPORT |
			D3D11_CREATE_DEVICE_SINGLETHREADED,
			NULL,
			0,
			D3D11_SDK_VERSION,
			&scd,
			&g_swapChain,
			&g_device11,
			NULL,
			&g_immediateContext
			);

		assert(SUCCEEDED(hResult));
	}

	// Create vertex buffer
	{
		const size_t vertexCount = 4;
		Vertex vertices[vertexCount] =
		{
			{ D3DXVECTOR3( -1.0f, -1.0f, 0.5f ),D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 1.0f ), D3DXVECTOR2( 0.0f, 1.0f ) },
			{ D3DXVECTOR3( 1.0f, -1.0f, 0.5f ), D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 1.0f ),D3DXVECTOR2( 1.0f, 1.0f ) },
			{ D3DXVECTOR3( 1.0f, 1.0f, 0.5f ),  D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 1.0f ),D3DXVECTOR2( 1.0f, 0.0f ) },
			{ D3DXVECTOR3( -1.0f, 1.0f, 0.5f ), D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 1.0f ),D3DXVECTOR2( 0.0f, 0.0f ) },
		};

		D3D11_BUFFER_DESC bd = {0};
		bd.Usage = D3D11_USAGE_DEFAULT;
		bd.ByteWidth = sizeof( Vertex ) * vertexCount;
		bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
		bd.CPUAccessFlags = 0;
		bd.MiscFlags = 0;
		D3D11_SUBRESOURCE_DATA InitData = {0};
		InitData.pSysMem = vertices;
		HRESULT hr = g_device11->CreateBuffer( &bd, &InitData, &g_pVertexBuffer );
		if( FAILED( hr ) )
			return hr;

		// Set vertex buffer
		UINT stride = sizeof( Vertex );
		UINT offset = 0;
		g_immediateContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride, &offset );
	}

	// Create index buffer	
	{
		DWORD indices[] =
		{
			3,1,0,
			2,1,3,
		};

		g_indexCount = sizeof(indices)/sizeof(DWORD);

		D3D11_BUFFER_DESC bd = {0};
		bd.Usage = D3D11_USAGE_DEFAULT;
		bd.ByteWidth = sizeof( DWORD ) * g_indexCount;
		bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
		bd.CPUAccessFlags = 0;
		bd.MiscFlags = 0;

		D3D11_SUBRESOURCE_DATA InitData = {0};
		InitData.pSysMem = indices;

		HRESULT hr = g_device11->CreateBuffer( &bd, &InitData, &g_pIndexBuffer );
		if( FAILED( hr ) )
			return hr;

		// Set index buffer
		g_immediateContext->IASetIndexBuffer( g_pIndexBuffer, DXGI_FORMAT_R32_UINT, 0 );

		// Set primitive topology
		g_immediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
	}

	ID3DBlob* vs = NULL;
	ID3DBlob* ps = NULL;

	// create shaders
	{
		HRESULT hr = S_OK;
		hr = CompileShaderFromFile(L"Data\\GUI_dx11.hlsl", "RenderSceneVS", "vs_4_0", &vs);
		assert(SUCCEEDED(hr));
		hr = CompileShaderFromFile(L"Data\\GUI_dx11.hlsl", "RenderScenePS", "ps_4_0", &ps);
		assert(SUCCEEDED(hr));
		hr = g_device11->CreateVertexShader( vs->GetBufferPointer(), vs->GetBufferSize(), NULL, &g_pVertexShader );
		assert(SUCCEEDED(hr));
		hr = g_device11->CreatePixelShader( ps->GetBufferPointer(), ps->GetBufferSize(), NULL, &g_pPixelShader );
		assert(SUCCEEDED(hr));
	}

	// create input layout
	{
		// Create our vertex input layout
		const 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 },
			{ "TEXCOORD",  0, DXGI_FORMAT_R32G32_FLOAT,    0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		};

		UINT numElements = sizeof( layout ) / sizeof( layout[0] );
		HRESULT hr = g_device11->CreateInputLayout( layout, numElements, vs->GetBufferPointer(),
			vs->GetBufferSize(), &g_pVertexLayout );
		assert(SUCCEEDED(hr));
	}

	SAFE_RELEASE(vs);
	SAFE_RELEASE(ps);

	RecreateTargets(window_width, window_height);

	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;
}
Example #25
0
//--------------------------------------------------------------------------------------
// Enumerate for each adapter all of the supported display modes, 
// device types, adapter formats, back buffer formats, window/full screen support, 
// depth stencil formats, multisampling types/qualities, and presentations intervals.
//
// For each combination of device type (HAL/REF), adapter format, back buffer format, and
// IsWindowed it will call the app's ConfirmDevice callback.  This allows the app
// to reject or allow that combination based on its caps/etc.  It also allows the 
// app to change the BehaviorFlags.  The BehaviorFlags defaults non-pure HWVP 
// if supported otherwise it will default to SWVP, however the app can change this 
// through the ConfirmDevice callback.
//--------------------------------------------------------------------------------------
_Use_decl_annotations_
HRESULT CD3D11Enumeration::Enumerate( LPDXUTCALLBACKISD3D11DEVICEACCEPTABLE IsD3D11DeviceAcceptableFunc,
                                      void* pIsD3D11DeviceAcceptableFuncUserContext )
{
    CDXUTPerfEventGenerator eventGenerator( DXUT_PERFEVENTCOLOR, L"DXUT D3D11 Enumeration" );
    HRESULT hr;
    IDXGIFactory1* pFactory = DXUTGetDXGIFactory();
    if( !pFactory )
        return E_FAIL;

    m_bHasEnumerated = true;
    m_IsD3D11DeviceAcceptableFunc = IsD3D11DeviceAcceptableFunc;
    m_pIsD3D11DeviceAcceptableFuncUserContext = pIsD3D11DeviceAcceptableFuncUserContext;

    ClearAdapterInfoList();

    for( int index = 0; ; ++index )
    {
        IDXGIAdapter* pAdapter = nullptr;
        hr = pFactory->EnumAdapters( index, &pAdapter );
        if( FAILED( hr ) ) // DXGIERR_NOT_FOUND is expected when the end of the list is hit
            break;

        IDXGIAdapter2* pAdapter2 = nullptr;
        if ( SUCCEEDED( pAdapter->QueryInterface( __uuidof(IDXGIAdapter2), ( LPVOID* )&pAdapter2 ) ) )
        {
            // Succeeds on DirectX 11.1 Runtime systems
            DXGI_ADAPTER_DESC2 desc;
            hr = pAdapter2->GetDesc2( &desc );
            pAdapter2->Release();

            if ( SUCCEEDED(hr) && ( desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE ) )
            {
                // Skip "always there" Microsoft Basics Display Driver
                pAdapter->Release();
                continue;
            }
        }

        CD3D11EnumAdapterInfo* pAdapterInfo = new (std::nothrow) CD3D11EnumAdapterInfo;
        if( !pAdapterInfo )
        {
            SAFE_RELEASE( pAdapter );
            return E_OUTOFMEMORY;
        }
        pAdapterInfo->AdapterOrdinal = index;
        pAdapter->GetDesc( &pAdapterInfo->AdapterDesc );
        pAdapterInfo->m_pAdapter = pAdapter;

        // Enumerate the device driver types on the adapter.
        hr = EnumerateDevices( pAdapterInfo );
        if( FAILED( hr ) )
        {
            delete pAdapterInfo;
            continue;
        }

        hr = EnumerateOutputs( pAdapterInfo );
        if( FAILED( hr ) || pAdapterInfo->outputInfoList.empty() )
        {
            delete pAdapterInfo;
            continue;
        }

        // Get info for each devicecombo on this device
        if( FAILED( hr = EnumerateDeviceCombos( pAdapterInfo ) ) )
        {
            delete pAdapterInfo;
            continue;
        }

        m_AdapterInfoList.push_back( pAdapterInfo );
    }

    //  If we did not get an adapter then we should still enumerate WARP and Ref.
    if (m_AdapterInfoList.size() == 0)
    {
        CD3D11EnumAdapterInfo* pAdapterInfo = new (std::nothrow) CD3D11EnumAdapterInfo;
        if( !pAdapterInfo )
        {
            return E_OUTOFMEMORY;
        }
        pAdapterInfo->bAdapterUnavailable = true;

        hr = EnumerateDevices( pAdapterInfo );

        // Get info for each devicecombo on this device
        if( FAILED( hr = EnumerateDeviceCombosNoAdapter(  pAdapterInfo ) ) )
        {
            delete pAdapterInfo;
        }

        if (SUCCEEDED(hr)) m_AdapterInfoList.push_back( pAdapterInfo );
    }

    //
    // Check for 2 or more adapters with the same name. Append the name
    // with some instance number if that's the case to help distinguish
    // them.
    //
    bool bUniqueDesc = true;
    for( size_t i = 0; i < m_AdapterInfoList.size(); i++ )
    {
        auto pAdapterInfo1 = m_AdapterInfoList[ i ];

        for( size_t j = i + 1; j < m_AdapterInfoList.size(); j++ )
        {
            auto pAdapterInfo2 = m_AdapterInfoList[ j ];
            if( wcsncmp( pAdapterInfo1->AdapterDesc.Description,
                pAdapterInfo2->AdapterDesc.Description, DXGI_MAX_DEVICE_IDENTIFIER_STRING ) == 0 )
            {
                bUniqueDesc = false;
                break;
            }
        }

        if( !bUniqueDesc )
            break;
    }

    for( auto it = m_AdapterInfoList.begin(); it != m_AdapterInfoList.end(); ++it )
    {
        wcscpy_s( (*it)->szUniqueDescription, 100, (*it)->AdapterDesc.Description );
        if( !bUniqueDesc )
        {
            WCHAR sz[100];
            swprintf_s( sz, 100, L" (#%u)", (*it)->AdapterOrdinal );
            wcscat_s( (*it)->szUniqueDescription, DXGI_MAX_DEVICE_IDENTIFIER_STRING, sz );
        }
    }

    D3D_FEATURE_LEVEL fLvl[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1 };

    // Check WARP max feature level
    {
        ID3D11Device* pDevice = nullptr;
        hr = DXUT_Dynamic_D3D11CreateDevice( nullptr, D3D_DRIVER_TYPE_WARP, 0, 0, fLvl, _countof(fLvl),
                                             D3D11_SDK_VERSION, &pDevice, &m_warpFL, nullptr );
        if ( hr == E_INVALIDARG )
        {
            // DirectX 11.0 runtime will not recognize FL 11.1, so try without it
            hr = DXUT_Dynamic_D3D11CreateDevice( nullptr, D3D_DRIVER_TYPE_WARP, 0, 0, &fLvl[1], _countof(fLvl) - 1,
                                                 D3D11_SDK_VERSION, &pDevice, &m_warpFL, nullptr );
        }

        if ( SUCCEEDED(hr) )
        {
            pDevice->Release();
        }
        else
            m_warpFL = D3D_FEATURE_LEVEL_10_1;
    }

    // Check REF max feature level
    {
        ID3D11Device* pDevice = nullptr;
        hr = DXUT_Dynamic_D3D11CreateDevice( nullptr, D3D_DRIVER_TYPE_REFERENCE, 0, 0, fLvl, _countof(fLvl),
                                             D3D11_SDK_VERSION, &pDevice, &m_refFL, nullptr );
        if ( hr == E_INVALIDARG )
        {
            // DirectX 11.0 runtime will not recognize FL 11.1, so try without it
            hr = DXUT_Dynamic_D3D11CreateDevice( nullptr, D3D_DRIVER_TYPE_REFERENCE, 0, 0, &fLvl[1], _countof(fLvl) - 1,
                                                 D3D11_SDK_VERSION, &pDevice, &m_refFL, nullptr );
        }

        if ( SUCCEEDED(hr) )
        {
            pDevice->Release();
        }
        else
            m_refFL = D3D_FEATURE_LEVEL_11_0;
    }

    return S_OK;
}
Example #26
0
bool DoD3D11Hook(ID3D11Device *device)
{
    HRESULT hErr;

    bD3D101Hooked = true;
    HMODULE hD3D10_1 = LoadLibrary(TEXT("d3d10_1.dll"));
    if(!hD3D10_1)
    {
        RUNONCE logOutput << "DoD3D11Hook: could not load d3d10.1" << endl;
        return false;
    }

    HMODULE hDXGI = GetModuleHandle(TEXT("dxgi.dll"));
    if(!hDXGI)
    {
        RUNONCE logOutput << "DoD3D11Hook: could not load dxgi" << endl;
        return false;
    }

    CREATEDXGIFACTORY1PROC createDXGIFactory1 = (CREATEDXGIFACTORY1PROC)GetProcAddress(hDXGI, "CreateDXGIFactory1");
    if(!createDXGIFactory1)
    {
        RUNONCE logOutput << "DoD3D11Hook: could not get address of CreateDXGIFactory1" << endl;
        return false;
    }

    PFN_D3D10_CREATE_DEVICE1 d3d10CreateDevice1 = (PFN_D3D10_CREATE_DEVICE1)GetProcAddress(hD3D10_1, "D3D10CreateDevice1");
    if(!d3d10CreateDevice1)
    {
        RUNONCE logOutput << "DoD3D11Hook: could not get address of D3D10CreateDevice1" << endl;
        return false;
    }

    IDXGIFactory1 *factory;
    if(FAILED(hErr = (*createDXGIFactory1)(__uuidof(IDXGIFactory1), (void**)&factory)))
    {
        RUNONCE logOutput << "DoD3D11Hook: CreateDXGIFactory1 failed, result = " << UINT(hErr) << endl;
        return false;
    }

    IDXGIAdapter1 *adapter;
    if(FAILED(hErr = factory->EnumAdapters1(0, &adapter)))
    {
        RUNONCE logOutput << "DoD3D11Hook: factory->EnumAdapters1 failed, result = " << UINT(hErr) << endl;
        factory->Release();
        return false;
    }

    if(FAILED(hErr = (*d3d10CreateDevice1)(adapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, 0, D3D10_FEATURE_LEVEL_10_1, D3D10_1_SDK_VERSION, &shareDevice)))
    {
        if(FAILED(hErr = (*d3d10CreateDevice1)(adapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, 0, D3D10_FEATURE_LEVEL_9_3, D3D10_1_SDK_VERSION, &shareDevice)))
        {
            RUNONCE logOutput << "DoD3D11Hook: device creation failed, result = " << UINT(hErr) << endl;
            adapter->Release();
            factory->Release();
            return false;
        }
    }

    adapter->Release();
    factory->Release();

    //------------------------------------------------

    D3D11_TEXTURE2D_DESC texGameDesc;
    ZeroMemory(&texGameDesc, sizeof(texGameDesc));
    texGameDesc.Width               = d3d11CaptureInfo.cx;
    texGameDesc.Height              = d3d11CaptureInfo.cy;
    texGameDesc.MipLevels           = 1;
    texGameDesc.ArraySize           = 1;
    texGameDesc.Format              = dxgiFormat;
    texGameDesc.SampleDesc.Count    = 1;
    texGameDesc.BindFlags           = D3D11_BIND_RENDER_TARGET|D3D11_BIND_SHADER_RESOURCE;
    texGameDesc.Usage               = D3D11_USAGE_DEFAULT;
    texGameDesc.MiscFlags           = D3D11_RESOURCE_MISC_SHARED;

    ID3D11Texture2D *d3d11Tex;
    if(FAILED(hErr = device->CreateTexture2D(&texGameDesc, NULL, &d3d11Tex)))
    {
        RUNONCE logOutput << "DoD3D11Hook: creation of intermediary texture failed, result = " << UINT(hErr) << endl;
        return false;
    }

    if(FAILED(hErr = d3d11Tex->QueryInterface(__uuidof(ID3D11Resource), (void**)&copyTextureGame)))
    {
        RUNONCE logOutput << "DoD3D11Hook: d3d11Tex->QueryInterface(ID3D11Resource) failed, result = " << UINT(hErr) << endl;
        d3d11Tex->Release();
        return false;
    }

    IDXGIResource *res;
    if(FAILED(hErr = d3d11Tex->QueryInterface(IID_IDXGIResource, (void**)&res)))
    {
        RUNONCE logOutput << "DoD3D11Hook: d3d11Tex->QueryInterface(IID_IDXGIResource) failed, result = " << UINT(hErr) << endl;
        d3d11Tex->Release();
        return false;
    }

    HANDLE handle;
    if(FAILED(hErr = res->GetSharedHandle(&handle)))
    {
        RUNONCE logOutput << "DoD3D11Hook: res->GetSharedHandle failed, result = " << UINT(hErr) << endl;
        d3d11Tex->Release();
        res->Release();
        return false;
    }

    d3d11Tex->Release();
    res->Release();

    //------------------------------------------------

    if(FAILED(hErr = shareDevice->OpenSharedResource(handle, __uuidof(ID3D10Resource), (void**)&copyTextureIntermediary)))
    {
        RUNONCE logOutput << "DoD3D11Hook: shareDevice->OpenSharedResource failed, result = " << UINT(hErr) << endl;
        return false;
    }

    //------------------------------------------------

    D3D10_TEXTURE2D_DESC texDesc;
    ZeroMemory(&texDesc, sizeof(texDesc));
    texDesc.Width               = d3d11CaptureInfo.cx;
    texDesc.Height              = d3d11CaptureInfo.cy;
    texDesc.MipLevels           = 1;
    texDesc.ArraySize           = 1;
    texDesc.Format              = dxgiFormat;
    texDesc.SampleDesc.Count    = 1;
    texDesc.BindFlags           = D3D10_BIND_RENDER_TARGET|D3D10_BIND_SHADER_RESOURCE;
    texDesc.Usage               = D3D10_USAGE_DEFAULT;
    texDesc.MiscFlags           = D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX;

    for(UINT i=0; i<2; i++)
    {
        ID3D10Texture2D *d3d10tex;
        if(FAILED(hErr = shareDevice->CreateTexture2D(&texDesc, NULL, &d3d10tex)))
        {
            RUNONCE logOutput << "DoD3D11Hook: shareDevice->CreateTexture2D " << i << " failed, result = " << UINT(hErr) << endl;
            return false;
        }

        if(FAILED(hErr = d3d10tex->QueryInterface(__uuidof(ID3D10Resource), (void**)&sharedTextures[i])))
        {
            RUNONCE logOutput << "DoD3D11Hook: d3d10tex->QueryInterface(ID3D10Resource) " << i << " failed, result = " << UINT(hErr) << endl;
            d3d10tex->Release();
            return false;
        }

        if(FAILED(hErr = d3d10tex->QueryInterface(__uuidof(IDXGIKeyedMutex), (void**)&keyedMutexes[i])))
        {
            RUNONCE logOutput << "DoD3D11Hook: d3d10tex->QueryInterface(IDXGIKeyedMutex) " << i << " failed, result = " << UINT(hErr) << endl;
            d3d10tex->Release();
            return false;
        }

        IDXGIResource *res;
        if(FAILED(hErr = d3d10tex->QueryInterface(__uuidof(IDXGIResource), (void**)&res)))
        {
            RUNONCE logOutput << "DoD3D11Hook: d3d10tex->QueryInterface(IDXGIResource) " << i << " failed, result = " << UINT(hErr) << endl;
            d3d10tex->Release();
            return false;
        }

        if(FAILED(hErr = res->GetSharedHandle(&sharedHandles[i])))
        {
            RUNONCE logOutput << "DoD3D11Hook: res->GetSharedHandle " << i << " failed, result = " << UINT(hErr) << endl;
            res->Release();
            d3d10tex->Release();
            return false;
        }

        res->Release();
        d3d10tex->Release();
    }

    return true;
}
Example #27
0
D3D10System::D3D10System()
{
    HRESULT err;

#ifdef USE_DXGI1_2
    REFIID iidVal = OSGetVersion() >= 8 ? __uuidof(IDXGIFactory2) : __uuidof(IDXGIFactory1);
#else
    REFIID iidVal = __uuidof(IDXGIFactory1);
#endif

    UINT adapterID = GlobalConfig->GetInt(TEXT("Video"), TEXT("Adapter"), 0);

    IDXGIFactory1 *factory;
    if(FAILED(err = CreateDXGIFactory1(iidVal, (void**)&factory)))
        CrashError(TEXT("Could not create DXGI factory"));

    IDXGIAdapter1 *adapter;
    if(FAILED(err = factory->EnumAdapters1(adapterID, &adapter)))
        CrashError(TEXT("Could not get DXGI adapter"));

    //------------------------------------------------------------------

    DXGI_SWAP_CHAIN_DESC swapDesc;
    zero(&swapDesc, sizeof(swapDesc));
    swapDesc.BufferCount = 2;
    swapDesc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
    swapDesc.BufferDesc.Width  = App->renderFrameWidth;
    swapDesc.BufferDesc.Height = App->renderFrameHeight;
    swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    swapDesc.Flags = 0;
    swapDesc.OutputWindow = hwndRenderFrame;
    swapDesc.SampleDesc.Count = 1;
    swapDesc.Windowed = TRUE;

    bDisableCompatibilityMode = 1;//AppConfig->GetInt(TEXT("Video"), TEXT("DisableD3DCompatibilityMode"), 1) != 0;

    UINT createFlags = D3D10_CREATE_DEVICE_BGRA_SUPPORT;
    if(GlobalConfig->GetInt(TEXT("General"), TEXT("UseDebugD3D")))
        createFlags |= D3D10_CREATE_DEVICE_DEBUG;

    D3D10_FEATURE_LEVEL1 level = bDisableCompatibilityMode ? D3D10_FEATURE_LEVEL_10_1 : D3D10_FEATURE_LEVEL_9_3;

    //D3D10_CREATE_DEVICE_DEBUG
    //D3D11_DRIVER_TYPE_REFERENCE, D3D11_DRIVER_TYPE_HARDWARE
    err = D3D10CreateDeviceAndSwapChain1(adapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, createFlags, level, D3D10_1_SDK_VERSION, &swapDesc, &swap, &d3d);
    if(FAILED(err))
    {
        bDisableCompatibilityMode = !bDisableCompatibilityMode;
        level = bDisableCompatibilityMode ? D3D10_FEATURE_LEVEL_10_1 : D3D10_FEATURE_LEVEL_9_3;
        err = D3D10CreateDeviceAndSwapChain1(adapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, createFlags, level, D3D10_1_SDK_VERSION, &swapDesc, &swap, &d3d);
    }

    if(FAILED(err))
        CrashError(TEXT("Could not create D3D10 device and swap chain.  This error can happen for one of the following reasons:\r\n\r\n1.) Your GPU is not supported (DirectX 10 support is required - many integrated laptop GPUs do not support DX10)\r\n2.) You're running Windows Vista without the \"Platform Update\"\r\n3.) Your video card drivers are out of date"));

    adapter->Release();
    factory->Release();

    //------------------------------------------------------------------

    Log(TEXT("Loading up D3D10..."));

    D3D10_DEPTH_STENCIL_DESC depthDesc;
    zero(&depthDesc, sizeof(depthDesc));
    depthDesc.DepthEnable = FALSE;

    err = d3d->CreateDepthStencilState(&depthDesc, &depthState);
    if(FAILED(err))
        CrashError(TEXT("Unable to create depth state"));

    d3d->OMSetDepthStencilState(depthState, 0);

    //------------------------------------------------------------------

    D3D10_RASTERIZER_DESC rasterizerDesc;
    zero(&rasterizerDesc, sizeof(rasterizerDesc));
    rasterizerDesc.FillMode = D3D10_FILL_SOLID;
    rasterizerDesc.CullMode = D3D10_CULL_NONE;
    rasterizerDesc.FrontCounterClockwise = FALSE;
    rasterizerDesc.DepthClipEnable = TRUE;

    err = d3d->CreateRasterizerState(&rasterizerDesc, &rasterizerState);
    if(FAILED(err))
        CrashError(TEXT("Unable to create rasterizer state"));

    d3d->RSSetState(rasterizerState);

    //------------------------------------------------------------------

    rasterizerDesc.ScissorEnable = TRUE;

    err = d3d->CreateRasterizerState(&rasterizerDesc, &scissorState);
    if(FAILED(err))
        CrashError(TEXT("Unable to create scissor state"));

    //------------------------------------------------------------------

    ID3D10Texture2D *backBuffer = NULL;
    err = swap->GetBuffer(0, IID_ID3D10Texture2D, (void**)&backBuffer);
    if(FAILED(err))
        CrashError(TEXT("Unable to get back buffer from swap chain"));

    err = d3d->CreateRenderTargetView(backBuffer, NULL, &swapRenderView);
    if(FAILED(err))
        CrashError(TEXT("Unable to get render view from back buffer"));

    backBuffer->Release();

    //------------------------------------------------------------------

    D3D10_BLEND_DESC disabledBlendDesc;
    zero(&disabledBlendDesc, sizeof(disabledBlendDesc));
    for(int i=0; i<8; i++)
    {
        disabledBlendDesc.BlendEnable[i]        = TRUE;
        disabledBlendDesc.RenderTargetWriteMask[i] = D3D10_COLOR_WRITE_ENABLE_ALL;
    }
    disabledBlendDesc.BlendOpAlpha          = D3D10_BLEND_OP_ADD;
    disabledBlendDesc.BlendOp               = D3D10_BLEND_OP_ADD;
    disabledBlendDesc.SrcBlendAlpha         = D3D10_BLEND_ONE;
    disabledBlendDesc.DestBlendAlpha        = D3D10_BLEND_ZERO;
    disabledBlendDesc.SrcBlend              = D3D10_BLEND_ONE;
    disabledBlendDesc.DestBlend             = D3D10_BLEND_ZERO;

    err = d3d->CreateBlendState(&disabledBlendDesc, &disabledBlend);
    if(FAILED(err))
        CrashError(TEXT("Unable to create disabled blend state"));

    this->BlendFunction(GS_BLEND_SRCALPHA, GS_BLEND_INVSRCALPHA, 1.0f);
    bBlendingEnabled = true;
}
int main() {

  printf("\n\ntest_win_api_directx_research\n\n");

  /* Retrieve a IDXGIFactory that can enumerate the adapters. */
  IDXGIFactory1* factory = NULL;
  HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)(&factory));

  if (S_OK != hr) {
    printf("Error: failed to retrieve the IDXGIFactory.\n");
    exit(EXIT_FAILURE);
  }

  /* Enumerate the adapters.*/
  UINT i = 0;
  IDXGIAdapter1* adapter = NULL;
  std::vector<IDXGIAdapter1*> adapters; /* Needs to be Released(). */

  while (DXGI_ERROR_NOT_FOUND != factory->EnumAdapters1(i, &adapter)) {
    adapters.push_back(adapter);
    ++i;
  }

  /* Get some info about the adapters (GPUs). */
  for (size_t i = 0; i < adapters.size(); ++i) {
    
    DXGI_ADAPTER_DESC1 desc;
    adapter = adapters[i];
    hr = adapter->GetDesc1(&desc);
    
    if (S_OK != hr) {
      printf("Error: failed to get a description for the adapter: %lu\n", i);
      continue;
    }

    wprintf(L"Adapter: %lu, description: %s\n", i, desc.Description);
  }

  /* Check what devices/monitors are attached to the adapters. */
  UINT dx = 0;
  IDXGIOutput* output = NULL;
  std::vector<IDXGIOutput*> outputs; /* Needs to be Released(). */
  
  for (size_t i = 0; i < adapters.size(); ++i) {

    dx = 0;
    adapter = adapters[i];
    
    while (DXGI_ERROR_NOT_FOUND != adapter->EnumOutputs(dx, &output)) {
      printf("Found monitor %d on adapter: %lu\n", dx, i);
      outputs.push_back(output);
      ++dx;
    }
  }

  if (0 >= outputs.size()) {
    printf("Error: no outputs found (%lu).\n", outputs.size());
    exit(EXIT_FAILURE);
  }

  /* Print some info about the monitors. */
  for (size_t i = 0; i < outputs.size(); ++i) {
    
    DXGI_OUTPUT_DESC desc;
    output = outputs[i];
    hr = output->GetDesc(&desc);
    
    if (S_OK != hr) {
      printf("Error: failed to retrieve a DXGI_OUTPUT_DESC for output %lu.\n", i);
      continue;
    }

    wprintf(L"Monitor: %s, attached to desktop: %c\n", desc.DeviceName, (desc.AttachedToDesktop) ? 'y' : 'n');
  }

  /*

    To get access to a OutputDuplication interface we need to have a 
    Direct3D device which handles the actuall rendering and "gpu" 
    stuff. According to a gamedev stackexchange it seems we can create
    one w/o a HWND. 

   */

  ID3D11Device* d3d_device = NULL; /* Needs to be released. */
  ID3D11DeviceContext* d3d_context = NULL; /* Needs to be released. */
  IDXGIAdapter1* d3d_adapter = NULL;
  D3D_FEATURE_LEVEL d3d_feature_level; /* The selected feature level (D3D version), selected from the Feature Levels array, which is NULL here; when it's NULL the default list is used see:  https://msdn.microsoft.com/en-us/library/windows/desktop/ff476082%28v=vs.85%29.aspx ) */
  
  { /* Start creating a D3D11 device */

#if 1
    /* 
       NOTE:  Apparently the D3D11CreateDevice function returns E_INVALIDARG, when
              you pass a pointer to an adapter for the first parameter and use the 
              D3D_DRIVER_TYPE_HARDWARE. When you want to pass a valid pointer for the
              adapter, you need to set the DriverType parameter (2nd) to 
              D3D_DRIVER_TYPE_UNKNOWN.
             
              @todo figure out what would be the best solution; easiest to use is 
              probably using NULL here. 
     */
    int use_adapter = 0;
    if (use_adapter >= adapters.size()) {
      printf("Invalid adapter index: %d, we only have: %lu - 1\n", use_adapter, adapters.size());
      exit(EXIT_FAILURE);
    }

    d3d_adapter = adapters[use_adapter];
    if (NULL == d3d_adapter) {
      printf("Error: the stored adapter is NULL.\n");
      exit(EXIT_FAILURE);
    }
#endif

    hr = D3D11CreateDevice(d3d_adapter,              /* Adapter: The adapter (video card) we want to use. We may use NULL to pick the default adapter. */  
                           D3D_DRIVER_TYPE_UNKNOWN,  /* DriverType: We use the GPU as backing device. */
                           NULL,                     /* Software: we're using a D3D_DRIVER_TYPE_HARDWARE so it's not applicaple. */
                           NULL,                     /* Flags: maybe we need to use D3D11_CREATE_DEVICE_BGRA_SUPPORT because desktop duplication is using this. */
                           NULL,                     /* Feature Levels (ptr to array):  what version to use. */
                           0,                        /* Number of feature levels. */
                           D3D11_SDK_VERSION,        /* The SDK version, use D3D11_SDK_VERSION */
                           &d3d_device,              /* OUT: the ID3D11Device object. */
                           &d3d_feature_level,       /* OUT: the selected feature level. */
                           &d3d_context);            /* OUT: the ID3D11DeviceContext that represents the above features. */

    if (S_OK != hr) {
      printf("Error: failed to create the D3D11 Device.\n");
      if (E_INVALIDARG == hr) {
        printf("Got INVALID arg passed into D3D11CreateDevice. Did you pass a adapter + a driver which is not the UNKNOWN driver?.\n");
      }
      exit(EXIT_FAILURE);
    }
    
  } /* End creating a D3D11 device. */
  
  /* 
     Create a IDXGIOutputDuplication for the first monitor. 
     
     - From a IDXGIOutput which represents an monitor, we query a IDXGIOutput1
       because the IDXGIOutput1 has the DuplicateOutput feature. 
  */

  IDXGIOutput1* output1 = NULL;
  IDXGIOutputDuplication* duplication = NULL;
  
  { /* Start IDGIOutputDuplication init. */
    
    int use_monitor = 0;
    if (use_monitor >= outputs.size()) {
      printf("Invalid monitor index: %d, we only have: %lu - 1\n", use_monitor, outputs.size());
      exit(EXIT_FAILURE);
    }

    output = outputs[use_monitor];
    if (NULL == output) {
      printf("No valid output found. The output is NULL.\n");
      exit(EXIT_FAILURE);
    }
    
    hr = output->QueryInterface(__uuidof(IDXGIOutput1), (void**)&output1);
    if (S_OK != hr) {
      printf("Error: failed to query the IDXGIOutput1 interface.\n");
      exit(EXIT_FAILURE);
    }

    hr = output1->DuplicateOutput(d3d_device, &duplication);
    if (S_OK != hr) {
      printf("Error: failed to create the duplication output.\n");
      exit(EXIT_FAILURE);
    }
    printf("Queried the IDXGIOutput1.\n");
                                
  } /* End IDGIOutputDuplication init. */

  if (NULL == duplication) {
    printf("Error: okay, we shouldn't arrive here but the duplication var is NULL.\n");
    exit(EXIT_FAILURE);
  }

  /*
    To download the pixel data from the GPU we need a 
    staging texture. Therefore we need to determine the width and 
    height of the buffers that we receive. 
    
    @TODO - We could also retrieve the width/height from the texture we got 
            from through the acquired frame (see the 'tex' variable below).
            That may be a safer solution.
  */
  DXGI_OUTPUT_DESC output_desc;
  {
    hr = output->GetDesc(&output_desc);
    if (S_OK != hr) {
      printf("Error: failed to get the DXGI_OUTPUT_DESC from the output (monitor). We need this to create a staging texture when downloading the pixels from the gpu.\n");
      exit(EXIT_FAILURE);
    }

    printf("The monitor has the following dimensions: left: %d, right: %d, top: %d, bottom: %d.\n"
           ,(int)output_desc.DesktopCoordinates.left
           ,(int)output_desc.DesktopCoordinates.right
           ,(int)output_desc.DesktopCoordinates.top
           ,(int)output_desc.DesktopCoordinates.bottom
           );
  }

  if (0 == output_desc.DesktopCoordinates.right
      || 0 == output_desc.DesktopCoordinates.bottom)
    {
      printf("The output desktop coordinates are invalid.\n");
      exit(EXIT_FAILURE);
    }
    
  /* Create the staging texture that we need to download the pixels from gpu. */
  D3D11_TEXTURE2D_DESC tex_desc;
  tex_desc.Width = output_desc.DesktopCoordinates.right;
  tex_desc.Height = output_desc.DesktopCoordinates.bottom;
  tex_desc.MipLevels = 1;
  tex_desc.ArraySize = 1; /* When using a texture array. */
  tex_desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; /* This is the default data when using desktop duplication, see https://msdn.microsoft.com/en-us/library/windows/desktop/hh404611(v=vs.85).aspx */
  tex_desc.SampleDesc.Count = 1; /* MultiSampling, we can use 1 as we're just downloading an existing one. */
  tex_desc.SampleDesc.Quality = 0; /* "" */
  tex_desc.Usage = D3D11_USAGE_STAGING;
  tex_desc.BindFlags = 0;
  tex_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
  tex_desc.MiscFlags = 0;

  ID3D11Texture2D* staging_tex = NULL;
  hr = d3d_device->CreateTexture2D(&tex_desc, NULL, &staging_tex);
  if (E_INVALIDARG == hr) {
    printf("Error: received E_INVALIDARG when trying to create the texture.\n");
    exit(EXIT_FAILURE);
  }
  else if (S_OK != hr) {
    printf("Error: failed to create the 2D texture, error: %d.\n", hr);
    exit(EXIT_FAILURE);
  }
   
  /* 
     Get some info about the output duplication. 
     When the DesktopImageInSystemMemory is TRUE you can use 
     the MapDesktopSurface/UnMapDesktopSurface directly to retrieve the
     pixel data. If not, then you need to use a surface. 

  */
  DXGI_OUTDUPL_DESC duplication_desc;
  duplication->GetDesc(&duplication_desc);
  printf("duplication desc.DesktopImageInSystemMemory: %c\n", (duplication_desc.DesktopImageInSystemMemory) ? 'y' : 'n');
  
  /* Access a couple of frames. */
  DXGI_OUTDUPL_FRAME_INFO frame_info;
  IDXGIResource* desktop_resource = NULL;
  ID3D11Texture2D* tex = NULL;
  DXGI_MAPPED_RECT mapped_rect;
  
  for (int i = 0; i < 500; ++i) {
    //  printf("%02d - ", i);
    
    hr = duplication->AcquireNextFrame(1000, &frame_info, &desktop_resource);
    if (DXGI_ERROR_ACCESS_LOST == hr) {
      printf("Received a DXGI_ERROR_ACCESS_LOST.\n");
    }
    else if (DXGI_ERROR_WAIT_TIMEOUT == hr) {
      printf("Received a DXGI_ERROR_WAIT_TIMEOUT.\n");
    }
    else if (DXGI_ERROR_INVALID_CALL == hr) {
      printf("Received a DXGI_ERROR_INVALID_CALL.\n");
    }
    else if (S_OK == hr) {
      //printf("Yay we got a frame.\n");

      /* Print some info. */
      //printf("frame_info.TotalMetadataBufferSize: %u\n", frame_info.TotalMetadataBufferSize);
      //printf("frame_info.AccumulatedFrames: %u\n", frame_info.AccumulatedFrames);

      /* Get the texture interface .. */
#if 1      
      hr = desktop_resource->QueryInterface(__uuidof(ID3D11Texture2D), (void**)&tex);
      if (S_OK != hr) {
        printf("Error: failed to query the ID3D11Texture2D interface on the IDXGIResource we got.\n");
        exit(EXIT_FAILURE);
      }
#endif      

      /* Map the desktop surface */
      hr = duplication->MapDesktopSurface(&mapped_rect);
      if (S_OK == hr) {
        printf("We got acess to the desktop surface\n");
        hr = duplication->UnMapDesktopSurface();
        if (S_OK != hr) {
          printf("Error: failed to unmap the desktop surface after successfully mapping it.\n");
        }
      }
      else if (DXGI_ERROR_UNSUPPORTED == hr) {
        //printf("MapDesktopSurface returned DXGI_ERROR_UNSUPPORTED.\n");
        /* 
           According to the docs, when we receive this error we need
           to transfer the image to a staging surface and then lock the 
            image by calling IDXGISurface::Map().

           To get the data from GPU to the CPU, we do:

               - copy the frame into our staging texture
               - map the texture 
               - ... do something 
               - unmap.

           @TODO figure out what solution is faster:

           There are multiple solutions to copy a texture. I have 
           to look into what solution is better. 
           -  d3d_context->CopySubresourceRegion();
           -  d3d_context->CopyResource(dest, src)

           @TODO we need to make sure that the width/height are valid. 
 
        */

        d3d_context->CopyResource(staging_tex, tex);

        D3D11_MAPPED_SUBRESOURCE map;
        HRESULT map_result = d3d_context->Map(staging_tex,          /* Resource */
                                              0,                    /* Subresource */ 
                                              D3D11_MAP_READ,       /* Map type. */
                                              0,                    /* Map flags. */
                                              &map);

        if (S_OK == map_result) {
          unsigned char* data = (unsigned char*)map.pData;
          //printf("Mapped the staging tex; we can access the data now.\n");
          printf("RowPitch: %u, DepthPitch: %u, %02X, %02X, %02X\n", map.RowPitch, map.DepthPitch, data[0], data[1], data[2]);
#if 0
          if (i < 25) {
            char fname[512];

            /* We have to make the image opaque. */

            for (int k = 0; k < tex_desc.Width; ++k) {
              for (int l = 0; l < tex_desc.Height; ++l) {
                int dx = l * tex_desc.Width * 4 + k * 4;
                data[dx + 3] = 0xFF;
              }
            }
            sprintf(fname, "capture_%03d.png", i);
            save_png(fname,
                     tex_desc.Width, tex_desc.Height, 8, PNG_COLOR_TYPE_RGBA,
                     (unsigned char*)map.pData, map.RowPitch, PNG_TRANSFORM_BGR);
          }
#endif
        }
        else {
          printf("Error: failed to map the staging tex. Cannot access the pixels.\n");
        }

        d3d_context->Unmap(staging_tex, 0);
      }
      else if (DXGI_ERROR_INVALID_CALL == hr) {
        printf("MapDesktopSurface returned DXGI_ERROR_INVALID_CALL.\n");
      }
      else if (DXGI_ERROR_ACCESS_LOST == hr) {
        printf("MapDesktopSurface returned DXGI_ERROR_ACCESS_LOST.\n");
      }
      else if (E_INVALIDARG == hr) {
        printf("MapDesktopSurface returned E_INVALIDARG.\n");
      }
      else {
        printf("MapDesktopSurface returned an unknown error.\n");
      }
    }

    /* Clean up */
    {

      if (NULL != tex) {
        tex->Release();
        tex = NULL;
      }
      
      if (NULL != desktop_resource) {
        desktop_resource->Release();
        desktop_resource = NULL;
      }

      /* We must release the frame. */
      hr = duplication->ReleaseFrame();
      if (S_OK != hr) {
        printf("Failed to release the duplication frame.\n");
      }
    }
  }
  
  //printf("Monitors connected to adapter: %lu\n", i);

  /* Cleanup */
  {

    if (NULL != staging_tex) {
      staging_tex->Release();
      staging_tex = NULL;
    }
    
    if (NULL != d3d_device) {
      d3d_device->Release();
      d3d_device = NULL;
    }

    if (NULL != d3d_context) {
      d3d_context->Release();
      d3d_context = NULL;
    }

    if (NULL != duplication) {
      duplication->Release();
      duplication = NULL;
    }
    
    for (size_t i = 0; i < adapters.size(); ++i) {
      if (NULL != adapters[i]) {
        adapters[i]->Release();
        adapters[i] = NULL;
      }
    }

    for (size_t i = 0; i < outputs.size(); ++i) {
      if (NULL != outputs[i]) {
        outputs[i]->Release();
        outputs[i] = NULL;
      }
    }

    if (NULL != output1) {
      output1->Release();
      output1 = NULL;
    }

    if (NULL != factory) {
      factory->Release();
      factory = NULL;
    }
  }
  
  return 0;
}
Example #29
0
bool DXGI1Device::Init(const mfxU32 adapterNum)
{
    // release the object before initialization
    Close();

    // load up the library if it is not loaded
    if (NULL == m_hModule)
    {
        LoadDLLModule(L"dxgi.dll");
    }

    if (m_hModule)
    {
        DXGICreateFactoryFunc pFunc;
        IDXGIFactory1 *pFactory;
        IDXGIAdapter1 *pAdapter;
        DXGI_ADAPTER_DESC1 desc;
        mfxU32 curAdapter, maxAdapters;
        HRESULT hRes;

        // load address of procedure to create DXGI 1.1 factory
        pFunc = (DXGICreateFactoryFunc) GetProcAddress(m_hModule, "CreateDXGIFactory1");
        if (NULL == pFunc)
        {
            return false;
        }

        // create the factory
#if _MSC_VER >= 1400
        hRes = pFunc(__uuidof(IDXGIFactory1), (void**) (&pFactory));
#else
        hRes = pFunc(IID_IDXGIFactory1, (void**) (&pFactory));
#endif
        if (FAILED(hRes))
        {
            return false;
        }
        m_pDXGIFactory1 = pFactory;

        // get the number of adapters
        curAdapter = 0;
        maxAdapters = 0;
        mfxU32 outputs = 0;
        do
        {
            // get the required adapted
            hRes = pFactory->EnumAdapters1(curAdapter, &pAdapter);
            if (FAILED(hRes))
            {
                break;
            }

            mfxU32 curOutput = 0;
            HRESULT h;
            do
            {
                IDXGIOutput *out;
                h = pAdapter->EnumOutputs(curOutput, &out);
                
                if(FAILED(h))
                    break;

                // if it is the required adapter, save the interface
                if (outputs == adapterNum)
                    m_pDXGIAdapter1 = pAdapter;

                out->Release();
                
                outputs += 1;
                curOutput += 1;
            } while(!m_pDXGIAdapter1 && SUCCEEDED(h));

            if(!m_pDXGIAdapter1)
                pAdapter->Release();

            curAdapter += 1;

        } while (!m_pDXGIAdapter1 && SUCCEEDED(hRes));
        maxAdapters = curAdapter;

        // there is no required adapter
        if (adapterNum >= outputs)
        {
            return false;
        }
        pAdapter = (IDXGIAdapter1 *) m_pDXGIAdapter1;

        // get the adapter's parameters
        hRes = pAdapter->GetDesc1(&desc);
        if (FAILED(hRes))
        {
            return false;
        }

        // save the parameters
        m_vendorID = desc.VendorId;
        m_deviceID = desc.DeviceId;
        *((LUID *) &m_luid) = desc.AdapterLuid;
    }

    return true;

} // bool DXGI1Device::Init(const mfxU32 adapterNum)
Example #30
0
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;
}