blob: 60e12cfad9f4b5af7e77e2aeec14398cf6885ca9 [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.comb9bb2792012-11-28 19:36:49 +000034 mDeviceLost = false;
35
daniel@transgaming.com25072f62012-11-28 19:31:32 +000036 mDevice = NULL;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000037 mDeviceContext = NULL;
daniel@transgaming.com65e65372012-11-28 19:33:50 +000038 mDxgiAdapter = NULL;
39 mDxgiFactory = NULL;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000040}
41
42Renderer11::~Renderer11()
43{
44 releaseDeviceResources();
45
daniel@transgaming.com65e65372012-11-28 19:33:50 +000046 if (mDxgiFactory)
47 {
48 mDxgiFactory->Release();
49 mDxgiFactory = NULL;
50 }
51
52 if (mDxgiAdapter)
53 {
54 mDxgiAdapter->Release();
55 mDxgiAdapter = NULL;
56 }
57
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000058 if (mDeviceContext)
59 {
60 mDeviceContext->Release();
61 mDeviceContext = NULL;
62 }
63
daniel@transgaming.com25072f62012-11-28 19:31:32 +000064 if (mDevice)
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000065 {
daniel@transgaming.com25072f62012-11-28 19:31:32 +000066 mDevice->Release();
67 mDevice = NULL;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000068 }
69
70 if (mD3d11Module)
71 {
daniel@transgaming.comc1e26342012-11-28 19:31:16 +000072 FreeLibrary(mD3d11Module);
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000073 mD3d11Module = NULL;
74 }
75
76 if (mDxgiModule)
77 {
daniel@transgaming.comc1e26342012-11-28 19:31:16 +000078 FreeLibrary(mDxgiModule);
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000079 mDxgiModule = NULL;
80 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000081}
82
83EGLint Renderer11::initialize()
84{
daniel@transgaming.comc1e26342012-11-28 19:31:16 +000085 mDxgiModule = LoadLibrary(TEXT("dxgi.dll"));
86 mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000087
88 if (mD3d11Module == NULL || mDxgiModule == NULL)
89 {
daniel@transgaming.comc1e26342012-11-28 19:31:16 +000090 ERR("Could not load D3D11 or DXGI library - aborting!\n");
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000091 return EGL_NOT_INITIALIZED;
92 }
93
daniel@transgaming.comc1e26342012-11-28 19:31:16 +000094 PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice");
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000095
daniel@transgaming.comc1e26342012-11-28 19:31:16 +000096 if (D3D11CreateDevice == NULL)
97 {
98 ERR("Could not retrieve D3D11CreateDevice address - aborting!\n");
99 return EGL_NOT_INITIALIZED;
100 }
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000101
102 D3D_FEATURE_LEVEL featureLevel[] =
103 {
104 D3D_FEATURE_LEVEL_11_0,
105 D3D_FEATURE_LEVEL_10_1,
106 D3D_FEATURE_LEVEL_10_0,
107 };
108
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000109 HRESULT result = D3D11CreateDevice(NULL,
110 D3D_DRIVER_TYPE_HARDWARE,
111 NULL,
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000112 0, // D3D11_CREATE_DEVICE_DEBUG
113 featureLevel,
114 sizeof(featureLevel)/sizeof(featureLevel[0]),
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000115 D3D11_SDK_VERSION,
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000116 &mDevice,
117 &mFeatureLevel,
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000118 &mDeviceContext);
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000119
120 if (!mDevice || FAILED(result))
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000121 {
122 ERR("Could not create D3D11 device - aborting!\n");
123 return EGL_NOT_INITIALIZED; // Cleanup done by destructor through glDestroyRenderer
124 }
daniel@transgaming.com65e65372012-11-28 19:33:50 +0000125
126 IDXGIDevice *dxgiDevice = NULL;
127 result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
128
129 if (FAILED(result))
130 {
131 ERR("Could not query DXGI device - aborting!\n");
132 return EGL_NOT_INITIALIZED;
133 }
134
135 result = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&mDxgiAdapter);
136
137 if (FAILED(result))
138 {
139 ERR("Could not retrieve DXGI adapter - aborting!\n");
140 return EGL_NOT_INITIALIZED;
141 }
142
143 dxgiDevice->Release();
144
145 result = mDxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&mDxgiFactory);
146
147 if (!mDxgiFactory || FAILED(result))
148 {
149 ERR("Could not create DXGI factory - aborting!\n");
150 return EGL_NOT_INITIALIZED;
151 }
152
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000153 initializeDevice();
154
155 return EGL_SUCCESS;
156}
157
158// do any one-time device initialization
159// NOTE: this is also needed after a device lost/reset
160// to reset the scene status and ensure the default states are reset.
161void Renderer11::initializeDevice()
162{
163 // Permanent non-default states
164 // TODO
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000165 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000166}
167
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000168int Renderer11::generateConfigs(ConfigDesc **configDescList)
169{
daniel@transgaming.com65e65372012-11-28 19:33:50 +0000170 int numRenderFormats = sizeof(RenderTargetFormats) / sizeof(RenderTargetFormats[0]);
171 int numDepthFormats = sizeof(DepthStencilFormats) / sizeof(DepthStencilFormats[0]);
172 (*configDescList) = new ConfigDesc[numRenderFormats * numDepthFormats];
173 int numConfigs = 0;
174
175 for (int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++)
176 {
177 for (int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++)
178 {
179 DXGI_FORMAT renderTargetFormat = RenderTargetFormats[formatIndex];
180
181 UINT formatSupport = 0;
182 HRESULT result = mDevice->CheckFormatSupport(renderTargetFormat, &formatSupport);
183
184 if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET))
185 {
186 DXGI_FORMAT depthStencilFormat = DepthStencilFormats[depthStencilIndex];
187
188 UINT formatSupport = 0;
189 HRESULT result = mDevice->CheckFormatSupport(depthStencilFormat, &formatSupport);
190
191 if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL))
192 {
193 ConfigDesc newConfig;
194 newConfig.renderTargetFormat = d3d11_gl::ConvertBackBufferFormat(renderTargetFormat);
195 newConfig.depthStencilFormat = d3d11_gl::ConvertDepthStencilFormat(depthStencilFormat);
196 newConfig.multiSample = 0; // FIXME: enumerate multi-sampling
197 newConfig.fastConfig = true; // Assume all DX11 format conversions to be fast
198
199 (*configDescList)[numConfigs++] = newConfig;
200 }
201 }
202 }
203 }
204
205 return numConfigs;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000206}
207
208void Renderer11::deleteConfigs(ConfigDesc *configDescList)
209{
210 delete [] (configDescList);
211}
212
213void Renderer11::startScene()
214{
215 // TODO: nop in d3d11?
216}
217
218void Renderer11::endScene()
219{
220 // TODO: nop in d3d11?
221}
222
223void Renderer11::sync(bool block)
224{
225 // TODO
226 UNIMPLEMENTED();
227}
228
daniel@transgaming.comb9bb2792012-11-28 19:36:49 +0000229SwapChain *Renderer11::createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
230{
231 // TODO
232 UNIMPLEMENTED();
233
234 //return new rx::SwapChain(this, window, shareHandle, backBufferFormat, depthBufferFormat);
235
236 return NULL;
237}
238
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000239void Renderer11::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState)
240{
241 // TODO
242 UNIMPLEMENTED();
243}
244
245void Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *texture)
246{
247 // TODO
248 UNIMPLEMENTED();
249}
250
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000251void Renderer11::setRasterizerState(const gl::RasterizerState &rasterState, unsigned int depthSize)
252{
253 // TODO
254 UNIMPLEMENTED();
255}
256
257void Renderer11::setBlendState(const gl::BlendState &blendState, const gl::Color &blendColor,
258 unsigned int sampleMask)
259{
260 // TODO
261 UNIMPLEMENTED();
262}
263
264void Renderer11::setDepthStencilState(const gl::DepthStencilState &depthStencilState, bool frontFaceCCW,
265 unsigned int stencilSize)
266{
267 // TODO
268 UNIMPLEMENTED();
269}
270
271void Renderer11::setScissorRectangle(const gl::Rectangle& scissor, unsigned int renderTargetWidth,
272 unsigned int renderTargetHeight)
273{
274 // TODO
275 UNIMPLEMENTED();
276}
277
278void Renderer11::applyRenderTarget(gl::Framebuffer *frameBuffer)
279{
280 // TODO
281 UNIMPLEMENTED();
282}
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000283
daniel@transgaming.comd084c622012-11-28 19:36:05 +0000284void Renderer11::clear(GLbitfield mask, const gl::Color &colorClear, float depthClear, int stencilClear,
285 gl::Framebuffer *frameBuffer)
286{
287 // TODO
288 UNIMPLEMENTED();
289}
290
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000291void Renderer11::releaseDeviceResources()
292{
293 // TODO
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000294 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000295}
296
297void Renderer11::markDeviceLost()
298{
299 mDeviceLost = true;
300}
301
302bool Renderer11::isDeviceLost()
303{
304 return mDeviceLost;
305}
306
307// set notify to true to broadcast a message to all contexts of the device loss
308bool Renderer11::testDeviceLost(bool notify)
309{
310 bool isLost = false;
311
312 // TODO
daniel@transgaming.comb9bb2792012-11-28 19:36:49 +0000313 //UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000314
315 if (isLost)
316 {
317 // ensure we note the device loss --
318 // we'll probably get this done again by markDeviceLost
319 // but best to remember it!
320 // Note that we don't want to clear the device loss status here
321 // -- this needs to be done by resetDevice
322 mDeviceLost = true;
323 if (notify)
324 {
325 mDisplay->notifyDeviceLost();
326 }
327 }
328
329 return isLost;
330}
331
332bool Renderer11::testDeviceResettable()
333{
334 HRESULT status = D3D_OK;
335
336 // TODO
337 UNIMPLEMENTED();
338
339 switch (status)
340 {
341 case D3DERR_DEVICENOTRESET:
342 case D3DERR_DEVICEHUNG:
343 return true;
344 default:
345 return false;
346 }
347}
348
349bool Renderer11::resetDevice()
350{
351 releaseDeviceResources();
352
353 // TODO
354 UNIMPLEMENTED();
355
356 // reset device defaults
357 initializeDevice();
358 mDeviceLost = false;
359
360 return true;
361}
362
363DWORD Renderer11::getAdapterVendor() const
364{
365 // TODO
366 UNIMPLEMENTED();
367 return 0;
368}
369
370const char *Renderer11::getAdapterDescription() const
371{
372 // TODO
373 UNIMPLEMENTED();
374 return "UNIMPLEMENTED";
375}
376
377GUID Renderer11::getAdapterIdentifier() const
378{
379 // TODO
380 UNIMPLEMENTED();
381 GUID foo = {};
382 return foo;
383}
384
385bool Renderer11::getDXT1TextureSupport()
386{
387 // TODO
388 UNIMPLEMENTED();
389 return false;
390}
391
392bool Renderer11::getDXT3TextureSupport()
393{
394 // TODO
395 UNIMPLEMENTED();
396 return false;
397}
398
399bool Renderer11::getDXT5TextureSupport()
400{
401 // TODO
402 UNIMPLEMENTED();
403 return false;
404}
405
406bool Renderer11::getDepthTextureSupport() const
407{
408 // TODO
409 UNIMPLEMENTED();
410 return false;
411}
412
413bool Renderer11::getFloat32TextureSupport(bool *filtering, bool *renderable)
414{
415 // TODO
416 UNIMPLEMENTED();
417
418 *filtering = false;
419 *renderable = false;
420 return false;
421}
422
423bool Renderer11::getFloat16TextureSupport(bool *filtering, bool *renderable)
424{
425 // TODO
426 UNIMPLEMENTED();
427
428 *filtering = false;
429 *renderable = false;
430 return false;
431}
432
433bool Renderer11::getLuminanceTextureSupport()
434{
435 // TODO
436 UNIMPLEMENTED();
437 return false;
438}
439
440bool Renderer11::getLuminanceAlphaTextureSupport()
441{
442 // TODO
443 UNIMPLEMENTED();
444 return false;
445}
446
447bool Renderer11::getTextureFilterAnisotropySupport() const
448{
449 // TODO
450 UNIMPLEMENTED();
451 return false;
452}
453
454float Renderer11::getTextureMaxAnisotropy() const
455{
456 // TODO
457 UNIMPLEMENTED();
458 return 1.0f;
459}
460
461bool Renderer11::getEventQuerySupport()
462{
463 // TODO
464 UNIMPLEMENTED();
465 return false;
466}
467
468bool Renderer11::getVertexTextureSupport() const
469{
470 // TODO
471 UNIMPLEMENTED();
472 return false;
473}
474
475bool Renderer11::getNonPower2TextureSupport() const
476{
477 // TODO
478 UNIMPLEMENTED();
479 return false;
480}
481
482bool Renderer11::getOcclusionQuerySupport() const
483{
484 // TODO
485 UNIMPLEMENTED();
486 return false;
487}
488
489bool Renderer11::getInstancingSupport() const
490{
491 // TODO
492 UNIMPLEMENTED();
493 return false;
494}
495
496bool Renderer11::getShareHandleSupport() const
497{
498 // TODO
daniel@transgaming.comb9bb2792012-11-28 19:36:49 +0000499 //UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000500
501 // PIX doesn't seem to support using share handles, so disable them.
502 return false && !gl::perfActive();
503}
504
505bool Renderer11::getShaderModel3Support() const
506{
507 // TODO
508 UNIMPLEMENTED();
509 return true;
510}
511
512float Renderer11::getMaxPointSize() const
513{
514 // TODO
515 UNIMPLEMENTED();
516 return 1.0f;
517}
518
519int Renderer11::getMaxTextureWidth() const
520{
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000521 switch (mFeatureLevel)
522 {
523 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
524 case D3D_FEATURE_LEVEL_10_1:
525 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
526 default: UNREACHABLE(); return 0;
527 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000528}
529
530int Renderer11::getMaxTextureHeight() const
531{
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000532 switch (mFeatureLevel)
533 {
534 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
535 case D3D_FEATURE_LEVEL_10_1:
536 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
537 default: UNREACHABLE(); return 0;
538 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000539}
540
541bool Renderer11::get32BitIndexSupport() const
542{
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000543 switch (mFeatureLevel)
544 {
545 case D3D_FEATURE_LEVEL_11_0:
546 case D3D_FEATURE_LEVEL_10_1:
547 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP >= 32; // true
548 default: UNREACHABLE(); return false;
549 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000550}
551
552int Renderer11::getMinSwapInterval() const
553{
daniel@transgaming.com8c7b1a92012-11-28 19:34:06 +0000554 return 0;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000555}
556
557int Renderer11::getMaxSwapInterval() const
558{
daniel@transgaming.com8c7b1a92012-11-28 19:34:06 +0000559 return 4;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000560}
561
562int Renderer11::getMaxSupportedSamples() const
563{
564 // TODO
565 UNIMPLEMENTED();
566 return 1;
567}
568
daniel@transgaming.com31b13e12012-11-28 19:34:30 +0000569bool Renderer11::copyToRenderTarget(TextureStorage2D *dest, TextureStorage2D *source)
daniel@transgaming.comad6aee72012-11-28 19:33:42 +0000570{
571 // TODO
572 UNIMPLEMENTED();
573 return false;
574}
575
daniel@transgaming.com31b13e12012-11-28 19:34:30 +0000576bool Renderer11::copyToRenderTarget(TextureStorageCubeMap *dest, TextureStorageCubeMap *source)
daniel@transgaming.comad6aee72012-11-28 19:33:42 +0000577{
578 // TODO
579 UNIMPLEMENTED();
580 return false;
581}
582
daniel@transgaming.com38380882012-11-28 19:36:39 +0000583bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat,
584 GLint xoffset, GLint yoffset, TextureStorage2D *storage, GLint level)
585{
586 // TODO
587 UNIMPLEMENTED();
588 return false;
589}
590
591bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat,
592 GLint xoffset, GLint yoffset, TextureStorageCubeMap *storage, GLenum target, GLint level)
593{
594 // TODO
595 UNIMPLEMENTED();
596 return false;
597}
598
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000599}