blob: 82cb0b994bf0e8f21ce4719bddf5b9af82f5604f [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.com084a2572012-11-28 20:55:17 +0000713void Renderer11::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer)
daniel@transgaming.comd084c622012-11-28 19:36:05 +0000714{
daniel@transgaming.com54e67542012-11-28 21:02:31 +0000715 if (clearParams.mask & GL_COLOR_BUFFER_BIT)
716 {
717 gl::Renderbuffer *renderbufferObject = frameBuffer->getColorbuffer();
718 if (renderbufferObject)
719 {
720 RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(renderbufferObject->getRenderTarget());
721 if (!renderTarget)
722 {
723 ERR("render target pointer unexpectedly null.");
724 return;
725 }
726
727 ID3D11RenderTargetView *framebufferRTV = renderTarget->getRenderTargetView();
728 if (!framebufferRTV)
729 {
730 ERR("render target view pointer unexpectedly null.");
731 return;
732 }
733
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000734 if (mScissorEnabled && (mCurScissor.x > 0 || mCurScissor.y > 0 ||
735 mCurScissor.x + mCurScissor.width < renderTarget->getWidth() ||
736 mCurScissor.y + mCurScissor.height < renderTarget->getHeight()))
daniel@transgaming.com54e67542012-11-28 21:02:31 +0000737 {
738 // TODO: clearing of subregion of render target
739 UNIMPLEMENTED();
740 }
741
742 bool alphaUnmasked = (gl::GetAlphaSize(mRenderTargetDesc.format) == 0) || clearParams.colorMaskAlpha;
743 const bool needMaskedColorClear = (clearParams.mask & GL_COLOR_BUFFER_BIT) &&
744 !(clearParams.colorMaskRed && clearParams.colorMaskGreen &&
745 clearParams.colorMaskBlue && alphaUnmasked);
746
747 if (needMaskedColorClear)
748 {
749 // TODO: masked color clearing
750 UNIMPLEMENTED();
751 }
752 else
753 {
754 const float clearValues[4] = { clearParams.colorClearValue.red,
755 clearParams.colorClearValue.green,
756 clearParams.colorClearValue.blue,
757 clearParams.colorClearValue.alpha };
758 mDeviceContext->ClearRenderTargetView(framebufferRTV, clearValues);
759 }
760
761 framebufferRTV->Release();
762 }
763 }
764 if (clearParams.mask & GL_DEPTH_BUFFER_BIT || clearParams.mask & GL_STENCIL_BUFFER_BIT)
765 {
766 gl::Renderbuffer *renderbufferObject = frameBuffer->getDepthOrStencilbuffer();
767 if (renderbufferObject)
768 {
769 RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(renderbufferObject->getRenderTarget());
770 if (!renderTarget)
771 {
772 ERR("render target pointer unexpectedly null.");
773 return;
774 }
775
776 ID3D11DepthStencilView *framebufferDSV = renderTarget->getDepthStencilView();
777 if (!framebufferDSV)
778 {
779 ERR("depth stencil view pointer unexpectedly null.");
780 return;
781 }
782
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000783 if (mScissorEnabled && (mCurScissor.x > 0 || mCurScissor.y > 0 ||
784 mCurScissor.x + mCurScissor.width < renderTarget->getWidth() ||
785 mCurScissor.y + mCurScissor.height < renderTarget->getHeight()))
daniel@transgaming.com54e67542012-11-28 21:02:31 +0000786 {
787 // TODO: clearing of subregion of depth stencil view
788 UNIMPLEMENTED();
789 }
790
791 unsigned int stencilUnmasked = 0x0;
792 if ((clearParams.mask & GL_STENCIL_BUFFER_BIT) && frameBuffer->hasStencil())
793 {
794 unsigned int stencilSize = gl::GetStencilSize(frameBuffer->getStencilbuffer()->getActualFormat());
795 stencilUnmasked = (0x1 << stencilSize) - 1;
796 }
797
798 const bool needMaskedStencilClear = (clearParams.mask & GL_STENCIL_BUFFER_BIT) &&
799 (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked;
800
801 if (needMaskedStencilClear)
802 {
803 // TODO: masked clearing of depth stencil
804 UNIMPLEMENTED();
805 }
806 else
807 {
808 UINT clearFlags = 0;
809 if (clearParams.mask & GL_DEPTH_BUFFER_BIT)
810 {
811 clearFlags |= D3D11_CLEAR_DEPTH;
812 }
813 if (clearParams.mask & GL_STENCIL_BUFFER_BIT)
814 {
815 clearFlags |= D3D11_CLEAR_STENCIL;
816 }
817
818 float depthClear = clearParams.depthClearValue;
819 UINT8 stencilClear = clearParams.stencilClearValue & 0x000000FF;
820
821 mDeviceContext->ClearDepthStencilView(framebufferDSV, clearFlags, depthClear, stencilClear);
822 }
823
824 framebufferDSV->Release();
825 }
826 }
daniel@transgaming.comd084c622012-11-28 19:36:05 +0000827}
828
daniel@transgaming.comc43a6052012-11-28 19:41:51 +0000829void Renderer11::markAllStateDirty()
830{
daniel@transgaming.com9a067372012-12-20 20:55:24 +0000831 mAppliedRenderTargetSerial = 0;
832 mAppliedDepthbufferSerial = 0;
833 mAppliedStencilbufferSerial = 0;
daniel@transgaming.com7b6b83e2012-11-28 21:00:30 +0000834 mDepthStencilInitialized = false;
835 mRenderTargetDescInitialized = false;
836
daniel@transgaming.comc43a6052012-11-28 19:41:51 +0000837 mForceSetBlendState = true;
838 mForceSetRasterState = true;
839 mForceSetDepthStencilState = true;
840 mForceSetScissor = true;
daniel@transgaming.com53670042012-11-28 20:55:51 +0000841 mForceSetViewport = true;
daniel@transgaming.come4991412012-12-20 20:55:34 +0000842
843 mAppliedProgramBinarySerial = 0;
daniel@transgaming.comc43a6052012-11-28 19:41:51 +0000844}
845
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000846void Renderer11::releaseDeviceResources()
847{
848 // TODO
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000849 // UNIMPLEMENTED();
daniel@transgaming.comf8ba1092012-11-28 19:37:53 +0000850 mStateCache.clear();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000851}
852
853void Renderer11::markDeviceLost()
854{
855 mDeviceLost = true;
856}
857
858bool Renderer11::isDeviceLost()
859{
860 return mDeviceLost;
861}
862
863// set notify to true to broadcast a message to all contexts of the device loss
864bool Renderer11::testDeviceLost(bool notify)
865{
866 bool isLost = false;
867
868 // TODO
daniel@transgaming.comb9bb2792012-11-28 19:36:49 +0000869 //UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000870
871 if (isLost)
872 {
873 // ensure we note the device loss --
874 // we'll probably get this done again by markDeviceLost
875 // but best to remember it!
876 // Note that we don't want to clear the device loss status here
877 // -- this needs to be done by resetDevice
878 mDeviceLost = true;
879 if (notify)
880 {
881 mDisplay->notifyDeviceLost();
882 }
883 }
884
885 return isLost;
886}
887
888bool Renderer11::testDeviceResettable()
889{
890 HRESULT status = D3D_OK;
891
892 // TODO
893 UNIMPLEMENTED();
894
895 switch (status)
896 {
897 case D3DERR_DEVICENOTRESET:
898 case D3DERR_DEVICEHUNG:
899 return true;
900 default:
901 return false;
902 }
903}
904
905bool Renderer11::resetDevice()
906{
907 releaseDeviceResources();
908
909 // TODO
910 UNIMPLEMENTED();
911
912 // reset device defaults
913 initializeDevice();
914 mDeviceLost = false;
915
916 return true;
917}
918
919DWORD Renderer11::getAdapterVendor() const
920{
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000921 return mAdapterDescription.VendorId;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000922}
923
924const char *Renderer11::getAdapterDescription() const
925{
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000926 return mDescription;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000927}
928
929GUID Renderer11::getAdapterIdentifier() const
930{
931 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000932 // UNIMPLEMENTED();
933 GUID foo = {0};
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000934 return foo;
935}
936
937bool Renderer11::getDXT1TextureSupport()
938{
939 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000940 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000941 return false;
942}
943
944bool Renderer11::getDXT3TextureSupport()
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::getDXT5TextureSupport()
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::getDepthTextureSupport() const
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::getFloat32TextureSupport(bool *filtering, bool *renderable)
966{
967 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000968 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000969
970 *filtering = false;
971 *renderable = false;
972 return false;
973}
974
975bool Renderer11::getFloat16TextureSupport(bool *filtering, bool *renderable)
976{
977 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000978 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000979
980 *filtering = false;
981 *renderable = false;
982 return false;
983}
984
985bool Renderer11::getLuminanceTextureSupport()
986{
987 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000988 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000989 return false;
990}
991
992bool Renderer11::getLuminanceAlphaTextureSupport()
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::getTextureFilterAnisotropySupport() const
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
1006float Renderer11::getTextureMaxAnisotropy() const
1007{
1008 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001009 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001010 return 1.0f;
1011}
1012
1013bool Renderer11::getEventQuerySupport()
1014{
1015 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001016 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001017 return false;
1018}
1019
1020bool Renderer11::getVertexTextureSupport() const
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::getNonPower2TextureSupport() 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::getOcclusionQuerySupport() 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::getInstancingSupport() 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::getShareHandleSupport() const
1049{
1050 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001051 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001052
1053 // PIX doesn't seem to support using share handles, so disable them.
1054 return false && !gl::perfActive();
1055}
1056
daniel@transgaming.com9549bea2012-11-28 20:57:23 +00001057int Renderer11::getMajorShaderModel() const
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001058{
daniel@transgaming.com9549bea2012-11-28 20:57:23 +00001059 switch (mFeatureLevel)
1060 {
1061 case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MAJOR_VERSION; // 5
1062 case D3D_FEATURE_LEVEL_10_1:
1063 case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MAJOR_VERSION; // 4
1064 default: UNREACHABLE(); return 0;
1065 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001066}
1067
1068float Renderer11::getMaxPointSize() const
1069{
1070 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001071 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001072 return 1.0f;
1073}
1074
1075int Renderer11::getMaxTextureWidth() const
1076{
daniel@transgaming.com25072f62012-11-28 19:31:32 +00001077 switch (mFeatureLevel)
1078 {
1079 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
1080 case D3D_FEATURE_LEVEL_10_1:
1081 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
1082 default: UNREACHABLE(); return 0;
1083 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001084}
1085
1086int Renderer11::getMaxTextureHeight() const
1087{
daniel@transgaming.com25072f62012-11-28 19:31:32 +00001088 switch (mFeatureLevel)
1089 {
1090 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
1091 case D3D_FEATURE_LEVEL_10_1:
1092 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
1093 default: UNREACHABLE(); return 0;
1094 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001095}
1096
1097bool Renderer11::get32BitIndexSupport() const
1098{
daniel@transgaming.com25072f62012-11-28 19:31:32 +00001099 switch (mFeatureLevel)
1100 {
1101 case D3D_FEATURE_LEVEL_11_0:
1102 case D3D_FEATURE_LEVEL_10_1:
1103 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP >= 32; // true
1104 default: UNREACHABLE(); return false;
1105 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001106}
1107
1108int Renderer11::getMinSwapInterval() const
1109{
daniel@transgaming.com8c7b1a92012-11-28 19:34:06 +00001110 return 0;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001111}
1112
1113int Renderer11::getMaxSwapInterval() const
1114{
daniel@transgaming.com8c7b1a92012-11-28 19:34:06 +00001115 return 4;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001116}
1117
1118int Renderer11::getMaxSupportedSamples() const
1119{
1120 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001121 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001122 return 1;
1123}
1124
daniel@transgaming.com31b13e12012-11-28 19:34:30 +00001125bool Renderer11::copyToRenderTarget(TextureStorage2D *dest, TextureStorage2D *source)
daniel@transgaming.comad6aee72012-11-28 19:33:42 +00001126{
1127 // TODO
1128 UNIMPLEMENTED();
1129 return false;
1130}
1131
daniel@transgaming.com31b13e12012-11-28 19:34:30 +00001132bool Renderer11::copyToRenderTarget(TextureStorageCubeMap *dest, TextureStorageCubeMap *source)
daniel@transgaming.comad6aee72012-11-28 19:33:42 +00001133{
1134 // TODO
1135 UNIMPLEMENTED();
1136 return false;
1137}
1138
daniel@transgaming.com38380882012-11-28 19:36:39 +00001139bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat,
1140 GLint xoffset, GLint yoffset, TextureStorage2D *storage, GLint level)
1141{
1142 // TODO
1143 UNIMPLEMENTED();
1144 return false;
1145}
1146
1147bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat,
1148 GLint xoffset, GLint yoffset, TextureStorageCubeMap *storage, GLenum target, GLint level)
1149{
1150 // TODO
1151 UNIMPLEMENTED();
1152 return false;
1153}
1154
daniel@transgaming.comf2423652012-11-28 20:53:50 +00001155RenderTarget *Renderer11::createRenderTarget(SwapChain *swapChain, bool depth)
1156{
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +00001157 SwapChain11 *swapChain11 = SwapChain11::makeSwapChain11(swapChain);
1158 RenderTarget11 *renderTarget = NULL;
1159 if (depth)
1160 {
1161 renderTarget = new RenderTarget11(this, swapChain11->getDepthStencil(), swapChain11->getWidth(), swapChain11->getHeight());
1162 }
1163 else
1164 {
1165 renderTarget = new RenderTarget11(this, swapChain11->getRenderTarget(), swapChain11->getWidth(), swapChain11->getHeight());
1166 }
1167 return renderTarget;
daniel@transgaming.comf2423652012-11-28 20:53:50 +00001168}
1169
1170RenderTarget *Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth)
1171{
1172 // TODO
1173 UNIMPLEMENTED();
1174 return NULL;
1175}
1176
daniel@transgaming.com7b18d0c2012-11-28 21:04:10 +00001177ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length, GLenum type, void *data)
daniel@transgaming.com55318902012-11-28 20:58:58 +00001178{
daniel@transgaming.coma2f9fbe2012-11-28 21:03:40 +00001179 ShaderExecutable11 *executable = NULL;
1180
1181 switch (type)
1182 {
1183 case GL_VERTEX_SHADER:
1184 {
1185 ID3D11VertexShader *vshader = NULL;
1186 HRESULT result = mDevice->CreateVertexShader(function, length, NULL, &vshader);
1187 ASSERT(SUCCEEDED(result));
1188
1189 if (vshader)
1190 {
daniel@transgaming.com7b18d0c2012-11-28 21:04:10 +00001191 executable = new ShaderExecutable11(function, length, vshader);
daniel@transgaming.coma2f9fbe2012-11-28 21:03:40 +00001192 }
1193 }
1194 break;
1195 case GL_FRAGMENT_SHADER:
1196 {
1197 ID3D11PixelShader *pshader = NULL;
1198 HRESULT result = mDevice->CreatePixelShader(function, length, NULL, &pshader);
1199 ASSERT(SUCCEEDED(result));
1200
1201 if (pshader)
1202 {
daniel@transgaming.com7b18d0c2012-11-28 21:04:10 +00001203 executable = new ShaderExecutable11(function, length, pshader);
daniel@transgaming.coma2f9fbe2012-11-28 21:03:40 +00001204 }
1205 }
1206 break;
1207 default:
1208 UNREACHABLE();
1209 break;
1210 }
1211
1212 return executable;
daniel@transgaming.com55318902012-11-28 20:58:58 +00001213}
1214
daniel@transgaming.coma9c71422012-11-28 20:58:45 +00001215ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, GLenum type)
1216{
daniel@transgaming.com071ee6a2012-11-28 21:03:21 +00001217 const char *profile = NULL;
1218
1219 switch (type)
1220 {
1221 case GL_VERTEX_SHADER:
1222 profile = "vs_4_0";
1223 break;
1224 case GL_FRAGMENT_SHADER:
1225 profile = "ps_4_0";
1226 break;
1227 default:
1228 UNREACHABLE();
1229 return NULL;
1230 }
1231
daniel@transgaming.com25e16af2012-11-28 21:05:57 +00001232 ID3DBlob *binary = compileToBinary(infoLog, shaderHLSL, profile, false);
daniel@transgaming.com071ee6a2012-11-28 21:03:21 +00001233 if (!binary)
1234 return NULL;
1235
1236 ShaderExecutable *executable = loadExecutable((DWORD *)binary->GetBufferPointer(), binary->GetBufferSize(), type, NULL);
1237 binary->Release();
1238
1239 return executable;
1240}
1241
daniel@transgaming.com3f255b42012-12-20 21:07:35 +00001242VertexBuffer *Renderer11::createVertexBuffer()
1243{
1244 // TODO
1245 UNIMPLEMENTED();
1246 return NULL;
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{
daniel@transgaming.coma8aac672012-12-20 21:08:00 +00001267 return new Image11();
daniel@transgaming.com244e1832012-12-20 20:52:35 +00001268}
1269
daniel@transgaming.comf721fdb2012-12-20 20:53:11 +00001270void Renderer11::generateMipmap(Image *dest, Image *src)
1271{
1272 // TODO
1273 UNIMPLEMENTED();
1274 return;
1275}
1276
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001277}