blob: c31ef56b6579f374b286ca440000219435d50c78 [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
272void Renderer11::releaseDeviceResources()
273{
274 // TODO
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000275 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000276}
277
278void Renderer11::markDeviceLost()
279{
280 mDeviceLost = true;
281}
282
283bool Renderer11::isDeviceLost()
284{
285 return mDeviceLost;
286}
287
288// set notify to true to broadcast a message to all contexts of the device loss
289bool Renderer11::testDeviceLost(bool notify)
290{
291 bool isLost = false;
292
293 // TODO
294 UNIMPLEMENTED();
295
296 if (isLost)
297 {
298 // ensure we note the device loss --
299 // we'll probably get this done again by markDeviceLost
300 // but best to remember it!
301 // Note that we don't want to clear the device loss status here
302 // -- this needs to be done by resetDevice
303 mDeviceLost = true;
304 if (notify)
305 {
306 mDisplay->notifyDeviceLost();
307 }
308 }
309
310 return isLost;
311}
312
313bool Renderer11::testDeviceResettable()
314{
315 HRESULT status = D3D_OK;
316
317 // TODO
318 UNIMPLEMENTED();
319
320 switch (status)
321 {
322 case D3DERR_DEVICENOTRESET:
323 case D3DERR_DEVICEHUNG:
324 return true;
325 default:
326 return false;
327 }
328}
329
330bool Renderer11::resetDevice()
331{
332 releaseDeviceResources();
333
334 // TODO
335 UNIMPLEMENTED();
336
337 // reset device defaults
338 initializeDevice();
339 mDeviceLost = false;
340
341 return true;
342}
343
344DWORD Renderer11::getAdapterVendor() const
345{
346 // TODO
347 UNIMPLEMENTED();
348 return 0;
349}
350
351const char *Renderer11::getAdapterDescription() const
352{
353 // TODO
354 UNIMPLEMENTED();
355 return "UNIMPLEMENTED";
356}
357
358GUID Renderer11::getAdapterIdentifier() const
359{
360 // TODO
361 UNIMPLEMENTED();
362 GUID foo = {};
363 return foo;
364}
365
366bool Renderer11::getDXT1TextureSupport()
367{
368 // TODO
369 UNIMPLEMENTED();
370 return false;
371}
372
373bool Renderer11::getDXT3TextureSupport()
374{
375 // TODO
376 UNIMPLEMENTED();
377 return false;
378}
379
380bool Renderer11::getDXT5TextureSupport()
381{
382 // TODO
383 UNIMPLEMENTED();
384 return false;
385}
386
387bool Renderer11::getDepthTextureSupport() const
388{
389 // TODO
390 UNIMPLEMENTED();
391 return false;
392}
393
394bool Renderer11::getFloat32TextureSupport(bool *filtering, bool *renderable)
395{
396 // TODO
397 UNIMPLEMENTED();
398
399 *filtering = false;
400 *renderable = false;
401 return false;
402}
403
404bool Renderer11::getFloat16TextureSupport(bool *filtering, bool *renderable)
405{
406 // TODO
407 UNIMPLEMENTED();
408
409 *filtering = false;
410 *renderable = false;
411 return false;
412}
413
414bool Renderer11::getLuminanceTextureSupport()
415{
416 // TODO
417 UNIMPLEMENTED();
418 return false;
419}
420
421bool Renderer11::getLuminanceAlphaTextureSupport()
422{
423 // TODO
424 UNIMPLEMENTED();
425 return false;
426}
427
428bool Renderer11::getTextureFilterAnisotropySupport() const
429{
430 // TODO
431 UNIMPLEMENTED();
432 return false;
433}
434
435float Renderer11::getTextureMaxAnisotropy() const
436{
437 // TODO
438 UNIMPLEMENTED();
439 return 1.0f;
440}
441
442bool Renderer11::getEventQuerySupport()
443{
444 // TODO
445 UNIMPLEMENTED();
446 return false;
447}
448
449bool Renderer11::getVertexTextureSupport() const
450{
451 // TODO
452 UNIMPLEMENTED();
453 return false;
454}
455
456bool Renderer11::getNonPower2TextureSupport() const
457{
458 // TODO
459 UNIMPLEMENTED();
460 return false;
461}
462
463bool Renderer11::getOcclusionQuerySupport() const
464{
465 // TODO
466 UNIMPLEMENTED();
467 return false;
468}
469
470bool Renderer11::getInstancingSupport() const
471{
472 // TODO
473 UNIMPLEMENTED();
474 return false;
475}
476
477bool Renderer11::getShareHandleSupport() const
478{
479 // TODO
480 UNIMPLEMENTED();
481
482 // PIX doesn't seem to support using share handles, so disable them.
483 return false && !gl::perfActive();
484}
485
486bool Renderer11::getShaderModel3Support() const
487{
488 // TODO
489 UNIMPLEMENTED();
490 return true;
491}
492
493float Renderer11::getMaxPointSize() const
494{
495 // TODO
496 UNIMPLEMENTED();
497 return 1.0f;
498}
499
500int Renderer11::getMaxTextureWidth() const
501{
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000502 switch (mFeatureLevel)
503 {
504 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
505 case D3D_FEATURE_LEVEL_10_1:
506 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
507 default: UNREACHABLE(); return 0;
508 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000509}
510
511int Renderer11::getMaxTextureHeight() const
512{
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000513 switch (mFeatureLevel)
514 {
515 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
516 case D3D_FEATURE_LEVEL_10_1:
517 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
518 default: UNREACHABLE(); return 0;
519 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000520}
521
522bool Renderer11::get32BitIndexSupport() const
523{
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000524 switch (mFeatureLevel)
525 {
526 case D3D_FEATURE_LEVEL_11_0:
527 case D3D_FEATURE_LEVEL_10_1:
528 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP >= 32; // true
529 default: UNREACHABLE(); return false;
530 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000531}
532
533int Renderer11::getMinSwapInterval() const
534{
daniel@transgaming.com8c7b1a92012-11-28 19:34:06 +0000535 return 0;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000536}
537
538int Renderer11::getMaxSwapInterval() const
539{
daniel@transgaming.com8c7b1a92012-11-28 19:34:06 +0000540 return 4;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000541}
542
543int Renderer11::getMaxSupportedSamples() const
544{
545 // TODO
546 UNIMPLEMENTED();
547 return 1;
548}
549
daniel@transgaming.com31b13e12012-11-28 19:34:30 +0000550bool Renderer11::copyToRenderTarget(TextureStorage2D *dest, TextureStorage2D *source)
daniel@transgaming.comad6aee72012-11-28 19:33:42 +0000551{
552 // TODO
553 UNIMPLEMENTED();
554 return false;
555}
556
daniel@transgaming.com31b13e12012-11-28 19:34:30 +0000557bool Renderer11::copyToRenderTarget(TextureStorageCubeMap *dest, TextureStorageCubeMap *source)
daniel@transgaming.comad6aee72012-11-28 19:33:42 +0000558{
559 // TODO
560 UNIMPLEMENTED();
561 return false;
562}
563
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000564}