예제 #1
0
	// Helper function for acquiring the first available hardware adapter that supports Direct3D 12.
	// If no such adapter can be found, *ppAdapter will be set to nullptr.
	void Renderer::GetHardwareAdapter(_In_ IDXGIFactory4* pFactory, _Outptr_result_maybenull_ IDXGIAdapter1** ppAdapter)
	{
		IDXGIAdapter1* pAdapter = nullptr;
		*ppAdapter = nullptr;

		for(UINT adapterIndex = 0; DXGI_ERROR_NOT_FOUND != pFactory->EnumAdapters1(adapterIndex, &pAdapter); ++adapterIndex)
		{
			DXGI_ADAPTER_DESC1 desc;
			pAdapter->GetDesc1(&desc);

			if(desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)
			{
				// Don't select the Basic Render Driver adapter.
				// If you want a software adapter, pass in "/warp" on the command line.
				continue;
			}

			// Check to see if the adapter supports Direct3D 12, but don't create the
			// actual device yet.
			if(SUCCEEDED(D3D12CreateDevice(pAdapter, D3D_FEATURE_LEVEL_12_1, _uuidof(ID3D12Device), nullptr)))
			{
				break;
			}
		}

		*ppAdapter = pAdapter;
	}
예제 #2
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();
}
예제 #3
0
파일: D3D10System.cpp 프로젝트: Soopah/OBS
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();
    }
}
예제 #4
0
파일: D3D10System.cpp 프로젝트: neilzar/OBS
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();
    }
}
예제 #5
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);
	}
예제 #6
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;
	}
예제 #7
0
bool CRenderer::FindAdapter(IDXGIFactory1** factory, IDXGIAdapter1** adapter)
{
	HRESULT hr = S_OK;
	IDXGIAdapter1 * pCurrentAdapter = nullptr;
	DXGI_ADAPTER_DESC1 Bestdesc;
	if (!factory) {
		Log("Cannot send in a NULL factory");
		return false;
	}
	if (!adapter) {
		Log("Cannot send in a NULL adapter");
		return false;
	}

	// Create a factory to enumerate all of the hardware in the system.
	DXCall(hr = CreateDXGIFactory1(__uuidof(IDXGIFactory), reinterpret_cast<void**>(factory)));

#pragma warning(suppress: 6102)
	if (!*factory) {
		Log("Could not create the factory");
		return false;
	}
	unsigned int index = 0;
	while (DXGI_ERROR_NOT_FOUND != (*factory)->EnumAdapters1(index++, &pCurrentAdapter)) {
		DXGI_ADAPTER_DESC1 desc;
		ZeroMemory(&desc, sizeof(desc));
		DXCall(pCurrentAdapter->GetDesc1(&desc));
		if (nullptr == *adapter) {
			*adapter = pCurrentAdapter;
			Bestdesc = desc;
		}
		else if (Bestdesc.DedicatedSystemMemory < desc.DedicatedSystemMemory) {
			(*adapter)->Release();
			*adapter = pCurrentAdapter;
			Bestdesc = desc;
		}
		else {
			pCurrentAdapter->Release();
		}
	}
	return true;
}
	//-----------------------------------------------------------------------
	BOOL D3D11DriverList::enumerate(IDXGIFactory1*	pDXGIFactory)
	{
		LogManager::getSingleton().logMessage( "D3D11: Driver Detection Starts" );
		// Create the DXGI Factory

		for( UINT iAdapter=0; ; iAdapter++ )
		{
			IDXGIAdapter1*					pDXGIAdapter;
			HRESULT hr = pDXGIFactory->EnumAdapters1( iAdapter, &pDXGIAdapter );
			if( DXGI_ERROR_NOT_FOUND == hr )
			{
				hr = S_OK;
				break;
			}
			if( FAILED(hr) )
			{
				delete pDXGIAdapter;
				return false;
			}

			// we don't want NVIDIA PerfHUD in the list - so - here we filter it out
			DXGI_ADAPTER_DESC1 adaptDesc;
			if ( SUCCEEDED( pDXGIAdapter->GetDesc1( &adaptDesc ) ) )
			{
				const bool isPerfHUD = wcscmp( adaptDesc.Description, L"NVIDIA PerfHUD" ) == 0;

				if (isPerfHUD)
				{
					continue;
				}
			}

			D3D11Device dev;
			mDriverList.push_back(new D3D11Driver( dev,  iAdapter,pDXGIAdapter) );

		}

		LogManager::getSingleton().logMessage( "D3D11: Driver Detection Ends" );

		return TRUE;
	}
예제 #9
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;
}
예제 #10
0
파일: D3D10System.cpp 프로젝트: Soopah/OBS
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();
    }
}
예제 #11
0
void EnumAllDeviceAdapter(rhi::IDeviceAdapter ** & adapterList, uint32 * num)
{
	PtrGIFactory factory;
	HRESULT hr = ::CreateDXGIFactory1(IID_PPV_ARGS(factory.GetAddressOf()));
	K3D_ASSERT(hr == S_OK, "create dx factory failed.");
	vector<IDXGIAdapter1*> adapters;
	IDXGIAdapter1* pAdapter = nullptr;
	for (UINT adapterIndex = 0; DXGI_ERROR_NOT_FOUND != factory->EnumAdapters1(adapterIndex, &pAdapter); ++adapterIndex) {
		DXGI_ADAPTER_DESC1 desc;
		pAdapter->GetDesc1(&desc);
		if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) {
			continue;
		}
		if (SUCCEEDED(D3D12CreateDevice(pAdapter, D3D_FEATURE_LEVEL_11_0, __uuidof(ID3D12Device), nullptr))) {
			adapters.push_back(pAdapter);
		}
	}

	*num = (uint32)adapters.size();
	if (adapters.empty())
	{
		return;
	}

	adapterList = new rhi::IDeviceAdapter*[adapters.size()];
	for (uint32 index = 0; index < adapters.size(); index++)
	{
		DXGI_ADAPTER_DESC1 desc;
		adapters[index]->GetDesc1(&desc);
		GpuVendor vendor = MapIdToVendor(desc.VendorId);
		char VendorName[256] = { 0 };
		StringUtil::WCharToChar(desc.Description, VendorName, 256);
		DX12LOG(Info, "Device", "Vendor is %s, Id is %d.", VendorName, desc.VendorId);
		adapterList[index] = new DeviceAdapter(adapters[index], vendor);
	}
};
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;
}
예제 #13
0
bool D3DApp::InitializeD3D()
{
	// describe our SwapChain Buffer
	DXGI_MODE_DESC mode_desc;
	ZeroMemory(&mode_desc, sizeof(DXGI_MODE_DESC));
	mode_desc.Width = m_width;
	mode_desc.Height = m_height;
	mode_desc.RefreshRate.Numerator = 60;
	mode_desc.RefreshRate.Denominator = 1;
	mode_desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
	mode_desc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
	mode_desc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;

	// describe our SwapChain
	DXGI_SWAP_CHAIN_DESC swapchain_desc; 
	ZeroMemory(&swapchain_desc, sizeof(DXGI_SWAP_CHAIN_DESC));
	swapchain_desc.BufferDesc = mode_desc;
	swapchain_desc.SampleDesc.Count = 1;
	swapchain_desc.SampleDesc.Quality = 0;
	swapchain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	swapchain_desc.BufferCount = 1;
	swapchain_desc.OutputWindow = m_hwnd; 
	swapchain_desc.Windowed = TRUE;
	swapchain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

	// create DXGI factory to enumerate adapters
	IDXGIFactory1 *dxgi_factory;
	HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&dxgi_factory);	

	// use the first adapter	
	IDXGIAdapter1 *adapter;
	hr = dxgi_factory->EnumAdapters1(0, &adapter);
	dxgi_factory->Release();

	// create our Direct3D 11 Device and SwapChain
	hr = D3D11CreateDeviceAndSwapChain(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, D3D11_CREATE_DEVICE_BGRA_SUPPORT,
		NULL, NULL,	D3D11_SDK_VERSION, &swapchain_desc, &m_swap_chain, &m_d3d11_device, NULL, &m_d3d11_device_context);

	// initialize Direct2D, Direct3D 10.1, DirectWrite
	InitializeDWrite(adapter);

	// release the Adapter interface
	adapter->Release();

	// create our BackBuffer and Render Target
	hr = m_swap_chain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&m_back_buffer);
	hr = m_d3d11_device->CreateRenderTargetView(m_back_buffer, NULL, &m_back_buffer_rtv);

	// describe our Depth/Stencil Buffer
	D3D11_TEXTURE2D_DESC depthstencil_desc;
	depthstencil_desc.Width     = m_width;
	depthstencil_desc.Height    = m_height;
	depthstencil_desc.MipLevels = 1;
	depthstencil_desc.ArraySize = 1;
	depthstencil_desc.Format    = DXGI_FORMAT_D24_UNORM_S8_UINT;
	depthstencil_desc.SampleDesc.Count   = 1;
	depthstencil_desc.SampleDesc.Quality = 0;
	depthstencil_desc.Usage          = D3D11_USAGE_DEFAULT;
	depthstencil_desc.BindFlags      = D3D11_BIND_DEPTH_STENCIL;
	depthstencil_desc.CPUAccessFlags = 0; 
	depthstencil_desc.MiscFlags      = 0;

	// create the Depth/Stencil View
	m_d3d11_device->CreateTexture2D(&depthstencil_desc, NULL, &m_depthstencil_buffer);
	m_d3d11_device->CreateDepthStencilView(m_depthstencil_buffer, NULL, &m_depthstencil_view);
	
	// set render target views and depth stencil view
	m_d3d11_device_context->OMSetRenderTargets(1, &m_back_buffer_rtv, m_depthstencil_view);

	// create a shader resource review from the texture D2D will render to
	hr = m_d3d11_device->CreateShaderResourceView(m_shared_texture, NULL, &m_d2d_texture);

	// create off-screen textures
	CD3D11_TEXTURE2D_DESC offscreen_tex_desc(DXGI_FORMAT_R16G16B16A16_FLOAT, m_width, m_height);
	offscreen_tex_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
	offscreen_tex_desc.MipLevels = 1;
	for (int i = 0; i != ARRAYSIZE(m_offscreen_textures); ++i)
	{
		m_d3d11_device->CreateTexture2D(&offscreen_tex_desc, NULL, &m_offscreen_textures[i]);
		m_d3d11_device->CreateShaderResourceView(m_offscreen_textures[i], NULL, &m_offscreen_srvs[i]);
		m_d3d11_device->CreateRenderTargetView(m_offscreen_textures[i], NULL, &m_offscreen_rtvs[i]);
	}

	// create a constant buffer
	D3D11_BUFFER_DESC buffer_desc;
	ZeroMemory(&buffer_desc, sizeof(D3D11_BUFFER_DESC));
	buffer_desc.Usage	  = D3D11_USAGE_DYNAMIC;
	buffer_desc.ByteWidth = sizeof(ShaderParameters);
	buffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
	buffer_desc.MiscFlags = 0;
	hr = m_d3d11_device->CreateBuffer(&buffer_desc, NULL, &m_parameter_buffer);

	buffer_desc.ByteWidth = sizeof(float4);
	hr = m_d3d11_device->CreateBuffer(&buffer_desc, NULL, &m_jitter_buffer);
	hr = m_d3d11_device->CreateBuffer(&buffer_desc, NULL, &m_interleave_buffer);

	// create a texture from file
	D3DX11CreateShaderResourceViewFromFile(m_d3d11_device, TEXT("media/tex.bmp"), NULL, NULL, &m_custom_texture, &hr);

	return true;
}
예제 #14
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)
예제 #15
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;
}
예제 #16
0
bool D3D11App::initAPI(const API_Revision api_revision, const DXGI_FORMAT backBufferFmt, const DXGI_FORMAT depthBufferFmt, const int samples, const uint flags)
{
	backBufferFormat = backBufferFmt;
	depthBufferFormat = depthBufferFmt;
	msaaSamples = samples;

	const bool sampleBackBuffer = (flags & SAMPLE_BACKBUFFER) != 0;

//	if (screen >= GetSystemMetrics(SM_CMONITORS)) screen = 0;

	IDXGIFactory1 *dxgiFactory;
	if (FAILED(CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void **) &dxgiFactory)))
	{
		ErrorMsg("Couldn't create DXGIFactory");
		return false;
	}

	IDXGIAdapter1 *dxgiAdapter;
	if (dxgiFactory->EnumAdapters1(0, &dxgiAdapter) == DXGI_ERROR_NOT_FOUND)
	{
		ErrorMsg("No adapters found");
		return false;
	}

//	DXGI_ADAPTER_DESC1 adapterDesc;
//	dxgiAdapter->GetDesc1(&adapterDesc);

	IDXGIOutput *dxgiOutput;
	if (dxgiAdapter->EnumOutputs(0, &dxgiOutput) == DXGI_ERROR_NOT_FOUND)
	{
		ErrorMsg("No outputs found");
		return false;
	}

	DXGI_OUTPUT_DESC oDesc;
	dxgiOutput->GetDesc(&oDesc);


	// Find a suitable fullscreen format
	int targetHz = 85;
	DXGI_RATIONAL fullScreenRefresh;
	int fsRefresh = 60;
	fullScreenRefresh.Numerator = fsRefresh;
	fullScreenRefresh.Denominator = 1;
	char str[128];

	uint nModes = 0;
	dxgiOutput->GetDisplayModeList(backBufferFormat, 0, &nModes, NULL);
	DXGI_MODE_DESC *modes = new DXGI_MODE_DESC[nModes];
	dxgiOutput->GetDisplayModeList(backBufferFormat, 0, &nModes, modes);

	resolution->clear();
	for (uint i = 0; i < nModes; i++)
	{
		if (modes[i].Width >= 640 && modes[i].Height >= 480)
		{
			sprintf(str, "%dx%d", modes[i].Width, modes[i].Height);
			int index = resolution->addItemUnique(str);

			if (int(modes[i].Width) == fullscreenWidth && int(modes[i].Height) == fullscreenHeight)
			{
				int refresh = modes[i].RefreshRate.Numerator / modes[i].RefreshRate.Denominator;
				if (abs(refresh - targetHz) < abs(fsRefresh - targetHz))
				{
					fsRefresh = refresh;
					fullScreenRefresh = modes[i].RefreshRate;
				}
				resolution->selectItem(index);
			}
		}
	}
	delete [] modes;

	sprintf(str, "%s (%dx%d)", getTitle(), width, height);

	DWORD wndFlags = 0;
	int x, y, w, h;
	if (fullscreen)
	{
		wndFlags |= WS_POPUP;
		x = y = 0;
		w = width;
		h = height;
	}
	else
	{
		wndFlags |= WS_OVERLAPPEDWINDOW;

		RECT wRect;
		wRect.left = 0;
		wRect.right = width;
		wRect.top = 0;
		wRect.bottom = height;
		AdjustWindowRect(&wRect, wndFlags, FALSE);

		MONITORINFO monInfo;
		monInfo.cbSize = sizeof(monInfo);
		GetMonitorInfo(oDesc.Monitor, &monInfo);

		w = min(wRect.right  - wRect.left, monInfo.rcWork.right  - monInfo.rcWork.left);
		h = min(wRect.bottom - wRect.top,  monInfo.rcWork.bottom - monInfo.rcWork.top);
		x = (monInfo.rcWork.left + monInfo.rcWork.right  - w) / 2;
		y = (monInfo.rcWork.top  + monInfo.rcWork.bottom - h) / 2;
	}


	hwnd = CreateWindow("Game", str, wndFlags, x, y, w, h, HWND_DESKTOP, NULL, hInstance, NULL);

	RECT rect;
	GetClientRect(hwnd, &rect);

	// Create device and swap chain
	DWORD deviceFlags = D3D11_CREATE_DEVICE_SINGLETHREADED;
#ifdef _DEBUG
    deviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

	D3D_FEATURE_LEVEL requested_feature_level = (api_revision == D3D11)? D3D_FEATURE_LEVEL_11_0 : (api_revision == D3D11_1)? D3D_FEATURE_LEVEL_10_1 : D3D_FEATURE_LEVEL_10_0;
	D3D_FEATURE_LEVEL feature_level;
	if (FAILED(D3D11CreateDevice(dxgiAdapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, deviceFlags, &requested_feature_level, 1, D3D11_SDK_VERSION, &device, &feature_level, &context)))
	{
		ErrorMsg("Couldn't create D3D11 device");
		return false;
	}

	while (msaaSamples > 0)
	{
		UINT nQuality;
		if (SUCCEEDED(device->CheckMultisampleQualityLevels(backBufferFormat, msaaSamples, &nQuality)) && nQuality > 0)
		{
			if ((flags & NO_SETTING_CHANGE) == 0) antiAliasSamples = msaaSamples;
			break;
		}
		else
		{
			msaaSamples -= 2;
		}
	}
	DXGI_SWAP_CHAIN_DESC sd;
	memset(&sd, 0, sizeof(sd));
	sd.BufferDesc.Width  = rect.right;
	sd.BufferDesc.Height = rect.bottom;
	sd.BufferDesc.Format = backBufferFormat;
	sd.BufferDesc.RefreshRate = fullScreenRefresh;
	sd.BufferUsage = /*DXGI_USAGE_BACK_BUFFER | */DXGI_USAGE_RENDER_TARGET_OUTPUT | (sampleBackBuffer? DXGI_USAGE_SHADER_INPUT : 0);
	sd.BufferCount = 1;
	sd.OutputWindow = hwnd;
	sd.Windowed = (BOOL) (!fullscreen);
	sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
	sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
	sd.SampleDesc.Count = msaaSamples;
	sd.SampleDesc.Quality = 0;

	if (FAILED(dxgiFactory->CreateSwapChain(device, &sd, &swapChain)))
	{
		ErrorMsg("Couldn't create swapchain");
		return false;
	}

	// We'll handle Alt-Enter ourselves thank you very much ...
	dxgiFactory->MakeWindowAssociation(hwnd, DXGI_MWA_NO_WINDOW_CHANGES | DXGI_MWA_NO_ALT_ENTER);

	dxgiOutput->Release();
	dxgiAdapter->Release();
	dxgiFactory->Release();

	if (fullscreen)
	{
		captureMouse(!configDialog->isVisible());
	}

	renderer = new Direct3D11Renderer(device, context);

	if (!createBuffers(sampleBackBuffer))
	{
		delete renderer;
		return false;
	}
	antiAlias->selectItem(antiAliasSamples / 2);

	linearClamp = renderer->addSamplerState(LINEAR, CLAMP, CLAMP, CLAMP);
	defaultFont = renderer->addFont("../Textures/Fonts/Future.dds", "../Textures/Fonts/Future.font", linearClamp);
	blendSrcAlpha = renderer->addBlendState(SRC_ALPHA, ONE_MINUS_SRC_ALPHA);
	noDepthTest  = renderer->addDepthState(false, false);
	noDepthWrite = renderer->addDepthState(true,  false);
	cullNone  = renderer->addRasterizerState(CULL_NONE);
	cullBack  = renderer->addRasterizerState(CULL_BACK);
	cullFront = renderer->addRasterizerState(CULL_FRONT);

	return true;
}
예제 #17
0
bool CRenderer::Initialize(int width, int height, HWND hwnd)
{
	HRESULT result;
	DXGI_SWAP_CHAIN_DESC swapChainDesc;
	D3D_FEATURE_LEVEL featureLevel;
	//ID3D11Texture2D* backBufferPtr;
	D3D11_TEXTURE2D_DESC depthBufferDesc;
	D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
	D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;
	D3D11_RASTERIZER_DESC rasterDesc;
	D3D11_VIEWPORT viewport;


	IDXGIFactory1* factory = nullptr;
	IDXGIAdapter1* adapter = nullptr;


	if (!FindAdapter(&factory, &adapter))
	{
		Log("Unable to find adapter!");
		return false;
	}

	DXCall(result = adapter->EnumOutputs(0, &g_pVideoOutput));

	// set up swapchain, device and context
	ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
	swapChainDesc.BufferCount = 1;
	swapChainDesc.BufferDesc.Width = width;
	swapChainDesc.BufferDesc.Height = height;
	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 = (BOOL)g_windowed;// (fullscreen ? FALSE : TRUE);

	swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
	swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
	swapChainDesc.Flags = 0;

	// used in lieu of default full list
	// will force error/crash if d3d11 is not supported
	featureLevel = D3D_FEATURE_LEVEL_11_0;

	UINT flags = 0;

#if _DEBUG
	flags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

	DXCall(result = D3D11CreateDeviceAndSwapChain(
		NULL,
		D3D_DRIVER_TYPE_HARDWARE,
		NULL,
		flags,
		&featureLevel,
		1,
		D3D11_SDK_VERSION,
		&swapChainDesc,
		&m_pd3dSwapChain,
		&m_pd3dDevice,
		NULL,
		&m_pd3dDeviceContext));

	if (SUCCEEDED(result))
	{
		Log("Device and swap chain created.");
	}
	else
	{
		Log("Renderer did a bad. No device 4 U");
		return false;
	}

	DXNameInit(m_pd3dDeviceContext);
	DXName(m_pd3dDevice, "The Device");
	DXName(m_pd3dDeviceContext, "The Device Context");
	DXName(m_pd3dSwapChain, "The Swap Chain");

	// attach backbuffer to RTV
	DXCall(result = m_pd3dSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&m_pd3dBackBuffer));
	DXCall(result = m_pd3dDevice->CreateRenderTargetView(m_pd3dBackBuffer, NULL, &m_pd3dRenderTargetView));
	//SAFE_RELEASE(backBufferPtr);

	DXName(m_pd3dRenderTargetView, "Backbuffer RTV");

	// setup depth buffer
	ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc));
	depthBufferDesc.Width = width;
	depthBufferDesc.Height = height;
	depthBufferDesc.MipLevels = 1;
	depthBufferDesc.ArraySize = 1;
	depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
	depthBufferDesc.SampleDesc.Count = 1;
	depthBufferDesc.SampleDesc.Quality = 0;
	depthBufferDesc.Usage = D3D11_USAGE_DEFAULT;
	depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;

	DXCall(result = m_pd3dDevice->CreateTexture2D(&depthBufferDesc, NULL, &m_pd3dDepthStencilBuffer));
	DXName(m_pd3dDepthStencilBuffer, "Z Buffer");

	// set up depth stencil state
	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;

	DXCall(result = m_pd3dDevice->CreateDepthStencilState(&depthStencilDesc, &m_pd3dDepthStencilStateEnabled));
	DXName(m_pd3dDepthStencilStateEnabled, "Depth Enabled State");

	m_pd3dDeviceContext->OMSetDepthStencilState(m_pd3dDepthStencilStateEnabled, 1);


	depthStencilDesc.DepthEnable = false;
	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;

	DXCall(result = m_pd3dDevice->CreateDepthStencilState(&depthStencilDesc, &m_pd3dDepthStencilStateDisabled));
	DXName(m_pd3dDepthStencilStateDisabled, "Depth Disabled State");


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

	DXCall(result = m_pd3dDevice->CreateDepthStencilView(m_pd3dDepthStencilBuffer, &depthStencilViewDesc, &m_pd3dDepthStencilView));
	DXName(m_pd3dDepthStencilView, "Depth Stencil View");

	m_pd3dDeviceContext->OMSetRenderTargets(1, &m_pd3dRenderTargetView, m_pd3dDepthStencilView);

	// set up rasterizer state
	ZeroMemory(&rasterDesc, sizeof(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 = TRUE;
	rasterDesc.MultisampleEnable = FALSE;
	rasterDesc.ScissorEnable = FALSE;
	rasterDesc.SlopeScaledDepthBias = 0.0f;

	DXCall(result = m_pd3dDevice->CreateRasterizerState(&rasterDesc, &m_pd3dRasterState));
	DXName(m_pd3dRasterState, "Backface Culled Raster State");

	m_pd3dDeviceContext->RSSetState(m_pd3dRasterState);

	// setup viewport
	viewport.Width = (FLOAT)width;
	viewport.Height = (FLOAT)height;
	viewport.MinDepth = 0.0f;
	viewport.MaxDepth = 1.0f;
	viewport.TopLeftX = viewport.TopLeftY = 0.0f;

	m_pd3dDeviceContext->RSSetViewports(1, &viewport);

	D3D11_BUFFER_DESC cb;
	ZeroMemory(&cb, sizeof(cb));
	cb.ByteWidth = sizeof(TPerFrame);
	cb.Usage = D3D11_USAGE_DYNAMIC;
	cb.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
	cb.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;

	DXCall(result = m_pd3dDevice->CreateBuffer(&cb, NULL, &m_pd3dSceneBuffer));
	DXName(m_pd3dSceneBuffer, "View Proj cBuffer");

	D3D11_BLEND_DESC blendDesc;
	ZeroMemory(&blendDesc, sizeof(blendDesc));

	// enabled blending
	blendDesc.RenderTarget[0].BlendEnable = TRUE;
	blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
	blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
	blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
	blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
	blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
	blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
	blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;

	DXCall(result = m_pd3dDevice->CreateBlendState(&blendDesc, &m_pd3dAlphaEnableBlendingState));
	DXName(m_pd3dAlphaEnableBlendingState, "Alpha Blending Enabled");

	// disabled blending
	blendDesc.RenderTarget[0].BlendEnable = FALSE;

	DXCall(result = m_pd3dDevice->CreateBlendState(&blendDesc, &m_pd3dAlphaDisableBlendingState));
	DXName(m_pd3dAlphaDisableBlendingState, "Alpha Blending Disabled");


	SetupSamplerStates();

	//init render contexts
	m_pDebugRC = new CDebugRenderContext();
	m_pDebugRC->Initialize(m_pd3dDevice, m_pd3dDeviceContext, m_pDefaultTexture);

	m_pParticleRC = new CParticleRenderContext();
	m_pParticleRC->Initialize(m_pd3dDevice, m_pd3dDeviceContext, m_pDefaultTexture);

	g_ClearColor[0] = 0.1f;
	g_ClearColor[1] = 0.1f;
	g_ClearColor[2] = 0.1f;
	g_ClearColor[3] = 1.0f;
	return true;
}
예제 #18
0
	HRESULT	D3D11Renderer::Create( HWND const &appWindow )
	{
		HRESULT	hr;

		D3D_FEATURE_LEVEL	featureLevelsSupported;
		D3D_FEATURE_LEVEL	featureLevelsRequested[] =
		{
			D3D_FEATURE_LEVEL_11_0,
			D3D_FEATURE_LEVEL_10_1,
			D3D_FEATURE_LEVEL_10_0,
			D3D_FEATURE_LEVEL_9_3,
			D3D_FEATURE_LEVEL_9_2,
			D3D_FEATURE_LEVEL_9_1,
		};

		UINT	deviceFlags = 0;
#if defined(DEBUG) || defined(_DEBUG)
		deviceFlags |= (D3D11_CREATE_DEVICE_DEBUG | D3D11_RLDO_DETAIL);
#endif

		HR(hr, D3D11CreateDevice(
			GetPrimaryAdaptor(),		// adapter
			D3D_DRIVER_TYPE_HARDWARE,	// drive type
			0,							// hmodule
			deviceFlags,				// device flags
			featureLevelsRequested,		// array of feature levels requests
			6,							// number of feature levels
			D3D11_SDK_VERSION,			// sdk version
			&m_device,					// pointer to device
			&featureLevelsSupported,	// number of feature levels supported
			&m_context));				// pointer to context
		/*
#if defined(DEBUG) || defined(_DEBUG)
		HR(hr, m_device->QueryInterface(__uuidof(ID3D11Debug), (void **)&m_debug));
#endif
		*/
		DXGI_FORMAT	formats[] =
		{
			g_settings.format,
			DXGI_FORMAT_R16G16B16A16_FLOAT,
			DXGI_FORMAT_R8G8B8A8_UNORM
		};
		UINT formatSupport = 0;
		UINT supportedFormatIndex = 0;

		for (supportedFormatIndex; supportedFormatIndex < 3; supportedFormatIndex++)
		{
			m_device->CheckFormatSupport(formats[supportedFormatIndex], &formatSupport);
			if (formatSupport &	D3D11_FORMAT_SUPPORT_RENDER_TARGET && formatSupport & D3D11_FORMAT_SUPPORT_DISPLAY)
			{
				g_settings.format = formats[supportedFormatIndex];
				break;
			}
		}

		ATOM_ASSERT(g_settings.xmsaa > 0, "XMSAA < 0, min value = 1");

		UINT	sampleCount = g_settings.xmsaa;
		UINT	numQualityLevels = 0;
		this->m_device->CheckMultisampleQualityLevels(
			g_settings.format,
			sampleCount,
			&numQualityLevels);
		//this->m_appSettings->qmsaa = numQualityLevels - 1;
		if (sampleCount < g_settings.xmsaa)
			g_settings.xmsaa = sampleCount;
		if (numQualityLevels - 1 < g_settings.qmsaa)
			g_settings.qmsaa = numQualityLevels - 1;

		DXGI_SWAP_CHAIN_DESC	sd;
		ZeroMemory(&sd, sizeof(sd));
		sd.BufferCount = SWAP_CHAIN_BUFFER_COUNT;
		sd.BufferDesc.Format = g_settings.format;
		sd.BufferDesc.Width = g_settings.width;
		sd.BufferDesc.Height = g_settings.height;
		sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
		sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

		sd.OutputWindow = appWindow;
		sd.SampleDesc.Count = g_settings.xmsaa;
		sd.SampleDesc.Quality = g_settings.qmsaa;
		sd.Windowed = true;

		GetDefaultRefreshRate();
		if (g_settings.frameRate <= 0)
		{
			DXGI_RATIONAL fr = GetDefaultRefreshRate();
			sd.BufferDesc.RefreshRate.Numerator = fr.Numerator;
			sd.BufferDesc.RefreshRate.Denominator = fr.Denominator;
			g_settings.frameRate = fr.Numerator / fr.Denominator;
		}
		else
		{
			sd.BufferDesc.RefreshRate.Numerator = g_settings.frameRate;
			sd.BufferDesc.RefreshRate.Denominator = 1;
		}

		IDXGIDevice1	*dxgiDevice = 0;
		IDXGIAdapter1	*dxgiAdapter = 0;
		IDXGIFactory1	*dxgiFactory = 0;
		HR(hr, m_device->QueryInterface(__uuidof(IDXGIDevice1), (void **)&dxgiDevice));
		HR(hr, dxgiDevice->GetParent(__uuidof(IDXGIAdapter1), (void **)&dxgiAdapter));
		HR(hr, dxgiAdapter->GetParent(__uuidof(IDXGIFactory1), (void **)&dxgiFactory));
		HR(hr, dxgiFactory->CreateSwapChain((IUnknown *)m_device, &sd, &m_swapChain));
		memory::SafeRelease(&dxgiDevice);
		memory::SafeRelease(&dxgiAdapter);
		memory::SafeRelease(&dxgiFactory);

		//LOG("num: %d, den: %d\n", sd.BufferDesc.RefreshRate.Numerator, sd.BufferDesc.RefreshRate.Denominator);
		//LOG("scaling: %d, scanline ordering: %d\n", sd.BufferDesc.Scaling, sd.BufferDesc.ScanlineOrdering);

#if defined(DEBUG) || defined(_DEBUG)
		//EnumerateDisplayModes();
		char	*featureLevelNames[] = { "D3D11", "D3D10.1", "D3D10", "D3D9.3", "D3D9.2", "D3D9.1" };
		for (int i = 0; i < 6; i++)
		{
			if (featureLevelsSupported == featureLevelsRequested[i])
				ATOM_LOG("[info]: D3D_FEATURE_LEVEL: %s\n", featureLevelNames[i]);
		}
		ATOM_LOG("[info]: using format: %d, index: %d\n", formats[supportedFormatIndex], supportedFormatIndex);
#endif

		InitRendererResources();

		return Resize(g_settings.width, g_settings.height);
	}
예제 #19
0
void DetectGpuInfo(std::ostream& os)
{
#if defined KLAYGE_PLATFORM_WINDOWS
	typedef HRESULT (WINAPI *CreateDXGIFactory1Func)(REFIID riid, void** ppFactory);

#if defined KLAYGE_PLATFORM_WINDOWS_DESKTOP
	HMODULE dxgi = ::LoadLibraryEx(L"dxgi.dll", nullptr, 0);
	if (!dxgi)
	{
		os << "Unknown GPU";
		return;
	}
	CreateDXGIFactory1Func DynamicCreateDXGIFactory1 = (CreateDXGIFactory1Func)::GetProcAddress(dxgi, "CreateDXGIFactory1");
	if (!DynamicCreateDXGIFactory1)
	{
		os << "Unknown GPU";
		return;
	}
#else
	CreateDXGIFactory1Func DynamicCreateDXGIFactory1 = CreateDXGIFactory1;
#endif

	IDXGIFactory1* factory;
	if (SUCCEEDED((*DynamicCreateDXGIFactory1)(IID_IDXGIFactory1, reinterpret_cast<void**>(&factory))))
	{
		UINT adapter_no = 0;
		IDXGIAdapter1* adapter = nullptr;
		while (factory->EnumAdapters1(adapter_no, &adapter) != DXGI_ERROR_NOT_FOUND)
		{
			if (adapter != nullptr)
			{
				DXGI_ADAPTER_DESC1 adapter_desc;
				adapter->GetDesc1(&adapter_desc);

				IDXGIAdapter2* adapter2;
				adapter->QueryInterface(IID_IDXGIAdapter2, reinterpret_cast<void**>(&adapter2));
				if (adapter2 != nullptr)
				{
					DXGI_ADAPTER_DESC2 desc2;
					adapter2->GetDesc2(&desc2);
					memcpy(adapter_desc.Description, desc2.Description, sizeof(desc2.Description));
					adapter_desc.VendorId = desc2.VendorId;
					adapter_desc.DeviceId = desc2.DeviceId;
					adapter_desc.SubSysId = desc2.SubSysId;
					adapter_desc.Revision = desc2.Revision;
					adapter_desc.DedicatedVideoMemory = desc2.DedicatedVideoMemory;
					adapter_desc.DedicatedSystemMemory = desc2.DedicatedSystemMemory;
					adapter_desc.SharedSystemMemory = desc2.SharedSystemMemory;
					adapter_desc.AdapterLuid = desc2.AdapterLuid;
					adapter_desc.Flags = desc2.Flags;
					adapter2->Release();
				}

				adapter->Release();

				if (adapter_desc.Flags != DXGI_ADAPTER_FLAG_SOFTWARE)
				{
					os << "Adapter " << adapter_no << endl << endl;
					std::string description;
					Convert(description, adapter_desc.Description);
					os << "Brand: " << description << endl;
					os << "Vendor ID: " << std::hex << std::uppercase << adapter_desc.VendorId << endl;
					os << "Device ID: " << std::hex << std::uppercase << adapter_desc.DeviceId << endl;
					os << "Revision: " << std::hex << std::uppercase << adapter_desc.Revision << endl;
					os << "Dedicated video memory: " << std::dec << adapter_desc.DedicatedVideoMemory / 1024 / 1024 << " MB" << endl;
					os << "Dedicated system memory: " << std::dec << adapter_desc.DedicatedSystemMemory / 1024 / 1024 << " MB" << endl;
					os << "Shared system memory: " << std::dec << adapter_desc.SharedSystemMemory / 1024 / 1024 << " MB" << endl;
				}
			}

			++ adapter_no;
		}
	}

#if defined KLAYGE_PLATFORM_WINDOWS_DESKTOP
	::FreeLibrary(dxgi);
#endif
#else
	os << "Unknown GPU" << endl;
#endif
}
예제 #20
0
DeviceManager::DeviceManager(void)
	: m_pd3dDevice(NULL), 
	m_pImmediateContext(NULL),    
	m_pDXGIFactory1(NULL)
{	
    
	// create DXGIFactory, d3d device

	HRESULT hr = S_OK;

	// create dxgi factory and keep it for future use.	
	hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)(&m_pDXGIFactory1) );
	if (Logger::IsFailureLog(hr))
	{
         return;
	}
    
    
	IDXGIAdapter1* pAdapter;    
    // hardware vendor ID
    uint32_t nvidia = 0x10DE;  // NVIDIA Corporation
    uint32_t ati  = 0x1002;    // ATI Technologies Inc. / Advanced Micro Devices, Inc.

    int i = 0;
    int adapterIndex = 0;

    printf("Available DXGIAdapters:\n");
    while(m_pDXGIFactory1->EnumAdapters1(i, &pAdapter) != DXGI_ERROR_NOT_FOUND) 
    {        
        DXGI_ADAPTER_DESC1 descr;
        pAdapter->GetDesc1(&descr);
        wprintf(L"\t%s\n",descr.Description);

        // choose discrete graphics over integrated.
        if(adapterIndex == 0 && (descr.VendorId == nvidia || descr.VendorId == ati))
        {
            adapterIndex = i;
        }
        i++;
        pAdapter->Release();
        pAdapter = NULL;
    }
    
	hr = m_pDXGIFactory1->EnumAdapters1(adapterIndex, &pAdapter);
	if (Logger::IsFailureLog(hr))
	{
         return;
	}

	
    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_0,
        D3D_FEATURE_LEVEL_10_1,
        D3D_FEATURE_LEVEL_10_0,
    };
	UINT numFeatureLevels = ARRAYSIZE( featureLevels );

	DXGI_ADAPTER_DESC1 pdescr;
	pAdapter->GetDesc1(&pdescr);
    Logger::Log(OutputMessageType::Info, L"%s\n",pdescr.Description);


    // Note: If you set the pAdapter parameter to a non-NULL value,
    //      you must also set the DriverType parameter 
    //      to the D3D_DRIVER_TYPE_UNKNOWN
    
	// create d3d11 device on the first graphics adapter.
	hr =  D3D11CreateDevice(
			pAdapter,
			D3D_DRIVER_TYPE_UNKNOWN,
			NULL,
			createDeviceFlags,
			featureLevels,
			numFeatureLevels,
			D3D11_SDK_VERSION,
			&m_pd3dDevice,
			NULL,
			&m_pImmediateContext);	
  		
	pAdapter->Release(); // no longer needed.

	if (Logger::IsFailureLog(hr))
	{
		return;
	}
    D3D_FEATURE_LEVEL featureLevel = m_pd3dDevice->GetFeatureLevel();
    wchar_t* strFeatureLevel = NULL;

    if( featureLevel == D3D_FEATURE_LEVEL_9_1)
    {
        strFeatureLevel = L"D3D_FEATURE_LEVEL_9_1";
    }
    else if( featureLevel == D3D_FEATURE_LEVEL_9_2)
    {
        strFeatureLevel = L"D3D_FEATURE_LEVEL_9_2";        
    }
    else if( featureLevel == D3D_FEATURE_LEVEL_9_3)
    {
        strFeatureLevel = L"D3D_FEATURE_LEVEL_9_3";        
    }
    else if( featureLevel ==D3D_FEATURE_LEVEL_10_0)
    {
        strFeatureLevel = L"D3D_FEATURE_LEVEL_10_0";                
    }
    else if( featureLevel ==D3D_FEATURE_LEVEL_10_1)
    {
        strFeatureLevel = L"D3D_FEATURE_LEVEL_10_1";                
    }
    else if( featureLevel ==D3D_FEATURE_LEVEL_11_0)
    {
        strFeatureLevel = L"D3D_FEATURE_LEVEL_11_0";                
    }
    else
    {
        strFeatureLevel = L"Newer than D3D_FEATURE_LEVEL_11_0";                        
    }        
    Logger::Log(OutputMessageType::Info,L"Feature Level: %s\n", strFeatureLevel);

}
예제 #21
0
bool RenderSystem::init(void* windowHandle, const InitParams& params)
{
  IDXGIFactory1* factory = 0;
  IDXGIOutput* output = 0;

  DXGI_MODE_DESC modeDesc;
  ::ZeroMemory(&modeDesc, sizeof(DXGI_MODE_DESC));
  modeDesc.Format = params.srgbTarget ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB : DXGI_FORMAT_R8G8B8A8_UNORM;
  modeDesc.Width = params.width;
  modeDesc.Height = params.height;

  if (SUCCEEDED(CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&factory)))
  {
    IDXGIAdapter1* adapter = 0;
    for (UINT i = 0; factory->EnumAdapters1(i, &adapter) != DXGI_ERROR_NOT_FOUND; ++i)
    {
      if (adapter->CheckInterfaceSupport(__uuidof(ID3D11Device), NULL))
        break;

      adapter->Release();
    }

    D3D_FEATURE_LEVEL supportedFeatureLevels[] =
    {
      D3D_FEATURE_LEVEL_11_0,
    };

    UINT flags = 0;

#if defined (_DEBUG)
    flags |= D3D11_CREATE_DEVICE_DEBUG;
#endif // _DEBUG

    if (adapter)
    {
      if (SUCCEEDED(D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, flags, supportedFeatureLevels, _countof(supportedFeatureLevels),
        D3D11_SDK_VERSION, &m_device, NULL, &m_renderContext)))
      {
        for (UINT i = 0; adapter->EnumOutputs(i, &output) != DXGI_ERROR_NOT_FOUND; ++i)
        {
          if (SUCCEEDED(output->FindClosestMatchingMode(&modeDesc, &modeDesc, m_device)))
          {
            // additional checks??
            break;
          }

          output->Release();
          output = 0;
        }

        /*if (output)
          output->Release();*/
      }

      adapter->Release();
    }

    if (m_device)
    {
      DXGI_SWAP_CHAIN_DESC sd;
      ::ZeroMemory(&sd, sizeof(DXGI_SWAP_CHAIN_DESC));
      sd.BufferCount = 1;
      sd.BufferDesc = modeDesc;
      sd.BufferUsage = D3D11_BIND_RENDER_TARGET;
      sd.Flags = 0;
      sd.OutputWindow = (HWND)windowHandle;
      sd.SampleDesc.Quality = 0;
      sd.SampleDesc.Count = 1;
      sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
      sd.Windowed = TRUE;

      if (params.msaaSamples > 0)
      {
        UINT numLevels = 0;
        if (SUCCEEDED(m_device->CheckMultisampleQualityLevels(modeDesc.Format, params.msaaSamples, &numLevels)) && numLevels > 0)
        {
          sd.SampleDesc.Quality = numLevels-1;
          sd.SampleDesc.Count = params.msaaSamples;
        }
        else
        {
          printf("multisample quality not supported");
        }
      }

      VALIDATE(factory->CreateSwapChain(m_device, &sd, &m_swapChain));
    }

    if (params.fullscreen)
    {
      m_isFullScreen = SUCCEEDED(m_swapChain->SetFullscreenState(TRUE, output));
    }

    // setup debug queue

    factory->MakeWindowAssociation((HWND)windowHandle, DXGI_MWA_NO_ALT_ENTER | DXGI_MWA_NO_WINDOW_CHANGES);

    if (output)
      output->Release();

    factory->Release();
  }

  m_stateCache = new PipelineStateCache(m_renderContext);

  createFrameBuffer();

  initDefaultResources();

  return (m_device && m_swapChain);
}
예제 #22
0
파일: D3D10System.cpp 프로젝트: Soopah/OBS
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;
}
예제 #23
0
bool Direct3D::Initialize(int _screenWidth, int _screenHeight, bool _vsync, HWND _hwnd, bool _fullscreen, float _screenDepth, float _screenNear, TextClass* _timer)
{
	HRESULT result;
	IDXGIFactory1* factory;
	IDXGIAdapter1* adapter;
	IDXGIOutput* adapterOutput;
	unsigned int numModes, i, numerator, denominator, stringLength;
	DXGI_MODE_DESC* displayModeList;
	DXGI_ADAPTER_DESC adapterDesc;
	int error;
	DXGI_SWAP_CHAIN_DESC swapChainDesc;
	D3D_FEATURE_LEVEL featureLevel;
	ID3D11Texture2D* backBufferPtr;
	D3D11_TEXTURE2D_DESC depthBufferDesc;
	D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
	D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;
	D3D11_RASTERIZER_DESC rasterDesc;
	float fieldOfView, screenAspect;
	D3D11_BLEND_DESC blendStateDescription;
	bool success;


	// Store the vsync setting.
	vsync_enabled = _vsync;

	// Create a DirectX graphics interface factory.
	result = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&factory);
	if (FAILED(result))
	{
		return false;
	}

	// Use the factory to create an adapter for the primary graphics interface (video card).
	result = factory->EnumAdapters1(0, &adapter);
	if (FAILED(result))
	{
		return false;
	}

	// Enumerate the primary adapter output (monitor).
	result = adapter->EnumOutputs(0, &adapterOutput);
	if (FAILED(result))
	{
		return false;
	}

	// Get the number of modes that fit the DXGI_FORMAT_R8G8B8A8_UNORM display format for the adapter output (monitor).
	result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, NULL);
	if (FAILED(result))
	{
		return false;
	}

	// Create a list to hold all the possible display modes for this monitor/video card combination.
	displayModeList = new DXGI_MODE_DESC[numModes];
	if (!displayModeList)
	{
		return false;
	}

	// Now fill the display mode list structures.
	result = adapterOutput->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &numModes, displayModeList);
	if (FAILED(result))
	{
		return false;
	}

	// Now go through all the display modes and find the one that matches the screen width and height.
	// When a match is found store the numerator and denominator of the refresh rate for that monitor.
	for (i = 0; i<numModes; i++)
	{
		if (displayModeList[i].Width == (unsigned int)_screenWidth)
		{
			if (displayModeList[i].Height == (unsigned int)_screenHeight)
			{
				numerator = displayModeList[i].RefreshRate.Numerator;
				denominator = displayModeList[i].RefreshRate.Denominator;
			}
		}
	}

	// Get the adapter (video card) description.
	result = adapter->GetDesc(&adapterDesc);
	if (FAILED(result))
	{
		return false;
	}

	// Store the dedicated video card memory in megabytes.
	videoCardMemory = (int)(adapterDesc.DedicatedVideoMemory / 1024 / 1024);

	// Convert the name of the video card to a character array and store it.
	error = wcstombs_s(&stringLength, videoCardDescription, 128, adapterDesc.Description, 128);
	if (error != 0)
	{
		return false;
	}

	// Release the display mode list.
	delete[] displayModeList;
	displayModeList = 0;

	// Release the adapter output.
	adapterOutput->Release();
	adapterOutput = 0;

	// Release the factory.
	factory->Release();
	factory = 0;


	// Initialize the swap chain description.
	ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));

	// Set to a single back buffer.
	swapChainDesc.BufferCount = 1;

	// Set the width and height of the back buffer.
	swapChainDesc.BufferDesc.Width = _screenWidth;
	swapChainDesc.BufferDesc.Height = _screenHeight;

	// Set regular 32-bit surface for the back buffer.
	swapChainDesc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;

	// Set the refresh rate of the back buffer.
	if (vsync_enabled)
	{
		swapChainDesc.BufferDesc.RefreshRate.Numerator = numerator;
		swapChainDesc.BufferDesc.RefreshRate.Denominator = denominator;
	}
	else
	{
		swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
		swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
	}

	// Set the usage of the back buffer.
	swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;

	// Set the handle for the window to render to. 
	swapChainDesc.OutputWindow = _hwnd;

	// Turn multisampling off.
	swapChainDesc.SampleDesc.Count = 1;
	swapChainDesc.SampleDesc.Quality = 0;

	// Set to full screen or windowed mode.
	if (_fullscreen)
	{
		swapChainDesc.Windowed = false;
	}
	else
	{
		swapChainDesc.Windowed = true;
	}

	//// Set the scan line ordering and scaling to unspecified.
	//swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
	//swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;

	//// Discard the back buffer contents after presenting.
	//swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

	// Don't set the advanced flags.
	swapChainDesc.Flags = 0;

	// Set the feature level to DirectX 11.
	featureLevel = D3D_FEATURE_LEVEL_11_0;

	// Create the swap chain, Direct3D device, and Direct3D device context.
	result = D3D11CreateDeviceAndSwapChain(adapter,
		D3D_DRIVER_TYPE_UNKNOWN,
		NULL,
		D3D11_CREATE_DEVICE_DEBUG | D3D11_CREATE_DEVICE_BGRA_SUPPORT,
		&featureLevel,
		1,
		D3D11_SDK_VERSION,
		&swapChainDesc,
		&swapChain,
		&device,
		NULL,
		&deviceContext);

	if (FAILED(result))
	{
		return false;
	}

	success = _timer->Initialize(device, adapter, _screenWidth, _screenHeight);
	if (!success)
	{
		return false;
	}

	// Release the adapter.
	adapter->Release();
	adapter = 0;

	// Get the pointer to the back buffer.
	result = swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&backBufferPtr);
	if (FAILED(result))
	{
		return false;
	}

	// Create the render target view with the back buffer pointer.
	result = device->CreateRenderTargetView(backBufferPtr, NULL, &backBuffer);
	if (FAILED(result))
	{
		return false;
	}

	// Release pointer to the back buffer as we no longer need it.
	backBufferPtr->Release();
	backBufferPtr = 0;


	// Initialize the description of the depth buffer.
	ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc));

	// Set up the description of the depth buffer.
	depthBufferDesc.Width = _screenWidth;
	depthBufferDesc.Height = _screenHeight;
	depthBufferDesc.MipLevels = 1;
	depthBufferDesc.ArraySize = 1;
	depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
	depthBufferDesc.SampleDesc.Count = 1;
	depthBufferDesc.SampleDesc.Quality = 0;
	depthBufferDesc.Usage = D3D11_USAGE_DEFAULT;
	depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
	depthBufferDesc.CPUAccessFlags = 0;
	depthBufferDesc.MiscFlags = 0;


	// Create the texture for the depth buffer using the filled out description.
	result = device->CreateTexture2D(&depthBufferDesc, NULL, &depthStencilBuffer);
	if (FAILED(result))
	{
		return false;
	}


	// Initialize the description of the stencil state.
	ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc));

	// Set up the description of the stencil state.
	depthStencilDesc.DepthEnable = true;
	depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
	depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;

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

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

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

	// Create the depth stencil state.
	result = device->CreateDepthStencilState(&depthStencilDesc, &depthStencilStateON);
	if (FAILED(result))
	{
		return false;
	}

	depthStencilDesc.DepthEnable = false;
	// Create the depth stencil state.
	result = device->CreateDepthStencilState(&depthStencilDesc, &depthStencilStateOFF);
	if (FAILED(result))
	{
		return false;
	}

	// Set the depth stencil state.
	deviceContext->OMSetDepthStencilState(depthStencilStateON, 1);

	// Initailze the depth stencil view.
	ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc));

	// Set up the depth stencil view description.
	depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
	depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
	depthStencilViewDesc.Texture2D.MipSlice = 0;

	// Create the depth stencil view.
	result = device->CreateDepthStencilView(depthStencilBuffer, &depthStencilViewDesc, &depthStencilView);
	if (FAILED(result))
	{
		return false;
	}

	// Bind the render target view and depth stencil buffer to the output render pipeline.
	deviceContext->OMSetRenderTargets(1, &backBuffer, depthStencilView);

	// Setup the raster description which will determine how and what polygons will be drawn.
	rasterDesc.AntialiasedLineEnable = false;
	rasterDesc.CullMode = D3D11_CULL_NONE;
	rasterDesc.DepthBias = 0;
	rasterDesc.DepthBiasClamp = 0.0f;
	rasterDesc.DepthClipEnable = true;
	rasterDesc.FillMode = D3D11_FILL_SOLID;
	rasterDesc.FrontCounterClockwise = false;
	rasterDesc.MultisampleEnable = false;
	rasterDesc.ScissorEnable = false;
	rasterDesc.SlopeScaledDepthBias = 0.0f;

	// Create the rasterizer state from the description we just filled out.
	result = device->CreateRasterizerState(&rasterDesc, &rasterState);
	if (FAILED(result))
	{
		return false;
	}

	// Now set the rasterizer state.
	deviceContext->RSSetState(rasterState);

	// Setup the viewport for rendering.
	viewport.Width = (float)_screenWidth;
	viewport.Height = (float)_screenHeight;
	viewport.MinDepth = 0.0f;
	viewport.MaxDepth = 1.0f;
	viewport.TopLeftX = 0.0f;
	viewport.TopLeftY = 0.0f;

	// Create the viewport.
	deviceContext->RSSetViewports(1, &viewport);

	// Setup the projection matrix.
	fieldOfView = (float)XM_PI / 4.0f;
	screenAspect = (float)_screenWidth / (float)_screenHeight;

	// Create the projection matrix for 3D rendering.
	DirectX::XMStoreFloat4x4(&projectionMatrix, XMMatrixPerspectiveFovLH(fieldOfView, screenAspect, _screenNear, _screenDepth));

	// Create an orthographic projection matrix for 2D rendering.
	DirectX::XMStoreFloat4x4(&orthoMatrix, XMMatrixOrthographicLH((float)_screenWidth, (float)_screenHeight, _screenNear, _screenDepth));

	// Clear the blend state description.
	ZeroMemory(&blendStateDescription, sizeof(D3D11_BLEND_DESC));

	// Create an alpha enabled blend state description.
	blendStateDescription.RenderTarget[0].BlendEnable = TRUE;
	blendStateDescription.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_COLOR;
	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 = 0x0f;

	// Create the blend state using the description.
	result = device->CreateBlendState(&blendStateDescription, &alphaEnableBlendingState);
	if (FAILED(result))
	{
		return false;
	}

	// Modify the description to create an alpha disabled blend state description.
	blendStateDescription.RenderTarget[0].BlendEnable = FALSE;

	// Create the blend state using the description.
	result = device->CreateBlendState(&blendStateDescription, &alphaDisableBlendingState);
	if (FAILED(result))
	{
		return false;
	}

	renderer = new RenderManager();
	if (!renderer)
	{
		return false;
	}
	result = renderer->Initialize(device,XMLoadFloat4x4(&projectionMatrix), _screenWidth, _screenHeight);

	return true;
}
예제 #24
0
bool D3DApp::InitializeDirect3d11App(HINSTANCE hInstance)
{
	//Describe our Buffer
	DXGI_MODE_DESC bufferDesc;

	ZeroMemory(&bufferDesc, sizeof(DXGI_MODE_DESC));

	bufferDesc.Width = Width;
	bufferDesc.Height = Height;
	bufferDesc.RefreshRate.Numerator = 60;
	bufferDesc.RefreshRate.Denominator = 1;
	bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
	bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;

	//Describe our SwapChain
	DXGI_SWAP_CHAIN_DESC swapChainDesc;

	ZeroMemory(&swapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));

	swapChainDesc.BufferDesc = bufferDesc;
	swapChainDesc.SampleDesc.Count = 1;
	swapChainDesc.SampleDesc.Quality = 0;
	swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	swapChainDesc.BufferCount = 1;
	swapChainDesc.OutputWindow = hwnd;
	swapChainDesc.Windowed = TRUE;
	swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

	// Create DXGI factory to enumerate adapters///////////////////////////////////////////////////////////////////////////
	IDXGIFactory1 *DXGIFactory;

	HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&DXGIFactory);

	// Use the first adapter	
	IDXGIAdapter1 *Adapter;

	hr = DXGIFactory->EnumAdapters1(0, &Adapter);

	DXGIFactory->Release();

	//Create our Direct3D 11 Device and SwapChain//////////////////////////////////////////////////////////////////////////
	hr = D3D11CreateDeviceAndSwapChain(Adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, D3D11_CREATE_DEVICE_DEBUG | D3D11_CREATE_DEVICE_BGRA_SUPPORT,
		NULL, NULL, D3D11_SDK_VERSION, &swapChainDesc, &SwapChain, &d3d11Device, NULL, &d3d11DevCon);

	//Initialize Direct2D, Direct3D 10.1, DirectWrite
	InitD2D_D3D101_DWrite(Adapter);

	//Release the Adapter interface
	Adapter->Release();

	//Create our BackBuffer and Render Target
	hr = SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&BackBuffer11);
	hr = d3d11Device->CreateRenderTargetView(BackBuffer11, NULL, &renderTargetView);

	//Describe our Depth/Stencil Buffer
	D3D11_TEXTURE2D_DESC depthStencilDesc;

	depthStencilDesc.Width = Width;
	depthStencilDesc.Height = Height;
	depthStencilDesc.MipLevels = 1;
	depthStencilDesc.ArraySize = 1;
	depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
	depthStencilDesc.SampleDesc.Count = 1;
	depthStencilDesc.SampleDesc.Quality = 0;
	depthStencilDesc.Usage = D3D11_USAGE_DEFAULT;
	depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
	depthStencilDesc.CPUAccessFlags = 0;
	depthStencilDesc.MiscFlags = 0;

	//Create the Depth/Stencil View
	d3d11Device->CreateTexture2D(&depthStencilDesc, NULL, &depthStencilBuffer);
	d3d11Device->CreateDepthStencilView(depthStencilBuffer, NULL, &depthStencilView);

	return true;
}
예제 #25
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;
};
예제 #26
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;
  }
예제 #27
0
	EErrorCode::Type GraphicsDevice::Initialize( RendererDesc *pDesc )
	{
		// Only create this for immediate render context
		if ( pDesc->deviceContextType != EDeviceContext::IMMEDIATE )
			return EErrorCode::GRAPHICS;

		GraphicsInfrastructure *pGI = GraphicsInfrastructure::GetInstance();
		DXGIFactoryPtr pFactory = pGI->GetFactory();
		IDXGIAdapter1 *pAdapter;
		UINT createFlags = 0;
		HRESULT hr;

		// Get adapter
		pFactory->EnumAdapters1( pDesc->adapter, &pAdapter );

		if ( pDesc->bDebug )
			createFlags |= D3D11_CREATE_DEVICE_DEBUG;

		D3D_FEATURE_LEVEL featureLevel[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0 };
		D3D_FEATURE_LEVEL retFet;
		hr = D3D11CreateDevice( pAdapter, 
			DX11Mapping::ToDXProcessingType(ERendererProcessingType::UNKNOWN),
			//DX11Mapping::ToDXProcessingType(pDesc->processingType),
			PSX_NULL,
			createFlags,
			featureLevel,
			1,
			D3D11_SDK_VERSION,
			&m_pDevice,
			&retFet,
			&m_pDeviceContext );

		if ( FAILED(hr) )
		{
			PSX_PushError( "Failed to create GraphicsDevice object." );
		
			if ( pDesc->processingType == ERendererProcessingType::HARDWARE && pDesc->bSoftwareRendererFallback )
			{
				PSX_PushLog1( "Attempting to create software device renderer." );

				// TODO: This fallback create device doesn't work. Fix this.
				hr = D3D11CreateDevice( pAdapter, 
					D3D_DRIVER_TYPE_REFERENCE,
					PSX_NULL,
					createFlags,
					featureLevel,
					1,
					D3D11_SDK_VERSION,
					&m_pDevice,
					&retFet,
					&m_pDeviceContext );

				if ( FAILED(hr ) )
					PSX_PushError( "Failed to create software renderer device. Something went terribly wrong!" );
			}
		}

		pAdapter->Release();

		// It's now safe to initialize graphics resource manager
		if ( GraphicsResourceManager::GetInstance()->Initialize() != EErrorCode::OKAY )
		{
			PSX_PushError( "Failed to initialize Graphics Resource Manager." );
			return EErrorCode::GRAPHICS;
		}

		return m_pDevice ? EErrorCode::OKAY : EErrorCode::GRAPHICS;
	}