blob: 53b2fdd4da8115a1a6dcb2f8f59b85806dc0580a [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.coma8aac672012-12-20 21:08:00 +000022#include "libGLESv2/renderer/Image11.h"
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000023
24#include "libEGL/Config.h"
25#include "libEGL/Display.h"
26
27namespace rx
28{
daniel@transgaming.com65e65372012-11-28 19:33:50 +000029static const DXGI_FORMAT RenderTargetFormats[] =
30 {
31 DXGI_FORMAT_R8G8B8A8_UNORM
32 };
33
34static const DXGI_FORMAT DepthStencilFormats[] =
35 {
36 DXGI_FORMAT_D24_UNORM_S8_UINT
37 };
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000038
39Renderer11::Renderer11(egl::Display *display, HDC hDc) : Renderer(display), mDc(hDc)
40{
41 mD3d11Module = NULL;
42 mDxgiModule = NULL;
43
daniel@transgaming.comb9bb2792012-11-28 19:36:49 +000044 mDeviceLost = false;
45
daniel@transgaming.com25072f62012-11-28 19:31:32 +000046 mDevice = NULL;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000047 mDeviceContext = NULL;
daniel@transgaming.com65e65372012-11-28 19:33:50 +000048 mDxgiAdapter = NULL;
49 mDxgiFactory = NULL;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000050}
51
52Renderer11::~Renderer11()
53{
54 releaseDeviceResources();
55
daniel@transgaming.com65e65372012-11-28 19:33:50 +000056 if (mDxgiFactory)
57 {
58 mDxgiFactory->Release();
59 mDxgiFactory = NULL;
60 }
61
62 if (mDxgiAdapter)
63 {
64 mDxgiAdapter->Release();
65 mDxgiAdapter = NULL;
66 }
67
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000068 if (mDeviceContext)
69 {
70 mDeviceContext->Release();
71 mDeviceContext = NULL;
72 }
73
daniel@transgaming.com25072f62012-11-28 19:31:32 +000074 if (mDevice)
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000075 {
daniel@transgaming.com25072f62012-11-28 19:31:32 +000076 mDevice->Release();
77 mDevice = NULL;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000078 }
79
80 if (mD3d11Module)
81 {
daniel@transgaming.comc1e26342012-11-28 19:31:16 +000082 FreeLibrary(mD3d11Module);
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000083 mD3d11Module = NULL;
84 }
85
86 if (mDxgiModule)
87 {
daniel@transgaming.comc1e26342012-11-28 19:31:16 +000088 FreeLibrary(mDxgiModule);
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000089 mDxgiModule = NULL;
90 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000091}
92
daniel@transgaming.comb64ed282012-11-28 20:54:02 +000093Renderer11 *Renderer11::makeRenderer11(Renderer *renderer)
94{
95 ASSERT(dynamic_cast<rx::Renderer11*>(renderer) != NULL);
96 return static_cast<rx::Renderer11*>(renderer);
97}
98
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000099EGLint Renderer11::initialize()
100{
daniel@transgaming.com25e16af2012-11-28 21:05:57 +0000101 if (!initializeCompiler())
102 {
103 return EGL_NOT_INITIALIZED;
104 }
105
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000106 mDxgiModule = LoadLibrary(TEXT("dxgi.dll"));
107 mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000108
109 if (mD3d11Module == NULL || mDxgiModule == NULL)
110 {
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000111 ERR("Could not load D3D11 or DXGI library - aborting!\n");
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000112 return EGL_NOT_INITIALIZED;
113 }
114
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000115 PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice");
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000116
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000117 if (D3D11CreateDevice == NULL)
118 {
119 ERR("Could not retrieve D3D11CreateDevice address - aborting!\n");
120 return EGL_NOT_INITIALIZED;
121 }
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000122
123 D3D_FEATURE_LEVEL featureLevel[] =
124 {
125 D3D_FEATURE_LEVEL_11_0,
126 D3D_FEATURE_LEVEL_10_1,
127 D3D_FEATURE_LEVEL_10_0,
128 };
129
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000130 HRESULT result = D3D11CreateDevice(NULL,
131 D3D_DRIVER_TYPE_HARDWARE,
132 NULL,
daniel@transgaming.coma60160b2012-11-28 19:41:15 +0000133 #if defined(_DEBUG)
134 D3D11_CREATE_DEVICE_DEBUG,
135 #else
136 0,
137 #endif
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000138 featureLevel,
139 sizeof(featureLevel)/sizeof(featureLevel[0]),
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000140 D3D11_SDK_VERSION,
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000141 &mDevice,
142 &mFeatureLevel,
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000143 &mDeviceContext);
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000144
145 if (!mDevice || FAILED(result))
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000146 {
147 ERR("Could not create D3D11 device - aborting!\n");
148 return EGL_NOT_INITIALIZED; // Cleanup done by destructor through glDestroyRenderer
149 }
daniel@transgaming.com65e65372012-11-28 19:33:50 +0000150
151 IDXGIDevice *dxgiDevice = NULL;
152 result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
153
154 if (FAILED(result))
155 {
156 ERR("Could not query DXGI device - aborting!\n");
157 return EGL_NOT_INITIALIZED;
158 }
159
160 result = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&mDxgiAdapter);
161
162 if (FAILED(result))
163 {
164 ERR("Could not retrieve DXGI adapter - aborting!\n");
165 return EGL_NOT_INITIALIZED;
166 }
167
168 dxgiDevice->Release();
169
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000170 mDxgiAdapter->GetDesc(&mAdapterDescription);
171 memset(mDescription, 0, sizeof(mDescription));
172 wcstombs(mDescription, mAdapterDescription.Description, sizeof(mDescription) - 1);
173
daniel@transgaming.com65e65372012-11-28 19:33:50 +0000174 result = mDxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&mDxgiFactory);
175
176 if (!mDxgiFactory || FAILED(result))
177 {
178 ERR("Could not create DXGI factory - aborting!\n");
179 return EGL_NOT_INITIALIZED;
180 }
181
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000182 initializeDevice();
183
184 return EGL_SUCCESS;
185}
186
187// do any one-time device initialization
188// NOTE: this is also needed after a device lost/reset
189// to reset the scene status and ensure the default states are reset.
190void Renderer11::initializeDevice()
191{
daniel@transgaming.comf8ba1092012-11-28 19:37:53 +0000192 mStateCache.initialize(mDevice);
193
daniel@transgaming.comc43a6052012-11-28 19:41:51 +0000194 markAllStateDirty();
195
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000196 // Permanent non-default states
197 // TODO
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000198 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000199}
200
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000201int Renderer11::generateConfigs(ConfigDesc **configDescList)
202{
daniel@transgaming.come3e826d2012-11-28 19:42:35 +0000203 unsigned int numRenderFormats = sizeof(RenderTargetFormats) / sizeof(RenderTargetFormats[0]);
204 unsigned int numDepthFormats = sizeof(DepthStencilFormats) / sizeof(DepthStencilFormats[0]);
daniel@transgaming.com65e65372012-11-28 19:33:50 +0000205 (*configDescList) = new ConfigDesc[numRenderFormats * numDepthFormats];
206 int numConfigs = 0;
207
daniel@transgaming.come3e826d2012-11-28 19:42:35 +0000208 for (unsigned int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++)
daniel@transgaming.com65e65372012-11-28 19:33:50 +0000209 {
daniel@transgaming.come3e826d2012-11-28 19:42:35 +0000210 for (unsigned int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++)
daniel@transgaming.com65e65372012-11-28 19:33:50 +0000211 {
212 DXGI_FORMAT renderTargetFormat = RenderTargetFormats[formatIndex];
213
214 UINT formatSupport = 0;
215 HRESULT result = mDevice->CheckFormatSupport(renderTargetFormat, &formatSupport);
216
217 if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET))
218 {
219 DXGI_FORMAT depthStencilFormat = DepthStencilFormats[depthStencilIndex];
220
221 UINT formatSupport = 0;
222 HRESULT result = mDevice->CheckFormatSupport(depthStencilFormat, &formatSupport);
223
224 if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL))
225 {
226 ConfigDesc newConfig;
227 newConfig.renderTargetFormat = d3d11_gl::ConvertBackBufferFormat(renderTargetFormat);
228 newConfig.depthStencilFormat = d3d11_gl::ConvertDepthStencilFormat(depthStencilFormat);
229 newConfig.multiSample = 0; // FIXME: enumerate multi-sampling
230 newConfig.fastConfig = true; // Assume all DX11 format conversions to be fast
231
232 (*configDescList)[numConfigs++] = newConfig;
233 }
234 }
235 }
236 }
237
238 return numConfigs;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000239}
240
241void Renderer11::deleteConfigs(ConfigDesc *configDescList)
242{
243 delete [] (configDescList);
244}
245
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000246void Renderer11::sync(bool block)
247{
248 // TODO
249 UNIMPLEMENTED();
250}
251
daniel@transgaming.comb9bb2792012-11-28 19:36:49 +0000252SwapChain *Renderer11::createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
253{
daniel@transgaming.coma60160b2012-11-28 19:41:15 +0000254 return new rx::SwapChain11(this, window, shareHandle, backBufferFormat, depthBufferFormat);
daniel@transgaming.comb9bb2792012-11-28 19:36:49 +0000255}
256
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000257void Renderer11::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState)
258{
259 // TODO
260 UNIMPLEMENTED();
261}
262
263void Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *texture)
264{
265 // TODO
266 UNIMPLEMENTED();
267}
268
daniel@transgaming.com237bc7e2012-11-28 21:01:06 +0000269void Renderer11::setRasterizerState(const gl::RasterizerState &rasterState)
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000270{
daniel@transgaming.com237bc7e2012-11-28 21:01:06 +0000271 if (mForceSetRasterState || memcmp(&rasterState, &mCurRasterState, sizeof(gl::RasterizerState)) != 0)
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000272 {
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000273 ID3D11RasterizerState *dxRasterState = mStateCache.getRasterizerState(rasterState, mScissorEnabled,
274 mCurDepthSize);
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000275 if (!dxRasterState)
276 {
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000277 ERR("NULL blend state returned by RenderStateCache::getRasterizerState, setting the default"
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000278 "rasterizer state.");
279 }
280
281 mDeviceContext->RSSetState(dxRasterState);
282
283 if (dxRasterState)
284 {
285 dxRasterState->Release();
286 }
287 mCurRasterState = rasterState;
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000288 }
289
290 mForceSetRasterState = false;
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000291}
292
293void Renderer11::setBlendState(const gl::BlendState &blendState, const gl::Color &blendColor,
294 unsigned int sampleMask)
295{
daniel@transgaming.comf8ba1092012-11-28 19:37:53 +0000296 if (mForceSetBlendState ||
297 memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0 ||
298 memcmp(&blendColor, &mCurBlendColor, sizeof(gl::Color)) != 0 ||
299 sampleMask != mCurSampleMask)
300 {
301 ID3D11BlendState *dxBlendState = mStateCache.getBlendState(blendState);
302 if (!dxBlendState)
303 {
304 ERR("NULL blend state returned by RenderStateCache::getBlendState, setting the default "
305 "blend state.");
306 }
307
308 const float blendColors[] = { blendColor.red, blendColor.green, blendColor.blue, blendColor.alpha };
309 mDeviceContext->OMSetBlendState(dxBlendState, blendColors, sampleMask);
310
311 if (dxBlendState)
312 {
313 dxBlendState->Release();
314 }
315 mCurBlendState = blendState;
316 mCurBlendColor = blendColor;
317 mCurSampleMask = sampleMask;
318 }
319
320 mForceSetBlendState = false;
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000321}
322
daniel@transgaming.com08c331d2012-11-28 19:38:39 +0000323void Renderer11::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
daniel@transgaming.com3a0ef482012-11-28 21:01:20 +0000324 int stencilBackRef, bool frontFaceCCW)
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000325{
daniel@transgaming.com5503fd02012-11-28 19:38:57 +0000326 if (mForceSetDepthStencilState ||
327 memcmp(&depthStencilState, &mCurDepthStencilState, sizeof(gl::DepthStencilState)) != 0 ||
328 stencilRef != mCurStencilRef || stencilBackRef != mCurStencilBackRef)
329 {
330 if (depthStencilState.stencilWritemask != depthStencilState.stencilBackWritemask ||
331 stencilRef != stencilBackRef ||
332 depthStencilState.stencilMask != depthStencilState.stencilBackMask)
333 {
334 ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are "
335 "invalid under WebGL.");
336 return error(GL_INVALID_OPERATION);
337 }
338
339 ID3D11DepthStencilState *dxDepthStencilState = mStateCache.getDepthStencilState(depthStencilState);
340 if (!dxDepthStencilState)
341 {
342 ERR("NULL depth stencil state returned by RenderStateCache::getDepthStencilState, "
343 "setting the default depth stencil state.");
344 }
345
346 mDeviceContext->OMSetDepthStencilState(dxDepthStencilState, static_cast<UINT>(stencilRef));
347
348 if (dxDepthStencilState)
349 {
350 dxDepthStencilState->Release();
351 }
352 mCurDepthStencilState = depthStencilState;
353 mCurStencilRef = stencilRef;
354 mCurStencilBackRef = stencilBackRef;
355 }
356
357 mForceSetDepthStencilState = false;
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000358}
359
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000360void Renderer11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled)
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000361{
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000362 if (mForceSetScissor || memcmp(&scissor, &mCurScissor, sizeof(gl::Rectangle)) != 0 ||
363 enabled != mScissorEnabled)
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000364 {
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000365 if (enabled)
366 {
367 D3D11_RECT rect;
368 rect.left = gl::clamp(scissor.x, 0, static_cast<int>(mRenderTargetDesc.width));
369 rect.top = gl::clamp(scissor.y, 0, static_cast<int>(mRenderTargetDesc.height));
370 rect.right = gl::clamp(scissor.x + scissor.width, 0, static_cast<int>(mRenderTargetDesc.width));
371 rect.bottom = gl::clamp(scissor.y + scissor.height, 0, static_cast<int>(mRenderTargetDesc.height));
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000372
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000373 mDeviceContext->RSSetScissorRects(1, &rect);
374 }
375
376 if (enabled != mScissorEnabled)
377 {
378 mForceSetRasterState = true;
379 }
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000380
381 mCurScissor = scissor;
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000382 mScissorEnabled = enabled;
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000383 }
384
385 mForceSetScissor = false;
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000386}
387
daniel@transgaming.com12985182012-12-20 20:56:31 +0000388bool Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
389 bool ignoreViewport, gl::ProgramBinary *currentProgram, bool forceSetUniforms)
daniel@transgaming.com83e80ee2012-11-28 19:40:53 +0000390{
daniel@transgaming.com4c4ce232012-11-28 21:01:40 +0000391 gl::Rectangle actualViewport = viewport;
392 float actualZNear = gl::clamp01(zNear);
393 float actualZFar = gl::clamp01(zFar);
394 if (ignoreViewport)
395 {
396 actualViewport.x = 0;
397 actualViewport.y = 0;
398 actualViewport.width = mRenderTargetDesc.width;
399 actualViewport.height = mRenderTargetDesc.height;
400 actualZNear = 0.0f;
401 actualZFar = 1.0f;
402 }
daniel@transgaming.com53670042012-11-28 20:55:51 +0000403
404 D3D11_VIEWPORT dxViewport;
daniel@transgaming.com4c4ce232012-11-28 21:01:40 +0000405 dxViewport.TopLeftX = gl::clamp(actualViewport.x, 0, static_cast<int>(mRenderTargetDesc.width));
406 dxViewport.TopLeftY = gl::clamp(actualViewport.y, 0, static_cast<int>(mRenderTargetDesc.height));
407 dxViewport.Width = gl::clamp(actualViewport.width, 0, static_cast<int>(mRenderTargetDesc.width) - static_cast<int>(dxViewport.TopLeftX));
408 dxViewport.Height = gl::clamp(actualViewport.height, 0, static_cast<int>(mRenderTargetDesc.height) - static_cast<int>(dxViewport.TopLeftY));
409 dxViewport.MinDepth = actualZNear;
410 dxViewport.MaxDepth = actualZFar;
daniel@transgaming.com53670042012-11-28 20:55:51 +0000411
412 if (dxViewport.Width <= 0 || dxViewport.Height <= 0)
413 {
414 return false; // Nothing to render
415 }
416
daniel@transgaming.com4c4ce232012-11-28 21:01:40 +0000417 bool viewportChanged = mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 ||
418 actualZNear != mCurNear || actualZFar != mCurFar;
419
daniel@transgaming.com53670042012-11-28 20:55:51 +0000420 if (viewportChanged)
421 {
422 mDeviceContext->RSSetViewports(1, &dxViewport);
423
daniel@transgaming.com4c4ce232012-11-28 21:01:40 +0000424 mCurViewport = actualViewport;
425 mCurNear = actualZNear;
426 mCurFar = actualZFar;
daniel@transgaming.com53670042012-11-28 20:55:51 +0000427 }
428
429 if (currentProgram && (viewportChanged || forceSetUniforms))
430 {
daniel@transgaming.com88853c52012-12-20 20:56:40 +0000431 currentProgram->applyDxHalfPixelSize(0.0f, 0.0f);
daniel@transgaming.com53670042012-11-28 20:55:51 +0000432
433 // These values are used for computing gl_FragCoord in Program::linkVaryings().
daniel@transgaming.com88853c52012-12-20 20:56:40 +0000434 currentProgram->applyDxCoord(actualViewport.width * 0.5f,
435 actualViewport.height * 0.5f,
436 actualViewport.x + (actualViewport.width * 0.5f),
437 actualViewport.y + (actualViewport.height * 0.5f));
daniel@transgaming.com53670042012-11-28 20:55:51 +0000438
daniel@transgaming.com12985182012-12-20 20:56:31 +0000439 GLfloat ccw = !gl::IsTriangleMode(drawMode) ? 0.0f : (frontFace == GL_CCW ? 1.0f : -1.0f);
daniel@transgaming.com88853c52012-12-20 20:56:40 +0000440 currentProgram->applyDxDepthFront((actualZFar - actualZNear) * 0.5f, (actualZNear + actualZFar) * 0.5f, ccw);
daniel@transgaming.com53670042012-11-28 20:55:51 +0000441
daniel@transgaming.com88853c52012-12-20 20:56:40 +0000442 currentProgram->applyDxDepthRange(actualZNear, actualZFar, actualZFar - actualZNear);
daniel@transgaming.com53670042012-11-28 20:55:51 +0000443 }
444
445 mForceSetViewport = false;
daniel@transgaming.com83e80ee2012-11-28 19:40:53 +0000446 return true;
447}
448
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000449bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count)
450{
daniel@transgaming.comc52be632012-11-28 21:04:28 +0000451 D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000452
daniel@transgaming.com0b03b062012-11-28 21:03:49 +0000453 switch (mode)
454 {
daniel@transgaming.comc52be632012-11-28 21:04:28 +0000455 case GL_POINTS: primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; break;
456 case GL_LINES: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINELIST; break;
daniel@transgaming.com0b03b062012-11-28 21:03:49 +0000457 case GL_LINE_LOOP: UNIMPLEMENTED(); /* TODO */ break;
daniel@transgaming.comc52be632012-11-28 21:04:28 +0000458 case GL_LINE_STRIP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; break;
459 case GL_TRIANGLES: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; break;
460 case GL_TRIANGLE_STRIP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; break;
daniel@transgaming.com0b03b062012-11-28 21:03:49 +0000461 case GL_TRIANGLE_FAN: UNIMPLEMENTED(); /* TODO */ break;
462 default:
463 return error(GL_INVALID_ENUM, false);
464 }
465
daniel@transgaming.comc52be632012-11-28 21:04:28 +0000466 mDeviceContext->IASetPrimitiveTopology(primitiveTopology);
daniel@transgaming.com0b03b062012-11-28 21:03:49 +0000467
468 return count > 0;
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000469}
470
471bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer)
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000472{
daniel@transgaming.com80fc3322012-11-28 21:02:13 +0000473 // Get the color render buffer and serial
474 gl::Renderbuffer *renderbufferObject = NULL;
475 unsigned int renderTargetSerial = 0;
476 if (framebuffer->getColorbufferType() != GL_NONE)
477 {
478 renderbufferObject = framebuffer->getColorbuffer();
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000479
daniel@transgaming.com80fc3322012-11-28 21:02:13 +0000480 if (!renderbufferObject)
481 {
482 ERR("render target pointer unexpectedly null.");
daniel@transgaming.come9c71b42012-11-28 21:02:23 +0000483 return false;
daniel@transgaming.com80fc3322012-11-28 21:02:13 +0000484 }
485
486 renderTargetSerial = renderbufferObject->getSerial();
487 }
488
489 // Get the depth stencil render buffer and serials
490 gl::Renderbuffer *depthStencil = NULL;
491 unsigned int depthbufferSerial = 0;
492 unsigned int stencilbufferSerial = 0;
493 if (framebuffer->getDepthbufferType() != GL_NONE)
494 {
495 depthStencil = framebuffer->getDepthbuffer();
496 if (!depthStencil)
497 {
498 ERR("Depth stencil pointer unexpectedly null.");
499 return false;
500 }
501
502 depthbufferSerial = depthStencil->getSerial();
503 }
504 else if (framebuffer->getStencilbufferType() != GL_NONE)
505 {
506 depthStencil = framebuffer->getStencilbuffer();
507 if (!depthStencil)
508 {
509 ERR("Depth stencil pointer unexpectedly null.");
510 return false;
511 }
512
513 stencilbufferSerial = depthStencil->getSerial();
514 }
515
516 // Extract the render target dimensions and view
517 unsigned int renderTargetWidth = 0;
518 unsigned int renderTargetHeight = 0;
519 GLenum renderTargetFormat = 0;
520 ID3D11RenderTargetView* framebufferRTV = NULL;
521 if (renderbufferObject)
522 {
523 RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(renderbufferObject->getRenderTarget());
524 if (!renderTarget)
525 {
526 ERR("render target pointer unexpectedly null.");
527 return false;
528 }
529
530 framebufferRTV = renderTarget->getRenderTargetView();
531 if (!framebufferRTV)
532 {
533 ERR("render target view pointer unexpectedly null.");
534 return false;
535 }
536
537 renderTargetWidth = renderbufferObject->getWidth();
538 renderTargetHeight = renderbufferObject->getHeight();
539 renderTargetFormat = renderbufferObject->getActualFormat();
540 }
541
542 // Extract the depth stencil sizes and view
543 unsigned int depthSize = 0;
544 unsigned int stencilSize = 0;
545 ID3D11DepthStencilView* framebufferDSV = NULL;
546 if (depthStencil)
547 {
548 RenderTarget11 *depthStencilRenderTarget = RenderTarget11::makeRenderTarget11(depthStencil->getDepthStencil());
549 if (!depthStencilRenderTarget)
550 {
551 ERR("render target pointer unexpectedly null.");
552 if (framebufferRTV)
553 {
554 framebufferRTV->Release();
555 }
556 return false;
557 }
558
559 framebufferDSV = depthStencilRenderTarget->getDepthStencilView();
560 if (!framebufferDSV)
561 {
562 ERR("depth stencil view pointer unexpectedly null.");
563 if (framebufferRTV)
564 {
565 framebufferRTV->Release();
566 }
567 return false;
568 }
569
570 // If there is no render buffer, the width, height and format values come from
571 // the depth stencil
572 if (!renderbufferObject)
573 {
574 renderTargetWidth = depthStencil->getWidth();
575 renderTargetHeight = depthStencil->getHeight();
576 renderTargetFormat = depthStencil->getActualFormat();
577 }
578
579 depthSize = depthStencil->getDepthSize();
580 stencilSize = depthStencil->getStencilSize();
581 }
582
583 // Apply the render target and depth stencil
584 if (!mRenderTargetDescInitialized || !mDepthStencilInitialized ||
585 renderTargetSerial != mAppliedRenderTargetSerial ||
586 depthbufferSerial != mAppliedDepthbufferSerial ||
587 stencilbufferSerial != mAppliedStencilbufferSerial)
588 {
589 mDeviceContext->OMSetRenderTargets(1, &framebufferRTV, framebufferDSV);
590
591 mRenderTargetDesc.width = renderTargetWidth;
592 mRenderTargetDesc.height = renderTargetHeight;
593 mRenderTargetDesc.format = renderTargetFormat;
594 mForceSetViewport = true; // TODO: It may not be required to clamp the viewport in D3D11
595 mForceSetScissor = true; // TODO: It may not be required to clamp the scissor in D3D11
596
597 if (!mDepthStencilInitialized || depthSize != mCurDepthSize)
598 {
599 mCurDepthSize = depthSize;
600 mForceSetRasterState = true;
601 }
602
603 mCurStencilSize = stencilSize;
604
605 mAppliedRenderTargetSerial = renderTargetSerial;
606 mAppliedDepthbufferSerial = depthbufferSerial;
607 mAppliedStencilbufferSerial = stencilbufferSerial;
608 mRenderTargetDescInitialized = true;
609 mDepthStencilInitialized = true;
610 }
611
612 if (framebufferRTV)
613 {
614 framebufferRTV->Release();
615 }
616 if (framebufferDSV)
617 {
618 framebufferDSV->Release();
619 }
daniel@transgaming.comae39ee22012-11-28 19:42:02 +0000620
621 return true;
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000622}
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000623
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000624GLenum Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances)
daniel@transgaming.comdef9f0f2012-11-28 20:53:20 +0000625{
daniel@transgaming.com18adad02012-11-28 21:04:03 +0000626 // TODO: Create/update vertex buffers for arbitrary GL attributes
627 ASSERT(vertexAttributes[0].mBoundBuffer.get() == 0); // UNIMPLEMENTED();
628
629 UINT stride = vertexAttributes[0].mStride != 0 ? vertexAttributes[0].mStride : vertexAttributes[0].typeSize();
630 UINT size = stride * count;
631
632 D3D11_BUFFER_DESC vertexBufferDescription = {0};
633 vertexBufferDescription.ByteWidth = size;
634 vertexBufferDescription.Usage = D3D11_USAGE_DYNAMIC;
635 vertexBufferDescription.BindFlags = D3D11_BIND_VERTEX_BUFFER;
636 vertexBufferDescription.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
637 vertexBufferDescription.MiscFlags = 0;
638 vertexBufferDescription.StructureByteStride = 0;
639
640 ID3D11Buffer *vertexBuffer = NULL;
641 HRESULT result = mDevice->CreateBuffer(&vertexBufferDescription, NULL, &vertexBuffer);
642 ASSERT(SUCCEEDED(result));
643
644 D3D11_MAPPED_SUBRESOURCE map;
645 result = mDeviceContext->Map(vertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
646 ASSERT(SUCCEEDED(result));
647 memcpy(map.pData, vertexAttributes[0].mPointer, size);
648 mDeviceContext->Unmap(vertexBuffer, 0);
649
650 UINT offset = 0;
651 mDeviceContext->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);
652 vertexBuffer->Release();
653
daniel@transgaming.comda495a12012-11-28 21:03:56 +0000654 // TODO: Build the input layout from the (translated) attribute information
655 D3D11_INPUT_ELEMENT_DESC inputElementDescriptions[1] =
656 {
657 {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}
658 };
659
daniel@transgaming.com7b18d0c2012-11-28 21:04:10 +0000660 ShaderExecutable *vertexExecutable = programBinary->getVertexExecutable();
661
daniel@transgaming.comda495a12012-11-28 21:03:56 +0000662 ID3D11InputLayout *inputLayout = NULL;
daniel@transgaming.com7b18d0c2012-11-28 21:04:10 +0000663 result = mDevice->CreateInputLayout(inputElementDescriptions, 1, vertexExecutable->getFunction(), vertexExecutable->getLength(), &inputLayout);
daniel@transgaming.com18adad02012-11-28 21:04:03 +0000664 ASSERT(SUCCEEDED(result));
daniel@transgaming.comda495a12012-11-28 21:03:56 +0000665
666 mDeviceContext->IASetInputLayout(inputLayout);
667 inputLayout->Release(); // TODO: Build a cache of input layouts
668
daniel@transgaming.com18adad02012-11-28 21:04:03 +0000669 return GL_NO_ERROR;
daniel@transgaming.comdef9f0f2012-11-28 20:53:20 +0000670}
671
daniel@transgaming.com31240482012-11-28 21:06:41 +0000672GLenum Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000673{
674 // TODO
675 UNIMPLEMENTED();
676
677 return GL_OUT_OF_MEMORY;
678}
679
680void Renderer11::drawArrays(GLenum mode, GLsizei count, GLsizei instances)
681{
daniel@transgaming.comd4cf2512012-11-28 21:05:41 +0000682 mDeviceContext->Draw(count, 0);
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000683}
684
daniel@transgaming.com31240482012-11-28 21:06:41 +0000685void 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 +0000686{
687 // TODO
688 UNIMPLEMENTED();
689}
690
daniel@transgaming.com5fbf1772012-11-28 20:54:43 +0000691void Renderer11::applyShaders(gl::ProgramBinary *programBinary)
692{
daniel@transgaming.come4991412012-12-20 20:55:34 +0000693 unsigned int programBinarySerial = programBinary->getSerial();
694 if (programBinarySerial != mAppliedProgramBinarySerial)
695 {
696 ShaderExecutable *vertexExe = programBinary->getVertexExecutable();
697 ShaderExecutable *pixelExe = programBinary->getPixelExecutable();
daniel@transgaming.comd4b2db22012-11-28 21:05:15 +0000698
daniel@transgaming.come4991412012-12-20 20:55:34 +0000699 ID3D11VertexShader *vertexShader = NULL;
700 if (vertexExe) vertexShader = ShaderExecutable11::makeShaderExecutable11(vertexExe)->getVertexShader();
daniel@transgaming.comd4b2db22012-11-28 21:05:15 +0000701
daniel@transgaming.come4991412012-12-20 20:55:34 +0000702 ID3D11PixelShader *pixelShader = NULL;
703 if (pixelExe) pixelShader = ShaderExecutable11::makeShaderExecutable11(pixelExe)->getPixelShader();
daniel@transgaming.comd4b2db22012-11-28 21:05:15 +0000704
daniel@transgaming.come4991412012-12-20 20:55:34 +0000705 mDeviceContext->PSSetShader(pixelShader, NULL, 0);
706 mDeviceContext->VSSetShader(vertexShader, NULL, 0);
707 programBinary->dirtyAllUniforms();
708
709 mAppliedProgramBinarySerial = programBinarySerial;
710 }
daniel@transgaming.com5fbf1772012-11-28 20:54:43 +0000711}
712
daniel@transgaming.comab1c1462012-12-20 21:08:30 +0000713void Renderer11::applyUniforms(const gl::UniformArray *uniformArray)
714{
715 // TODO
716 if (uniformArray->size() != 0)
717 {
718 UNIMPLEMENTED();
719 }
720}
721
daniel@transgaming.com084a2572012-11-28 20:55:17 +0000722void Renderer11::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer)
daniel@transgaming.comd084c622012-11-28 19:36:05 +0000723{
daniel@transgaming.com54e67542012-11-28 21:02:31 +0000724 if (clearParams.mask & GL_COLOR_BUFFER_BIT)
725 {
726 gl::Renderbuffer *renderbufferObject = frameBuffer->getColorbuffer();
727 if (renderbufferObject)
728 {
729 RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(renderbufferObject->getRenderTarget());
730 if (!renderTarget)
731 {
732 ERR("render target pointer unexpectedly null.");
733 return;
734 }
735
736 ID3D11RenderTargetView *framebufferRTV = renderTarget->getRenderTargetView();
737 if (!framebufferRTV)
738 {
739 ERR("render target view pointer unexpectedly null.");
740 return;
741 }
742
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000743 if (mScissorEnabled && (mCurScissor.x > 0 || mCurScissor.y > 0 ||
744 mCurScissor.x + mCurScissor.width < renderTarget->getWidth() ||
745 mCurScissor.y + mCurScissor.height < renderTarget->getHeight()))
daniel@transgaming.com54e67542012-11-28 21:02:31 +0000746 {
747 // TODO: clearing of subregion of render target
748 UNIMPLEMENTED();
749 }
750
751 bool alphaUnmasked = (gl::GetAlphaSize(mRenderTargetDesc.format) == 0) || clearParams.colorMaskAlpha;
752 const bool needMaskedColorClear = (clearParams.mask & GL_COLOR_BUFFER_BIT) &&
753 !(clearParams.colorMaskRed && clearParams.colorMaskGreen &&
754 clearParams.colorMaskBlue && alphaUnmasked);
755
756 if (needMaskedColorClear)
757 {
758 // TODO: masked color clearing
759 UNIMPLEMENTED();
760 }
761 else
762 {
763 const float clearValues[4] = { clearParams.colorClearValue.red,
764 clearParams.colorClearValue.green,
765 clearParams.colorClearValue.blue,
766 clearParams.colorClearValue.alpha };
767 mDeviceContext->ClearRenderTargetView(framebufferRTV, clearValues);
768 }
769
770 framebufferRTV->Release();
771 }
772 }
773 if (clearParams.mask & GL_DEPTH_BUFFER_BIT || clearParams.mask & GL_STENCIL_BUFFER_BIT)
774 {
775 gl::Renderbuffer *renderbufferObject = frameBuffer->getDepthOrStencilbuffer();
776 if (renderbufferObject)
777 {
778 RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(renderbufferObject->getRenderTarget());
779 if (!renderTarget)
780 {
781 ERR("render target pointer unexpectedly null.");
782 return;
783 }
784
785 ID3D11DepthStencilView *framebufferDSV = renderTarget->getDepthStencilView();
786 if (!framebufferDSV)
787 {
788 ERR("depth stencil view pointer unexpectedly null.");
789 return;
790 }
791
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000792 if (mScissorEnabled && (mCurScissor.x > 0 || mCurScissor.y > 0 ||
793 mCurScissor.x + mCurScissor.width < renderTarget->getWidth() ||
794 mCurScissor.y + mCurScissor.height < renderTarget->getHeight()))
daniel@transgaming.com54e67542012-11-28 21:02:31 +0000795 {
796 // TODO: clearing of subregion of depth stencil view
797 UNIMPLEMENTED();
798 }
799
800 unsigned int stencilUnmasked = 0x0;
801 if ((clearParams.mask & GL_STENCIL_BUFFER_BIT) && frameBuffer->hasStencil())
802 {
803 unsigned int stencilSize = gl::GetStencilSize(frameBuffer->getStencilbuffer()->getActualFormat());
804 stencilUnmasked = (0x1 << stencilSize) - 1;
805 }
806
807 const bool needMaskedStencilClear = (clearParams.mask & GL_STENCIL_BUFFER_BIT) &&
808 (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked;
809
810 if (needMaskedStencilClear)
811 {
812 // TODO: masked clearing of depth stencil
813 UNIMPLEMENTED();
814 }
815 else
816 {
817 UINT clearFlags = 0;
818 if (clearParams.mask & GL_DEPTH_BUFFER_BIT)
819 {
820 clearFlags |= D3D11_CLEAR_DEPTH;
821 }
822 if (clearParams.mask & GL_STENCIL_BUFFER_BIT)
823 {
824 clearFlags |= D3D11_CLEAR_STENCIL;
825 }
826
827 float depthClear = clearParams.depthClearValue;
828 UINT8 stencilClear = clearParams.stencilClearValue & 0x000000FF;
829
830 mDeviceContext->ClearDepthStencilView(framebufferDSV, clearFlags, depthClear, stencilClear);
831 }
832
833 framebufferDSV->Release();
834 }
835 }
daniel@transgaming.comd084c622012-11-28 19:36:05 +0000836}
837
daniel@transgaming.comc43a6052012-11-28 19:41:51 +0000838void Renderer11::markAllStateDirty()
839{
daniel@transgaming.com9a067372012-12-20 20:55:24 +0000840 mAppliedRenderTargetSerial = 0;
841 mAppliedDepthbufferSerial = 0;
842 mAppliedStencilbufferSerial = 0;
daniel@transgaming.com7b6b83e2012-11-28 21:00:30 +0000843 mDepthStencilInitialized = false;
844 mRenderTargetDescInitialized = false;
845
daniel@transgaming.comc43a6052012-11-28 19:41:51 +0000846 mForceSetBlendState = true;
847 mForceSetRasterState = true;
848 mForceSetDepthStencilState = true;
849 mForceSetScissor = true;
daniel@transgaming.com53670042012-11-28 20:55:51 +0000850 mForceSetViewport = true;
daniel@transgaming.come4991412012-12-20 20:55:34 +0000851
852 mAppliedProgramBinarySerial = 0;
daniel@transgaming.comc43a6052012-11-28 19:41:51 +0000853}
854
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000855void Renderer11::releaseDeviceResources()
856{
857 // TODO
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000858 // UNIMPLEMENTED();
daniel@transgaming.comf8ba1092012-11-28 19:37:53 +0000859 mStateCache.clear();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000860}
861
862void Renderer11::markDeviceLost()
863{
864 mDeviceLost = true;
865}
866
867bool Renderer11::isDeviceLost()
868{
869 return mDeviceLost;
870}
871
872// set notify to true to broadcast a message to all contexts of the device loss
873bool Renderer11::testDeviceLost(bool notify)
874{
875 bool isLost = false;
876
877 // TODO
daniel@transgaming.comb9bb2792012-11-28 19:36:49 +0000878 //UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000879
880 if (isLost)
881 {
882 // ensure we note the device loss --
883 // we'll probably get this done again by markDeviceLost
884 // but best to remember it!
885 // Note that we don't want to clear the device loss status here
886 // -- this needs to be done by resetDevice
887 mDeviceLost = true;
888 if (notify)
889 {
890 mDisplay->notifyDeviceLost();
891 }
892 }
893
894 return isLost;
895}
896
897bool Renderer11::testDeviceResettable()
898{
899 HRESULT status = D3D_OK;
900
901 // TODO
902 UNIMPLEMENTED();
903
904 switch (status)
905 {
906 case D3DERR_DEVICENOTRESET:
907 case D3DERR_DEVICEHUNG:
908 return true;
909 default:
910 return false;
911 }
912}
913
914bool Renderer11::resetDevice()
915{
916 releaseDeviceResources();
917
918 // TODO
919 UNIMPLEMENTED();
920
921 // reset device defaults
922 initializeDevice();
923 mDeviceLost = false;
924
925 return true;
926}
927
928DWORD Renderer11::getAdapterVendor() const
929{
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000930 return mAdapterDescription.VendorId;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000931}
932
933const char *Renderer11::getAdapterDescription() const
934{
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000935 return mDescription;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000936}
937
938GUID Renderer11::getAdapterIdentifier() const
939{
940 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000941 // UNIMPLEMENTED();
942 GUID foo = {0};
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000943 return foo;
944}
945
946bool Renderer11::getDXT1TextureSupport()
947{
948 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000949 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000950 return false;
951}
952
953bool Renderer11::getDXT3TextureSupport()
954{
955 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000956 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000957 return false;
958}
959
960bool Renderer11::getDXT5TextureSupport()
961{
962 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000963 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000964 return false;
965}
966
967bool Renderer11::getDepthTextureSupport() const
968{
969 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000970 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000971 return false;
972}
973
974bool Renderer11::getFloat32TextureSupport(bool *filtering, bool *renderable)
975{
976 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000977 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000978
979 *filtering = false;
980 *renderable = false;
981 return false;
982}
983
984bool Renderer11::getFloat16TextureSupport(bool *filtering, bool *renderable)
985{
986 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000987 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000988
989 *filtering = false;
990 *renderable = false;
991 return false;
992}
993
994bool Renderer11::getLuminanceTextureSupport()
995{
996 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000997 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000998 return false;
999}
1000
1001bool Renderer11::getLuminanceAlphaTextureSupport()
1002{
1003 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001004 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001005 return false;
1006}
1007
1008bool Renderer11::getTextureFilterAnisotropySupport() const
1009{
1010 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001011 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001012 return false;
1013}
1014
1015float Renderer11::getTextureMaxAnisotropy() const
1016{
1017 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001018 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001019 return 1.0f;
1020}
1021
1022bool Renderer11::getEventQuerySupport()
1023{
1024 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001025 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001026 return false;
1027}
1028
1029bool Renderer11::getVertexTextureSupport() const
1030{
1031 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001032 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001033 return false;
1034}
1035
1036bool Renderer11::getNonPower2TextureSupport() const
1037{
1038 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001039 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001040 return false;
1041}
1042
1043bool Renderer11::getOcclusionQuerySupport() const
1044{
1045 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001046 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001047 return false;
1048}
1049
1050bool Renderer11::getInstancingSupport() const
1051{
1052 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001053 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001054 return false;
1055}
1056
1057bool Renderer11::getShareHandleSupport() const
1058{
1059 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001060 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001061
1062 // PIX doesn't seem to support using share handles, so disable them.
1063 return false && !gl::perfActive();
1064}
1065
daniel@transgaming.com9549bea2012-11-28 20:57:23 +00001066int Renderer11::getMajorShaderModel() const
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001067{
daniel@transgaming.com9549bea2012-11-28 20:57:23 +00001068 switch (mFeatureLevel)
1069 {
1070 case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MAJOR_VERSION; // 5
1071 case D3D_FEATURE_LEVEL_10_1:
1072 case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MAJOR_VERSION; // 4
1073 default: UNREACHABLE(); return 0;
1074 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001075}
1076
1077float Renderer11::getMaxPointSize() const
1078{
1079 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001080 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001081 return 1.0f;
1082}
1083
1084int Renderer11::getMaxTextureWidth() const
1085{
daniel@transgaming.com25072f62012-11-28 19:31:32 +00001086 switch (mFeatureLevel)
1087 {
1088 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
1089 case D3D_FEATURE_LEVEL_10_1:
1090 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
1091 default: UNREACHABLE(); return 0;
1092 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001093}
1094
1095int Renderer11::getMaxTextureHeight() const
1096{
daniel@transgaming.com25072f62012-11-28 19:31:32 +00001097 switch (mFeatureLevel)
1098 {
1099 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
1100 case D3D_FEATURE_LEVEL_10_1:
1101 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
1102 default: UNREACHABLE(); return 0;
1103 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001104}
1105
1106bool Renderer11::get32BitIndexSupport() const
1107{
daniel@transgaming.com25072f62012-11-28 19:31:32 +00001108 switch (mFeatureLevel)
1109 {
1110 case D3D_FEATURE_LEVEL_11_0:
1111 case D3D_FEATURE_LEVEL_10_1:
1112 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP >= 32; // true
1113 default: UNREACHABLE(); return false;
1114 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001115}
1116
1117int Renderer11::getMinSwapInterval() const
1118{
daniel@transgaming.com8c7b1a92012-11-28 19:34:06 +00001119 return 0;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001120}
1121
1122int Renderer11::getMaxSwapInterval() const
1123{
daniel@transgaming.com8c7b1a92012-11-28 19:34:06 +00001124 return 4;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001125}
1126
1127int Renderer11::getMaxSupportedSamples() const
1128{
1129 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001130 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001131 return 1;
1132}
1133
daniel@transgaming.com31b13e12012-11-28 19:34:30 +00001134bool Renderer11::copyToRenderTarget(TextureStorage2D *dest, TextureStorage2D *source)
daniel@transgaming.comad6aee72012-11-28 19:33:42 +00001135{
1136 // TODO
1137 UNIMPLEMENTED();
1138 return false;
1139}
1140
daniel@transgaming.com31b13e12012-11-28 19:34:30 +00001141bool Renderer11::copyToRenderTarget(TextureStorageCubeMap *dest, TextureStorageCubeMap *source)
daniel@transgaming.comad6aee72012-11-28 19:33:42 +00001142{
1143 // TODO
1144 UNIMPLEMENTED();
1145 return false;
1146}
1147
daniel@transgaming.com38380882012-11-28 19:36:39 +00001148bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat,
1149 GLint xoffset, GLint yoffset, TextureStorage2D *storage, GLint level)
1150{
1151 // TODO
1152 UNIMPLEMENTED();
1153 return false;
1154}
1155
1156bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat,
1157 GLint xoffset, GLint yoffset, TextureStorageCubeMap *storage, GLenum target, GLint level)
1158{
1159 // TODO
1160 UNIMPLEMENTED();
1161 return false;
1162}
1163
daniel@transgaming.comf2423652012-11-28 20:53:50 +00001164RenderTarget *Renderer11::createRenderTarget(SwapChain *swapChain, bool depth)
1165{
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +00001166 SwapChain11 *swapChain11 = SwapChain11::makeSwapChain11(swapChain);
1167 RenderTarget11 *renderTarget = NULL;
1168 if (depth)
1169 {
1170 renderTarget = new RenderTarget11(this, swapChain11->getDepthStencil(), swapChain11->getWidth(), swapChain11->getHeight());
1171 }
1172 else
1173 {
1174 renderTarget = new RenderTarget11(this, swapChain11->getRenderTarget(), swapChain11->getWidth(), swapChain11->getHeight());
1175 }
1176 return renderTarget;
daniel@transgaming.comf2423652012-11-28 20:53:50 +00001177}
1178
1179RenderTarget *Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth)
1180{
1181 // TODO
1182 UNIMPLEMENTED();
1183 return NULL;
1184}
1185
daniel@transgaming.com7b18d0c2012-11-28 21:04:10 +00001186ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length, GLenum type, void *data)
daniel@transgaming.com55318902012-11-28 20:58:58 +00001187{
daniel@transgaming.coma2f9fbe2012-11-28 21:03:40 +00001188 ShaderExecutable11 *executable = NULL;
1189
1190 switch (type)
1191 {
1192 case GL_VERTEX_SHADER:
1193 {
1194 ID3D11VertexShader *vshader = NULL;
1195 HRESULT result = mDevice->CreateVertexShader(function, length, NULL, &vshader);
1196 ASSERT(SUCCEEDED(result));
1197
1198 if (vshader)
1199 {
daniel@transgaming.com7b18d0c2012-11-28 21:04:10 +00001200 executable = new ShaderExecutable11(function, length, vshader);
daniel@transgaming.coma2f9fbe2012-11-28 21:03:40 +00001201 }
1202 }
1203 break;
1204 case GL_FRAGMENT_SHADER:
1205 {
1206 ID3D11PixelShader *pshader = NULL;
1207 HRESULT result = mDevice->CreatePixelShader(function, length, NULL, &pshader);
1208 ASSERT(SUCCEEDED(result));
1209
1210 if (pshader)
1211 {
daniel@transgaming.com7b18d0c2012-11-28 21:04:10 +00001212 executable = new ShaderExecutable11(function, length, pshader);
daniel@transgaming.coma2f9fbe2012-11-28 21:03:40 +00001213 }
1214 }
1215 break;
1216 default:
1217 UNREACHABLE();
1218 break;
1219 }
1220
1221 return executable;
daniel@transgaming.com55318902012-11-28 20:58:58 +00001222}
1223
daniel@transgaming.coma9c71422012-11-28 20:58:45 +00001224ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, GLenum type)
1225{
daniel@transgaming.com071ee6a2012-11-28 21:03:21 +00001226 const char *profile = NULL;
1227
1228 switch (type)
1229 {
1230 case GL_VERTEX_SHADER:
1231 profile = "vs_4_0";
1232 break;
1233 case GL_FRAGMENT_SHADER:
1234 profile = "ps_4_0";
1235 break;
1236 default:
1237 UNREACHABLE();
1238 return NULL;
1239 }
1240
daniel@transgaming.com25e16af2012-11-28 21:05:57 +00001241 ID3DBlob *binary = compileToBinary(infoLog, shaderHLSL, profile, false);
daniel@transgaming.com071ee6a2012-11-28 21:03:21 +00001242 if (!binary)
1243 return NULL;
1244
1245 ShaderExecutable *executable = loadExecutable((DWORD *)binary->GetBufferPointer(), binary->GetBufferSize(), type, NULL);
1246 binary->Release();
1247
1248 return executable;
1249}
1250
daniel@transgaming.com3f255b42012-12-20 21:07:35 +00001251VertexBuffer *Renderer11::createVertexBuffer()
1252{
1253 // TODO
1254 UNIMPLEMENTED();
1255 return NULL;
1256}
1257
daniel@transgaming.com6c872172012-11-28 19:39:33 +00001258bool Renderer11::blitRect(gl::Framebuffer *readTarget, gl::Rectangle *readRect, gl::Framebuffer *drawTarget, gl::Rectangle *drawRect,
1259 bool blitRenderTarget, bool blitDepthStencil)
1260{
1261 // TODO
1262 UNIMPLEMENTED();
1263 return false;
1264}
1265
1266void Renderer11::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
1267 GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels)
1268{
1269 // TODO
1270 UNIMPLEMENTED();
1271 return;
1272}
1273
daniel@transgaming.com244e1832012-12-20 20:52:35 +00001274Image *Renderer11::createImage()
1275{
daniel@transgaming.coma8aac672012-12-20 21:08:00 +00001276 return new Image11();
daniel@transgaming.com244e1832012-12-20 20:52:35 +00001277}
1278
daniel@transgaming.comf721fdb2012-12-20 20:53:11 +00001279void Renderer11::generateMipmap(Image *dest, Image *src)
1280{
1281 // TODO
1282 UNIMPLEMENTED();
1283 return;
1284}
1285
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001286}