Exemple #1
0
void Reset()
{
	// release all back buffer references
	SAFE_RELEASE(backbuf);

	// resize swapchain buffers
	RECT client;
	GetClientRect(hWnd, &client);
	xres = client.right - client.left;
	yres = client.bottom - client.top;
	D3D::swapchain->ResizeBuffers(1, xres, yres, DXGI_FORMAT_R8G8B8A8_UNORM, 0);

	// recreate back buffer texture
	ID3D11Texture2D* buf;
	HRESULT hr = swapchain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&buf);
	if (FAILED(hr))
	{
		MessageBox(hWnd, _T("Failed to get swapchain buffer"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR);
		SAFE_RELEASE(device);
		SAFE_RELEASE(context);
		SAFE_RELEASE(swapchain);
		return;
	}
	backbuf = new D3DTexture2D(buf, D3D11_BIND_RENDER_TARGET);
	SAFE_RELEASE(buf);
	CHECK(backbuf!=nullptr, "Create back buffer texture");
	SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetTex(), "backbuffer texture");
	SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetRTV(), "backbuffer render target view");
}
Exemple #2
0
void InitUtils()
{
	util_vbuf = new UtilVertexBuffer(0x4000);

	float border[4] = { 0.f, 0.f, 0.f, 0.f };
	D3D11_SAMPLER_DESC samDesc = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_POINT, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, 0.f, 1, D3D11_COMPARISON_ALWAYS, border, 0.f, 0.f);
	HRESULT hr = D3D::device->CreateSamplerState(&samDesc, &point_copy_sampler);
	if (FAILED(hr)) PanicAlert("Failed to create sampler state at %s %d\n", __FILE__, __LINE__);
	else SetDebugObjectName((ID3D11DeviceChild*)point_copy_sampler, "point copy sampler state");

	samDesc = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_LINEAR, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, 0.f, 1, D3D11_COMPARISON_ALWAYS, border, 0.f, 0.f);
	hr = D3D::device->CreateSamplerState(&samDesc, &linear_copy_sampler);
	if (FAILED(hr)) PanicAlert("Failed to create sampler state at %s %d\n", __FILE__, __LINE__);
	else SetDebugObjectName((ID3D11DeviceChild*)linear_copy_sampler, "linear copy sampler state");

	// cached data used to avoid unnecessarily reloading the vertex buffers
	memset(&tex_quad_data, 0, sizeof(tex_quad_data));
	memset(&tex_sub_quad_data, 0, sizeof(tex_sub_quad_data));
	memset(&draw_quad_data, 0, sizeof(draw_quad_data));
	memset(&clear_quad_data, 0, sizeof(clear_quad_data));

	// make sure to properly load the vertex data whenever the corresponding functions get called the first time
	stq_observer = stsq_observer = cq_observer = clearq_observer = true;
	util_vbuf->AddWrapObserver(&stq_observer);
	util_vbuf->AddWrapObserver(&stsq_observer);
	util_vbuf->AddWrapObserver(&cq_observer);
	util_vbuf->AddWrapObserver(&clearq_observer);

	font.Init();
}
Exemple #3
0
void InitUtils()
{
	util_vbuf = new UtilVertexBuffer(0x4000);

	float border[4] = { 0.f, 0.f, 0.f, 0.f };
	D3D11_SAMPLER_DESC samDesc = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_POINT, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, 0.f, 1, D3D11_COMPARISON_ALWAYS, border, 0.f, 0.f);
	HRESULT hr = D3D::device->CreateSamplerState(&samDesc, &point_copy_sampler);
	if (FAILED(hr)) PanicAlert("Failed to create sampler state at %s %d\n", __FILE__, __LINE__);
	else SetDebugObjectName((ID3D11DeviceChild*)point_copy_sampler, "point copy sampler state");

	samDesc = CD3D11_SAMPLER_DESC(D3D11_FILTER_MIN_MAG_MIP_LINEAR, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, D3D11_TEXTURE_ADDRESS_BORDER, 0.f, 1, D3D11_COMPARISON_ALWAYS, border, 0.f, 0.f);
	hr = D3D::device->CreateSamplerState(&samDesc, &linear_copy_sampler);
	if (FAILED(hr)) PanicAlert("Failed to create sampler state at %s %d\n", __FILE__, __LINE__);
	else SetDebugObjectName((ID3D11DeviceChild*)linear_copy_sampler, "linear copy sampler state");

	// cached data used to avoid unnecessarily reloading the vertex buffers
	memset(&tex_quad_data, 0, sizeof(tex_quad_data));
	memset(&tex_sub_quad_data, 0, sizeof(tex_sub_quad_data));
	memset(&draw_quad_data, 0, sizeof(draw_quad_data));
	memset(&clear_quad_data, 0, sizeof(clear_quad_data));

	// make sure to properly load the vertex data whenever the corresponding functions get called the first time
	stq_observer = stsq_observer = cq_observer = clearq_observer = true;
	util_vbuf->AddWrapObserver(&stq_observer);
	util_vbuf->AddWrapObserver(&stsq_observer);
	util_vbuf->AddWrapObserver(&cq_observer);
	util_vbuf->AddWrapObserver(&clearq_observer);

	font.Init();
	
	// Create resources for encoder quads

	// Create vertex quad
	D3D11_BUFFER_DESC bd = CD3D11_BUFFER_DESC(sizeof(ENCODER_QUAD_VERTS),
		D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_IMMUTABLE);
	D3D11_SUBRESOURCE_DATA srd = { ENCODER_QUAD_VERTS, 0, 0 };
	hr = D3D::device->CreateBuffer(&bd, &srd, &s_encoderQuad);
	CHECK(SUCCEEDED(hr), "create encoder quad buffer");

	// Create vertex shader
	D3DBlob* blob;
	D3D::CompileVertexShader(ENCODER_VS, sizeof(ENCODER_VS), &blob);
	s_encoderVShader = D3D::CreateVertexShaderFromByteCode(blob);
	CHECK(SUCCEEDED(hr), "create encoder vertex shader");

	// Create input layout
	hr = D3D::device->CreateInputLayout(ENCODER_QUAD_LAYOUT_DESC,
		sizeof(ENCODER_QUAD_LAYOUT_DESC) / sizeof(D3D11_INPUT_ELEMENT_DESC),
		blob->Data(), blob->Size(), &s_encoderQuadLayout);
	CHECK(SUCCEEDED(hr), "create encoder input layout");

	blob->Release();

	// Create vertex shader for encoder quads with texture coords
	s_encoderTexVShader = D3D::CompileAndCreateVertexShader(ENCODER_TEX_VS, sizeof(ENCODER_TEX_VS));
}
Exemple #4
0
static bool CreateSwapChainTextures()
{
  ID3D11Texture2D* buf;
  HRESULT hr = swapchain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&buf);
  CHECK(SUCCEEDED(hr), "GetBuffer for swap chain failed with HRESULT %08X", hr);
  if (FAILED(hr))
    return false;

  s_backbuf = new D3DTexture2D(buf, D3D11_BIND_RENDER_TARGET);
  SAFE_RELEASE(buf);
  SetDebugObjectName(s_backbuf->GetTex(), "backbuffer texture");
  SetDebugObjectName(s_backbuf->GetRTV(), "backbuffer render target view");
  return true;
}
  void Panel::initInstanceInfoBuffer()
  {
    uint32_t info[4] = {0};

    D3D10_BUFFER_DESC desc;
    desc.ByteWidth = sizeof(info);
    desc.Usage = D3D10_USAGE_IMMUTABLE;
    desc.BindFlags = D3D10_BIND_CONSTANT_BUFFER;
    desc.CPUAccessFlags = 0;
    desc.MiscFlags = 0;

    D3D10_SUBRESOURCE_DATA contents = {static_cast<void*>(&info)};
    m_instance_info_buffer = getDevice().createBuffer(desc, contents);

    SetDebugObjectName(m_instance_info_buffer, "Instance info buffer");
  }
  void Panel::initWorldMatrixBuffer()
  {
    Identity43 world_matrices[2];

    D3D10_BUFFER_DESC desc;
    desc.ByteWidth = sizeof(world_matrices);
    desc.Usage = D3D10_USAGE_IMMUTABLE;
    desc.BindFlags = D3D10_BIND_CONSTANT_BUFFER;
    desc.CPUAccessFlags = 0;
    desc.MiscFlags = 0;

    D3D10_SUBRESOURCE_DATA contents = {static_cast<void*>(&world_matrices)};
    m_world_matrix_buffer = getDevice().createBuffer(desc, contents);

    SetDebugObjectName(m_world_matrix_buffer, "World matrix buffer");
  }
Exemple #7
0
HRESULT Create(HWND wnd)
{
	hWnd = wnd;
	HRESULT hr;

	RECT client;
	GetClientRect(hWnd, &client);
	xres = client.right - client.left;
	yres = client.bottom - client.top;

	hr = LoadDXGI();
	if (SUCCEEDED(hr)) hr = LoadD3D();
	if (SUCCEEDED(hr)) hr = LoadD3DCompiler();
	if (FAILED(hr))
	{
		UnloadDXGI();
		UnloadD3D();
		UnloadD3DCompiler();
		return hr;
	}

	IDXGIFactory* factory;
	IDXGIAdapter* adapter;
	IDXGIOutput* output;
	hr = PCreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory);
	if (FAILED(hr)) MessageBox(wnd, _T("Failed to create IDXGIFactory object"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR);

	hr = factory->EnumAdapters(g_ActiveConfig.iAdapter, &adapter);
	if (FAILED(hr))
	{
		// try using the first one
		hr = factory->EnumAdapters(0, &adapter);
		if (FAILED(hr)) MessageBox(wnd, _T("Failed to enumerate adapters"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR);
	}

	// TODO: Make this configurable
	hr = adapter->EnumOutputs(0, &output);
	if (FAILED(hr))
	{
		// try using the first one
		hr = adapter->EnumOutputs(0, &output);
		if (FAILED(hr)) MessageBox(wnd, _T("Failed to enumerate outputs!\n")
		                                _T("This usually happens when you've set your video adapter to the Nvidia GPU in an Optimus-equipped system.\n")
		                                _T("Set Dolphin to use the high-performance graphics in Nvidia's drivers instead and leave Dolphin's video adapter set to the Intel GPU."),
		                                _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR);
	}

	// get supported AA modes
	aa_modes = EnumAAModes(adapter);
	if (g_Config.iMultisampleMode >= (int)aa_modes.size())
	{
		g_Config.iMultisampleMode = 0;
		UpdateActiveConfig();
	}

	DXGI_SWAP_CHAIN_DESC swap_chain_desc;
	memset(&swap_chain_desc, 0, sizeof(swap_chain_desc));
	swap_chain_desc.BufferCount = 1;
	swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	swap_chain_desc.OutputWindow = wnd;
	swap_chain_desc.SampleDesc.Count = 1;
	swap_chain_desc.SampleDesc.Quality = 0;
	swap_chain_desc.Windowed = !g_ActiveConfig.bFullscreen;

	DXGI_OUTPUT_DESC out_desc;
	memset(&out_desc, 0, sizeof(out_desc));
	output->GetDesc(&out_desc);

	DXGI_MODE_DESC mode_desc;
	memset(&mode_desc, 0, sizeof(mode_desc));
	mode_desc.Width = out_desc.DesktopCoordinates.right - out_desc.DesktopCoordinates.left;
	mode_desc.Height = out_desc.DesktopCoordinates.bottom - out_desc.DesktopCoordinates.top;
	mode_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	mode_desc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
	hr = output->FindClosestMatchingMode(&mode_desc, &swap_chain_desc.BufferDesc, nullptr);
	if (FAILED(hr)) MessageBox(wnd, _T("Failed to find a supported video mode"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR);

	if (swap_chain_desc.Windowed)
	{
		// forcing buffer resolution to xres and yres..
		// this is not a problem as long as we're in windowed mode
		swap_chain_desc.BufferDesc.Width = xres;
		swap_chain_desc.BufferDesc.Height = yres;
	}

#if defined(_DEBUG) || defined(DEBUGFAST)
	// Creating debug devices can sometimes fail if the user doesn't have the correct
	// version of the DirectX SDK. If it does, simply fallback to a non-debug device.
	{
		hr = PD3D11CreateDeviceAndSwapChain(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr,
											D3D11_CREATE_DEVICE_SINGLETHREADED | D3D11_CREATE_DEVICE_DEBUG,
											supported_feature_levels, NUM_SUPPORTED_FEATURE_LEVELS,
											D3D11_SDK_VERSION, &swap_chain_desc, &swapchain, &device,
											&featlevel, &context);
	}

	if (FAILED(hr))
#endif
	{
		hr = PD3D11CreateDeviceAndSwapChain(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr,
											D3D11_CREATE_DEVICE_SINGLETHREADED,
											supported_feature_levels, NUM_SUPPORTED_FEATURE_LEVELS,
											D3D11_SDK_VERSION, &swap_chain_desc, &swapchain, &device,
											&featlevel, &context);
	}

	if (FAILED(hr))
	{
		MessageBox(wnd, _T("Failed to initialize Direct3D.\nMake sure your video card supports at least D3D 10.0"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR);
		SAFE_RELEASE(device);
		SAFE_RELEASE(context);
		SAFE_RELEASE(swapchain);
		return E_FAIL;
	}

	// prevent DXGI from responding to Alt+Enter, unfortunately DXGI_MWA_NO_ALT_ENTER
	// does not work so we disable all monitoring of window messages. However this
	// may make it more difficult for DXGI to handle display mode changes.
	hr = factory->MakeWindowAssociation(wnd, DXGI_MWA_NO_WINDOW_CHANGES);
	if (FAILED(hr)) MessageBox(wnd, _T("Failed to associate the window"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR);

	SetDebugObjectName((ID3D11DeviceChild*)context, "device context");
	SAFE_RELEASE(factory);
	SAFE_RELEASE(output);
	SAFE_RELEASE(adapter);

	ID3D11Texture2D* buf;
	hr = swapchain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&buf);
	if (FAILED(hr))
	{
		MessageBox(wnd, _T("Failed to get swapchain buffer"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR);
		SAFE_RELEASE(device);
		SAFE_RELEASE(context);
		SAFE_RELEASE(swapchain);
		return E_FAIL;
	}
	backbuf = new D3DTexture2D(buf, D3D11_BIND_RENDER_TARGET);
	SAFE_RELEASE(buf);
	CHECK(backbuf!=nullptr, "Create back buffer texture");
	SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetTex(), "backbuffer texture");
	SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetRTV(), "backbuffer render target view");

	context->OMSetRenderTargets(1, &backbuf->GetRTV(), nullptr);

	// BGRA textures are easier to deal with in TextureCache, but might not be supported by the hardware
	UINT format_support;
	device->CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, &format_support);
	bgra_textures_supported = (format_support & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0;

	stateman = new StateManager;
	return S_OK;
}
Exemple #8
0
HRESULT Create(HWND wnd)
{
	hWnd = wnd;
	HRESULT hr;

	RECT client;
	GetClientRect(hWnd, &client);
	xres = client.right - client.left;
	yres = client.bottom - client.top;

	hr = LoadDXGI();
	if (SUCCEEDED(hr)) hr = LoadD3D();
	if (SUCCEEDED(hr)) hr = LoadD3DX();
	if (SUCCEEDED(hr)) hr = LoadD3DCompiler();
	if (FAILED(hr))
	{
		UnloadDXGI();
		UnloadD3D();
		UnloadD3DX();
		UnloadD3DCompiler();
		return hr;
	}

	IDXGIFactory* factory;
	IDXGIAdapter* adapter;
	IDXGIOutput* output;
	hr = PCreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&factory);
	if (FAILED(hr)) MessageBox(wnd, _T("Failed to create IDXGIFactory object"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR);

	hr = factory->EnumAdapters(g_ActiveConfig.iAdapter, &adapter);
	if (FAILED(hr))
	{
		// try using the first one
		hr = factory->EnumAdapters(0, &adapter);
		if (FAILED(hr)) MessageBox(wnd, _T("Failed to enumerate adapters"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR);
	}

	// TODO: Make this configurable
	hr = adapter->EnumOutputs(0, &output);
	if (FAILED(hr))
	{
		// try using the first one
		hr = adapter->EnumOutputs(0, &output);
		if (FAILED(hr)) MessageBox(wnd, _T("Failed to enumerate outputs"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR);
	}

	// get supported AA modes
	aa_modes = EnumAAModes(adapter);
	if (g_Config.iMultisampleMode >= (int)aa_modes.size())
	{
		g_Config.iMultisampleMode = 0;
		UpdateActiveConfig();
	}

	DXGI_SWAP_CHAIN_DESC swap_chain_desc;
	memset(&swap_chain_desc, 0, sizeof(swap_chain_desc));
	swap_chain_desc.BufferCount = 1;
	swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	swap_chain_desc.OutputWindow = wnd;
	swap_chain_desc.SampleDesc.Count = 1;
	swap_chain_desc.SampleDesc.Quality = 0;
	swap_chain_desc.Windowed = TRUE;

	DXGI_MODE_DESC mode_desc;
	memset(&mode_desc, 0, sizeof(mode_desc));
	mode_desc.Width = xres;
	mode_desc.Height = yres;
	mode_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
	mode_desc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
	hr = output->FindClosestMatchingMode(&mode_desc, &swap_chain_desc.BufferDesc, NULL);
	if (FAILED(hr)) MessageBox(wnd, _T("Failed to find a supported video mode"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR);

	// forcing buffer resolution to xres and yres.. TODO: The new video mode might not actually be supported!
	swap_chain_desc.BufferDesc.Width = xres;
	swap_chain_desc.BufferDesc.Height = yres;

#if defined(_DEBUG) || defined(DEBUGFAST)
	// Creating debug devices can sometimes fail if the user doesn't have the correct
	// version of the DirectX SDK. If it does, simply fallback to a non-debug device.
	{
		hr = PD3D11CreateDeviceAndSwapChain(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL,
											D3D11_CREATE_DEVICE_SINGLETHREADED | D3D11_CREATE_DEVICE_DEBUG,
											supported_feature_levels, NUM_SUPPORTED_FEATURE_LEVELS,
											D3D11_SDK_VERSION, &swap_chain_desc, &swapchain, &device,
											&featlevel, &context);
	}

	if (FAILED(hr))
#endif
	{
		hr = PD3D11CreateDeviceAndSwapChain(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL,
											D3D11_CREATE_DEVICE_SINGLETHREADED,
											supported_feature_levels, NUM_SUPPORTED_FEATURE_LEVELS,
											D3D11_SDK_VERSION, &swap_chain_desc, &swapchain, &device,
											&featlevel, &context);
	}

	if (FAILED(hr))
	{
		MessageBox(wnd, _T("Failed to initialize Direct3D.\nMake sure your video card supports at least D3D 10.0"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR);
		SAFE_RELEASE(device);
		SAFE_RELEASE(context);
		SAFE_RELEASE(swapchain);
		return E_FAIL;
	}
	SetDebugObjectName((ID3D11DeviceChild*)context, "device context");
	SAFE_RELEASE(factory);
	SAFE_RELEASE(output);
	SAFE_RELEASE(adapter);

	ID3D11Texture2D* buf;
	hr = swapchain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&buf);
	if (FAILED(hr))
	{
		MessageBox(wnd, _T("Failed to get swapchain buffer"), _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR);
		SAFE_RELEASE(device);
		SAFE_RELEASE(context);
		SAFE_RELEASE(swapchain);
		return E_FAIL;
	}
	backbuf = new D3DTexture2D(buf, D3D11_BIND_RENDER_TARGET);
	SAFE_RELEASE(buf);
	CHECK(backbuf!=NULL, "Create back buffer texture");
	SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetTex(), "backbuffer texture");
	SetDebugObjectName((ID3D11DeviceChild*)backbuf->GetRTV(), "backbuffer render target view");

	context->OMSetRenderTargets(1, &backbuf->GetRTV(), NULL);

	// BGRA textures are easier to deal with in TextureCache, but might not be supported by the hardware
	UINT format_support;
	device->CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, &format_support);
	bgra_textures_supported = (format_support & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0;

	stateman = new StateManager;
	return S_OK;
}
Exemple #9
0
HRESULT Create(HWND wnd)
{
  HRESULT hr = LoadDXGI();
  if (SUCCEEDED(hr))
    hr = LoadD3D();
  if (SUCCEEDED(hr))
    hr = LoadD3DCompiler();
  if (FAILED(hr))
  {
    UnloadDXGI();
    UnloadD3D();
    UnloadD3DCompiler();
    return hr;
  }

  hr = PCreateDXGIFactory(__uuidof(IDXGIFactory2), (void**)&s_dxgi_factory);
  if (FAILED(hr))
    MessageBox(wnd, _T("Failed to create IDXGIFactory object"), _T("Dolphin Direct3D 11 backend"),
               MB_OK | MB_ICONERROR);

  IDXGIAdapter* adapter;
  hr = s_dxgi_factory->EnumAdapters(g_ActiveConfig.iAdapter, &adapter);
  if (FAILED(hr))
  {
    // try using the first one
    hr = s_dxgi_factory->EnumAdapters(0, &adapter);
    if (FAILED(hr))
      MessageBox(wnd, _T("Failed to enumerate adapters"), _T("Dolphin Direct3D 11 backend"),
                 MB_OK | MB_ICONERROR);
  }

  // get supported AA modes
  s_aa_modes = EnumAAModes(adapter);

  if (std::find_if(s_aa_modes.begin(), s_aa_modes.end(), [](const DXGI_SAMPLE_DESC& desc) {
        return desc.Count == g_Config.iMultisamples;
      }) == s_aa_modes.end())
  {
    Config::SetCurrent(Config::GFX_MSAA, UINT32_C(1));
    UpdateActiveConfig();
  }

  // Check support for allow tearing, we query the interface for backwards compatibility
  UINT allow_tearing = FALSE;
  IDXGIFactory5* factory5;
  hr = s_dxgi_factory->QueryInterface(&factory5);
  if (SUCCEEDED(hr))
  {
    hr = factory5->CheckFeatureSupport(DXGI_FEATURE_PRESENT_ALLOW_TEARING, &allow_tearing,
                                       sizeof(allow_tearing));
    factory5->Release();
  }
  s_allow_tearing_supported = SUCCEEDED(hr) && allow_tearing;

  // Creating debug devices can sometimes fail if the user doesn't have the correct
  // version of the DirectX SDK. If it does, simply fallback to a non-debug device.
  if (g_Config.bEnableValidationLayer)
  {
    hr = s_d3d11_create_device(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, D3D11_CREATE_DEVICE_DEBUG,
                               supported_feature_levels, NUM_SUPPORTED_FEATURE_LEVELS,
                               D3D11_SDK_VERSION, &device, &s_featlevel, &context);

    // Debugbreak on D3D error
    if (SUCCEEDED(hr) && SUCCEEDED(device->QueryInterface(__uuidof(ID3D11Debug), (void**)&s_debug)))
    {
      ID3D11InfoQueue* infoQueue = nullptr;
      if (SUCCEEDED(s_debug->QueryInterface(__uuidof(ID3D11InfoQueue), (void**)&infoQueue)))
      {
        infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true);
        infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true);

        D3D11_MESSAGE_ID hide[] = {D3D11_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS};

        D3D11_INFO_QUEUE_FILTER filter = {};
        filter.DenyList.NumIDs = sizeof(hide) / sizeof(D3D11_MESSAGE_ID);
        filter.DenyList.pIDList = hide;
        infoQueue->AddStorageFilterEntries(&filter);
        infoQueue->Release();
      }
    }
  }

  if (!g_Config.bEnableValidationLayer || FAILED(hr))
  {
    hr = s_d3d11_create_device(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, 0,
                               supported_feature_levels, NUM_SUPPORTED_FEATURE_LEVELS,
                               D3D11_SDK_VERSION, &device, &s_featlevel, &context);
  }

  SAFE_RELEASE(adapter);

  if (FAILED(hr) || (wnd && !CreateSwapChain(wnd)))
  {
    MessageBox(
        wnd,
        _T("Failed to initialize Direct3D.\nMake sure your video card supports at least D3D 10.0"),
        _T("Dolphin Direct3D 11 backend"), MB_OK | MB_ICONERROR);
    SAFE_RELEASE(device);
    SAFE_RELEASE(context);
    SAFE_RELEASE(s_dxgi_factory);
    return E_FAIL;
  }

  hr = device->QueryInterface<ID3D11Device1>(&device1);
  if (FAILED(hr))
  {
    WARN_LOG(VIDEO, "Missing Direct3D 11.1 support. Logical operations will not be supported.");
    g_Config.backend_info.bSupportsLogicOp = false;
  }

  // BGRA textures are easier to deal with in TextureCache, but might not be supported
  UINT format_support;
  device->CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, &format_support);
  s_bgra_textures_supported = (format_support & D3D11_FORMAT_SUPPORT_TEXTURE2D) != 0;
  g_Config.backend_info.bSupportsST3CTextures = SupportsS3TCTextures(device);
  g_Config.backend_info.bSupportsBPTCTextures = SupportsBPTCTextures(device);

  // prevent DXGI from responding to Alt+Enter, unfortunately DXGI_MWA_NO_ALT_ENTER
  // does not work so we disable all monitoring of window messages. However this
  // may make it more difficult for DXGI to handle display mode changes.
  if (wnd)
  {
    hr = s_dxgi_factory->MakeWindowAssociation(wnd, DXGI_MWA_NO_WINDOW_CHANGES);
    if (FAILED(hr))
      MessageBox(wnd, _T("Failed to associate the window"), _T("Dolphin Direct3D 11 backend"),
                 MB_OK | MB_ICONERROR);
  }

  SetDebugObjectName(context, "device context");

  stateman = new StateManager;
  return S_OK;
}
_Use_decl_annotations_
HRESULT DirectX::CreateWICTextureFromMemoryEx( ID3D11Device* d3dDevice,
                                               ID3D11DeviceContext* d3dContext,
                                               const uint8_t* wicData,
                                               size_t wicDataSize,
                                               size_t maxsize,
                                               D3D11_USAGE usage,
                                               unsigned int bindFlags,
                                               unsigned int cpuAccessFlags,
                                               unsigned int miscFlags,
                                               bool forceSRGB,
                                               ID3D11Resource** texture,
                                               ID3D11ShaderResourceView** textureView )
{
    if ( texture )
    {
        *texture = nullptr;
    }
    if ( textureView )
    {
        *textureView = nullptr;
    }

    if (!d3dDevice || !wicData || (!texture && !textureView))
        return E_INVALIDARG;

    if ( !wicDataSize )
        return E_FAIL;

#ifdef _M_AMD64
    if ( wicDataSize > 0xFFFFFFFF )
        return HRESULT_FROM_WIN32( ERROR_FILE_TOO_LARGE );
#endif

    IWICImagingFactory* pWIC = _GetWIC();
    if ( !pWIC )
        return E_NOINTERFACE;

    // Create input stream for memory
    ScopedObject<IWICStream> stream;
    HRESULT hr = pWIC->CreateStream( &stream );
    if ( FAILED(hr) )
        return hr;

    hr = stream->InitializeFromMemory( const_cast<uint8_t*>( wicData ), static_cast<DWORD>( wicDataSize ) );
    if ( FAILED(hr) )
        return hr;

    // Initialize WIC
    ScopedObject<IWICBitmapDecoder> decoder;
    hr = pWIC->CreateDecoderFromStream( stream.Get(), 0, WICDecodeMetadataCacheOnDemand, &decoder );
    if ( FAILED(hr) )
        return hr;

    ScopedObject<IWICBitmapFrameDecode> frame;
    hr = decoder->GetFrame( 0, &frame );
    if ( FAILED(hr) )
        return hr;

    hr = CreateTextureFromWIC( d3dDevice, d3dContext, frame.Get(), maxsize,
                               usage, bindFlags, cpuAccessFlags, miscFlags, forceSRGB,
                               texture, textureView );
    if ( FAILED(hr)) 
        return hr;

    if (texture != 0 && *texture != 0)
    {
        SetDebugObjectName(*texture, "WICTextureLoader");
    }

    if (textureView != 0 && *textureView != 0)
    {
        SetDebugObjectName(*textureView, "WICTextureLoader");
    }

    return hr;
}
//---------------------------------------------------------------------------------
static HRESULT CreateTextureFromWIC( _In_ ID3D11Device* d3dDevice,
                                     _In_opt_ ID3D11DeviceContext* d3dContext,
                                     _In_ IWICBitmapFrameDecode *frame,
                                     _In_ size_t maxsize,
                                     _In_ D3D11_USAGE usage,
                                     _In_ unsigned int bindFlags,
                                     _In_ unsigned int cpuAccessFlags,
                                     _In_ unsigned int miscFlags,
                                     _In_ bool forceSRGB,
                                     _Out_opt_ ID3D11Resource** texture,
                                     _Out_opt_ ID3D11ShaderResourceView** textureView )
{
    UINT width, height;
    HRESULT hr = frame->GetSize( &width, &height );
    if ( FAILED(hr) )
        return hr;

    assert( width > 0 && height > 0 );

    if ( !maxsize )
    {
        // This is a bit conservative because the hardware could support larger textures than
        // the Feature Level defined minimums, but doing it this way is much easier and more
        // performant for WIC than the 'fail and retry' model used by DDSTextureLoader

        switch( d3dDevice->GetFeatureLevel() )
        {
            case D3D_FEATURE_LEVEL_9_1:
            case D3D_FEATURE_LEVEL_9_2:
                maxsize = 2048 /*D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION*/;
                break;

            case D3D_FEATURE_LEVEL_9_3:
                maxsize = 4096 /*D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION*/;
                break;

            case D3D_FEATURE_LEVEL_10_0:
            case D3D_FEATURE_LEVEL_10_1:
                maxsize = 8192 /*D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION*/;
                break;

            default:
                maxsize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
                break;
        }
    }

    assert( maxsize > 0 );

    UINT twidth, theight;
    if ( width > maxsize || height > maxsize )
    {
        float ar = static_cast<float>(height) / static_cast<float>(width);
        if ( width > height )
        {
            twidth = static_cast<UINT>( maxsize );
            theight = static_cast<UINT>( static_cast<float>(maxsize) * ar );
        }
        else
        {
            theight = static_cast<UINT>( maxsize );
            twidth = static_cast<UINT>( static_cast<float>(maxsize) / ar );
        }
        assert( twidth <= maxsize && theight <= maxsize );
    }
    else
    {
        twidth = width;
        theight = height;
    }

    // Determine format
    WICPixelFormatGUID pixelFormat;
    hr = frame->GetPixelFormat( &pixelFormat );
    if ( FAILED(hr) )
        return hr;

    WICPixelFormatGUID convertGUID;
    memcpy( &convertGUID, &pixelFormat, sizeof(WICPixelFormatGUID) );

    size_t bpp = 0;

    DXGI_FORMAT format = _WICToDXGI( pixelFormat );
    if ( format == DXGI_FORMAT_UNKNOWN )
    {
        if ( memcmp( &GUID_WICPixelFormat96bppRGBFixedPoint, &pixelFormat, sizeof(WICPixelFormatGUID) ) == 0 )
        {
#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/) || defined(_WIN7_PLATFORM_UPDATE)
            if ( g_WIC2 )
            {
                memcpy( &convertGUID, &GUID_WICPixelFormat96bppRGBFloat, sizeof(WICPixelFormatGUID) );
                format = DXGI_FORMAT_R32G32B32_FLOAT;
            }
            else
#endif
            {
                memcpy( &convertGUID, &GUID_WICPixelFormat128bppRGBAFloat, sizeof(WICPixelFormatGUID) );
                format = DXGI_FORMAT_R32G32B32A32_FLOAT;
            }
        }
        else
        {
            for( size_t i=0; i < _countof(g_WICConvert); ++i )
            {
                if ( memcmp( &g_WICConvert[i].source, &pixelFormat, sizeof(WICPixelFormatGUID) ) == 0 )
                {
                    memcpy( &convertGUID, &g_WICConvert[i].target, sizeof(WICPixelFormatGUID) );

                    format = _WICToDXGI( g_WICConvert[i].target );
                    assert( format != DXGI_FORMAT_UNKNOWN );
                    bpp = _WICBitsPerPixel( convertGUID );
                    break;
                }
            }
        }

        if ( format == DXGI_FORMAT_UNKNOWN )
            return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
    }
    else
    {
        bpp = _WICBitsPerPixel( pixelFormat );
    }

#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/) || defined(_WIN7_PLATFORM_UPDATE)
    if ( (format == DXGI_FORMAT_R32G32B32_FLOAT) && d3dContext != 0 && textureView != 0 )
    {
        // Special case test for optional device support for autogen mipchains for R32G32B32_FLOAT 
        UINT fmtSupport = 0;
        hr = d3dDevice->CheckFormatSupport( DXGI_FORMAT_R32G32B32_FLOAT, &fmtSupport );
        if ( FAILED(hr) || !( fmtSupport & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN ) )
        {
            // Use R32G32B32A32_FLOAT instead which is required for Feature Level 10.0 and up
            memcpy( &convertGUID, &GUID_WICPixelFormat128bppRGBAFloat, sizeof(WICPixelFormatGUID) );
            format = DXGI_FORMAT_R32G32B32A32_FLOAT;
            bpp = 128;
        }
    }
#endif

    if ( !bpp )
        return E_FAIL;

    // Verify our target format is supported by the current device
    // (handles WDDM 1.0 or WDDM 1.1 device driver cases as well as DirectX 11.0 Runtime without 16bpp format support)
    UINT support = 0;
    hr = d3dDevice->CheckFormatSupport( format, &support );
    if ( FAILED(hr) || !(support & D3D11_FORMAT_SUPPORT_TEXTURE2D) )
    {
        // Fallback to RGBA 32-bit format which is supported by all devices
        memcpy( &convertGUID, &GUID_WICPixelFormat32bppRGBA, sizeof(WICPixelFormatGUID) );
        format = DXGI_FORMAT_R8G8B8A8_UNORM;
        bpp = 32;
    }

    // Allocate temporary memory for image
    size_t rowPitch = ( twidth * bpp + 7 ) / 8;
    size_t imageSize = rowPitch * theight;

    std::unique_ptr<uint8_t[]> temp( new (std::nothrow) uint8_t[ imageSize ] );
    if (!temp)
        return E_OUTOFMEMORY;

    // Load image data
    if ( memcmp( &convertGUID, &pixelFormat, sizeof(GUID) ) == 0
         && twidth == width
         && theight == height )
    {
        // No format conversion or resize needed
        hr = frame->CopyPixels( 0, static_cast<UINT>( rowPitch ), static_cast<UINT>( imageSize ), temp.get() );  
        if ( FAILED(hr) )
            return hr;
    }
    else if ( twidth != width || theight != height )
    {
        // Resize
        IWICImagingFactory* pWIC = _GetWIC();
        if ( !pWIC )
            return E_NOINTERFACE;

        ScopedObject<IWICBitmapScaler> scaler;
        hr = pWIC->CreateBitmapScaler( &scaler );
        if ( FAILED(hr) )
            return hr;

        hr = scaler->Initialize( frame, twidth, theight, WICBitmapInterpolationModeFant );
        if ( FAILED(hr) )
            return hr;

        WICPixelFormatGUID pfScaler;
        hr = scaler->GetPixelFormat( &pfScaler );
        if ( FAILED(hr) )
            return hr;

        if ( memcmp( &convertGUID, &pfScaler, sizeof(GUID) ) == 0 )
        {
            // No format conversion needed
            hr = scaler->CopyPixels( 0, static_cast<UINT>( rowPitch ), static_cast<UINT>( imageSize ), temp.get() );  
            if ( FAILED(hr) )
                return hr;
        }
        else
        {
            ScopedObject<IWICFormatConverter> FC;
            hr = pWIC->CreateFormatConverter( &FC );
            if ( FAILED(hr) )
                return hr;

            hr = FC->Initialize( scaler.Get(), convertGUID, WICBitmapDitherTypeErrorDiffusion, 0, 0, WICBitmapPaletteTypeCustom );
            if ( FAILED(hr) )
                return hr;

            hr = FC->CopyPixels( 0, static_cast<UINT>( rowPitch ), static_cast<UINT>( imageSize ), temp.get() );  
            if ( FAILED(hr) )
                return hr;
        }
    }
    else
    {
        // Format conversion but no resize
        IWICImagingFactory* pWIC = _GetWIC();
        if ( !pWIC )
            return E_NOINTERFACE;

        ScopedObject<IWICFormatConverter> FC;
        hr = pWIC->CreateFormatConverter( &FC );
        if ( FAILED(hr) )
            return hr;

        hr = FC->Initialize( frame, convertGUID, WICBitmapDitherTypeErrorDiffusion, 0, 0, WICBitmapPaletteTypeCustom );
        if ( FAILED(hr) )
            return hr;

        hr = FC->CopyPixels( 0, static_cast<UINT>( rowPitch ), static_cast<UINT>( imageSize ), temp.get() );  
        if ( FAILED(hr) )
            return hr;
    }

    // See if format is supported for auto-gen mipmaps (varies by feature level)
    bool autogen = false;
    if ( d3dContext != 0 && textureView != 0 ) // Must have context and shader-view to auto generate mipmaps
    {
        UINT fmtSupport = 0;
        hr = d3dDevice->CheckFormatSupport( format, &fmtSupport );
        if ( SUCCEEDED(hr) && ( fmtSupport & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN ) )
        {
            autogen = true;
        }
    }

    // Create texture
    D3D11_TEXTURE2D_DESC desc;
    desc.Width = twidth;
    desc.Height = theight;
    desc.MipLevels = (autogen) ? 0 : 1;
    desc.ArraySize = 1;
    desc.Format = (forceSRGB) ? MakeSRGB( format ) : format;
    desc.SampleDesc.Count = 1;
    desc.SampleDesc.Quality = 0;
    desc.Usage = usage;
    desc.CPUAccessFlags = cpuAccessFlags;

    if ( autogen )
    {
        desc.BindFlags = bindFlags | D3D11_BIND_RENDER_TARGET;
        desc.MiscFlags = miscFlags | D3D11_RESOURCE_MISC_GENERATE_MIPS;
    }
    else
    {
        desc.BindFlags = bindFlags;
        desc.MiscFlags = miscFlags;
    }

    D3D11_SUBRESOURCE_DATA initData;
    initData.pSysMem = temp.get();
    initData.SysMemPitch = static_cast<UINT>( rowPitch );
    initData.SysMemSlicePitch = static_cast<UINT>( imageSize );

    ID3D11Texture2D* tex = nullptr;
    hr = d3dDevice->CreateTexture2D( &desc, (autogen) ? nullptr : &initData, &tex );
    if ( SUCCEEDED(hr) && tex != 0 )
    {
        if (textureView != 0)
        {
            D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc;
            memset( &SRVDesc, 0, sizeof( SRVDesc ) );
            SRVDesc.Format = desc.Format;

            SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
            SRVDesc.Texture2D.MipLevels = (autogen) ? -1 : 1;

            hr = d3dDevice->CreateShaderResourceView( tex, &SRVDesc, textureView );
            if ( FAILED(hr) )
            {
                tex->Release();
                return hr;
            }

            if ( autogen )
            {
                assert( d3dContext != 0 );
                d3dContext->UpdateSubresource( tex, 0, nullptr, temp.get(), static_cast<UINT>(rowPitch), static_cast<UINT>(imageSize) );
                d3dContext->GenerateMips( *textureView );
            }
        }

        if (texture != 0)
        {
            *texture = tex;
        }
        else
        {
            SetDebugObjectName(tex, "WICTextureLoader");
            tex->Release();
        }
    }

    return hr;
}
Exemple #12
0
// Returns true if the block D3D data was recreated
bool CEffect::ApplyRenderStateBlock(_In_ SBaseBlock *pBlock)
{
    if( pBlock->IsUserManaged )
    {
        return false;
    }

    bool bRecreate = pBlock->ApplyAssignments(this);

    if (bRecreate)
    {
        switch (pBlock->BlockType)
        {
        case EBT_Sampler:
            {
                SSamplerBlock *pSBlock = pBlock->AsSampler();

                assert(pSBlock->pD3DObject != 0);
                _Analysis_assume_(pSBlock->pD3DObject != 0);
                pSBlock->pD3DObject->Release();

                HRESULT hr = m_pDevice->CreateSamplerState( &pSBlock->BackingStore.SamplerDesc, &pSBlock->pD3DObject );
                if ( SUCCEEDED(hr) )
                {
                    SetDebugObjectName(pSBlock->pD3DObject, "D3DX11Effect");
                }
            }
            break;

        case EBT_DepthStencil:
            {
                SDepthStencilBlock *pDSBlock = pBlock->AsDepthStencil();

                assert(nullptr != pDSBlock->pDSObject);
                SAFE_RELEASE( pDSBlock->pDSObject );
                if( SUCCEEDED( m_pDevice->CreateDepthStencilState( &pDSBlock->BackingStore, &pDSBlock->pDSObject ) ) )
                {
                    pDSBlock->IsValid = true;
                    SetDebugObjectName( pDSBlock->pDSObject, "D3DX11Effect" );
                }
                else
                    pDSBlock->IsValid = false;
            }
            break;
        
        case EBT_Blend:
            {
                SBlendBlock *pBBlock = pBlock->AsBlend();

                assert(nullptr != pBBlock->pBlendObject);
                SAFE_RELEASE( pBBlock->pBlendObject );
                if( SUCCEEDED( m_pDevice->CreateBlendState( &pBBlock->BackingStore, &pBBlock->pBlendObject ) ) )
                {
                    pBBlock->IsValid = true;
                    SetDebugObjectName( pBBlock->pBlendObject, "D3DX11Effect" );
                }
                else
                    pBBlock->IsValid = false;
            }
            break;

        case EBT_Rasterizer:
            {
                SRasterizerBlock *pRBlock = pBlock->AsRasterizer();

                assert(nullptr != pRBlock->pRasterizerObject);

                SAFE_RELEASE( pRBlock->pRasterizerObject );
                if( SUCCEEDED( m_pDevice->CreateRasterizerState( &pRBlock->BackingStore, &pRBlock->pRasterizerObject ) ) )
                {
                    pRBlock->IsValid = true;
                    SetDebugObjectName( pRBlock->pRasterizerObject, "D3DX11Effect" );
                }
                else
                    pRBlock->IsValid = false;
            }
            break;
        
        default:
            assert(0);
        }
    }

    return bRecreate;
}