aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/modules/engines/direct3d/evas_direct3d_device.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/evas/src/modules/engines/direct3d/evas_direct3d_device.cpp')
-rw-r--r--libraries/evas/src/modules/engines/direct3d/evas_direct3d_device.cpp393
1 files changed, 393 insertions, 0 deletions
diff --git a/libraries/evas/src/modules/engines/direct3d/evas_direct3d_device.cpp b/libraries/evas/src/modules/engines/direct3d/evas_direct3d_device.cpp
new file mode 100644
index 0000000..ce0d985
--- /dev/null
+++ b/libraries/evas/src/modules/engines/direct3d/evas_direct3d_device.cpp
@@ -0,0 +1,393 @@
1//#define ENABLE_LOG_PRINTF
2
3#include "evas_direct3d_device.h"
4
5#include "evas_direct3d_vertex_buffer_cache.h"
6
7D3DDevice::D3DDevice()
8{
9 ResetParams();
10}
11
12bool D3DDevice::Init(HWND window, int depth, bool fullscreen)
13{
14 D3DPRESENT_PARAMETERS pp;
15 D3DDISPLAYMODE dm;
16 D3DCAPS9 caps;
17 RECT rect;
18 DWORD flag;
19 HRESULT hr;
20
21 if (window == NULL)
22 return false;
23
24 Destroy();
25
26 _object = Direct3DCreate9(D3D_SDK_VERSION);
27 if (_object == NULL)
28 return false;
29
30 if (FAILED(hr = _object->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &dm)))
31 {
32 ERR("GetAdapterDisplayMode failed: %x", hr);
33 Destroy();
34 return false;
35 }
36
37 if (FAILED(hr = _object->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps)))
38 {
39 ERR("GetDeviceCaps failed: %x", hr);
40 Destroy();
41 return false;
42 }
43
44 if (!GetClientRect(window, &rect))
45 {
46 ERR("GetClientRect failed: %x", GetLastError());
47 Destroy();
48 return false;
49 }
50
51 if (SUCCEEDED(_object->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
52 dm.Format, 0, D3DRTYPE_TEXTURE, (depth == 16) ? D3DFMT_R5G6B5 : D3DFMT_A8R8G8B8)))
53 {
54 dm.Format = (depth == 16) ? D3DFMT_R5G6B5 : D3DFMT_A8R8G8B8;
55 }
56
57 flag = (caps.VertexProcessingCaps != 0) ?
58 (D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE) :
59 D3DCREATE_SOFTWARE_VERTEXPROCESSING;
60
61 ZeroMemory(&pp, sizeof(pp));
62 if (!fullscreen)
63 {
64 pp.BackBufferWidth = rect.right - rect.left;
65 pp.BackBufferHeight = rect.bottom - rect.top;
66 }
67 else
68 {
69 pp.BackBufferWidth = ::GetSystemMetrics(SM_CXSCREEN);
70 pp.BackBufferHeight = ::GetSystemMetrics(SM_CYSCREEN);
71 }
72 pp.BackBufferFormat = dm.Format;
73 pp.BackBufferCount = 1;
74 pp.MultiSampleType = D3DMULTISAMPLE_NONE;
75 pp.MultiSampleQuality = 0;
76 pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
77 pp.hDeviceWindow = window;
78 pp.Windowed = fullscreen ? FALSE : TRUE;
79 //pp.EnableAutoDepthStencil = TRUE;
80 //pp.AutoDepthStencilFormat = D3DFMT_D16;
81 pp.FullScreen_RefreshRateInHz = 0;
82 pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
83
84 if (FAILED(hr = _object->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
85 window, flag, &pp, &_device)))
86 {
87 WRN("CreateDevice failed: %x", hr);
88 Destroy();
89 return false;
90 }
91
92 LPDIRECT3DSURFACE9 backbuffer = NULL;
93 _device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
94 backbuffer->GetDesc(&_backbuffer_desc);
95 backbuffer->Release();
96
97 switch (dm.Format) {
98 case D3DFMT_A8R8G8B8:
99 case D3DFMT_X8R8G8B8:
100 _depth = 32;
101 break;
102 case D3DFMT_R5G6B5:
103 _depth = 16;
104 break;
105 default:
106 WRN("No supported format found");
107 Destroy();
108 return false;
109 }
110
111 //_render_to_texture = false;
112
113 _d3dpp = pp;
114 _device_lost = FALSE;
115 _scene_rendering = FALSE;
116 _width = rect.right - rect.left;
117 _height = rect.bottom - rect.top;
118 _window = window;
119
120 if (FAILED(CreateRenderTarget()))
121 {
122 ERR("Failed to create render target");
123 Destroy();
124 return false;
125 }
126
127 Log("initialized");
128 return true;
129}
130
131bool D3DDevice::Reset(int width, int height, int fullscreen)
132{
133 D3DPRESENT_PARAMETERS pp = _d3dpp;
134 _d3dpp.BackBufferWidth = (width > 0) ? width : _d3dpp.BackBufferWidth;
135 _d3dpp.BackBufferHeight = (height > 0) ? height : _d3dpp.BackBufferHeight;
136 _d3dpp.Windowed = (fullscreen == 1) ? FALSE : ((fullscreen == 0) ? TRUE : _d3dpp.Windowed);
137 if (FAILED(ResetDevice()))
138 {
139 WRN("Couldnt restore device");
140 _d3dpp = pp;
141 return SUCCEEDED(ResetDevice());
142 }
143 _width = _d3dpp.BackBufferWidth;
144 _height = _d3dpp.BackBufferHeight;
145 return true;
146}
147
148void D3DDevice::Destroy()
149{
150 //if (_render_target != NULL)
151 //{
152 // _render_target->Release();
153 // _render_target = NULL;
154 //}
155 if (_render_target_data != NULL)
156 {
157 _render_target_data->Release();
158 _render_target_data = NULL;
159 }
160 if (_device != NULL)
161 {
162 int num = _device->Release();
163 assert(num == 0);
164 }
165 if (_object != NULL)
166 _object->Release();
167 ResetParams();
168
169 INF("uninitialized");
170}
171
172void D3DDevice::ResetParams()
173{
174 _window = NULL;
175 _object = NULL;
176 _device = NULL;
177 _width = 0;
178 _height = 0;
179 _rot = 0;
180 _depth = 0;
181 _device_lost = false;
182 _scene_rendering = false;
183 ZeroMemory(&_d3dpp, sizeof(_d3dpp));
184 ZeroMemory(&_backbuffer_desc, sizeof(_backbuffer_desc));
185 //_render_target = NULL;
186 _render_target_data = NULL;
187 _render_data_updated = false;
188 _render_data.Resize();
189 //_original_render_target = NULL;
190 //_render_to_texture = false;
191}
192
193HRESULT D3DDevice::RestoreDevice()
194{
195 Log("restore");
196 assert(_device != NULL);
197
198 HRESULT hr = S_OK;
199
200 // Test the cooperative level to see if it's okay to render
201 if (SUCCEEDED(hr = _device->TestCooperativeLevel()))
202 {
203 _device_lost = FALSE;
204 DBG("render test ok");
205 return S_OK;
206 }
207
208 // If the device was lost, do not render until we get it back
209 if (hr == D3DERR_DEVICELOST)
210 return E_FAIL;
211
212 // Check if the device needs to be reset.
213 if (hr == D3DERR_DEVICENOTRESET)
214 {
215 if (FAILED(hr = ResetDevice()))
216 return hr;
217 }
218 return hr;
219}
220
221HRESULT D3DDevice::ResetDevice()
222{
223 DBG("reset");
224 HRESULT hr = S_OK;
225
226 _scene_rendering = FALSE;
227
228 // Release all video memory objects
229 // Bad to call such, make better
230 D3DVertexBufferCache::Current()->Uninitialize();
231
232 //if (_render_target != NULL)
233 //{
234 // _render_target->Release();
235 // _render_target = NULL;
236 //}
237 if (_render_target_data != NULL)
238 {
239 _render_target_data->Release();
240 _render_target_data = NULL;
241 }
242
243 // Reset the device
244 if (FAILED(hr = _device->Reset(&_d3dpp)))
245 {
246 ERR("D3DDevice: Reset of the device failed! Error (%X)", (DWORD)hr);
247 return hr;
248 }
249
250 // Store render target surface desc
251 LPDIRECT3DSURFACE9 backbuffer = NULL;
252 _device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
253 if (backbuffer != NULL)
254 {
255 backbuffer->GetDesc(&_backbuffer_desc);
256 backbuffer->Release();
257 }
258
259 // Initialize the app's device-dependent objects
260 hr = CreateRenderTarget();
261
262 if (FAILED(hr))
263 {
264 WRN("Restoration of device objects failed");
265 // Invalidate objects
266
267 return E_FAIL;
268 }
269
270 DBG("Device objects were successfuly restored");
271 _textures.Set(NULL);
272
273 //_device_objects_restored = true;
274 return S_OK;
275}
276
277bool D3DDevice::Begin()
278{
279 if (FAILED(RestoreDevice()))
280 return false;
281
282 //if (_render_to_texture && _render_target != NULL)
283 //{
284 // if (FAILED(_device->GetRenderTarget(0, &_original_render_target)))
285 // return false;
286 // if (FAILED(_device->SetRenderTarget(0, _render_target)))
287 // return false;
288 //}
289
290 HRESULT hr;
291 if (FAILED(hr = _device->BeginScene()))
292 {
293 WRN("Cannot begin scene: %X", (DWORD)hr);
294 return false;
295 }
296
297 //static const D3DVIEWPORT9 vp = {0, 0, _width, _height, 0.f, 1.f};
298 //_device->SetViewport(&vp);
299 //_device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
300
301 //_device->Clear(0, NULL, D3DCLEAR_TARGET /*| D3DCLEAR_ZBUFFER*/, 0xff8080ff, 1.f, 0);
302 return true;
303}
304
305bool D3DDevice::End()
306{
307 _device->EndScene();
308 _device->Present(NULL, NULL, NULL, NULL);
309
310 _render_data_updated = false;
311
312 //if (_render_to_texture && _render_target != NULL && _original_render_target != NULL)
313 //{
314 // if (FAILED(_device->SetRenderTarget(0, _original_render_target)))
315 // return false;
316 //}
317
318 return true;
319}
320
321TArray<DWORD> &D3DDevice::GetRenderData()
322{
323 if (_render_data_updated)
324 return _render_data;
325 _render_data.Allocate(0);
326 if (_render_target_data == NULL)
327 return _render_data;
328
329 LPDIRECT3DSURFACE9 surf = NULL;
330 HRESULT hr;
331 if (FAILED(_device->GetRenderTarget(0, &surf)))
332 return _render_data;
333 if (FAILED(hr = _device->GetRenderTargetData(surf, _render_target_data)))
334 {
335 WRN("Failed to get render target data (%X)", (DWORD)hr);
336 surf->Release();
337 return _render_data;
338 }
339 D3DLOCKED_RECT lr;
340 if (FAILED(_render_target_data->LockRect(&lr, NULL, D3DLOCK_READONLY)))
341 {
342 surf->Release();
343 return _render_data;
344 }
345 _render_data.Allocate(_width * _height);
346
347 for (int i = 0; i < _height; i++)
348 {
349 CopyMemory(&_render_data[i * _width], (BYTE *)lr.pBits + i * lr.Pitch,
350 _width * sizeof(DWORD));
351 }
352
353 _render_target_data->UnlockRect();
354 _render_data_updated = true;
355 surf->Release();
356 return _render_data;
357}
358
359HRESULT D3DDevice::SetTexture(DWORD stage, LPDIRECT3DTEXTURE9 tex)
360{
361 if (stage >= 8)
362 return E_FAIL;
363 if (_textures.Length() <= (int)stage)
364 _textures.Allocate(stage + 1);
365 if (_textures[stage] != tex)
366 {
367 _textures[stage] = tex;
368 return _device->SetTexture(stage, tex);
369 }
370 return S_OK;
371}
372
373HRESULT D3DDevice::CreateRenderTarget()
374{
375 if (_device == NULL)
376 return E_FAIL;
377 //if (_render_target != NULL &&
378 if (_render_target_data != NULL)
379 return S_OK;
380
381 //if (FAILED(_device->CreateRenderTarget(_width, _height, _backbuffer_desc.Format,
382 // D3DMULTISAMPLE_NONE, 0, FALSE, &_render_target, NULL)))
383 //{
384 // return E_FAIL;
385 //}
386 if (FAILED(_device->CreateOffscreenPlainSurface(_backbuffer_desc.Width,
387 _backbuffer_desc.Height, _backbuffer_desc.Format, D3DPOOL_SYSTEMMEM,
388 &_render_target_data, NULL)))
389 {
390 return E_FAIL;
391 }
392 return S_OK;
393}