blob: 02a153571e5e458f3b52489f829cc7b5fc5ef373 [file] [log] [blame]
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001//
2// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Renderer11.cpp: Implements a back-end specific class for the D3D11 renderer.
8
9#include "common/debug.h"
10#include "libGLESv2/utilities.h"
11#include "libGLESv2/renderer/Renderer11.h"
daniel@transgaming.com65e65372012-11-28 19:33:50 +000012#include "libGLESv2/renderer/renderer11_utils.h"
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000013
14#include "libEGL/Config.h"
15#include "libEGL/Display.h"
16
17namespace rx
18{
daniel@transgaming.com65e65372012-11-28 19:33:50 +000019static const DXGI_FORMAT RenderTargetFormats[] =
20 {
21 DXGI_FORMAT_R8G8B8A8_UNORM
22 };
23
24static const DXGI_FORMAT DepthStencilFormats[] =
25 {
26 DXGI_FORMAT_D24_UNORM_S8_UINT
27 };
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000028
29Renderer11::Renderer11(egl::Display *display, HDC hDc) : Renderer(display), mDc(hDc)
30{
31 mD3d11Module = NULL;
32 mDxgiModule = NULL;
33
daniel@transgaming.com25072f62012-11-28 19:31:32 +000034 mDevice = NULL;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000035 mDeviceContext = NULL;
daniel@transgaming.com65e65372012-11-28 19:33:50 +000036 mDxgiAdapter = NULL;
37 mDxgiFactory = NULL;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000038}
39
40Renderer11::~Renderer11()
41{
42 releaseDeviceResources();
43
daniel@transgaming.com65e65372012-11-28 19:33:50 +000044 if (mDxgiFactory)
45 {
46 mDxgiFactory->Release();
47 mDxgiFactory = NULL;
48 }
49
50 if (mDxgiAdapter)
51 {
52 mDxgiAdapter->Release();
53 mDxgiAdapter = NULL;
54 }
55
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000056 if (mDeviceContext)
57 {
58 mDeviceContext->Release();
59 mDeviceContext = NULL;
60 }
61
daniel@transgaming.com25072f62012-11-28 19:31:32 +000062 if (mDevice)
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000063 {
daniel@transgaming.com25072f62012-11-28 19:31:32 +000064 mDevice->Release();
65 mDevice = NULL;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000066 }
67
68 if (mD3d11Module)
69 {
daniel@transgaming.comc1e26342012-11-28 19:31:16 +000070 FreeLibrary(mD3d11Module);
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000071 mD3d11Module = NULL;
72 }
73
74 if (mDxgiModule)
75 {
daniel@transgaming.comc1e26342012-11-28 19:31:16 +000076 FreeLibrary(mDxgiModule);
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000077 mDxgiModule = NULL;
78 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000079}
80
81EGLint Renderer11::initialize()
82{
daniel@transgaming.comc1e26342012-11-28 19:31:16 +000083 mDxgiModule = LoadLibrary(TEXT("dxgi.dll"));
84 mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000085
86 if (mD3d11Module == NULL || mDxgiModule == NULL)
87 {
daniel@transgaming.comc1e26342012-11-28 19:31:16 +000088 ERR("Could not load D3D11 or DXGI library - aborting!\n");
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000089 return EGL_NOT_INITIALIZED;
90 }
91
daniel@transgaming.comc1e26342012-11-28 19:31:16 +000092 PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice");
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000093
daniel@transgaming.comc1e26342012-11-28 19:31:16 +000094 if (D3D11CreateDevice == NULL)
95 {
96 ERR("Could not retrieve D3D11CreateDevice address - aborting!\n");
97 return EGL_NOT_INITIALIZED;
98 }
daniel@transgaming.com25072f62012-11-28 19:31:32 +000099
100 D3D_FEATURE_LEVEL featureLevel[] =
101 {
102 D3D_FEATURE_LEVEL_11_0,
103 D3D_FEATURE_LEVEL_10_1,
104 D3D_FEATURE_LEVEL_10_0,
105 };
106
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000107 HRESULT result = D3D11CreateDevice(NULL,
108 D3D_DRIVER_TYPE_HARDWARE,
109 NULL,
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000110 0, // D3D11_CREATE_DEVICE_DEBUG
111 featureLevel,
112 sizeof(featureLevel)/sizeof(featureLevel[0]),
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000113 D3D11_SDK_VERSION,
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000114 &mDevice,
115 &mFeatureLevel,
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000116 &mDeviceContext);
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000117
118 if (!mDevice || FAILED(result))
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000119 {
120 ERR("Could not create D3D11 device - aborting!\n");
121 return EGL_NOT_INITIALIZED; // Cleanup done by destructor through glDestroyRenderer
122 }
daniel@transgaming.com65e65372012-11-28 19:33:50 +0000123
124 IDXGIDevice *dxgiDevice = NULL;
125 result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
126
127 if (FAILED(result))
128 {
129 ERR("Could not query DXGI device - aborting!\n");
130 return EGL_NOT_INITIALIZED;
131 }
132
133 result = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&mDxgiAdapter);
134
135 if (FAILED(result))
136 {
137 ERR("Could not retrieve DXGI adapter - aborting!\n");
138 return EGL_NOT_INITIALIZED;
139 }
140
141 dxgiDevice->Release();
142
143 result = mDxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&mDxgiFactory);
144
145 if (!mDxgiFactory || FAILED(result))
146 {
147 ERR("Could not create DXGI factory - aborting!\n");
148 return EGL_NOT_INITIALIZED;
149 }
150
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000151 initializeDevice();
152
153 return EGL_SUCCESS;
154}
155
156// do any one-time device initialization
157// NOTE: this is also needed after a device lost/reset
158// to reset the scene status and ensure the default states are reset.
159void Renderer11::initializeDevice()
160{
161 // Permanent non-default states
162 // TODO
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000163 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000164}
165
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000166int Renderer11::generateConfigs(ConfigDesc **configDescList)
167{
daniel@transgaming.com65e65372012-11-28 19:33:50 +0000168 int numRenderFormats = sizeof(RenderTargetFormats) / sizeof(RenderTargetFormats[0]);
169 int numDepthFormats = sizeof(DepthStencilFormats) / sizeof(DepthStencilFormats[0]);
170 (*configDescList) = new ConfigDesc[numRenderFormats * numDepthFormats];
171 int numConfigs = 0;
172
173 for (int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++)
174 {
175 for (int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++)
176 {
177 DXGI_FORMAT renderTargetFormat = RenderTargetFormats[formatIndex];
178
179 UINT formatSupport = 0;
180 HRESULT result = mDevice->CheckFormatSupport(renderTargetFormat, &formatSupport);
181
182 if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET))
183 {
184 DXGI_FORMAT depthStencilFormat = DepthStencilFormats[depthStencilIndex];
185
186 UINT formatSupport = 0;
187 HRESULT result = mDevice->CheckFormatSupport(depthStencilFormat, &formatSupport);
188
189 if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL))
190 {
191 ConfigDesc newConfig;
192 newConfig.renderTargetFormat = d3d11_gl::ConvertBackBufferFormat(renderTargetFormat);
193 newConfig.depthStencilFormat = d3d11_gl::ConvertDepthStencilFormat(depthStencilFormat);
194 newConfig.multiSample = 0; // FIXME: enumerate multi-sampling
195 newConfig.fastConfig = true; // Assume all DX11 format conversions to be fast
196
197 (*configDescList)[numConfigs++] = newConfig;
198 }
199 }
200 }
201 }
202
203 return numConfigs;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000204}
205
206void Renderer11::deleteConfigs(ConfigDesc *configDescList)
207{
208 delete [] (configDescList);
209}
210
211void Renderer11::startScene()
212{
213 // TODO: nop in d3d11?
214}
215
216void Renderer11::endScene()
217{
218 // TODO: nop in d3d11?
219}
220
221void Renderer11::sync(bool block)
222{
223 // TODO
224 UNIMPLEMENTED();
225}
226
227void Renderer11::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState)
228{
229 // TODO
230 UNIMPLEMENTED();
231}
232
233void Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *texture)
234{
235 // TODO
236 UNIMPLEMENTED();
237}
238
239
240void Renderer11::releaseDeviceResources()
241{
242 // TODO
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000243 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000244}
245
246void Renderer11::markDeviceLost()
247{
248 mDeviceLost = true;
249}
250
251bool Renderer11::isDeviceLost()
252{
253 return mDeviceLost;
254}
255
256// set notify to true to broadcast a message to all contexts of the device loss
257bool Renderer11::testDeviceLost(bool notify)
258{
259 bool isLost = false;
260
261 // TODO
262 UNIMPLEMENTED();
263
264 if (isLost)
265 {
266 // ensure we note the device loss --
267 // we'll probably get this done again by markDeviceLost
268 // but best to remember it!
269 // Note that we don't want to clear the device loss status here
270 // -- this needs to be done by resetDevice
271 mDeviceLost = true;
272 if (notify)
273 {
274 mDisplay->notifyDeviceLost();
275 }
276 }
277
278 return isLost;
279}
280
281bool Renderer11::testDeviceResettable()
282{
283 HRESULT status = D3D_OK;
284
285 // TODO
286 UNIMPLEMENTED();
287
288 switch (status)
289 {
290 case D3DERR_DEVICENOTRESET:
291 case D3DERR_DEVICEHUNG:
292 return true;
293 default:
294 return false;
295 }
296}
297
298bool Renderer11::resetDevice()
299{
300 releaseDeviceResources();
301
302 // TODO
303 UNIMPLEMENTED();
304
305 // reset device defaults
306 initializeDevice();
307 mDeviceLost = false;
308
309 return true;
310}
311
312DWORD Renderer11::getAdapterVendor() const
313{
314 // TODO
315 UNIMPLEMENTED();
316 return 0;
317}
318
319const char *Renderer11::getAdapterDescription() const
320{
321 // TODO
322 UNIMPLEMENTED();
323 return "UNIMPLEMENTED";
324}
325
326GUID Renderer11::getAdapterIdentifier() const
327{
328 // TODO
329 UNIMPLEMENTED();
330 GUID foo = {};
331 return foo;
332}
333
334bool Renderer11::getDXT1TextureSupport()
335{
336 // TODO
337 UNIMPLEMENTED();
338 return false;
339}
340
341bool Renderer11::getDXT3TextureSupport()
342{
343 // TODO
344 UNIMPLEMENTED();
345 return false;
346}
347
348bool Renderer11::getDXT5TextureSupport()
349{
350 // TODO
351 UNIMPLEMENTED();
352 return false;
353}
354
355bool Renderer11::getDepthTextureSupport() const
356{
357 // TODO
358 UNIMPLEMENTED();
359 return false;
360}
361
362bool Renderer11::getFloat32TextureSupport(bool *filtering, bool *renderable)
363{
364 // TODO
365 UNIMPLEMENTED();
366
367 *filtering = false;
368 *renderable = false;
369 return false;
370}
371
372bool Renderer11::getFloat16TextureSupport(bool *filtering, bool *renderable)
373{
374 // TODO
375 UNIMPLEMENTED();
376
377 *filtering = false;
378 *renderable = false;
379 return false;
380}
381
382bool Renderer11::getLuminanceTextureSupport()
383{
384 // TODO
385 UNIMPLEMENTED();
386 return false;
387}
388
389bool Renderer11::getLuminanceAlphaTextureSupport()
390{
391 // TODO
392 UNIMPLEMENTED();
393 return false;
394}
395
396bool Renderer11::getTextureFilterAnisotropySupport() const
397{
398 // TODO
399 UNIMPLEMENTED();
400 return false;
401}
402
403float Renderer11::getTextureMaxAnisotropy() const
404{
405 // TODO
406 UNIMPLEMENTED();
407 return 1.0f;
408}
409
410bool Renderer11::getEventQuerySupport()
411{
412 // TODO
413 UNIMPLEMENTED();
414 return false;
415}
416
417bool Renderer11::getVertexTextureSupport() const
418{
419 // TODO
420 UNIMPLEMENTED();
421 return false;
422}
423
424bool Renderer11::getNonPower2TextureSupport() const
425{
426 // TODO
427 UNIMPLEMENTED();
428 return false;
429}
430
431bool Renderer11::getOcclusionQuerySupport() const
432{
433 // TODO
434 UNIMPLEMENTED();
435 return false;
436}
437
438bool Renderer11::getInstancingSupport() const
439{
440 // TODO
441 UNIMPLEMENTED();
442 return false;
443}
444
445bool Renderer11::getShareHandleSupport() const
446{
447 // TODO
448 UNIMPLEMENTED();
449
450 // PIX doesn't seem to support using share handles, so disable them.
451 return false && !gl::perfActive();
452}
453
454bool Renderer11::getShaderModel3Support() const
455{
456 // TODO
457 UNIMPLEMENTED();
458 return true;
459}
460
461float Renderer11::getMaxPointSize() const
462{
463 // TODO
464 UNIMPLEMENTED();
465 return 1.0f;
466}
467
468int Renderer11::getMaxTextureWidth() const
469{
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000470 switch (mFeatureLevel)
471 {
472 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
473 case D3D_FEATURE_LEVEL_10_1:
474 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
475 default: UNREACHABLE(); return 0;
476 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000477}
478
479int Renderer11::getMaxTextureHeight() const
480{
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000481 switch (mFeatureLevel)
482 {
483 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
484 case D3D_FEATURE_LEVEL_10_1:
485 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
486 default: UNREACHABLE(); return 0;
487 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000488}
489
490bool Renderer11::get32BitIndexSupport() const
491{
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000492 switch (mFeatureLevel)
493 {
494 case D3D_FEATURE_LEVEL_11_0:
495 case D3D_FEATURE_LEVEL_10_1:
496 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP >= 32; // true
497 default: UNREACHABLE(); return false;
498 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000499}
500
501int Renderer11::getMinSwapInterval() const
502{
503 // TODO
504 UNIMPLEMENTED();
505 return 1;
506}
507
508int Renderer11::getMaxSwapInterval() const
509{
510 // TODO
511 UNIMPLEMENTED();
512 return 1;
513}
514
515int Renderer11::getMaxSupportedSamples() const
516{
517 // TODO
518 UNIMPLEMENTED();
519 return 1;
520}
521
daniel@transgaming.comad6aee72012-11-28 19:33:42 +0000522bool Renderer11::copyToRenderTarget(gl::TextureStorage2D *dest, gl::TextureStorage2D *source)
523{
524 // TODO
525 UNIMPLEMENTED();
526 return false;
527}
528
529bool Renderer11::copyToRenderTarget(gl::TextureStorageCubeMap *dest, gl::TextureStorageCubeMap *source)
530{
531 // TODO
532 UNIMPLEMENTED();
533 return false;
534}
535
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000536}