blob: 088f654da06b4f3889684cb90807913cf621b2f4 [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"
daniel@transgaming.com5503fd02012-11-28 19:38:57 +000010#include "libGLESv2/main.h"
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000011#include "libGLESv2/utilities.h"
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +000012#include "libGLESv2/mathutil.h"
daniel@transgaming.com18adad02012-11-28 21:04:03 +000013#include "libGLESv2/Buffer.h"
daniel@transgaming.com53670042012-11-28 20:55:51 +000014#include "libGLESv2/Program.h"
15#include "libGLESv2/ProgramBinary.h"
daniel@transgaming.com80fc3322012-11-28 21:02:13 +000016#include "libGLESv2/Framebuffer.h"
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000017#include "libGLESv2/renderer/Renderer11.h"
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +000018#include "libGLESv2/renderer/RenderTarget11.h"
daniel@transgaming.com65e65372012-11-28 19:33:50 +000019#include "libGLESv2/renderer/renderer11_utils.h"
daniel@transgaming.coma2f9fbe2012-11-28 21:03:40 +000020#include "libGLESv2/renderer/ShaderExecutable11.h"
daniel@transgaming.coma60160b2012-11-28 19:41:15 +000021#include "libGLESv2/renderer/SwapChain11.h"
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000022
23#include "libEGL/Config.h"
24#include "libEGL/Display.h"
25
26namespace rx
27{
daniel@transgaming.com65e65372012-11-28 19:33:50 +000028static const DXGI_FORMAT RenderTargetFormats[] =
29 {
30 DXGI_FORMAT_R8G8B8A8_UNORM
31 };
32
33static const DXGI_FORMAT DepthStencilFormats[] =
34 {
35 DXGI_FORMAT_D24_UNORM_S8_UINT
36 };
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000037
38Renderer11::Renderer11(egl::Display *display, HDC hDc) : Renderer(display), mDc(hDc)
39{
40 mD3d11Module = NULL;
41 mDxgiModule = NULL;
42
daniel@transgaming.comb9bb2792012-11-28 19:36:49 +000043 mDeviceLost = false;
44
daniel@transgaming.com25072f62012-11-28 19:31:32 +000045 mDevice = NULL;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000046 mDeviceContext = NULL;
daniel@transgaming.com65e65372012-11-28 19:33:50 +000047 mDxgiAdapter = NULL;
48 mDxgiFactory = NULL;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000049}
50
51Renderer11::~Renderer11()
52{
53 releaseDeviceResources();
54
daniel@transgaming.com65e65372012-11-28 19:33:50 +000055 if (mDxgiFactory)
56 {
57 mDxgiFactory->Release();
58 mDxgiFactory = NULL;
59 }
60
61 if (mDxgiAdapter)
62 {
63 mDxgiAdapter->Release();
64 mDxgiAdapter = NULL;
65 }
66
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000067 if (mDeviceContext)
68 {
69 mDeviceContext->Release();
70 mDeviceContext = NULL;
71 }
72
daniel@transgaming.com25072f62012-11-28 19:31:32 +000073 if (mDevice)
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000074 {
daniel@transgaming.com25072f62012-11-28 19:31:32 +000075 mDevice->Release();
76 mDevice = NULL;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000077 }
78
79 if (mD3d11Module)
80 {
daniel@transgaming.comc1e26342012-11-28 19:31:16 +000081 FreeLibrary(mD3d11Module);
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000082 mD3d11Module = NULL;
83 }
84
85 if (mDxgiModule)
86 {
daniel@transgaming.comc1e26342012-11-28 19:31:16 +000087 FreeLibrary(mDxgiModule);
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000088 mDxgiModule = NULL;
89 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000090}
91
daniel@transgaming.comb64ed282012-11-28 20:54:02 +000092Renderer11 *Renderer11::makeRenderer11(Renderer *renderer)
93{
94 ASSERT(dynamic_cast<rx::Renderer11*>(renderer) != NULL);
95 return static_cast<rx::Renderer11*>(renderer);
96}
97
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000098EGLint Renderer11::initialize()
99{
daniel@transgaming.com25e16af2012-11-28 21:05:57 +0000100 if (!initializeCompiler())
101 {
102 return EGL_NOT_INITIALIZED;
103 }
104
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000105 mDxgiModule = LoadLibrary(TEXT("dxgi.dll"));
106 mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000107
108 if (mD3d11Module == NULL || mDxgiModule == NULL)
109 {
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000110 ERR("Could not load D3D11 or DXGI library - aborting!\n");
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000111 return EGL_NOT_INITIALIZED;
112 }
113
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000114 PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice");
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000115
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000116 if (D3D11CreateDevice == NULL)
117 {
118 ERR("Could not retrieve D3D11CreateDevice address - aborting!\n");
119 return EGL_NOT_INITIALIZED;
120 }
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000121
122 D3D_FEATURE_LEVEL featureLevel[] =
123 {
124 D3D_FEATURE_LEVEL_11_0,
125 D3D_FEATURE_LEVEL_10_1,
126 D3D_FEATURE_LEVEL_10_0,
127 };
128
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000129 HRESULT result = D3D11CreateDevice(NULL,
130 D3D_DRIVER_TYPE_HARDWARE,
131 NULL,
daniel@transgaming.coma60160b2012-11-28 19:41:15 +0000132 #if defined(_DEBUG)
133 D3D11_CREATE_DEVICE_DEBUG,
134 #else
135 0,
136 #endif
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000137 featureLevel,
138 sizeof(featureLevel)/sizeof(featureLevel[0]),
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000139 D3D11_SDK_VERSION,
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000140 &mDevice,
141 &mFeatureLevel,
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000142 &mDeviceContext);
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000143
144 if (!mDevice || FAILED(result))
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000145 {
146 ERR("Could not create D3D11 device - aborting!\n");
147 return EGL_NOT_INITIALIZED; // Cleanup done by destructor through glDestroyRenderer
148 }
daniel@transgaming.com65e65372012-11-28 19:33:50 +0000149
150 IDXGIDevice *dxgiDevice = NULL;
151 result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
152
153 if (FAILED(result))
154 {
155 ERR("Could not query DXGI device - aborting!\n");
156 return EGL_NOT_INITIALIZED;
157 }
158
159 result = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&mDxgiAdapter);
160
161 if (FAILED(result))
162 {
163 ERR("Could not retrieve DXGI adapter - aborting!\n");
164 return EGL_NOT_INITIALIZED;
165 }
166
167 dxgiDevice->Release();
168
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000169 mDxgiAdapter->GetDesc(&mAdapterDescription);
170 memset(mDescription, 0, sizeof(mDescription));
171 wcstombs(mDescription, mAdapterDescription.Description, sizeof(mDescription) - 1);
172
daniel@transgaming.com65e65372012-11-28 19:33:50 +0000173 result = mDxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&mDxgiFactory);
174
175 if (!mDxgiFactory || FAILED(result))
176 {
177 ERR("Could not create DXGI factory - aborting!\n");
178 return EGL_NOT_INITIALIZED;
179 }
180
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000181 initializeDevice();
182
183 return EGL_SUCCESS;
184}
185
186// do any one-time device initialization
187// NOTE: this is also needed after a device lost/reset
188// to reset the scene status and ensure the default states are reset.
189void Renderer11::initializeDevice()
190{
daniel@transgaming.comf8ba1092012-11-28 19:37:53 +0000191 mStateCache.initialize(mDevice);
192
daniel@transgaming.comc43a6052012-11-28 19:41:51 +0000193 markAllStateDirty();
194
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000195 // Permanent non-default states
196 // TODO
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000197 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000198}
199
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000200int Renderer11::generateConfigs(ConfigDesc **configDescList)
201{
daniel@transgaming.come3e826d2012-11-28 19:42:35 +0000202 unsigned int numRenderFormats = sizeof(RenderTargetFormats) / sizeof(RenderTargetFormats[0]);
203 unsigned int numDepthFormats = sizeof(DepthStencilFormats) / sizeof(DepthStencilFormats[0]);
daniel@transgaming.com65e65372012-11-28 19:33:50 +0000204 (*configDescList) = new ConfigDesc[numRenderFormats * numDepthFormats];
205 int numConfigs = 0;
206
daniel@transgaming.come3e826d2012-11-28 19:42:35 +0000207 for (unsigned int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++)
daniel@transgaming.com65e65372012-11-28 19:33:50 +0000208 {
daniel@transgaming.come3e826d2012-11-28 19:42:35 +0000209 for (unsigned int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++)
daniel@transgaming.com65e65372012-11-28 19:33:50 +0000210 {
211 DXGI_FORMAT renderTargetFormat = RenderTargetFormats[formatIndex];
212
213 UINT formatSupport = 0;
214 HRESULT result = mDevice->CheckFormatSupport(renderTargetFormat, &formatSupport);
215
216 if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET))
217 {
218 DXGI_FORMAT depthStencilFormat = DepthStencilFormats[depthStencilIndex];
219
220 UINT formatSupport = 0;
221 HRESULT result = mDevice->CheckFormatSupport(depthStencilFormat, &formatSupport);
222
223 if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL))
224 {
225 ConfigDesc newConfig;
226 newConfig.renderTargetFormat = d3d11_gl::ConvertBackBufferFormat(renderTargetFormat);
227 newConfig.depthStencilFormat = d3d11_gl::ConvertDepthStencilFormat(depthStencilFormat);
228 newConfig.multiSample = 0; // FIXME: enumerate multi-sampling
229 newConfig.fastConfig = true; // Assume all DX11 format conversions to be fast
230
231 (*configDescList)[numConfigs++] = newConfig;
232 }
233 }
234 }
235 }
236
237 return numConfigs;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000238}
239
240void Renderer11::deleteConfigs(ConfigDesc *configDescList)
241{
242 delete [] (configDescList);
243}
244
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000245void Renderer11::sync(bool block)
246{
247 // TODO
248 UNIMPLEMENTED();
249}
250
daniel@transgaming.comb9bb2792012-11-28 19:36:49 +0000251SwapChain *Renderer11::createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
252{
daniel@transgaming.coma60160b2012-11-28 19:41:15 +0000253 return new rx::SwapChain11(this, window, shareHandle, backBufferFormat, depthBufferFormat);
daniel@transgaming.comb9bb2792012-11-28 19:36:49 +0000254}
255
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000256void Renderer11::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState)
257{
258 // TODO
259 UNIMPLEMENTED();
260}
261
262void Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *texture)
263{
264 // TODO
265 UNIMPLEMENTED();
266}
267
daniel@transgaming.com237bc7e2012-11-28 21:01:06 +0000268void Renderer11::setRasterizerState(const gl::RasterizerState &rasterState)
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000269{
daniel@transgaming.com237bc7e2012-11-28 21:01:06 +0000270 if (mForceSetRasterState || memcmp(&rasterState, &mCurRasterState, sizeof(gl::RasterizerState)) != 0)
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000271 {
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000272 ID3D11RasterizerState *dxRasterState = mStateCache.getRasterizerState(rasterState, mScissorEnabled,
273 mCurDepthSize);
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000274 if (!dxRasterState)
275 {
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000276 ERR("NULL blend state returned by RenderStateCache::getRasterizerState, setting the default"
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000277 "rasterizer state.");
278 }
279
280 mDeviceContext->RSSetState(dxRasterState);
281
282 if (dxRasterState)
283 {
284 dxRasterState->Release();
285 }
286 mCurRasterState = rasterState;
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000287 }
288
289 mForceSetRasterState = false;
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000290}
291
292void Renderer11::setBlendState(const gl::BlendState &blendState, const gl::Color &blendColor,
293 unsigned int sampleMask)
294{
daniel@transgaming.comf8ba1092012-11-28 19:37:53 +0000295 if (mForceSetBlendState ||
296 memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0 ||
297 memcmp(&blendColor, &mCurBlendColor, sizeof(gl::Color)) != 0 ||
298 sampleMask != mCurSampleMask)
299 {
300 ID3D11BlendState *dxBlendState = mStateCache.getBlendState(blendState);
301 if (!dxBlendState)
302 {
303 ERR("NULL blend state returned by RenderStateCache::getBlendState, setting the default "
304 "blend state.");
305 }
306
307 const float blendColors[] = { blendColor.red, blendColor.green, blendColor.blue, blendColor.alpha };
308 mDeviceContext->OMSetBlendState(dxBlendState, blendColors, sampleMask);
309
310 if (dxBlendState)
311 {
312 dxBlendState->Release();
313 }
314 mCurBlendState = blendState;
315 mCurBlendColor = blendColor;
316 mCurSampleMask = sampleMask;
317 }
318
319 mForceSetBlendState = false;
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000320}
321
daniel@transgaming.com08c331d2012-11-28 19:38:39 +0000322void Renderer11::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
daniel@transgaming.com3a0ef482012-11-28 21:01:20 +0000323 int stencilBackRef, bool frontFaceCCW)
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000324{
daniel@transgaming.com5503fd02012-11-28 19:38:57 +0000325 if (mForceSetDepthStencilState ||
326 memcmp(&depthStencilState, &mCurDepthStencilState, sizeof(gl::DepthStencilState)) != 0 ||
327 stencilRef != mCurStencilRef || stencilBackRef != mCurStencilBackRef)
328 {
329 if (depthStencilState.stencilWritemask != depthStencilState.stencilBackWritemask ||
330 stencilRef != stencilBackRef ||
331 depthStencilState.stencilMask != depthStencilState.stencilBackMask)
332 {
333 ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are "
334 "invalid under WebGL.");
335 return error(GL_INVALID_OPERATION);
336 }
337
338 ID3D11DepthStencilState *dxDepthStencilState = mStateCache.getDepthStencilState(depthStencilState);
339 if (!dxDepthStencilState)
340 {
341 ERR("NULL depth stencil state returned by RenderStateCache::getDepthStencilState, "
342 "setting the default depth stencil state.");
343 }
344
345 mDeviceContext->OMSetDepthStencilState(dxDepthStencilState, static_cast<UINT>(stencilRef));
346
347 if (dxDepthStencilState)
348 {
349 dxDepthStencilState->Release();
350 }
351 mCurDepthStencilState = depthStencilState;
352 mCurStencilRef = stencilRef;
353 mCurStencilBackRef = stencilBackRef;
354 }
355
356 mForceSetDepthStencilState = false;
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000357}
358
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000359void Renderer11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled)
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000360{
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000361 if (mForceSetScissor || memcmp(&scissor, &mCurScissor, sizeof(gl::Rectangle)) != 0 ||
362 enabled != mScissorEnabled)
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000363 {
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000364 if (enabled)
365 {
366 D3D11_RECT rect;
367 rect.left = gl::clamp(scissor.x, 0, static_cast<int>(mRenderTargetDesc.width));
368 rect.top = gl::clamp(scissor.y, 0, static_cast<int>(mRenderTargetDesc.height));
369 rect.right = gl::clamp(scissor.x + scissor.width, 0, static_cast<int>(mRenderTargetDesc.width));
370 rect.bottom = gl::clamp(scissor.y + scissor.height, 0, static_cast<int>(mRenderTargetDesc.height));
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000371
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000372 mDeviceContext->RSSetScissorRects(1, &rect);
373 }
374
375 if (enabled != mScissorEnabled)
376 {
377 mForceSetRasterState = true;
378 }
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000379
380 mCurScissor = scissor;
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000381 mScissorEnabled = enabled;
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000382 }
383
384 mForceSetScissor = false;
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000385}
386
daniel@transgaming.com12985182012-12-20 20:56:31 +0000387bool Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
388 bool ignoreViewport, gl::ProgramBinary *currentProgram, bool forceSetUniforms)
daniel@transgaming.com83e80ee2012-11-28 19:40:53 +0000389{
daniel@transgaming.com4c4ce232012-11-28 21:01:40 +0000390 gl::Rectangle actualViewport = viewport;
391 float actualZNear = gl::clamp01(zNear);
392 float actualZFar = gl::clamp01(zFar);
393 if (ignoreViewport)
394 {
395 actualViewport.x = 0;
396 actualViewport.y = 0;
397 actualViewport.width = mRenderTargetDesc.width;
398 actualViewport.height = mRenderTargetDesc.height;
399 actualZNear = 0.0f;
400 actualZFar = 1.0f;
401 }
daniel@transgaming.com53670042012-11-28 20:55:51 +0000402
403 D3D11_VIEWPORT dxViewport;
daniel@transgaming.com4c4ce232012-11-28 21:01:40 +0000404 dxViewport.TopLeftX = gl::clamp(actualViewport.x, 0, static_cast<int>(mRenderTargetDesc.width));
405 dxViewport.TopLeftY = gl::clamp(actualViewport.y, 0, static_cast<int>(mRenderTargetDesc.height));
406 dxViewport.Width = gl::clamp(actualViewport.width, 0, static_cast<int>(mRenderTargetDesc.width) - static_cast<int>(dxViewport.TopLeftX));
407 dxViewport.Height = gl::clamp(actualViewport.height, 0, static_cast<int>(mRenderTargetDesc.height) - static_cast<int>(dxViewport.TopLeftY));
408 dxViewport.MinDepth = actualZNear;
409 dxViewport.MaxDepth = actualZFar;
daniel@transgaming.com53670042012-11-28 20:55:51 +0000410
411 if (dxViewport.Width <= 0 || dxViewport.Height <= 0)
412 {
413 return false; // Nothing to render
414 }
415
daniel@transgaming.com4c4ce232012-11-28 21:01:40 +0000416 bool viewportChanged = mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 ||
417 actualZNear != mCurNear || actualZFar != mCurFar;
418
daniel@transgaming.com53670042012-11-28 20:55:51 +0000419 if (viewportChanged)
420 {
421 mDeviceContext->RSSetViewports(1, &dxViewport);
422
daniel@transgaming.com4c4ce232012-11-28 21:01:40 +0000423 mCurViewport = actualViewport;
424 mCurNear = actualZNear;
425 mCurFar = actualZFar;
daniel@transgaming.com53670042012-11-28 20:55:51 +0000426 }
427
428 if (currentProgram && (viewportChanged || forceSetUniforms))
429 {
430 GLint halfPixelSize = currentProgram->getDxHalfPixelSizeLocation();
431 GLfloat xy[2] = { 0.0f, 0.0f };
432 currentProgram->setUniform2fv(halfPixelSize, 1, xy);
433
434 // These values are used for computing gl_FragCoord in Program::linkVaryings().
435 GLint coord = currentProgram->getDxCoordLocation();
daniel@transgaming.com4c4ce232012-11-28 21:01:40 +0000436 GLfloat whxy[4] = { actualViewport.width * 0.5f,
437 actualViewport.height * 0.5f,
438 actualViewport.x + (actualViewport.width * 0.5f),
439 actualViewport.y + (actualViewport.height * 0.5f) };
daniel@transgaming.com53670042012-11-28 20:55:51 +0000440 currentProgram->setUniform4fv(coord, 1, whxy);
441
daniel@transgaming.com12985182012-12-20 20:56:31 +0000442 GLint depthFront = currentProgram->getDxDepthFrontLocation();
443 GLfloat ccw = !gl::IsTriangleMode(drawMode) ? 0.0f : (frontFace == GL_CCW ? 1.0f : -1.0f);
444 GLfloat dz[3] = { (actualZFar - actualZNear) * 0.5f, (actualZNear + actualZFar) * 0.5f, ccw };
445 currentProgram->setUniform3fv(depthFront, 1, dz);
daniel@transgaming.com53670042012-11-28 20:55:51 +0000446
447 GLint depthRange = currentProgram->getDxDepthRangeLocation();
daniel@transgaming.com4c4ce232012-11-28 21:01:40 +0000448 GLfloat nearFarDiff[3] = { actualZNear, actualZFar, actualZFar - actualZNear };
daniel@transgaming.com53670042012-11-28 20:55:51 +0000449 currentProgram->setUniform3fv(depthRange, 1, nearFarDiff);
450 }
451
452 mForceSetViewport = false;
daniel@transgaming.com83e80ee2012-11-28 19:40:53 +0000453 return true;
454}
455
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000456bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count)
457{
daniel@transgaming.comc52be632012-11-28 21:04:28 +0000458 D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000459
daniel@transgaming.com0b03b062012-11-28 21:03:49 +0000460 switch (mode)
461 {
daniel@transgaming.comc52be632012-11-28 21:04:28 +0000462 case GL_POINTS: primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; break;
463 case GL_LINES: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINELIST; break;
daniel@transgaming.com0b03b062012-11-28 21:03:49 +0000464 case GL_LINE_LOOP: UNIMPLEMENTED(); /* TODO */ break;
daniel@transgaming.comc52be632012-11-28 21:04:28 +0000465 case GL_LINE_STRIP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; break;
466 case GL_TRIANGLES: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; break;
467 case GL_TRIANGLE_STRIP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; break;
daniel@transgaming.com0b03b062012-11-28 21:03:49 +0000468 case GL_TRIANGLE_FAN: UNIMPLEMENTED(); /* TODO */ break;
469 default:
470 return error(GL_INVALID_ENUM, false);
471 }
472
daniel@transgaming.comc52be632012-11-28 21:04:28 +0000473 mDeviceContext->IASetPrimitiveTopology(primitiveTopology);
daniel@transgaming.com0b03b062012-11-28 21:03:49 +0000474
475 return count > 0;
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000476}
477
478bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer)
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000479{
daniel@transgaming.com80fc3322012-11-28 21:02:13 +0000480 // Get the color render buffer and serial
481 gl::Renderbuffer *renderbufferObject = NULL;
482 unsigned int renderTargetSerial = 0;
483 if (framebuffer->getColorbufferType() != GL_NONE)
484 {
485 renderbufferObject = framebuffer->getColorbuffer();
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000486
daniel@transgaming.com80fc3322012-11-28 21:02:13 +0000487 if (!renderbufferObject)
488 {
489 ERR("render target pointer unexpectedly null.");
daniel@transgaming.come9c71b42012-11-28 21:02:23 +0000490 return false;
daniel@transgaming.com80fc3322012-11-28 21:02:13 +0000491 }
492
493 renderTargetSerial = renderbufferObject->getSerial();
494 }
495
496 // Get the depth stencil render buffer and serials
497 gl::Renderbuffer *depthStencil = NULL;
498 unsigned int depthbufferSerial = 0;
499 unsigned int stencilbufferSerial = 0;
500 if (framebuffer->getDepthbufferType() != GL_NONE)
501 {
502 depthStencil = framebuffer->getDepthbuffer();
503 if (!depthStencil)
504 {
505 ERR("Depth stencil pointer unexpectedly null.");
506 return false;
507 }
508
509 depthbufferSerial = depthStencil->getSerial();
510 }
511 else if (framebuffer->getStencilbufferType() != GL_NONE)
512 {
513 depthStencil = framebuffer->getStencilbuffer();
514 if (!depthStencil)
515 {
516 ERR("Depth stencil pointer unexpectedly null.");
517 return false;
518 }
519
520 stencilbufferSerial = depthStencil->getSerial();
521 }
522
523 // Extract the render target dimensions and view
524 unsigned int renderTargetWidth = 0;
525 unsigned int renderTargetHeight = 0;
526 GLenum renderTargetFormat = 0;
527 ID3D11RenderTargetView* framebufferRTV = NULL;
528 if (renderbufferObject)
529 {
530 RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(renderbufferObject->getRenderTarget());
531 if (!renderTarget)
532 {
533 ERR("render target pointer unexpectedly null.");
534 return false;
535 }
536
537 framebufferRTV = renderTarget->getRenderTargetView();
538 if (!framebufferRTV)
539 {
540 ERR("render target view pointer unexpectedly null.");
541 return false;
542 }
543
544 renderTargetWidth = renderbufferObject->getWidth();
545 renderTargetHeight = renderbufferObject->getHeight();
546 renderTargetFormat = renderbufferObject->getActualFormat();
547 }
548
549 // Extract the depth stencil sizes and view
550 unsigned int depthSize = 0;
551 unsigned int stencilSize = 0;
552 ID3D11DepthStencilView* framebufferDSV = NULL;
553 if (depthStencil)
554 {
555 RenderTarget11 *depthStencilRenderTarget = RenderTarget11::makeRenderTarget11(depthStencil->getDepthStencil());
556 if (!depthStencilRenderTarget)
557 {
558 ERR("render target pointer unexpectedly null.");
559 if (framebufferRTV)
560 {
561 framebufferRTV->Release();
562 }
563 return false;
564 }
565
566 framebufferDSV = depthStencilRenderTarget->getDepthStencilView();
567 if (!framebufferDSV)
568 {
569 ERR("depth stencil view pointer unexpectedly null.");
570 if (framebufferRTV)
571 {
572 framebufferRTV->Release();
573 }
574 return false;
575 }
576
577 // If there is no render buffer, the width, height and format values come from
578 // the depth stencil
579 if (!renderbufferObject)
580 {
581 renderTargetWidth = depthStencil->getWidth();
582 renderTargetHeight = depthStencil->getHeight();
583 renderTargetFormat = depthStencil->getActualFormat();
584 }
585
586 depthSize = depthStencil->getDepthSize();
587 stencilSize = depthStencil->getStencilSize();
588 }
589
590 // Apply the render target and depth stencil
591 if (!mRenderTargetDescInitialized || !mDepthStencilInitialized ||
592 renderTargetSerial != mAppliedRenderTargetSerial ||
593 depthbufferSerial != mAppliedDepthbufferSerial ||
594 stencilbufferSerial != mAppliedStencilbufferSerial)
595 {
596 mDeviceContext->OMSetRenderTargets(1, &framebufferRTV, framebufferDSV);
597
598 mRenderTargetDesc.width = renderTargetWidth;
599 mRenderTargetDesc.height = renderTargetHeight;
600 mRenderTargetDesc.format = renderTargetFormat;
601 mForceSetViewport = true; // TODO: It may not be required to clamp the viewport in D3D11
602 mForceSetScissor = true; // TODO: It may not be required to clamp the scissor in D3D11
603
604 if (!mDepthStencilInitialized || depthSize != mCurDepthSize)
605 {
606 mCurDepthSize = depthSize;
607 mForceSetRasterState = true;
608 }
609
610 mCurStencilSize = stencilSize;
611
612 mAppliedRenderTargetSerial = renderTargetSerial;
613 mAppliedDepthbufferSerial = depthbufferSerial;
614 mAppliedStencilbufferSerial = stencilbufferSerial;
615 mRenderTargetDescInitialized = true;
616 mDepthStencilInitialized = true;
617 }
618
619 if (framebufferRTV)
620 {
621 framebufferRTV->Release();
622 }
623 if (framebufferDSV)
624 {
625 framebufferDSV->Release();
626 }
daniel@transgaming.comae39ee22012-11-28 19:42:02 +0000627
628 return true;
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000629}
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000630
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000631GLenum Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances)
daniel@transgaming.comdef9f0f2012-11-28 20:53:20 +0000632{
daniel@transgaming.com18adad02012-11-28 21:04:03 +0000633 // TODO: Create/update vertex buffers for arbitrary GL attributes
634 ASSERT(vertexAttributes[0].mBoundBuffer.get() == 0); // UNIMPLEMENTED();
635
636 UINT stride = vertexAttributes[0].mStride != 0 ? vertexAttributes[0].mStride : vertexAttributes[0].typeSize();
637 UINT size = stride * count;
638
639 D3D11_BUFFER_DESC vertexBufferDescription = {0};
640 vertexBufferDescription.ByteWidth = size;
641 vertexBufferDescription.Usage = D3D11_USAGE_DYNAMIC;
642 vertexBufferDescription.BindFlags = D3D11_BIND_VERTEX_BUFFER;
643 vertexBufferDescription.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
644 vertexBufferDescription.MiscFlags = 0;
645 vertexBufferDescription.StructureByteStride = 0;
646
647 ID3D11Buffer *vertexBuffer = NULL;
648 HRESULT result = mDevice->CreateBuffer(&vertexBufferDescription, NULL, &vertexBuffer);
649 ASSERT(SUCCEEDED(result));
650
651 D3D11_MAPPED_SUBRESOURCE map;
652 result = mDeviceContext->Map(vertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
653 ASSERT(SUCCEEDED(result));
654 memcpy(map.pData, vertexAttributes[0].mPointer, size);
655 mDeviceContext->Unmap(vertexBuffer, 0);
656
657 UINT offset = 0;
658 mDeviceContext->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);
659 vertexBuffer->Release();
660
daniel@transgaming.comda495a12012-11-28 21:03:56 +0000661 // TODO: Build the input layout from the (translated) attribute information
662 D3D11_INPUT_ELEMENT_DESC inputElementDescriptions[1] =
663 {
664 {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}
665 };
666
daniel@transgaming.com7b18d0c2012-11-28 21:04:10 +0000667 ShaderExecutable *vertexExecutable = programBinary->getVertexExecutable();
668
daniel@transgaming.comda495a12012-11-28 21:03:56 +0000669 ID3D11InputLayout *inputLayout = NULL;
daniel@transgaming.com7b18d0c2012-11-28 21:04:10 +0000670 result = mDevice->CreateInputLayout(inputElementDescriptions, 1, vertexExecutable->getFunction(), vertexExecutable->getLength(), &inputLayout);
daniel@transgaming.com18adad02012-11-28 21:04:03 +0000671 ASSERT(SUCCEEDED(result));
daniel@transgaming.comda495a12012-11-28 21:03:56 +0000672
673 mDeviceContext->IASetInputLayout(inputLayout);
674 inputLayout->Release(); // TODO: Build a cache of input layouts
675
daniel@transgaming.com18adad02012-11-28 21:04:03 +0000676 return GL_NO_ERROR;
daniel@transgaming.comdef9f0f2012-11-28 20:53:20 +0000677}
678
daniel@transgaming.com31240482012-11-28 21:06:41 +0000679GLenum Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000680{
681 // TODO
682 UNIMPLEMENTED();
683
684 return GL_OUT_OF_MEMORY;
685}
686
687void Renderer11::drawArrays(GLenum mode, GLsizei count, GLsizei instances)
688{
daniel@transgaming.comd4cf2512012-11-28 21:05:41 +0000689 mDeviceContext->Draw(count, 0);
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000690}
691
daniel@transgaming.com31240482012-11-28 21:06:41 +0000692void Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo)
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000693{
694 // TODO
695 UNIMPLEMENTED();
696}
697
daniel@transgaming.com5fbf1772012-11-28 20:54:43 +0000698void Renderer11::applyShaders(gl::ProgramBinary *programBinary)
699{
daniel@transgaming.come4991412012-12-20 20:55:34 +0000700 unsigned int programBinarySerial = programBinary->getSerial();
701 if (programBinarySerial != mAppliedProgramBinarySerial)
702 {
703 ShaderExecutable *vertexExe = programBinary->getVertexExecutable();
704 ShaderExecutable *pixelExe = programBinary->getPixelExecutable();
daniel@transgaming.comd4b2db22012-11-28 21:05:15 +0000705
daniel@transgaming.come4991412012-12-20 20:55:34 +0000706 ID3D11VertexShader *vertexShader = NULL;
707 if (vertexExe) vertexShader = ShaderExecutable11::makeShaderExecutable11(vertexExe)->getVertexShader();
daniel@transgaming.comd4b2db22012-11-28 21:05:15 +0000708
daniel@transgaming.come4991412012-12-20 20:55:34 +0000709 ID3D11PixelShader *pixelShader = NULL;
710 if (pixelExe) pixelShader = ShaderExecutable11::makeShaderExecutable11(pixelExe)->getPixelShader();
daniel@transgaming.comd4b2db22012-11-28 21:05:15 +0000711
daniel@transgaming.come4991412012-12-20 20:55:34 +0000712 mDeviceContext->PSSetShader(pixelShader, NULL, 0);
713 mDeviceContext->VSSetShader(vertexShader, NULL, 0);
714 programBinary->dirtyAllUniforms();
715
716 mAppliedProgramBinarySerial = programBinarySerial;
717 }
daniel@transgaming.com5fbf1772012-11-28 20:54:43 +0000718}
719
daniel@transgaming.com084a2572012-11-28 20:55:17 +0000720void Renderer11::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer)
daniel@transgaming.comd084c622012-11-28 19:36:05 +0000721{
daniel@transgaming.com54e67542012-11-28 21:02:31 +0000722 if (clearParams.mask & GL_COLOR_BUFFER_BIT)
723 {
724 gl::Renderbuffer *renderbufferObject = frameBuffer->getColorbuffer();
725 if (renderbufferObject)
726 {
727 RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(renderbufferObject->getRenderTarget());
728 if (!renderTarget)
729 {
730 ERR("render target pointer unexpectedly null.");
731 return;
732 }
733
734 ID3D11RenderTargetView *framebufferRTV = renderTarget->getRenderTargetView();
735 if (!framebufferRTV)
736 {
737 ERR("render target view pointer unexpectedly null.");
738 return;
739 }
740
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000741 if (mScissorEnabled && (mCurScissor.x > 0 || mCurScissor.y > 0 ||
742 mCurScissor.x + mCurScissor.width < renderTarget->getWidth() ||
743 mCurScissor.y + mCurScissor.height < renderTarget->getHeight()))
daniel@transgaming.com54e67542012-11-28 21:02:31 +0000744 {
745 // TODO: clearing of subregion of render target
746 UNIMPLEMENTED();
747 }
748
749 bool alphaUnmasked = (gl::GetAlphaSize(mRenderTargetDesc.format) == 0) || clearParams.colorMaskAlpha;
750 const bool needMaskedColorClear = (clearParams.mask & GL_COLOR_BUFFER_BIT) &&
751 !(clearParams.colorMaskRed && clearParams.colorMaskGreen &&
752 clearParams.colorMaskBlue && alphaUnmasked);
753
754 if (needMaskedColorClear)
755 {
756 // TODO: masked color clearing
757 UNIMPLEMENTED();
758 }
759 else
760 {
761 const float clearValues[4] = { clearParams.colorClearValue.red,
762 clearParams.colorClearValue.green,
763 clearParams.colorClearValue.blue,
764 clearParams.colorClearValue.alpha };
765 mDeviceContext->ClearRenderTargetView(framebufferRTV, clearValues);
766 }
767
768 framebufferRTV->Release();
769 }
770 }
771 if (clearParams.mask & GL_DEPTH_BUFFER_BIT || clearParams.mask & GL_STENCIL_BUFFER_BIT)
772 {
773 gl::Renderbuffer *renderbufferObject = frameBuffer->getDepthOrStencilbuffer();
774 if (renderbufferObject)
775 {
776 RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(renderbufferObject->getRenderTarget());
777 if (!renderTarget)
778 {
779 ERR("render target pointer unexpectedly null.");
780 return;
781 }
782
783 ID3D11DepthStencilView *framebufferDSV = renderTarget->getDepthStencilView();
784 if (!framebufferDSV)
785 {
786 ERR("depth stencil view pointer unexpectedly null.");
787 return;
788 }
789
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000790 if (mScissorEnabled && (mCurScissor.x > 0 || mCurScissor.y > 0 ||
791 mCurScissor.x + mCurScissor.width < renderTarget->getWidth() ||
792 mCurScissor.y + mCurScissor.height < renderTarget->getHeight()))
daniel@transgaming.com54e67542012-11-28 21:02:31 +0000793 {
794 // TODO: clearing of subregion of depth stencil view
795 UNIMPLEMENTED();
796 }
797
798 unsigned int stencilUnmasked = 0x0;
799 if ((clearParams.mask & GL_STENCIL_BUFFER_BIT) && frameBuffer->hasStencil())
800 {
801 unsigned int stencilSize = gl::GetStencilSize(frameBuffer->getStencilbuffer()->getActualFormat());
802 stencilUnmasked = (0x1 << stencilSize) - 1;
803 }
804
805 const bool needMaskedStencilClear = (clearParams.mask & GL_STENCIL_BUFFER_BIT) &&
806 (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked;
807
808 if (needMaskedStencilClear)
809 {
810 // TODO: masked clearing of depth stencil
811 UNIMPLEMENTED();
812 }
813 else
814 {
815 UINT clearFlags = 0;
816 if (clearParams.mask & GL_DEPTH_BUFFER_BIT)
817 {
818 clearFlags |= D3D11_CLEAR_DEPTH;
819 }
820 if (clearParams.mask & GL_STENCIL_BUFFER_BIT)
821 {
822 clearFlags |= D3D11_CLEAR_STENCIL;
823 }
824
825 float depthClear = clearParams.depthClearValue;
826 UINT8 stencilClear = clearParams.stencilClearValue & 0x000000FF;
827
828 mDeviceContext->ClearDepthStencilView(framebufferDSV, clearFlags, depthClear, stencilClear);
829 }
830
831 framebufferDSV->Release();
832 }
833 }
daniel@transgaming.comd084c622012-11-28 19:36:05 +0000834}
835
daniel@transgaming.comc43a6052012-11-28 19:41:51 +0000836void Renderer11::markAllStateDirty()
837{
daniel@transgaming.com9a067372012-12-20 20:55:24 +0000838 mAppliedRenderTargetSerial = 0;
839 mAppliedDepthbufferSerial = 0;
840 mAppliedStencilbufferSerial = 0;
daniel@transgaming.com7b6b83e2012-11-28 21:00:30 +0000841 mDepthStencilInitialized = false;
842 mRenderTargetDescInitialized = false;
843
daniel@transgaming.comc43a6052012-11-28 19:41:51 +0000844 mForceSetBlendState = true;
845 mForceSetRasterState = true;
846 mForceSetDepthStencilState = true;
847 mForceSetScissor = true;
daniel@transgaming.com53670042012-11-28 20:55:51 +0000848 mForceSetViewport = true;
daniel@transgaming.come4991412012-12-20 20:55:34 +0000849
850 mAppliedProgramBinarySerial = 0;
daniel@transgaming.comc43a6052012-11-28 19:41:51 +0000851}
852
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000853void Renderer11::releaseDeviceResources()
854{
855 // TODO
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000856 // UNIMPLEMENTED();
daniel@transgaming.comf8ba1092012-11-28 19:37:53 +0000857 mStateCache.clear();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000858}
859
860void Renderer11::markDeviceLost()
861{
862 mDeviceLost = true;
863}
864
865bool Renderer11::isDeviceLost()
866{
867 return mDeviceLost;
868}
869
870// set notify to true to broadcast a message to all contexts of the device loss
871bool Renderer11::testDeviceLost(bool notify)
872{
873 bool isLost = false;
874
875 // TODO
daniel@transgaming.comb9bb2792012-11-28 19:36:49 +0000876 //UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000877
878 if (isLost)
879 {
880 // ensure we note the device loss --
881 // we'll probably get this done again by markDeviceLost
882 // but best to remember it!
883 // Note that we don't want to clear the device loss status here
884 // -- this needs to be done by resetDevice
885 mDeviceLost = true;
886 if (notify)
887 {
888 mDisplay->notifyDeviceLost();
889 }
890 }
891
892 return isLost;
893}
894
895bool Renderer11::testDeviceResettable()
896{
897 HRESULT status = D3D_OK;
898
899 // TODO
900 UNIMPLEMENTED();
901
902 switch (status)
903 {
904 case D3DERR_DEVICENOTRESET:
905 case D3DERR_DEVICEHUNG:
906 return true;
907 default:
908 return false;
909 }
910}
911
912bool Renderer11::resetDevice()
913{
914 releaseDeviceResources();
915
916 // TODO
917 UNIMPLEMENTED();
918
919 // reset device defaults
920 initializeDevice();
921 mDeviceLost = false;
922
923 return true;
924}
925
926DWORD Renderer11::getAdapterVendor() const
927{
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000928 return mAdapterDescription.VendorId;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000929}
930
931const char *Renderer11::getAdapterDescription() const
932{
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000933 return mDescription;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000934}
935
936GUID Renderer11::getAdapterIdentifier() const
937{
938 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000939 // UNIMPLEMENTED();
940 GUID foo = {0};
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000941 return foo;
942}
943
944bool Renderer11::getDXT1TextureSupport()
945{
946 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000947 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000948 return false;
949}
950
951bool Renderer11::getDXT3TextureSupport()
952{
953 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000954 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000955 return false;
956}
957
958bool Renderer11::getDXT5TextureSupport()
959{
960 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000961 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000962 return false;
963}
964
965bool Renderer11::getDepthTextureSupport() const
966{
967 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000968 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000969 return false;
970}
971
972bool Renderer11::getFloat32TextureSupport(bool *filtering, bool *renderable)
973{
974 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000975 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000976
977 *filtering = false;
978 *renderable = false;
979 return false;
980}
981
982bool Renderer11::getFloat16TextureSupport(bool *filtering, bool *renderable)
983{
984 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000985 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000986
987 *filtering = false;
988 *renderable = false;
989 return false;
990}
991
992bool Renderer11::getLuminanceTextureSupport()
993{
994 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000995 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000996 return false;
997}
998
999bool Renderer11::getLuminanceAlphaTextureSupport()
1000{
1001 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001002 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001003 return false;
1004}
1005
1006bool Renderer11::getTextureFilterAnisotropySupport() const
1007{
1008 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001009 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001010 return false;
1011}
1012
1013float Renderer11::getTextureMaxAnisotropy() const
1014{
1015 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001016 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001017 return 1.0f;
1018}
1019
1020bool Renderer11::getEventQuerySupport()
1021{
1022 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001023 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001024 return false;
1025}
1026
1027bool Renderer11::getVertexTextureSupport() const
1028{
1029 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001030 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001031 return false;
1032}
1033
1034bool Renderer11::getNonPower2TextureSupport() const
1035{
1036 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001037 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001038 return false;
1039}
1040
1041bool Renderer11::getOcclusionQuerySupport() const
1042{
1043 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001044 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001045 return false;
1046}
1047
1048bool Renderer11::getInstancingSupport() const
1049{
1050 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001051 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001052 return false;
1053}
1054
1055bool Renderer11::getShareHandleSupport() const
1056{
1057 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001058 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001059
1060 // PIX doesn't seem to support using share handles, so disable them.
1061 return false && !gl::perfActive();
1062}
1063
daniel@transgaming.com9549bea2012-11-28 20:57:23 +00001064int Renderer11::getMajorShaderModel() const
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001065{
daniel@transgaming.com9549bea2012-11-28 20:57:23 +00001066 switch (mFeatureLevel)
1067 {
1068 case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MAJOR_VERSION; // 5
1069 case D3D_FEATURE_LEVEL_10_1:
1070 case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MAJOR_VERSION; // 4
1071 default: UNREACHABLE(); return 0;
1072 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001073}
1074
1075float Renderer11::getMaxPointSize() const
1076{
1077 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001078 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001079 return 1.0f;
1080}
1081
1082int Renderer11::getMaxTextureWidth() const
1083{
daniel@transgaming.com25072f62012-11-28 19:31:32 +00001084 switch (mFeatureLevel)
1085 {
1086 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
1087 case D3D_FEATURE_LEVEL_10_1:
1088 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
1089 default: UNREACHABLE(); return 0;
1090 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001091}
1092
1093int Renderer11::getMaxTextureHeight() const
1094{
daniel@transgaming.com25072f62012-11-28 19:31:32 +00001095 switch (mFeatureLevel)
1096 {
1097 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
1098 case D3D_FEATURE_LEVEL_10_1:
1099 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
1100 default: UNREACHABLE(); return 0;
1101 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001102}
1103
1104bool Renderer11::get32BitIndexSupport() const
1105{
daniel@transgaming.com25072f62012-11-28 19:31:32 +00001106 switch (mFeatureLevel)
1107 {
1108 case D3D_FEATURE_LEVEL_11_0:
1109 case D3D_FEATURE_LEVEL_10_1:
1110 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP >= 32; // true
1111 default: UNREACHABLE(); return false;
1112 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001113}
1114
1115int Renderer11::getMinSwapInterval() const
1116{
daniel@transgaming.com8c7b1a92012-11-28 19:34:06 +00001117 return 0;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001118}
1119
1120int Renderer11::getMaxSwapInterval() const
1121{
daniel@transgaming.com8c7b1a92012-11-28 19:34:06 +00001122 return 4;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001123}
1124
1125int Renderer11::getMaxSupportedSamples() const
1126{
1127 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001128 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001129 return 1;
1130}
1131
daniel@transgaming.com31b13e12012-11-28 19:34:30 +00001132bool Renderer11::copyToRenderTarget(TextureStorage2D *dest, TextureStorage2D *source)
daniel@transgaming.comad6aee72012-11-28 19:33:42 +00001133{
1134 // TODO
1135 UNIMPLEMENTED();
1136 return false;
1137}
1138
daniel@transgaming.com31b13e12012-11-28 19:34:30 +00001139bool Renderer11::copyToRenderTarget(TextureStorageCubeMap *dest, TextureStorageCubeMap *source)
daniel@transgaming.comad6aee72012-11-28 19:33:42 +00001140{
1141 // TODO
1142 UNIMPLEMENTED();
1143 return false;
1144}
1145
daniel@transgaming.com38380882012-11-28 19:36:39 +00001146bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat,
1147 GLint xoffset, GLint yoffset, TextureStorage2D *storage, GLint level)
1148{
1149 // TODO
1150 UNIMPLEMENTED();
1151 return false;
1152}
1153
1154bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat,
1155 GLint xoffset, GLint yoffset, TextureStorageCubeMap *storage, GLenum target, GLint level)
1156{
1157 // TODO
1158 UNIMPLEMENTED();
1159 return false;
1160}
1161
daniel@transgaming.comf2423652012-11-28 20:53:50 +00001162RenderTarget *Renderer11::createRenderTarget(SwapChain *swapChain, bool depth)
1163{
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +00001164 SwapChain11 *swapChain11 = SwapChain11::makeSwapChain11(swapChain);
1165 RenderTarget11 *renderTarget = NULL;
1166 if (depth)
1167 {
1168 renderTarget = new RenderTarget11(this, swapChain11->getDepthStencil(), swapChain11->getWidth(), swapChain11->getHeight());
1169 }
1170 else
1171 {
1172 renderTarget = new RenderTarget11(this, swapChain11->getRenderTarget(), swapChain11->getWidth(), swapChain11->getHeight());
1173 }
1174 return renderTarget;
daniel@transgaming.comf2423652012-11-28 20:53:50 +00001175}
1176
1177RenderTarget *Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth)
1178{
1179 // TODO
1180 UNIMPLEMENTED();
1181 return NULL;
1182}
1183
daniel@transgaming.com7b18d0c2012-11-28 21:04:10 +00001184ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length, GLenum type, void *data)
daniel@transgaming.com55318902012-11-28 20:58:58 +00001185{
daniel@transgaming.coma2f9fbe2012-11-28 21:03:40 +00001186 ShaderExecutable11 *executable = NULL;
1187
1188 switch (type)
1189 {
1190 case GL_VERTEX_SHADER:
1191 {
1192 ID3D11VertexShader *vshader = NULL;
1193 HRESULT result = mDevice->CreateVertexShader(function, length, NULL, &vshader);
1194 ASSERT(SUCCEEDED(result));
1195
1196 if (vshader)
1197 {
daniel@transgaming.com7b18d0c2012-11-28 21:04:10 +00001198 executable = new ShaderExecutable11(function, length, vshader);
daniel@transgaming.coma2f9fbe2012-11-28 21:03:40 +00001199 }
1200 }
1201 break;
1202 case GL_FRAGMENT_SHADER:
1203 {
1204 ID3D11PixelShader *pshader = NULL;
1205 HRESULT result = mDevice->CreatePixelShader(function, length, NULL, &pshader);
1206 ASSERT(SUCCEEDED(result));
1207
1208 if (pshader)
1209 {
daniel@transgaming.com7b18d0c2012-11-28 21:04:10 +00001210 executable = new ShaderExecutable11(function, length, pshader);
daniel@transgaming.coma2f9fbe2012-11-28 21:03:40 +00001211 }
1212 }
1213 break;
1214 default:
1215 UNREACHABLE();
1216 break;
1217 }
1218
1219 return executable;
daniel@transgaming.com55318902012-11-28 20:58:58 +00001220}
1221
daniel@transgaming.coma9c71422012-11-28 20:58:45 +00001222ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, GLenum type)
1223{
daniel@transgaming.com071ee6a2012-11-28 21:03:21 +00001224 const char *profile = NULL;
1225
1226 switch (type)
1227 {
1228 case GL_VERTEX_SHADER:
1229 profile = "vs_4_0";
1230 break;
1231 case GL_FRAGMENT_SHADER:
1232 profile = "ps_4_0";
1233 break;
1234 default:
1235 UNREACHABLE();
1236 return NULL;
1237 }
1238
daniel@transgaming.com25e16af2012-11-28 21:05:57 +00001239 ID3DBlob *binary = compileToBinary(infoLog, shaderHLSL, profile, false);
daniel@transgaming.com071ee6a2012-11-28 21:03:21 +00001240 if (!binary)
1241 return NULL;
1242
1243 ShaderExecutable *executable = loadExecutable((DWORD *)binary->GetBufferPointer(), binary->GetBufferSize(), type, NULL);
1244 binary->Release();
1245
1246 return executable;
1247}
1248
daniel@transgaming.com6c872172012-11-28 19:39:33 +00001249bool Renderer11::blitRect(gl::Framebuffer *readTarget, gl::Rectangle *readRect, gl::Framebuffer *drawTarget, gl::Rectangle *drawRect,
1250 bool blitRenderTarget, bool blitDepthStencil)
1251{
1252 // TODO
1253 UNIMPLEMENTED();
1254 return false;
1255}
1256
1257void Renderer11::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
1258 GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels)
1259{
1260 // TODO
1261 UNIMPLEMENTED();
1262 return;
1263}
1264
daniel@transgaming.com244e1832012-12-20 20:52:35 +00001265Image *Renderer11::createImage()
1266{
1267 // TODO
1268 UNIMPLEMENTED();
1269 return NULL;
1270}
1271
daniel@transgaming.comf721fdb2012-12-20 20:53:11 +00001272void Renderer11::generateMipmap(Image *dest, Image *src)
1273{
1274 // TODO
1275 UNIMPLEMENTED();
1276 return;
1277}
1278
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001279}