blob: 5a862174c51254f3566da36a4f839711c4526acc [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
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000239void Renderer11::setRasterizerState(const gl::RasterizerState &rasterState, unsigned int depthSize)
240{
241 // TODO
242 UNIMPLEMENTED();
243}
244
245void Renderer11::setBlendState(const gl::BlendState &blendState, const gl::Color &blendColor,
246 unsigned int sampleMask)
247{
248 // TODO
249 UNIMPLEMENTED();
250}
251
252void Renderer11::setDepthStencilState(const gl::DepthStencilState &depthStencilState, bool frontFaceCCW,
253 unsigned int stencilSize)
254{
255 // TODO
256 UNIMPLEMENTED();
257}
258
259void Renderer11::setScissorRectangle(const gl::Rectangle& scissor, unsigned int renderTargetWidth,
260 unsigned int renderTargetHeight)
261{
262 // TODO
263 UNIMPLEMENTED();
264}
265
266void Renderer11::applyRenderTarget(gl::Framebuffer *frameBuffer)
267{
268 // TODO
269 UNIMPLEMENTED();
270}
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000271
daniel@transgaming.comd084c622012-11-28 19:36:05 +0000272void Renderer11::clear(GLbitfield mask, const gl::Color &colorClear, float depthClear, int stencilClear,
273 gl::Framebuffer *frameBuffer)
274{
275 // TODO
276 UNIMPLEMENTED();
277}
278
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000279void Renderer11::releaseDeviceResources()
280{
281 // TODO
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000282 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000283}
284
285void Renderer11::markDeviceLost()
286{
287 mDeviceLost = true;
288}
289
290bool Renderer11::isDeviceLost()
291{
292 return mDeviceLost;
293}
294
295// set notify to true to broadcast a message to all contexts of the device loss
296bool Renderer11::testDeviceLost(bool notify)
297{
298 bool isLost = false;
299
300 // TODO
301 UNIMPLEMENTED();
302
303 if (isLost)
304 {
305 // ensure we note the device loss --
306 // we'll probably get this done again by markDeviceLost
307 // but best to remember it!
308 // Note that we don't want to clear the device loss status here
309 // -- this needs to be done by resetDevice
310 mDeviceLost = true;
311 if (notify)
312 {
313 mDisplay->notifyDeviceLost();
314 }
315 }
316
317 return isLost;
318}
319
320bool Renderer11::testDeviceResettable()
321{
322 HRESULT status = D3D_OK;
323
324 // TODO
325 UNIMPLEMENTED();
326
327 switch (status)
328 {
329 case D3DERR_DEVICENOTRESET:
330 case D3DERR_DEVICEHUNG:
331 return true;
332 default:
333 return false;
334 }
335}
336
337bool Renderer11::resetDevice()
338{
339 releaseDeviceResources();
340
341 // TODO
342 UNIMPLEMENTED();
343
344 // reset device defaults
345 initializeDevice();
346 mDeviceLost = false;
347
348 return true;
349}
350
351DWORD Renderer11::getAdapterVendor() const
352{
353 // TODO
354 UNIMPLEMENTED();
355 return 0;
356}
357
358const char *Renderer11::getAdapterDescription() const
359{
360 // TODO
361 UNIMPLEMENTED();
362 return "UNIMPLEMENTED";
363}
364
365GUID Renderer11::getAdapterIdentifier() const
366{
367 // TODO
368 UNIMPLEMENTED();
369 GUID foo = {};
370 return foo;
371}
372
373bool Renderer11::getDXT1TextureSupport()
374{
375 // TODO
376 UNIMPLEMENTED();
377 return false;
378}
379
380bool Renderer11::getDXT3TextureSupport()
381{
382 // TODO
383 UNIMPLEMENTED();
384 return false;
385}
386
387bool Renderer11::getDXT5TextureSupport()
388{
389 // TODO
390 UNIMPLEMENTED();
391 return false;
392}
393
394bool Renderer11::getDepthTextureSupport() const
395{
396 // TODO
397 UNIMPLEMENTED();
398 return false;
399}
400
401bool Renderer11::getFloat32TextureSupport(bool *filtering, bool *renderable)
402{
403 // TODO
404 UNIMPLEMENTED();
405
406 *filtering = false;
407 *renderable = false;
408 return false;
409}
410
411bool Renderer11::getFloat16TextureSupport(bool *filtering, bool *renderable)
412{
413 // TODO
414 UNIMPLEMENTED();
415
416 *filtering = false;
417 *renderable = false;
418 return false;
419}
420
421bool Renderer11::getLuminanceTextureSupport()
422{
423 // TODO
424 UNIMPLEMENTED();
425 return false;
426}
427
428bool Renderer11::getLuminanceAlphaTextureSupport()
429{
430 // TODO
431 UNIMPLEMENTED();
432 return false;
433}
434
435bool Renderer11::getTextureFilterAnisotropySupport() const
436{
437 // TODO
438 UNIMPLEMENTED();
439 return false;
440}
441
442float Renderer11::getTextureMaxAnisotropy() const
443{
444 // TODO
445 UNIMPLEMENTED();
446 return 1.0f;
447}
448
449bool Renderer11::getEventQuerySupport()
450{
451 // TODO
452 UNIMPLEMENTED();
453 return false;
454}
455
456bool Renderer11::getVertexTextureSupport() const
457{
458 // TODO
459 UNIMPLEMENTED();
460 return false;
461}
462
463bool Renderer11::getNonPower2TextureSupport() const
464{
465 // TODO
466 UNIMPLEMENTED();
467 return false;
468}
469
470bool Renderer11::getOcclusionQuerySupport() const
471{
472 // TODO
473 UNIMPLEMENTED();
474 return false;
475}
476
477bool Renderer11::getInstancingSupport() const
478{
479 // TODO
480 UNIMPLEMENTED();
481 return false;
482}
483
484bool Renderer11::getShareHandleSupport() const
485{
486 // TODO
487 UNIMPLEMENTED();
488
489 // PIX doesn't seem to support using share handles, so disable them.
490 return false && !gl::perfActive();
491}
492
493bool Renderer11::getShaderModel3Support() const
494{
495 // TODO
496 UNIMPLEMENTED();
497 return true;
498}
499
500float Renderer11::getMaxPointSize() const
501{
502 // TODO
503 UNIMPLEMENTED();
504 return 1.0f;
505}
506
507int Renderer11::getMaxTextureWidth() const
508{
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000509 switch (mFeatureLevel)
510 {
511 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
512 case D3D_FEATURE_LEVEL_10_1:
513 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
514 default: UNREACHABLE(); return 0;
515 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000516}
517
518int Renderer11::getMaxTextureHeight() const
519{
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000520 switch (mFeatureLevel)
521 {
522 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
523 case D3D_FEATURE_LEVEL_10_1:
524 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
525 default: UNREACHABLE(); return 0;
526 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000527}
528
529bool Renderer11::get32BitIndexSupport() const
530{
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000531 switch (mFeatureLevel)
532 {
533 case D3D_FEATURE_LEVEL_11_0:
534 case D3D_FEATURE_LEVEL_10_1:
535 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP >= 32; // true
536 default: UNREACHABLE(); return false;
537 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000538}
539
540int Renderer11::getMinSwapInterval() const
541{
daniel@transgaming.com8c7b1a92012-11-28 19:34:06 +0000542 return 0;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000543}
544
545int Renderer11::getMaxSwapInterval() const
546{
daniel@transgaming.com8c7b1a92012-11-28 19:34:06 +0000547 return 4;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000548}
549
550int Renderer11::getMaxSupportedSamples() const
551{
552 // TODO
553 UNIMPLEMENTED();
554 return 1;
555}
556
daniel@transgaming.com31b13e12012-11-28 19:34:30 +0000557bool Renderer11::copyToRenderTarget(TextureStorage2D *dest, TextureStorage2D *source)
daniel@transgaming.comad6aee72012-11-28 19:33:42 +0000558{
559 // TODO
560 UNIMPLEMENTED();
561 return false;
562}
563
daniel@transgaming.com31b13e12012-11-28 19:34:30 +0000564bool Renderer11::copyToRenderTarget(TextureStorageCubeMap *dest, TextureStorageCubeMap *source)
daniel@transgaming.comad6aee72012-11-28 19:33:42 +0000565{
566 // TODO
567 UNIMPLEMENTED();
568 return false;
569}
570
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000571}