1 // Copyright (C) 2003 Dolphin Project.
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, version 2.0.
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 // GNU General Public License 2.0 for more details.
12 // A copy of the GPL 2.0 should have been included with the program.
13 // If not, see http://www.gnu.org/licenses/
15 // Official SVN repository and contact information can be found at
16 // http://code.google.com/p/dolphin-emu/
19 #include "D3DTexture.h"
20 #include "D3DShader.h"
21 #include "D3Dcompiler.h"
22 #include "VideoConfig.h"
24 #include "XFStructs.h"
34 ID3D11Device
* device
= NULL
;
35 ID3D11DeviceContext
* context
= NULL
;
36 IDXGISwapChain
* swapchain
= NULL
;
37 D3D_FEATURE_LEVEL featlevel
;
38 D3DTexture2D
* backbuf
= NULL
;
41 #define NUM_SUPPORTED_FEATURE_LEVELS 3
42 const D3D_FEATURE_LEVEL supported_feature_levels
[NUM_SUPPORTED_FEATURE_LEVELS
] = {
43 D3D_FEATURE_LEVEL_11_0
,
44 D3D_FEATURE_LEVEL_10_1
,
45 D3D_FEATURE_LEVEL_10_0
48 unsigned int xres
, yres
;
50 bool bFrameInProgress
= false;
52 HRESULT
Create(HWND wnd
)
58 GetClientRect(hWnd
, &client
);
59 xres
= client
.right
- client
.left
;
60 yres
= client
.bottom
- client
.top
;
62 IDXGIFactory
* factory
;
63 IDXGIAdapter
* adapter
;
65 hr
= CreateDXGIFactory(__uuidof(IDXGIFactory
), (void**)&factory
);
66 if (FAILED(hr
)) MessageBox(wnd
, _T("Failed to create IDXGIFactory object"), _T("Dolphin Direct3D 11 plugin"), MB_OK
| MB_ICONERROR
);
68 hr
= factory
->EnumAdapters(g_ActiveConfig
.iAdapter
, &adapter
);
71 // try using the first one
72 hr
= factory
->EnumAdapters(0, &adapter
);
73 if (FAILED(hr
)) MessageBox(wnd
, _T("Failed to enumerate adapters"), _T("Dolphin Direct3D 11 plugin"), MB_OK
| MB_ICONERROR
);
76 // TODO: Make this configurable
77 hr
= adapter
->EnumOutputs(0, &output
);
80 // try using the first one
81 hr
= adapter
->EnumOutputs(0, &output
);
82 if (FAILED(hr
)) MessageBox(wnd
, _T("Failed to enumerate outputs"), _T("Dolphin Direct3D 11 plugin"), MB_OK
| MB_ICONERROR
);
85 // this will need to be changed once multisampling gets implemented
86 DXGI_SWAP_CHAIN_DESC swap_chain_desc
;
87 memset(&swap_chain_desc
, 0, sizeof(swap_chain_desc
));
88 swap_chain_desc
.BufferCount
= 1;
89 swap_chain_desc
.BufferUsage
= DXGI_USAGE_RENDER_TARGET_OUTPUT
;
90 swap_chain_desc
.OutputWindow
= wnd
;
91 swap_chain_desc
.SampleDesc
.Count
= 1;
92 swap_chain_desc
.SampleDesc
.Quality
= 0;
93 swap_chain_desc
.Windowed
= TRUE
;
95 DXGI_MODE_DESC mode_desc
;
96 memset(&mode_desc
, 0, sizeof(mode_desc
));
97 mode_desc
.Width
= xres
;
98 mode_desc
.Height
= yres
;
99 mode_desc
.Format
= DXGI_FORMAT_R8G8B8A8_UNORM
;
100 mode_desc
.Scaling
= DXGI_MODE_SCALING_UNSPECIFIED
;
101 hr
= output
->FindClosestMatchingMode(&mode_desc
, &swap_chain_desc
.BufferDesc
, NULL
);
102 if (FAILED(hr
)) MessageBox(wnd
, _T("Failed to find a supported video mode"), _T("Dolphin Direct3D 11 plugin"), MB_OK
| MB_ICONERROR
);
104 // forcing buffer resolution to xres and yres.. TODO: The new video mode might not actually be supported!
105 swap_chain_desc
.BufferDesc
.Width
= xres
;
106 swap_chain_desc
.BufferDesc
.Height
= yres
;
108 #if defined(_DEBUG) || defined(DEBUGFAST)
109 D3D11_CREATE_DEVICE_FLAG device_flags
= (D3D11_CREATE_DEVICE_FLAG
)(D3D11_CREATE_DEVICE_DEBUG
|D3D11_CREATE_DEVICE_SINGLETHREADED
);
111 D3D11_CREATE_DEVICE_FLAG device_flags
= D3D11_CREATE_DEVICE_SINGLETHREADED
;
113 hr
= D3D11CreateDeviceAndSwapChain(adapter
, D3D_DRIVER_TYPE_UNKNOWN
, NULL
, device_flags
,
114 supported_feature_levels
, NUM_SUPPORTED_FEATURE_LEVELS
,
115 D3D11_SDK_VERSION
, &swap_chain_desc
, &swapchain
, &device
,
116 &featlevel
, &context
);
117 if (FAILED(hr
) || !device
|| !context
|| !swapchain
)
119 MessageBox(wnd
, _T("Failed to initialize Direct3D.\nMake sure your video card supports at least D3D 10.0"), _T("Dolphin Direct3D 11 plugin"), MB_OK
| MB_ICONERROR
);
120 SAFE_RELEASE(device
);
121 SAFE_RELEASE(context
);
122 SAFE_RELEASE(swapchain
);
125 SetDebugObjectName((ID3D11DeviceChild
*)context
, "device context");
130 ID3D11Texture2D
* buf
;
131 hr
= swapchain
->GetBuffer(0, IID_ID3D11Texture2D
, (void**)&buf
);
134 MessageBox(wnd
, _T("Failed to get swapchain buffer"), _T("Dolphin Direct3D 11 plugin"), MB_OK
| MB_ICONERROR
);
137 swapchain
->Release();
140 backbuf
= new D3DTexture2D(buf
, D3D11_BIND_RENDER_TARGET
);
142 CHECK(backbuf
!=NULL
, "Create back buffer texture");
143 SetDebugObjectName((ID3D11DeviceChild
*)backbuf
->GetTex(), "backbuffer texture");
144 SetDebugObjectName((ID3D11DeviceChild
*)backbuf
->GetRTV(), "backbuffer render target view");
146 context
->OMSetRenderTargets(1, &backbuf
->GetRTV(), NULL
);
148 gfxstate
= new EmuGfxState
;
149 stateman
= new StateManager
;
155 // release all bound resources
156 context
->ClearState();
157 SAFE_RELEASE(backbuf
);
158 SAFE_RELEASE(swapchain
);
159 SAFE_DELETE(gfxstate
);
160 SAFE_DELETE(stateman
);
161 context
->Flush(); // immediately destroy device objects
163 SAFE_RELEASE(context
);
164 ULONG references
= device
->Release();
167 ERROR_LOG(VIDEO
, "Unreleased references: %i.", references
);
171 NOTICE_LOG(VIDEO
, "Successfully released all device references!");
176 /* just returning the 4_0 ones here */
177 const char* VertexShaderVersionString() { return "vs_4_0"; }
178 const char* PixelShaderVersionString() { return "ps_4_0"; }
180 D3DTexture2D
* &GetBackBuffer() { return backbuf
; }
181 unsigned int GetBackBufferWidth() { return xres
; }
182 unsigned int GetBackBufferHeight() { return yres
; }
186 // release all back buffer references
187 SAFE_RELEASE(backbuf
);
189 // resize swapchain buffers
191 GetClientRect(hWnd
, &client
);
192 xres
= client
.right
- client
.left
;
193 yres
= client
.bottom
- client
.top
;
194 D3D::swapchain
->ResizeBuffers(1, xres
, yres
, DXGI_FORMAT_R8G8B8A8_UNORM
, 0);
196 // recreate back buffer texture
197 ID3D11Texture2D
* buf
;
198 HRESULT hr
= swapchain
->GetBuffer(0, IID_ID3D11Texture2D
, (void**)&buf
);
201 MessageBox(hWnd
, _T("Failed to get swapchain buffer"), _T("Dolphin Direct3D 11 plugin"), MB_OK
| MB_ICONERROR
);
204 swapchain
->Release();
207 backbuf
= new D3DTexture2D(buf
, D3D11_BIND_RENDER_TARGET
);
209 CHECK(backbuf
!=NULL
, "Create back buffer texture");
210 SetDebugObjectName((ID3D11DeviceChild
*)backbuf
->GetTex(), "backbuffer texture");
211 SetDebugObjectName((ID3D11DeviceChild
*)backbuf
->GetRTV(), "backbuffer render target view");
216 if (bFrameInProgress
)
218 PanicAlert("BeginFrame called although a frame is already in progress");
221 bFrameInProgress
= true;
222 return (device
!= NULL
);
227 if (!bFrameInProgress
)
229 PanicAlert("EndFrame called although no frame is in progress");
232 bFrameInProgress
= false;
237 // TODO: Is 1 the correct value for vsyncing?
238 swapchain
->Present((UINT
)g_ActiveConfig
.bVSync
, 0);