blob: 8045b9876538136d161cb3bebe79507e66f4b5fe [file] [log] [blame]
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001//
2// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Renderer11.cpp: Implements a back-end specific class for the D3D11 renderer.
8
9#include "common/debug.h"
daniel@transgaming.com5503fd02012-11-28 19:38:57 +000010#include "libGLESv2/main.h"
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000011#include "libGLESv2/utilities.h"
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +000012#include "libGLESv2/mathutil.h"
daniel@transgaming.com18adad02012-11-28 21:04:03 +000013#include "libGLESv2/Buffer.h"
daniel@transgaming.com53670042012-11-28 20:55:51 +000014#include "libGLESv2/Program.h"
15#include "libGLESv2/ProgramBinary.h"
daniel@transgaming.com80fc3322012-11-28 21:02:13 +000016#include "libGLESv2/Framebuffer.h"
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000017#include "libGLESv2/renderer/Renderer11.h"
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +000018#include "libGLESv2/renderer/RenderTarget11.h"
daniel@transgaming.com65e65372012-11-28 19:33:50 +000019#include "libGLESv2/renderer/renderer11_utils.h"
daniel@transgaming.coma2f9fbe2012-11-28 21:03:40 +000020#include "libGLESv2/renderer/ShaderExecutable11.h"
daniel@transgaming.coma60160b2012-11-28 19:41:15 +000021#include "libGLESv2/renderer/SwapChain11.h"
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000022
23#include "libEGL/Config.h"
24#include "libEGL/Display.h"
25
26namespace rx
27{
daniel@transgaming.com65e65372012-11-28 19:33:50 +000028static const DXGI_FORMAT RenderTargetFormats[] =
29 {
30 DXGI_FORMAT_R8G8B8A8_UNORM
31 };
32
33static const DXGI_FORMAT DepthStencilFormats[] =
34 {
35 DXGI_FORMAT_D24_UNORM_S8_UINT
36 };
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000037
38Renderer11::Renderer11(egl::Display *display, HDC hDc) : Renderer(display), mDc(hDc)
39{
40 mD3d11Module = NULL;
41 mDxgiModule = NULL;
42
daniel@transgaming.comb9bb2792012-11-28 19:36:49 +000043 mDeviceLost = false;
44
daniel@transgaming.com25072f62012-11-28 19:31:32 +000045 mDevice = NULL;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000046 mDeviceContext = NULL;
daniel@transgaming.com65e65372012-11-28 19:33:50 +000047 mDxgiAdapter = NULL;
48 mDxgiFactory = NULL;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000049}
50
51Renderer11::~Renderer11()
52{
53 releaseDeviceResources();
54
daniel@transgaming.com65e65372012-11-28 19:33:50 +000055 if (mDxgiFactory)
56 {
57 mDxgiFactory->Release();
58 mDxgiFactory = NULL;
59 }
60
61 if (mDxgiAdapter)
62 {
63 mDxgiAdapter->Release();
64 mDxgiAdapter = NULL;
65 }
66
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000067 if (mDeviceContext)
68 {
69 mDeviceContext->Release();
70 mDeviceContext = NULL;
71 }
72
daniel@transgaming.com25072f62012-11-28 19:31:32 +000073 if (mDevice)
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000074 {
daniel@transgaming.com25072f62012-11-28 19:31:32 +000075 mDevice->Release();
76 mDevice = NULL;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000077 }
78
79 if (mD3d11Module)
80 {
daniel@transgaming.comc1e26342012-11-28 19:31:16 +000081 FreeLibrary(mD3d11Module);
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000082 mD3d11Module = NULL;
83 }
84
85 if (mDxgiModule)
86 {
daniel@transgaming.comc1e26342012-11-28 19:31:16 +000087 FreeLibrary(mDxgiModule);
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000088 mDxgiModule = NULL;
89 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000090}
91
daniel@transgaming.comb64ed282012-11-28 20:54:02 +000092Renderer11 *Renderer11::makeRenderer11(Renderer *renderer)
93{
94 ASSERT(dynamic_cast<rx::Renderer11*>(renderer) != NULL);
95 return static_cast<rx::Renderer11*>(renderer);
96}
97
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000098EGLint Renderer11::initialize()
99{
daniel@transgaming.com25e16af2012-11-28 21:05:57 +0000100 if (!initializeCompiler())
101 {
102 return EGL_NOT_INITIALIZED;
103 }
104
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000105 mDxgiModule = LoadLibrary(TEXT("dxgi.dll"));
106 mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000107
108 if (mD3d11Module == NULL || mDxgiModule == NULL)
109 {
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000110 ERR("Could not load D3D11 or DXGI library - aborting!\n");
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000111 return EGL_NOT_INITIALIZED;
112 }
113
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000114 PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice");
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000115
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000116 if (D3D11CreateDevice == NULL)
117 {
118 ERR("Could not retrieve D3D11CreateDevice address - aborting!\n");
119 return EGL_NOT_INITIALIZED;
120 }
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000121
122 D3D_FEATURE_LEVEL featureLevel[] =
123 {
124 D3D_FEATURE_LEVEL_11_0,
125 D3D_FEATURE_LEVEL_10_1,
126 D3D_FEATURE_LEVEL_10_0,
127 };
128
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000129 HRESULT result = D3D11CreateDevice(NULL,
130 D3D_DRIVER_TYPE_HARDWARE,
131 NULL,
daniel@transgaming.coma60160b2012-11-28 19:41:15 +0000132 #if defined(_DEBUG)
133 D3D11_CREATE_DEVICE_DEBUG,
134 #else
135 0,
136 #endif
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000137 featureLevel,
138 sizeof(featureLevel)/sizeof(featureLevel[0]),
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000139 D3D11_SDK_VERSION,
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000140 &mDevice,
141 &mFeatureLevel,
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000142 &mDeviceContext);
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000143
144 if (!mDevice || FAILED(result))
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000145 {
146 ERR("Could not create D3D11 device - aborting!\n");
147 return EGL_NOT_INITIALIZED; // Cleanup done by destructor through glDestroyRenderer
148 }
daniel@transgaming.com65e65372012-11-28 19:33:50 +0000149
150 IDXGIDevice *dxgiDevice = NULL;
151 result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
152
153 if (FAILED(result))
154 {
155 ERR("Could not query DXGI device - aborting!\n");
156 return EGL_NOT_INITIALIZED;
157 }
158
159 result = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&mDxgiAdapter);
160
161 if (FAILED(result))
162 {
163 ERR("Could not retrieve DXGI adapter - aborting!\n");
164 return EGL_NOT_INITIALIZED;
165 }
166
167 dxgiDevice->Release();
168
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000169 mDxgiAdapter->GetDesc(&mAdapterDescription);
170 memset(mDescription, 0, sizeof(mDescription));
171 wcstombs(mDescription, mAdapterDescription.Description, sizeof(mDescription) - 1);
172
daniel@transgaming.com65e65372012-11-28 19:33:50 +0000173 result = mDxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&mDxgiFactory);
174
175 if (!mDxgiFactory || FAILED(result))
176 {
177 ERR("Could not create DXGI factory - aborting!\n");
178 return EGL_NOT_INITIALIZED;
179 }
180
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000181 initializeDevice();
182
183 return EGL_SUCCESS;
184}
185
186// do any one-time device initialization
187// NOTE: this is also needed after a device lost/reset
188// to reset the scene status and ensure the default states are reset.
189void Renderer11::initializeDevice()
190{
daniel@transgaming.comf8ba1092012-11-28 19:37:53 +0000191 mStateCache.initialize(mDevice);
192
daniel@transgaming.comc43a6052012-11-28 19:41:51 +0000193 markAllStateDirty();
194
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000195 // Permanent non-default states
196 // TODO
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000197 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000198}
199
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000200int Renderer11::generateConfigs(ConfigDesc **configDescList)
201{
daniel@transgaming.come3e826d2012-11-28 19:42:35 +0000202 unsigned int numRenderFormats = sizeof(RenderTargetFormats) / sizeof(RenderTargetFormats[0]);
203 unsigned int numDepthFormats = sizeof(DepthStencilFormats) / sizeof(DepthStencilFormats[0]);
daniel@transgaming.com65e65372012-11-28 19:33:50 +0000204 (*configDescList) = new ConfigDesc[numRenderFormats * numDepthFormats];
205 int numConfigs = 0;
206
daniel@transgaming.come3e826d2012-11-28 19:42:35 +0000207 for (unsigned int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++)
daniel@transgaming.com65e65372012-11-28 19:33:50 +0000208 {
daniel@transgaming.come3e826d2012-11-28 19:42:35 +0000209 for (unsigned int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++)
daniel@transgaming.com65e65372012-11-28 19:33:50 +0000210 {
211 DXGI_FORMAT renderTargetFormat = RenderTargetFormats[formatIndex];
212
213 UINT formatSupport = 0;
214 HRESULT result = mDevice->CheckFormatSupport(renderTargetFormat, &formatSupport);
215
216 if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET))
217 {
218 DXGI_FORMAT depthStencilFormat = DepthStencilFormats[depthStencilIndex];
219
220 UINT formatSupport = 0;
221 HRESULT result = mDevice->CheckFormatSupport(depthStencilFormat, &formatSupport);
222
223 if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL))
224 {
225 ConfigDesc newConfig;
226 newConfig.renderTargetFormat = d3d11_gl::ConvertBackBufferFormat(renderTargetFormat);
227 newConfig.depthStencilFormat = d3d11_gl::ConvertDepthStencilFormat(depthStencilFormat);
228 newConfig.multiSample = 0; // FIXME: enumerate multi-sampling
229 newConfig.fastConfig = true; // Assume all DX11 format conversions to be fast
230
231 (*configDescList)[numConfigs++] = newConfig;
232 }
233 }
234 }
235 }
236
237 return numConfigs;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000238}
239
240void Renderer11::deleteConfigs(ConfigDesc *configDescList)
241{
242 delete [] (configDescList);
243}
244
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000245void Renderer11::sync(bool block)
246{
247 // TODO
248 UNIMPLEMENTED();
249}
250
daniel@transgaming.comb9bb2792012-11-28 19:36:49 +0000251SwapChain *Renderer11::createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
252{
daniel@transgaming.coma60160b2012-11-28 19:41:15 +0000253 return new rx::SwapChain11(this, window, shareHandle, backBufferFormat, depthBufferFormat);
daniel@transgaming.comb9bb2792012-11-28 19:36:49 +0000254}
255
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000256void Renderer11::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState)
257{
258 // TODO
259 UNIMPLEMENTED();
260}
261
262void Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *texture)
263{
264 // TODO
265 UNIMPLEMENTED();
266}
267
daniel@transgaming.com237bc7e2012-11-28 21:01:06 +0000268void Renderer11::setRasterizerState(const gl::RasterizerState &rasterState)
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000269{
daniel@transgaming.com237bc7e2012-11-28 21:01:06 +0000270 if (mForceSetRasterState || memcmp(&rasterState, &mCurRasterState, sizeof(gl::RasterizerState)) != 0)
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000271 {
daniel@transgaming.com237bc7e2012-11-28 21:01:06 +0000272 ID3D11RasterizerState *dxRasterState = mStateCache.getRasterizerState(rasterState, mCurDepthSize);
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000273 if (!dxRasterState)
274 {
275 ERR("NULL blend state returned by RenderStateCache::getRasterizerState, setting the "
276 "rasterizer state.");
277 }
278
279 mDeviceContext->RSSetState(dxRasterState);
280
281 if (dxRasterState)
282 {
283 dxRasterState->Release();
284 }
285 mCurRasterState = rasterState;
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000286 }
287
288 mForceSetRasterState = false;
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000289}
290
291void Renderer11::setBlendState(const gl::BlendState &blendState, const gl::Color &blendColor,
292 unsigned int sampleMask)
293{
daniel@transgaming.comf8ba1092012-11-28 19:37:53 +0000294 if (mForceSetBlendState ||
295 memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0 ||
296 memcmp(&blendColor, &mCurBlendColor, sizeof(gl::Color)) != 0 ||
297 sampleMask != mCurSampleMask)
298 {
299 ID3D11BlendState *dxBlendState = mStateCache.getBlendState(blendState);
300 if (!dxBlendState)
301 {
302 ERR("NULL blend state returned by RenderStateCache::getBlendState, setting the default "
303 "blend state.");
304 }
305
306 const float blendColors[] = { blendColor.red, blendColor.green, blendColor.blue, blendColor.alpha };
307 mDeviceContext->OMSetBlendState(dxBlendState, blendColors, sampleMask);
308
309 if (dxBlendState)
310 {
311 dxBlendState->Release();
312 }
313 mCurBlendState = blendState;
314 mCurBlendColor = blendColor;
315 mCurSampleMask = sampleMask;
316 }
317
318 mForceSetBlendState = false;
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000319}
320
daniel@transgaming.com08c331d2012-11-28 19:38:39 +0000321void Renderer11::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
daniel@transgaming.com3a0ef482012-11-28 21:01:20 +0000322 int stencilBackRef, bool frontFaceCCW)
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000323{
daniel@transgaming.com5503fd02012-11-28 19:38:57 +0000324 if (mForceSetDepthStencilState ||
325 memcmp(&depthStencilState, &mCurDepthStencilState, sizeof(gl::DepthStencilState)) != 0 ||
326 stencilRef != mCurStencilRef || stencilBackRef != mCurStencilBackRef)
327 {
328 if (depthStencilState.stencilWritemask != depthStencilState.stencilBackWritemask ||
329 stencilRef != stencilBackRef ||
330 depthStencilState.stencilMask != depthStencilState.stencilBackMask)
331 {
332 ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are "
333 "invalid under WebGL.");
334 return error(GL_INVALID_OPERATION);
335 }
336
337 ID3D11DepthStencilState *dxDepthStencilState = mStateCache.getDepthStencilState(depthStencilState);
338 if (!dxDepthStencilState)
339 {
340 ERR("NULL depth stencil state returned by RenderStateCache::getDepthStencilState, "
341 "setting the default depth stencil state.");
342 }
343
344 mDeviceContext->OMSetDepthStencilState(dxDepthStencilState, static_cast<UINT>(stencilRef));
345
346 if (dxDepthStencilState)
347 {
348 dxDepthStencilState->Release();
349 }
350 mCurDepthStencilState = depthStencilState;
351 mCurStencilRef = stencilRef;
352 mCurStencilBackRef = stencilBackRef;
353 }
354
355 mForceSetDepthStencilState = false;
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000356}
357
daniel@transgaming.com04f1b332012-11-28 21:00:40 +0000358void Renderer11::setScissorRectangle(const gl::Rectangle &scissor)
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000359{
daniel@transgaming.com04f1b332012-11-28 21:00:40 +0000360 if (mForceSetScissor || memcmp(&scissor, &mCurScissor, sizeof(gl::Rectangle)) != 0)
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000361 {
362 D3D11_RECT rect;
daniel@transgaming.com04f1b332012-11-28 21:00:40 +0000363 rect.left = gl::clamp(scissor.x, 0, static_cast<int>(mRenderTargetDesc.width));
364 rect.top = gl::clamp(scissor.y, 0, static_cast<int>(mRenderTargetDesc.height));
365 rect.right = gl::clamp(scissor.x + scissor.width, 0, static_cast<int>(mRenderTargetDesc.width));
366 rect.bottom = gl::clamp(scissor.y + scissor.height, 0, static_cast<int>(mRenderTargetDesc.height));
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000367
368 mDeviceContext->RSSetScissorRects(1, &rect);
369
370 mCurScissor = scissor;
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000371 }
372
373 mForceSetScissor = false;
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000374}
375
daniel@transgaming.com4c4ce232012-11-28 21:01:40 +0000376bool Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, bool ignoreViewport,
daniel@transgaming.com83e80ee2012-11-28 19:40:53 +0000377 gl::ProgramBinary *currentProgram, bool forceSetUniforms)
378{
daniel@transgaming.com4c4ce232012-11-28 21:01:40 +0000379 gl::Rectangle actualViewport = viewport;
380 float actualZNear = gl::clamp01(zNear);
381 float actualZFar = gl::clamp01(zFar);
382 if (ignoreViewport)
383 {
384 actualViewport.x = 0;
385 actualViewport.y = 0;
386 actualViewport.width = mRenderTargetDesc.width;
387 actualViewport.height = mRenderTargetDesc.height;
388 actualZNear = 0.0f;
389 actualZFar = 1.0f;
390 }
daniel@transgaming.com53670042012-11-28 20:55:51 +0000391
392 D3D11_VIEWPORT dxViewport;
daniel@transgaming.com4c4ce232012-11-28 21:01:40 +0000393 dxViewport.TopLeftX = gl::clamp(actualViewport.x, 0, static_cast<int>(mRenderTargetDesc.width));
394 dxViewport.TopLeftY = gl::clamp(actualViewport.y, 0, static_cast<int>(mRenderTargetDesc.height));
395 dxViewport.Width = gl::clamp(actualViewport.width, 0, static_cast<int>(mRenderTargetDesc.width) - static_cast<int>(dxViewport.TopLeftX));
396 dxViewport.Height = gl::clamp(actualViewport.height, 0, static_cast<int>(mRenderTargetDesc.height) - static_cast<int>(dxViewport.TopLeftY));
397 dxViewport.MinDepth = actualZNear;
398 dxViewport.MaxDepth = actualZFar;
daniel@transgaming.com53670042012-11-28 20:55:51 +0000399
400 if (dxViewport.Width <= 0 || dxViewport.Height <= 0)
401 {
402 return false; // Nothing to render
403 }
404
daniel@transgaming.com4c4ce232012-11-28 21:01:40 +0000405 bool viewportChanged = mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 ||
406 actualZNear != mCurNear || actualZFar != mCurFar;
407
daniel@transgaming.com53670042012-11-28 20:55:51 +0000408 if (viewportChanged)
409 {
410 mDeviceContext->RSSetViewports(1, &dxViewport);
411
daniel@transgaming.com4c4ce232012-11-28 21:01:40 +0000412 mCurViewport = actualViewport;
413 mCurNear = actualZNear;
414 mCurFar = actualZFar;
daniel@transgaming.com53670042012-11-28 20:55:51 +0000415 }
416
417 if (currentProgram && (viewportChanged || forceSetUniforms))
418 {
419 GLint halfPixelSize = currentProgram->getDxHalfPixelSizeLocation();
420 GLfloat xy[2] = { 0.0f, 0.0f };
421 currentProgram->setUniform2fv(halfPixelSize, 1, xy);
422
423 // These values are used for computing gl_FragCoord in Program::linkVaryings().
424 GLint coord = currentProgram->getDxCoordLocation();
daniel@transgaming.com4c4ce232012-11-28 21:01:40 +0000425 GLfloat whxy[4] = { actualViewport.width * 0.5f,
426 actualViewport.height * 0.5f,
427 actualViewport.x + (actualViewport.width * 0.5f),
428 actualViewport.y + (actualViewport.height * 0.5f) };
daniel@transgaming.com53670042012-11-28 20:55:51 +0000429 currentProgram->setUniform4fv(coord, 1, whxy);
430
431 GLint depth = currentProgram->getDxDepthLocation();
daniel@transgaming.com4c4ce232012-11-28 21:01:40 +0000432 GLfloat dz[2] = { (actualZFar - actualZNear) * 0.5f, (actualZNear + actualZFar) * 0.5f };
daniel@transgaming.com53670042012-11-28 20:55:51 +0000433 currentProgram->setUniform2fv(depth, 1, dz);
434
435 GLint depthRange = currentProgram->getDxDepthRangeLocation();
daniel@transgaming.com4c4ce232012-11-28 21:01:40 +0000436 GLfloat nearFarDiff[3] = { actualZNear, actualZFar, actualZFar - actualZNear };
daniel@transgaming.com53670042012-11-28 20:55:51 +0000437 currentProgram->setUniform3fv(depthRange, 1, nearFarDiff);
438 }
439
440 mForceSetViewport = false;
daniel@transgaming.com83e80ee2012-11-28 19:40:53 +0000441 return true;
442}
443
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000444bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count)
445{
daniel@transgaming.comc52be632012-11-28 21:04:28 +0000446 D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000447
daniel@transgaming.com0b03b062012-11-28 21:03:49 +0000448 switch (mode)
449 {
daniel@transgaming.comc52be632012-11-28 21:04:28 +0000450 case GL_POINTS: primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; break;
451 case GL_LINES: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINELIST; break;
daniel@transgaming.com0b03b062012-11-28 21:03:49 +0000452 case GL_LINE_LOOP: UNIMPLEMENTED(); /* TODO */ break;
daniel@transgaming.comc52be632012-11-28 21:04:28 +0000453 case GL_LINE_STRIP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; break;
454 case GL_TRIANGLES: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; break;
455 case GL_TRIANGLE_STRIP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; break;
daniel@transgaming.com0b03b062012-11-28 21:03:49 +0000456 case GL_TRIANGLE_FAN: UNIMPLEMENTED(); /* TODO */ break;
457 default:
458 return error(GL_INVALID_ENUM, false);
459 }
460
daniel@transgaming.comc52be632012-11-28 21:04:28 +0000461 mDeviceContext->IASetPrimitiveTopology(primitiveTopology);
daniel@transgaming.com0b03b062012-11-28 21:03:49 +0000462
463 return count > 0;
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000464}
465
466bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer)
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000467{
daniel@transgaming.com80fc3322012-11-28 21:02:13 +0000468 // Get the color render buffer and serial
469 gl::Renderbuffer *renderbufferObject = NULL;
470 unsigned int renderTargetSerial = 0;
471 if (framebuffer->getColorbufferType() != GL_NONE)
472 {
473 renderbufferObject = framebuffer->getColorbuffer();
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000474
daniel@transgaming.com80fc3322012-11-28 21:02:13 +0000475 if (!renderbufferObject)
476 {
477 ERR("render target pointer unexpectedly null.");
daniel@transgaming.come9c71b42012-11-28 21:02:23 +0000478 return false;
daniel@transgaming.com80fc3322012-11-28 21:02:13 +0000479 }
480
481 renderTargetSerial = renderbufferObject->getSerial();
482 }
483
484 // Get the depth stencil render buffer and serials
485 gl::Renderbuffer *depthStencil = NULL;
486 unsigned int depthbufferSerial = 0;
487 unsigned int stencilbufferSerial = 0;
488 if (framebuffer->getDepthbufferType() != GL_NONE)
489 {
490 depthStencil = framebuffer->getDepthbuffer();
491 if (!depthStencil)
492 {
493 ERR("Depth stencil pointer unexpectedly null.");
494 return false;
495 }
496
497 depthbufferSerial = depthStencil->getSerial();
498 }
499 else if (framebuffer->getStencilbufferType() != GL_NONE)
500 {
501 depthStencil = framebuffer->getStencilbuffer();
502 if (!depthStencil)
503 {
504 ERR("Depth stencil pointer unexpectedly null.");
505 return false;
506 }
507
508 stencilbufferSerial = depthStencil->getSerial();
509 }
510
511 // Extract the render target dimensions and view
512 unsigned int renderTargetWidth = 0;
513 unsigned int renderTargetHeight = 0;
514 GLenum renderTargetFormat = 0;
515 ID3D11RenderTargetView* framebufferRTV = NULL;
516 if (renderbufferObject)
517 {
518 RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(renderbufferObject->getRenderTarget());
519 if (!renderTarget)
520 {
521 ERR("render target pointer unexpectedly null.");
522 return false;
523 }
524
525 framebufferRTV = renderTarget->getRenderTargetView();
526 if (!framebufferRTV)
527 {
528 ERR("render target view pointer unexpectedly null.");
529 return false;
530 }
531
532 renderTargetWidth = renderbufferObject->getWidth();
533 renderTargetHeight = renderbufferObject->getHeight();
534 renderTargetFormat = renderbufferObject->getActualFormat();
535 }
536
537 // Extract the depth stencil sizes and view
538 unsigned int depthSize = 0;
539 unsigned int stencilSize = 0;
540 ID3D11DepthStencilView* framebufferDSV = NULL;
541 if (depthStencil)
542 {
543 RenderTarget11 *depthStencilRenderTarget = RenderTarget11::makeRenderTarget11(depthStencil->getDepthStencil());
544 if (!depthStencilRenderTarget)
545 {
546 ERR("render target pointer unexpectedly null.");
547 if (framebufferRTV)
548 {
549 framebufferRTV->Release();
550 }
551 return false;
552 }
553
554 framebufferDSV = depthStencilRenderTarget->getDepthStencilView();
555 if (!framebufferDSV)
556 {
557 ERR("depth stencil view pointer unexpectedly null.");
558 if (framebufferRTV)
559 {
560 framebufferRTV->Release();
561 }
562 return false;
563 }
564
565 // If there is no render buffer, the width, height and format values come from
566 // the depth stencil
567 if (!renderbufferObject)
568 {
569 renderTargetWidth = depthStencil->getWidth();
570 renderTargetHeight = depthStencil->getHeight();
571 renderTargetFormat = depthStencil->getActualFormat();
572 }
573
574 depthSize = depthStencil->getDepthSize();
575 stencilSize = depthStencil->getStencilSize();
576 }
577
578 // Apply the render target and depth stencil
579 if (!mRenderTargetDescInitialized || !mDepthStencilInitialized ||
580 renderTargetSerial != mAppliedRenderTargetSerial ||
581 depthbufferSerial != mAppliedDepthbufferSerial ||
582 stencilbufferSerial != mAppliedStencilbufferSerial)
583 {
584 mDeviceContext->OMSetRenderTargets(1, &framebufferRTV, framebufferDSV);
585
586 mRenderTargetDesc.width = renderTargetWidth;
587 mRenderTargetDesc.height = renderTargetHeight;
588 mRenderTargetDesc.format = renderTargetFormat;
589 mForceSetViewport = true; // TODO: It may not be required to clamp the viewport in D3D11
590 mForceSetScissor = true; // TODO: It may not be required to clamp the scissor in D3D11
591
592 if (!mDepthStencilInitialized || depthSize != mCurDepthSize)
593 {
594 mCurDepthSize = depthSize;
595 mForceSetRasterState = true;
596 }
597
598 mCurStencilSize = stencilSize;
599
600 mAppliedRenderTargetSerial = renderTargetSerial;
601 mAppliedDepthbufferSerial = depthbufferSerial;
602 mAppliedStencilbufferSerial = stencilbufferSerial;
603 mRenderTargetDescInitialized = true;
604 mDepthStencilInitialized = true;
605 }
606
607 if (framebufferRTV)
608 {
609 framebufferRTV->Release();
610 }
611 if (framebufferDSV)
612 {
613 framebufferDSV->Release();
614 }
daniel@transgaming.comae39ee22012-11-28 19:42:02 +0000615
616 return true;
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000617}
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000618
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000619GLenum Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances)
daniel@transgaming.comdef9f0f2012-11-28 20:53:20 +0000620{
daniel@transgaming.com18adad02012-11-28 21:04:03 +0000621 // TODO: Create/update vertex buffers for arbitrary GL attributes
622 ASSERT(vertexAttributes[0].mBoundBuffer.get() == 0); // UNIMPLEMENTED();
623
624 UINT stride = vertexAttributes[0].mStride != 0 ? vertexAttributes[0].mStride : vertexAttributes[0].typeSize();
625 UINT size = stride * count;
626
627 D3D11_BUFFER_DESC vertexBufferDescription = {0};
628 vertexBufferDescription.ByteWidth = size;
629 vertexBufferDescription.Usage = D3D11_USAGE_DYNAMIC;
630 vertexBufferDescription.BindFlags = D3D11_BIND_VERTEX_BUFFER;
631 vertexBufferDescription.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
632 vertexBufferDescription.MiscFlags = 0;
633 vertexBufferDescription.StructureByteStride = 0;
634
635 ID3D11Buffer *vertexBuffer = NULL;
636 HRESULT result = mDevice->CreateBuffer(&vertexBufferDescription, NULL, &vertexBuffer);
637 ASSERT(SUCCEEDED(result));
638
639 D3D11_MAPPED_SUBRESOURCE map;
640 result = mDeviceContext->Map(vertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
641 ASSERT(SUCCEEDED(result));
642 memcpy(map.pData, vertexAttributes[0].mPointer, size);
643 mDeviceContext->Unmap(vertexBuffer, 0);
644
645 UINT offset = 0;
646 mDeviceContext->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);
647 vertexBuffer->Release();
648
daniel@transgaming.comda495a12012-11-28 21:03:56 +0000649 // TODO: Build the input layout from the (translated) attribute information
650 D3D11_INPUT_ELEMENT_DESC inputElementDescriptions[1] =
651 {
652 {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}
653 };
654
daniel@transgaming.com7b18d0c2012-11-28 21:04:10 +0000655 ShaderExecutable *vertexExecutable = programBinary->getVertexExecutable();
656
daniel@transgaming.comda495a12012-11-28 21:03:56 +0000657 ID3D11InputLayout *inputLayout = NULL;
daniel@transgaming.com7b18d0c2012-11-28 21:04:10 +0000658 result = mDevice->CreateInputLayout(inputElementDescriptions, 1, vertexExecutable->getFunction(), vertexExecutable->getLength(), &inputLayout);
daniel@transgaming.com18adad02012-11-28 21:04:03 +0000659 ASSERT(SUCCEEDED(result));
daniel@transgaming.comda495a12012-11-28 21:03:56 +0000660
661 mDeviceContext->IASetInputLayout(inputLayout);
662 inputLayout->Release(); // TODO: Build a cache of input layouts
663
daniel@transgaming.com18adad02012-11-28 21:04:03 +0000664 return GL_NO_ERROR;
daniel@transgaming.comdef9f0f2012-11-28 20:53:20 +0000665}
666
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000667GLenum Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, gl::TranslatedIndexData *indexInfo)
668{
669 // TODO
670 UNIMPLEMENTED();
671
672 return GL_OUT_OF_MEMORY;
673}
674
675void Renderer11::drawArrays(GLenum mode, GLsizei count, GLsizei instances)
676{
daniel@transgaming.comd4cf2512012-11-28 21:05:41 +0000677 mDeviceContext->Draw(count, 0);
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000678}
679
daniel@transgaming.com97400dd2012-11-28 20:57:00 +0000680void Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const gl::TranslatedIndexData &indexInfo)
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000681{
682 // TODO
683 UNIMPLEMENTED();
684}
685
daniel@transgaming.com5fbf1772012-11-28 20:54:43 +0000686void Renderer11::applyShaders(gl::ProgramBinary *programBinary)
687{
daniel@transgaming.comd4b2db22012-11-28 21:05:15 +0000688 ShaderExecutable *vertexExe = programBinary->getVertexExecutable();
689 ShaderExecutable *pixelExe = programBinary->getPixelExecutable();
690
691 ID3D11VertexShader *vertexShader = NULL;
692 if (vertexExe) vertexShader = ShaderExecutable11::makeShaderExecutable11(vertexExe)->getVertexShader();
693
694 ID3D11PixelShader *pixelShader = NULL;
695 if (pixelExe) pixelShader = ShaderExecutable11::makeShaderExecutable11(pixelExe)->getPixelShader();
696
697 mDeviceContext->PSSetShader(pixelShader, NULL, 0);
698 mDeviceContext->VSSetShader(vertexShader, NULL, 0);
699 programBinary->dirtyAllUniforms();
daniel@transgaming.com5fbf1772012-11-28 20:54:43 +0000700}
701
daniel@transgaming.com084a2572012-11-28 20:55:17 +0000702void Renderer11::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer)
daniel@transgaming.comd084c622012-11-28 19:36:05 +0000703{
daniel@transgaming.com54e67542012-11-28 21:02:31 +0000704 if (clearParams.mask & GL_COLOR_BUFFER_BIT)
705 {
706 gl::Renderbuffer *renderbufferObject = frameBuffer->getColorbuffer();
707 if (renderbufferObject)
708 {
709 RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(renderbufferObject->getRenderTarget());
710 if (!renderTarget)
711 {
712 ERR("render target pointer unexpectedly null.");
713 return;
714 }
715
716 ID3D11RenderTargetView *framebufferRTV = renderTarget->getRenderTargetView();
717 if (!framebufferRTV)
718 {
719 ERR("render target view pointer unexpectedly null.");
720 return;
721 }
722
723 if (mCurScissor.x > 0 || mCurScissor.y > 0 ||
724 mCurScissor.x + mCurScissor.width < renderTarget->getWidth() ||
725 mCurScissor.y + mCurScissor.height < renderTarget->getHeight())
726 {
727 // TODO: clearing of subregion of render target
728 UNIMPLEMENTED();
729 }
730
731 bool alphaUnmasked = (gl::GetAlphaSize(mRenderTargetDesc.format) == 0) || clearParams.colorMaskAlpha;
732 const bool needMaskedColorClear = (clearParams.mask & GL_COLOR_BUFFER_BIT) &&
733 !(clearParams.colorMaskRed && clearParams.colorMaskGreen &&
734 clearParams.colorMaskBlue && alphaUnmasked);
735
736 if (needMaskedColorClear)
737 {
738 // TODO: masked color clearing
739 UNIMPLEMENTED();
740 }
741 else
742 {
743 const float clearValues[4] = { clearParams.colorClearValue.red,
744 clearParams.colorClearValue.green,
745 clearParams.colorClearValue.blue,
746 clearParams.colorClearValue.alpha };
747 mDeviceContext->ClearRenderTargetView(framebufferRTV, clearValues);
748 }
749
750 framebufferRTV->Release();
751 }
752 }
753 if (clearParams.mask & GL_DEPTH_BUFFER_BIT || clearParams.mask & GL_STENCIL_BUFFER_BIT)
754 {
755 gl::Renderbuffer *renderbufferObject = frameBuffer->getDepthOrStencilbuffer();
756 if (renderbufferObject)
757 {
758 RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(renderbufferObject->getRenderTarget());
759 if (!renderTarget)
760 {
761 ERR("render target pointer unexpectedly null.");
762 return;
763 }
764
765 ID3D11DepthStencilView *framebufferDSV = renderTarget->getDepthStencilView();
766 if (!framebufferDSV)
767 {
768 ERR("depth stencil view pointer unexpectedly null.");
769 return;
770 }
771
772 if (mCurScissor.x > 0 || mCurScissor.y > 0 ||
773 mCurScissor.x + mCurScissor.width < renderTarget->getWidth() ||
774 mCurScissor.y + mCurScissor.height < renderTarget->getHeight())
775 {
776 // TODO: clearing of subregion of depth stencil view
777 UNIMPLEMENTED();
778 }
779
780 unsigned int stencilUnmasked = 0x0;
781 if ((clearParams.mask & GL_STENCIL_BUFFER_BIT) && frameBuffer->hasStencil())
782 {
783 unsigned int stencilSize = gl::GetStencilSize(frameBuffer->getStencilbuffer()->getActualFormat());
784 stencilUnmasked = (0x1 << stencilSize) - 1;
785 }
786
787 const bool needMaskedStencilClear = (clearParams.mask & GL_STENCIL_BUFFER_BIT) &&
788 (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked;
789
790 if (needMaskedStencilClear)
791 {
792 // TODO: masked clearing of depth stencil
793 UNIMPLEMENTED();
794 }
795 else
796 {
797 UINT clearFlags = 0;
798 if (clearParams.mask & GL_DEPTH_BUFFER_BIT)
799 {
800 clearFlags |= D3D11_CLEAR_DEPTH;
801 }
802 if (clearParams.mask & GL_STENCIL_BUFFER_BIT)
803 {
804 clearFlags |= D3D11_CLEAR_STENCIL;
805 }
806
807 float depthClear = clearParams.depthClearValue;
808 UINT8 stencilClear = clearParams.stencilClearValue & 0x000000FF;
809
810 mDeviceContext->ClearDepthStencilView(framebufferDSV, clearFlags, depthClear, stencilClear);
811 }
812
813 framebufferDSV->Release();
814 }
815 }
daniel@transgaming.comd084c622012-11-28 19:36:05 +0000816}
817
daniel@transgaming.comc43a6052012-11-28 19:41:51 +0000818void Renderer11::markAllStateDirty()
819{
daniel@transgaming.com7b6b83e2012-11-28 21:00:30 +0000820 mDepthStencilInitialized = false;
821 mRenderTargetDescInitialized = false;
822
daniel@transgaming.comc43a6052012-11-28 19:41:51 +0000823 mForceSetBlendState = true;
824 mForceSetRasterState = true;
825 mForceSetDepthStencilState = true;
826 mForceSetScissor = true;
daniel@transgaming.com53670042012-11-28 20:55:51 +0000827 mForceSetViewport = true;
daniel@transgaming.comc43a6052012-11-28 19:41:51 +0000828}
829
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000830void Renderer11::releaseDeviceResources()
831{
832 // TODO
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000833 // UNIMPLEMENTED();
daniel@transgaming.comf8ba1092012-11-28 19:37:53 +0000834 mStateCache.clear();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000835}
836
837void Renderer11::markDeviceLost()
838{
839 mDeviceLost = true;
840}
841
842bool Renderer11::isDeviceLost()
843{
844 return mDeviceLost;
845}
846
847// set notify to true to broadcast a message to all contexts of the device loss
848bool Renderer11::testDeviceLost(bool notify)
849{
850 bool isLost = false;
851
852 // TODO
daniel@transgaming.comb9bb2792012-11-28 19:36:49 +0000853 //UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000854
855 if (isLost)
856 {
857 // ensure we note the device loss --
858 // we'll probably get this done again by markDeviceLost
859 // but best to remember it!
860 // Note that we don't want to clear the device loss status here
861 // -- this needs to be done by resetDevice
862 mDeviceLost = true;
863 if (notify)
864 {
865 mDisplay->notifyDeviceLost();
866 }
867 }
868
869 return isLost;
870}
871
872bool Renderer11::testDeviceResettable()
873{
874 HRESULT status = D3D_OK;
875
876 // TODO
877 UNIMPLEMENTED();
878
879 switch (status)
880 {
881 case D3DERR_DEVICENOTRESET:
882 case D3DERR_DEVICEHUNG:
883 return true;
884 default:
885 return false;
886 }
887}
888
889bool Renderer11::resetDevice()
890{
891 releaseDeviceResources();
892
893 // TODO
894 UNIMPLEMENTED();
895
896 // reset device defaults
897 initializeDevice();
898 mDeviceLost = false;
899
900 return true;
901}
902
903DWORD Renderer11::getAdapterVendor() const
904{
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000905 return mAdapterDescription.VendorId;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000906}
907
908const char *Renderer11::getAdapterDescription() const
909{
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000910 return mDescription;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000911}
912
913GUID Renderer11::getAdapterIdentifier() const
914{
915 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000916 // UNIMPLEMENTED();
917 GUID foo = {0};
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000918 return foo;
919}
920
921bool Renderer11::getDXT1TextureSupport()
922{
923 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000924 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000925 return false;
926}
927
928bool Renderer11::getDXT3TextureSupport()
929{
930 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000931 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000932 return false;
933}
934
935bool Renderer11::getDXT5TextureSupport()
936{
937 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000938 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000939 return false;
940}
941
942bool Renderer11::getDepthTextureSupport() const
943{
944 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000945 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000946 return false;
947}
948
949bool Renderer11::getFloat32TextureSupport(bool *filtering, bool *renderable)
950{
951 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000952 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000953
954 *filtering = false;
955 *renderable = false;
956 return false;
957}
958
959bool Renderer11::getFloat16TextureSupport(bool *filtering, bool *renderable)
960{
961 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000962 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000963
964 *filtering = false;
965 *renderable = false;
966 return false;
967}
968
969bool Renderer11::getLuminanceTextureSupport()
970{
971 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000972 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000973 return false;
974}
975
976bool Renderer11::getLuminanceAlphaTextureSupport()
977{
978 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000979 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000980 return false;
981}
982
983bool Renderer11::getTextureFilterAnisotropySupport() const
984{
985 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000986 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000987 return false;
988}
989
990float Renderer11::getTextureMaxAnisotropy() const
991{
992 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000993 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000994 return 1.0f;
995}
996
997bool Renderer11::getEventQuerySupport()
998{
999 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001000 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001001 return false;
1002}
1003
1004bool Renderer11::getVertexTextureSupport() const
1005{
1006 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001007 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001008 return false;
1009}
1010
1011bool Renderer11::getNonPower2TextureSupport() const
1012{
1013 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001014 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001015 return false;
1016}
1017
1018bool Renderer11::getOcclusionQuerySupport() const
1019{
1020 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001021 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001022 return false;
1023}
1024
1025bool Renderer11::getInstancingSupport() const
1026{
1027 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001028 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001029 return false;
1030}
1031
1032bool Renderer11::getShareHandleSupport() const
1033{
1034 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001035 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001036
1037 // PIX doesn't seem to support using share handles, so disable them.
1038 return false && !gl::perfActive();
1039}
1040
daniel@transgaming.com9549bea2012-11-28 20:57:23 +00001041int Renderer11::getMajorShaderModel() const
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001042{
daniel@transgaming.com9549bea2012-11-28 20:57:23 +00001043 switch (mFeatureLevel)
1044 {
1045 case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MAJOR_VERSION; // 5
1046 case D3D_FEATURE_LEVEL_10_1:
1047 case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MAJOR_VERSION; // 4
1048 default: UNREACHABLE(); return 0;
1049 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001050}
1051
1052float Renderer11::getMaxPointSize() const
1053{
1054 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001055 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001056 return 1.0f;
1057}
1058
1059int Renderer11::getMaxTextureWidth() const
1060{
daniel@transgaming.com25072f62012-11-28 19:31:32 +00001061 switch (mFeatureLevel)
1062 {
1063 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
1064 case D3D_FEATURE_LEVEL_10_1:
1065 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
1066 default: UNREACHABLE(); return 0;
1067 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001068}
1069
1070int Renderer11::getMaxTextureHeight() const
1071{
daniel@transgaming.com25072f62012-11-28 19:31:32 +00001072 switch (mFeatureLevel)
1073 {
1074 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
1075 case D3D_FEATURE_LEVEL_10_1:
1076 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
1077 default: UNREACHABLE(); return 0;
1078 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001079}
1080
1081bool Renderer11::get32BitIndexSupport() const
1082{
daniel@transgaming.com25072f62012-11-28 19:31:32 +00001083 switch (mFeatureLevel)
1084 {
1085 case D3D_FEATURE_LEVEL_11_0:
1086 case D3D_FEATURE_LEVEL_10_1:
1087 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP >= 32; // true
1088 default: UNREACHABLE(); return false;
1089 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001090}
1091
1092int Renderer11::getMinSwapInterval() const
1093{
daniel@transgaming.com8c7b1a92012-11-28 19:34:06 +00001094 return 0;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001095}
1096
1097int Renderer11::getMaxSwapInterval() const
1098{
daniel@transgaming.com8c7b1a92012-11-28 19:34:06 +00001099 return 4;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001100}
1101
1102int Renderer11::getMaxSupportedSamples() const
1103{
1104 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001105 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001106 return 1;
1107}
1108
daniel@transgaming.com31b13e12012-11-28 19:34:30 +00001109bool Renderer11::copyToRenderTarget(TextureStorage2D *dest, TextureStorage2D *source)
daniel@transgaming.comad6aee72012-11-28 19:33:42 +00001110{
1111 // TODO
1112 UNIMPLEMENTED();
1113 return false;
1114}
1115
daniel@transgaming.com31b13e12012-11-28 19:34:30 +00001116bool Renderer11::copyToRenderTarget(TextureStorageCubeMap *dest, TextureStorageCubeMap *source)
daniel@transgaming.comad6aee72012-11-28 19:33:42 +00001117{
1118 // TODO
1119 UNIMPLEMENTED();
1120 return false;
1121}
1122
daniel@transgaming.com38380882012-11-28 19:36:39 +00001123bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat,
1124 GLint xoffset, GLint yoffset, TextureStorage2D *storage, GLint level)
1125{
1126 // TODO
1127 UNIMPLEMENTED();
1128 return false;
1129}
1130
1131bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat,
1132 GLint xoffset, GLint yoffset, TextureStorageCubeMap *storage, GLenum target, GLint level)
1133{
1134 // TODO
1135 UNIMPLEMENTED();
1136 return false;
1137}
1138
daniel@transgaming.comf2423652012-11-28 20:53:50 +00001139RenderTarget *Renderer11::createRenderTarget(SwapChain *swapChain, bool depth)
1140{
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +00001141 SwapChain11 *swapChain11 = SwapChain11::makeSwapChain11(swapChain);
1142 RenderTarget11 *renderTarget = NULL;
1143 if (depth)
1144 {
1145 renderTarget = new RenderTarget11(this, swapChain11->getDepthStencil(), swapChain11->getWidth(), swapChain11->getHeight());
1146 }
1147 else
1148 {
1149 renderTarget = new RenderTarget11(this, swapChain11->getRenderTarget(), swapChain11->getWidth(), swapChain11->getHeight());
1150 }
1151 return renderTarget;
daniel@transgaming.comf2423652012-11-28 20:53:50 +00001152}
1153
1154RenderTarget *Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth)
1155{
1156 // TODO
1157 UNIMPLEMENTED();
1158 return NULL;
1159}
1160
daniel@transgaming.com7b18d0c2012-11-28 21:04:10 +00001161ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length, GLenum type, void *data)
daniel@transgaming.com55318902012-11-28 20:58:58 +00001162{
daniel@transgaming.coma2f9fbe2012-11-28 21:03:40 +00001163 ShaderExecutable11 *executable = NULL;
1164
1165 switch (type)
1166 {
1167 case GL_VERTEX_SHADER:
1168 {
1169 ID3D11VertexShader *vshader = NULL;
1170 HRESULT result = mDevice->CreateVertexShader(function, length, NULL, &vshader);
1171 ASSERT(SUCCEEDED(result));
1172
1173 if (vshader)
1174 {
daniel@transgaming.com7b18d0c2012-11-28 21:04:10 +00001175 executable = new ShaderExecutable11(function, length, vshader);
daniel@transgaming.coma2f9fbe2012-11-28 21:03:40 +00001176 }
1177 }
1178 break;
1179 case GL_FRAGMENT_SHADER:
1180 {
1181 ID3D11PixelShader *pshader = NULL;
1182 HRESULT result = mDevice->CreatePixelShader(function, length, NULL, &pshader);
1183 ASSERT(SUCCEEDED(result));
1184
1185 if (pshader)
1186 {
daniel@transgaming.com7b18d0c2012-11-28 21:04:10 +00001187 executable = new ShaderExecutable11(function, length, pshader);
daniel@transgaming.coma2f9fbe2012-11-28 21:03:40 +00001188 }
1189 }
1190 break;
1191 default:
1192 UNREACHABLE();
1193 break;
1194 }
1195
1196 return executable;
daniel@transgaming.com55318902012-11-28 20:58:58 +00001197}
1198
daniel@transgaming.coma9c71422012-11-28 20:58:45 +00001199ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, GLenum type)
1200{
daniel@transgaming.com071ee6a2012-11-28 21:03:21 +00001201 const char *profile = NULL;
1202
1203 switch (type)
1204 {
1205 case GL_VERTEX_SHADER:
1206 profile = "vs_4_0";
1207 break;
1208 case GL_FRAGMENT_SHADER:
1209 profile = "ps_4_0";
1210 break;
1211 default:
1212 UNREACHABLE();
1213 return NULL;
1214 }
1215
daniel@transgaming.com25e16af2012-11-28 21:05:57 +00001216 ID3DBlob *binary = compileToBinary(infoLog, shaderHLSL, profile, false);
daniel@transgaming.com071ee6a2012-11-28 21:03:21 +00001217 if (!binary)
1218 return NULL;
1219
1220 ShaderExecutable *executable = loadExecutable((DWORD *)binary->GetBufferPointer(), binary->GetBufferSize(), type, NULL);
1221 binary->Release();
1222
1223 return executable;
1224}
1225
daniel@transgaming.com6c872172012-11-28 19:39:33 +00001226bool Renderer11::blitRect(gl::Framebuffer *readTarget, gl::Rectangle *readRect, gl::Framebuffer *drawTarget, gl::Rectangle *drawRect,
1227 bool blitRenderTarget, bool blitDepthStencil)
1228{
1229 // TODO
1230 UNIMPLEMENTED();
1231 return false;
1232}
1233
1234void Renderer11::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
1235 GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels)
1236{
1237 // TODO
1238 UNIMPLEMENTED();
1239 return;
1240}
1241
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001242}