blob: f41df6b34f0eef2b3e3c1e603394fd895415177a [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.comf8ba1092012-11-28 19:37:53 +000040
41 mForceSetBlendState = true;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000042}
43
44Renderer11::~Renderer11()
45{
46 releaseDeviceResources();
47
daniel@transgaming.com65e65372012-11-28 19:33:50 +000048 if (mDxgiFactory)
49 {
50 mDxgiFactory->Release();
51 mDxgiFactory = NULL;
52 }
53
54 if (mDxgiAdapter)
55 {
56 mDxgiAdapter->Release();
57 mDxgiAdapter = NULL;
58 }
59
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000060 if (mDeviceContext)
61 {
62 mDeviceContext->Release();
63 mDeviceContext = NULL;
64 }
65
daniel@transgaming.com25072f62012-11-28 19:31:32 +000066 if (mDevice)
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000067 {
daniel@transgaming.com25072f62012-11-28 19:31:32 +000068 mDevice->Release();
69 mDevice = NULL;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000070 }
71
72 if (mD3d11Module)
73 {
daniel@transgaming.comc1e26342012-11-28 19:31:16 +000074 FreeLibrary(mD3d11Module);
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000075 mD3d11Module = NULL;
76 }
77
78 if (mDxgiModule)
79 {
daniel@transgaming.comc1e26342012-11-28 19:31:16 +000080 FreeLibrary(mDxgiModule);
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000081 mDxgiModule = NULL;
82 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000083}
84
85EGLint Renderer11::initialize()
86{
daniel@transgaming.comc1e26342012-11-28 19:31:16 +000087 mDxgiModule = LoadLibrary(TEXT("dxgi.dll"));
88 mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000089
90 if (mD3d11Module == NULL || mDxgiModule == NULL)
91 {
daniel@transgaming.comc1e26342012-11-28 19:31:16 +000092 ERR("Could not load D3D11 or DXGI library - aborting!\n");
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000093 return EGL_NOT_INITIALIZED;
94 }
95
daniel@transgaming.comc1e26342012-11-28 19:31:16 +000096 PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice");
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000097
daniel@transgaming.comc1e26342012-11-28 19:31:16 +000098 if (D3D11CreateDevice == NULL)
99 {
100 ERR("Could not retrieve D3D11CreateDevice address - aborting!\n");
101 return EGL_NOT_INITIALIZED;
102 }
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000103
104 D3D_FEATURE_LEVEL featureLevel[] =
105 {
106 D3D_FEATURE_LEVEL_11_0,
107 D3D_FEATURE_LEVEL_10_1,
108 D3D_FEATURE_LEVEL_10_0,
109 };
110
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000111 HRESULT result = D3D11CreateDevice(NULL,
112 D3D_DRIVER_TYPE_HARDWARE,
113 NULL,
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000114 0, // D3D11_CREATE_DEVICE_DEBUG
115 featureLevel,
116 sizeof(featureLevel)/sizeof(featureLevel[0]),
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000117 D3D11_SDK_VERSION,
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000118 &mDevice,
119 &mFeatureLevel,
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000120 &mDeviceContext);
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000121
122 if (!mDevice || FAILED(result))
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000123 {
124 ERR("Could not create D3D11 device - aborting!\n");
125 return EGL_NOT_INITIALIZED; // Cleanup done by destructor through glDestroyRenderer
126 }
daniel@transgaming.com65e65372012-11-28 19:33:50 +0000127
128 IDXGIDevice *dxgiDevice = NULL;
129 result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
130
131 if (FAILED(result))
132 {
133 ERR("Could not query DXGI device - aborting!\n");
134 return EGL_NOT_INITIALIZED;
135 }
136
137 result = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&mDxgiAdapter);
138
139 if (FAILED(result))
140 {
141 ERR("Could not retrieve DXGI adapter - aborting!\n");
142 return EGL_NOT_INITIALIZED;
143 }
144
145 dxgiDevice->Release();
146
147 result = mDxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&mDxgiFactory);
148
149 if (!mDxgiFactory || FAILED(result))
150 {
151 ERR("Could not create DXGI factory - aborting!\n");
152 return EGL_NOT_INITIALIZED;
153 }
154
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000155 initializeDevice();
156
157 return EGL_SUCCESS;
158}
159
160// do any one-time device initialization
161// NOTE: this is also needed after a device lost/reset
162// to reset the scene status and ensure the default states are reset.
163void Renderer11::initializeDevice()
164{
daniel@transgaming.comf8ba1092012-11-28 19:37:53 +0000165 mStateCache.initialize(mDevice);
166
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000167 // Permanent non-default states
168 // TODO
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000169 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000170}
171
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000172int Renderer11::generateConfigs(ConfigDesc **configDescList)
173{
daniel@transgaming.com65e65372012-11-28 19:33:50 +0000174 int numRenderFormats = sizeof(RenderTargetFormats) / sizeof(RenderTargetFormats[0]);
175 int numDepthFormats = sizeof(DepthStencilFormats) / sizeof(DepthStencilFormats[0]);
176 (*configDescList) = new ConfigDesc[numRenderFormats * numDepthFormats];
177 int numConfigs = 0;
178
179 for (int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++)
180 {
181 for (int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++)
182 {
183 DXGI_FORMAT renderTargetFormat = RenderTargetFormats[formatIndex];
184
185 UINT formatSupport = 0;
186 HRESULT result = mDevice->CheckFormatSupport(renderTargetFormat, &formatSupport);
187
188 if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET))
189 {
190 DXGI_FORMAT depthStencilFormat = DepthStencilFormats[depthStencilIndex];
191
192 UINT formatSupport = 0;
193 HRESULT result = mDevice->CheckFormatSupport(depthStencilFormat, &formatSupport);
194
195 if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL))
196 {
197 ConfigDesc newConfig;
198 newConfig.renderTargetFormat = d3d11_gl::ConvertBackBufferFormat(renderTargetFormat);
199 newConfig.depthStencilFormat = d3d11_gl::ConvertDepthStencilFormat(depthStencilFormat);
200 newConfig.multiSample = 0; // FIXME: enumerate multi-sampling
201 newConfig.fastConfig = true; // Assume all DX11 format conversions to be fast
202
203 (*configDescList)[numConfigs++] = newConfig;
204 }
205 }
206 }
207 }
208
209 return numConfigs;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000210}
211
212void Renderer11::deleteConfigs(ConfigDesc *configDescList)
213{
214 delete [] (configDescList);
215}
216
217void Renderer11::startScene()
218{
219 // TODO: nop in d3d11?
220}
221
222void Renderer11::endScene()
223{
224 // TODO: nop in d3d11?
225}
226
227void Renderer11::sync(bool block)
228{
229 // TODO
230 UNIMPLEMENTED();
231}
232
daniel@transgaming.comb9bb2792012-11-28 19:36:49 +0000233SwapChain *Renderer11::createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
234{
235 // TODO
236 UNIMPLEMENTED();
237
238 //return new rx::SwapChain(this, window, shareHandle, backBufferFormat, depthBufferFormat);
239
240 return NULL;
241}
242
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000243void Renderer11::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState)
244{
245 // TODO
246 UNIMPLEMENTED();
247}
248
249void Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *texture)
250{
251 // TODO
252 UNIMPLEMENTED();
253}
254
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000255void Renderer11::setRasterizerState(const gl::RasterizerState &rasterState, unsigned int depthSize)
256{
257 // TODO
258 UNIMPLEMENTED();
259}
260
261void Renderer11::setBlendState(const gl::BlendState &blendState, const gl::Color &blendColor,
262 unsigned int sampleMask)
263{
daniel@transgaming.comf8ba1092012-11-28 19:37:53 +0000264 if (mForceSetBlendState ||
265 memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0 ||
266 memcmp(&blendColor, &mCurBlendColor, sizeof(gl::Color)) != 0 ||
267 sampleMask != mCurSampleMask)
268 {
269 ID3D11BlendState *dxBlendState = mStateCache.getBlendState(blendState);
270 if (!dxBlendState)
271 {
272 ERR("NULL blend state returned by RenderStateCache::getBlendState, setting the default "
273 "blend state.");
274 }
275
276 const float blendColors[] = { blendColor.red, blendColor.green, blendColor.blue, blendColor.alpha };
277 mDeviceContext->OMSetBlendState(dxBlendState, blendColors, sampleMask);
278
279 if (dxBlendState)
280 {
281 dxBlendState->Release();
282 }
283 mCurBlendState = blendState;
284 mCurBlendColor = blendColor;
285 mCurSampleMask = sampleMask;
286 }
287
288 mForceSetBlendState = false;
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000289}
290
291void Renderer11::setDepthStencilState(const gl::DepthStencilState &depthStencilState, bool frontFaceCCW,
292 unsigned int stencilSize)
293{
294 // TODO
295 UNIMPLEMENTED();
296}
297
298void Renderer11::setScissorRectangle(const gl::Rectangle& scissor, unsigned int renderTargetWidth,
299 unsigned int renderTargetHeight)
300{
301 // TODO
302 UNIMPLEMENTED();
303}
304
305void Renderer11::applyRenderTarget(gl::Framebuffer *frameBuffer)
306{
307 // TODO
308 UNIMPLEMENTED();
309}
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000310
daniel@transgaming.comd084c622012-11-28 19:36:05 +0000311void Renderer11::clear(GLbitfield mask, const gl::Color &colorClear, float depthClear, int stencilClear,
312 gl::Framebuffer *frameBuffer)
313{
314 // TODO
315 UNIMPLEMENTED();
316}
317
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000318void Renderer11::releaseDeviceResources()
319{
320 // TODO
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000321 // UNIMPLEMENTED();
daniel@transgaming.comf8ba1092012-11-28 19:37:53 +0000322 mStateCache.clear();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000323}
324
325void Renderer11::markDeviceLost()
326{
327 mDeviceLost = true;
328}
329
330bool Renderer11::isDeviceLost()
331{
332 return mDeviceLost;
333}
334
335// set notify to true to broadcast a message to all contexts of the device loss
336bool Renderer11::testDeviceLost(bool notify)
337{
338 bool isLost = false;
339
340 // TODO
daniel@transgaming.comb9bb2792012-11-28 19:36:49 +0000341 //UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000342
343 if (isLost)
344 {
345 // ensure we note the device loss --
346 // we'll probably get this done again by markDeviceLost
347 // but best to remember it!
348 // Note that we don't want to clear the device loss status here
349 // -- this needs to be done by resetDevice
350 mDeviceLost = true;
351 if (notify)
352 {
353 mDisplay->notifyDeviceLost();
354 }
355 }
356
357 return isLost;
358}
359
360bool Renderer11::testDeviceResettable()
361{
362 HRESULT status = D3D_OK;
363
364 // TODO
365 UNIMPLEMENTED();
366
367 switch (status)
368 {
369 case D3DERR_DEVICENOTRESET:
370 case D3DERR_DEVICEHUNG:
371 return true;
372 default:
373 return false;
374 }
375}
376
377bool Renderer11::resetDevice()
378{
379 releaseDeviceResources();
380
381 // TODO
382 UNIMPLEMENTED();
383
384 // reset device defaults
385 initializeDevice();
386 mDeviceLost = false;
387
daniel@transgaming.comf8ba1092012-11-28 19:37:53 +0000388 mForceSetBlendState = true;
389
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000390 return true;
391}
392
393DWORD Renderer11::getAdapterVendor() const
394{
395 // TODO
396 UNIMPLEMENTED();
397 return 0;
398}
399
400const char *Renderer11::getAdapterDescription() const
401{
402 // TODO
403 UNIMPLEMENTED();
404 return "UNIMPLEMENTED";
405}
406
407GUID Renderer11::getAdapterIdentifier() const
408{
409 // TODO
410 UNIMPLEMENTED();
411 GUID foo = {};
412 return foo;
413}
414
415bool Renderer11::getDXT1TextureSupport()
416{
417 // TODO
418 UNIMPLEMENTED();
419 return false;
420}
421
422bool Renderer11::getDXT3TextureSupport()
423{
424 // TODO
425 UNIMPLEMENTED();
426 return false;
427}
428
429bool Renderer11::getDXT5TextureSupport()
430{
431 // TODO
432 UNIMPLEMENTED();
433 return false;
434}
435
436bool Renderer11::getDepthTextureSupport() const
437{
438 // TODO
439 UNIMPLEMENTED();
440 return false;
441}
442
443bool Renderer11::getFloat32TextureSupport(bool *filtering, bool *renderable)
444{
445 // TODO
446 UNIMPLEMENTED();
447
448 *filtering = false;
449 *renderable = false;
450 return false;
451}
452
453bool Renderer11::getFloat16TextureSupport(bool *filtering, bool *renderable)
454{
455 // TODO
456 UNIMPLEMENTED();
457
458 *filtering = false;
459 *renderable = false;
460 return false;
461}
462
463bool Renderer11::getLuminanceTextureSupport()
464{
465 // TODO
466 UNIMPLEMENTED();
467 return false;
468}
469
470bool Renderer11::getLuminanceAlphaTextureSupport()
471{
472 // TODO
473 UNIMPLEMENTED();
474 return false;
475}
476
477bool Renderer11::getTextureFilterAnisotropySupport() const
478{
479 // TODO
480 UNIMPLEMENTED();
481 return false;
482}
483
484float Renderer11::getTextureMaxAnisotropy() const
485{
486 // TODO
487 UNIMPLEMENTED();
488 return 1.0f;
489}
490
491bool Renderer11::getEventQuerySupport()
492{
493 // TODO
494 UNIMPLEMENTED();
495 return false;
496}
497
498bool Renderer11::getVertexTextureSupport() const
499{
500 // TODO
501 UNIMPLEMENTED();
502 return false;
503}
504
505bool Renderer11::getNonPower2TextureSupport() const
506{
507 // TODO
508 UNIMPLEMENTED();
509 return false;
510}
511
512bool Renderer11::getOcclusionQuerySupport() const
513{
514 // TODO
515 UNIMPLEMENTED();
516 return false;
517}
518
519bool Renderer11::getInstancingSupport() const
520{
521 // TODO
522 UNIMPLEMENTED();
523 return false;
524}
525
526bool Renderer11::getShareHandleSupport() const
527{
528 // TODO
daniel@transgaming.comb9bb2792012-11-28 19:36:49 +0000529 //UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000530
531 // PIX doesn't seem to support using share handles, so disable them.
532 return false && !gl::perfActive();
533}
534
535bool Renderer11::getShaderModel3Support() const
536{
537 // TODO
538 UNIMPLEMENTED();
539 return true;
540}
541
542float Renderer11::getMaxPointSize() const
543{
544 // TODO
545 UNIMPLEMENTED();
546 return 1.0f;
547}
548
549int Renderer11::getMaxTextureWidth() const
550{
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000551 switch (mFeatureLevel)
552 {
553 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
554 case D3D_FEATURE_LEVEL_10_1:
555 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
556 default: UNREACHABLE(); return 0;
557 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000558}
559
560int Renderer11::getMaxTextureHeight() const
561{
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000562 switch (mFeatureLevel)
563 {
564 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
565 case D3D_FEATURE_LEVEL_10_1:
566 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
567 default: UNREACHABLE(); return 0;
568 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000569}
570
571bool Renderer11::get32BitIndexSupport() const
572{
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000573 switch (mFeatureLevel)
574 {
575 case D3D_FEATURE_LEVEL_11_0:
576 case D3D_FEATURE_LEVEL_10_1:
577 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP >= 32; // true
578 default: UNREACHABLE(); return false;
579 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000580}
581
582int Renderer11::getMinSwapInterval() const
583{
daniel@transgaming.com8c7b1a92012-11-28 19:34:06 +0000584 return 0;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000585}
586
587int Renderer11::getMaxSwapInterval() const
588{
daniel@transgaming.com8c7b1a92012-11-28 19:34:06 +0000589 return 4;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000590}
591
592int Renderer11::getMaxSupportedSamples() const
593{
594 // TODO
595 UNIMPLEMENTED();
596 return 1;
597}
598
daniel@transgaming.com31b13e12012-11-28 19:34:30 +0000599bool Renderer11::copyToRenderTarget(TextureStorage2D *dest, TextureStorage2D *source)
daniel@transgaming.comad6aee72012-11-28 19:33:42 +0000600{
601 // TODO
602 UNIMPLEMENTED();
603 return false;
604}
605
daniel@transgaming.com31b13e12012-11-28 19:34:30 +0000606bool Renderer11::copyToRenderTarget(TextureStorageCubeMap *dest, TextureStorageCubeMap *source)
daniel@transgaming.comad6aee72012-11-28 19:33:42 +0000607{
608 // TODO
609 UNIMPLEMENTED();
610 return false;
611}
612
daniel@transgaming.com38380882012-11-28 19:36:39 +0000613bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat,
614 GLint xoffset, GLint yoffset, TextureStorage2D *storage, GLint level)
615{
616 // TODO
617 UNIMPLEMENTED();
618 return false;
619}
620
621bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat,
622 GLint xoffset, GLint yoffset, TextureStorageCubeMap *storage, GLenum target, GLint level)
623{
624 // TODO
625 UNIMPLEMENTED();
626 return false;
627}
628
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000629}