blob: e2a20bb3f6ff3ad92932751f71946954733319e5 [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.com2c4d0702012-12-20 21:08:51 +000023#include "libGLESv2/renderer/VertexBuffer11.h"
daniel@transgaming.com11c2af52012-12-20 21:10:01 +000024#include "libGLESv2/renderer/IndexBuffer11.h"
daniel@transgaming.comc5431eb2012-12-20 21:10:15 +000025#include "libGLESv2/renderer/VertexDataManager.h"
26#include "libGLESv2/renderer/IndexDataManager.h"
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000027
28#include "libEGL/Config.h"
29#include "libEGL/Display.h"
30
31namespace rx
32{
daniel@transgaming.com65e65372012-11-28 19:33:50 +000033static const DXGI_FORMAT RenderTargetFormats[] =
34 {
35 DXGI_FORMAT_R8G8B8A8_UNORM
36 };
37
38static const DXGI_FORMAT DepthStencilFormats[] =
39 {
40 DXGI_FORMAT_D24_UNORM_S8_UINT
41 };
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000042
43Renderer11::Renderer11(egl::Display *display, HDC hDc) : Renderer(display), mDc(hDc)
44{
daniel@transgaming.comc5431eb2012-12-20 21:10:15 +000045 mVertexDataManager = NULL;
46 mIndexDataManager = NULL;
47
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000048 mD3d11Module = NULL;
49 mDxgiModule = NULL;
50
daniel@transgaming.comb9bb2792012-11-28 19:36:49 +000051 mDeviceLost = false;
52
daniel@transgaming.com25072f62012-11-28 19:31:32 +000053 mDevice = NULL;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000054 mDeviceContext = NULL;
daniel@transgaming.com65e65372012-11-28 19:33:50 +000055 mDxgiAdapter = NULL;
56 mDxgiFactory = NULL;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000057}
58
59Renderer11::~Renderer11()
60{
61 releaseDeviceResources();
62
daniel@transgaming.com65e65372012-11-28 19:33:50 +000063 if (mDxgiFactory)
64 {
65 mDxgiFactory->Release();
66 mDxgiFactory = NULL;
67 }
68
69 if (mDxgiAdapter)
70 {
71 mDxgiAdapter->Release();
72 mDxgiAdapter = NULL;
73 }
74
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000075 if (mDeviceContext)
76 {
77 mDeviceContext->Release();
78 mDeviceContext = NULL;
79 }
80
daniel@transgaming.com25072f62012-11-28 19:31:32 +000081 if (mDevice)
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000082 {
daniel@transgaming.com25072f62012-11-28 19:31:32 +000083 mDevice->Release();
84 mDevice = NULL;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000085 }
86
87 if (mD3d11Module)
88 {
daniel@transgaming.comc1e26342012-11-28 19:31:16 +000089 FreeLibrary(mD3d11Module);
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000090 mD3d11Module = NULL;
91 }
92
93 if (mDxgiModule)
94 {
daniel@transgaming.comc1e26342012-11-28 19:31:16 +000095 FreeLibrary(mDxgiModule);
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000096 mDxgiModule = NULL;
97 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +000098}
99
daniel@transgaming.comb64ed282012-11-28 20:54:02 +0000100Renderer11 *Renderer11::makeRenderer11(Renderer *renderer)
101{
102 ASSERT(dynamic_cast<rx::Renderer11*>(renderer) != NULL);
103 return static_cast<rx::Renderer11*>(renderer);
104}
105
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000106EGLint Renderer11::initialize()
107{
daniel@transgaming.com25e16af2012-11-28 21:05:57 +0000108 if (!initializeCompiler())
109 {
110 return EGL_NOT_INITIALIZED;
111 }
112
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000113 mDxgiModule = LoadLibrary(TEXT("dxgi.dll"));
114 mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000115
116 if (mD3d11Module == NULL || mDxgiModule == NULL)
117 {
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000118 ERR("Could not load D3D11 or DXGI library - aborting!\n");
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000119 return EGL_NOT_INITIALIZED;
120 }
121
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000122 PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice");
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000123
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000124 if (D3D11CreateDevice == NULL)
125 {
126 ERR("Could not retrieve D3D11CreateDevice address - aborting!\n");
127 return EGL_NOT_INITIALIZED;
128 }
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000129
130 D3D_FEATURE_LEVEL featureLevel[] =
131 {
132 D3D_FEATURE_LEVEL_11_0,
133 D3D_FEATURE_LEVEL_10_1,
134 D3D_FEATURE_LEVEL_10_0,
135 };
136
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000137 HRESULT result = D3D11CreateDevice(NULL,
138 D3D_DRIVER_TYPE_HARDWARE,
139 NULL,
daniel@transgaming.coma60160b2012-11-28 19:41:15 +0000140 #if defined(_DEBUG)
141 D3D11_CREATE_DEVICE_DEBUG,
142 #else
143 0,
144 #endif
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000145 featureLevel,
146 sizeof(featureLevel)/sizeof(featureLevel[0]),
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000147 D3D11_SDK_VERSION,
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000148 &mDevice,
149 &mFeatureLevel,
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000150 &mDeviceContext);
daniel@transgaming.com25072f62012-11-28 19:31:32 +0000151
152 if (!mDevice || FAILED(result))
daniel@transgaming.comc1e26342012-11-28 19:31:16 +0000153 {
154 ERR("Could not create D3D11 device - aborting!\n");
155 return EGL_NOT_INITIALIZED; // Cleanup done by destructor through glDestroyRenderer
156 }
daniel@transgaming.com65e65372012-11-28 19:33:50 +0000157
158 IDXGIDevice *dxgiDevice = NULL;
159 result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
160
161 if (FAILED(result))
162 {
163 ERR("Could not query DXGI device - aborting!\n");
164 return EGL_NOT_INITIALIZED;
165 }
166
167 result = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&mDxgiAdapter);
168
169 if (FAILED(result))
170 {
171 ERR("Could not retrieve DXGI adapter - aborting!\n");
172 return EGL_NOT_INITIALIZED;
173 }
174
175 dxgiDevice->Release();
176
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000177 mDxgiAdapter->GetDesc(&mAdapterDescription);
178 memset(mDescription, 0, sizeof(mDescription));
179 wcstombs(mDescription, mAdapterDescription.Description, sizeof(mDescription) - 1);
180
daniel@transgaming.com65e65372012-11-28 19:33:50 +0000181 result = mDxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&mDxgiFactory);
182
183 if (!mDxgiFactory || FAILED(result))
184 {
185 ERR("Could not create DXGI factory - aborting!\n");
186 return EGL_NOT_INITIALIZED;
187 }
188
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000189 initializeDevice();
190
191 return EGL_SUCCESS;
192}
193
194// do any one-time device initialization
195// NOTE: this is also needed after a device lost/reset
196// to reset the scene status and ensure the default states are reset.
197void Renderer11::initializeDevice()
198{
daniel@transgaming.comf8ba1092012-11-28 19:37:53 +0000199 mStateCache.initialize(mDevice);
daniel@transgaming.comc5431eb2012-12-20 21:10:15 +0000200 mInputLayoutCache.initialize(mDevice, mDeviceContext);
201
202 ASSERT(!mVertexDataManager && !mIndexDataManager);
203 mVertexDataManager = new VertexDataManager(this);
204 mIndexDataManager = new IndexDataManager(this);
daniel@transgaming.comf8ba1092012-11-28 19:37:53 +0000205
daniel@transgaming.comc43a6052012-11-28 19:41:51 +0000206 markAllStateDirty();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000207}
208
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000209int Renderer11::generateConfigs(ConfigDesc **configDescList)
210{
daniel@transgaming.come3e826d2012-11-28 19:42:35 +0000211 unsigned int numRenderFormats = sizeof(RenderTargetFormats) / sizeof(RenderTargetFormats[0]);
212 unsigned int numDepthFormats = sizeof(DepthStencilFormats) / sizeof(DepthStencilFormats[0]);
daniel@transgaming.com65e65372012-11-28 19:33:50 +0000213 (*configDescList) = new ConfigDesc[numRenderFormats * numDepthFormats];
214 int numConfigs = 0;
215
daniel@transgaming.come3e826d2012-11-28 19:42:35 +0000216 for (unsigned int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++)
daniel@transgaming.com65e65372012-11-28 19:33:50 +0000217 {
daniel@transgaming.come3e826d2012-11-28 19:42:35 +0000218 for (unsigned int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++)
daniel@transgaming.com65e65372012-11-28 19:33:50 +0000219 {
220 DXGI_FORMAT renderTargetFormat = RenderTargetFormats[formatIndex];
221
222 UINT formatSupport = 0;
223 HRESULT result = mDevice->CheckFormatSupport(renderTargetFormat, &formatSupport);
224
225 if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET))
226 {
227 DXGI_FORMAT depthStencilFormat = DepthStencilFormats[depthStencilIndex];
228
229 UINT formatSupport = 0;
230 HRESULT result = mDevice->CheckFormatSupport(depthStencilFormat, &formatSupport);
231
232 if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL))
233 {
234 ConfigDesc newConfig;
235 newConfig.renderTargetFormat = d3d11_gl::ConvertBackBufferFormat(renderTargetFormat);
236 newConfig.depthStencilFormat = d3d11_gl::ConvertDepthStencilFormat(depthStencilFormat);
237 newConfig.multiSample = 0; // FIXME: enumerate multi-sampling
238 newConfig.fastConfig = true; // Assume all DX11 format conversions to be fast
239
240 (*configDescList)[numConfigs++] = newConfig;
241 }
242 }
243 }
244 }
245
246 return numConfigs;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000247}
248
249void Renderer11::deleteConfigs(ConfigDesc *configDescList)
250{
251 delete [] (configDescList);
252}
253
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000254void Renderer11::sync(bool block)
255{
256 // TODO
257 UNIMPLEMENTED();
258}
259
daniel@transgaming.comb9bb2792012-11-28 19:36:49 +0000260SwapChain *Renderer11::createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
261{
daniel@transgaming.coma60160b2012-11-28 19:41:15 +0000262 return new rx::SwapChain11(this, window, shareHandle, backBufferFormat, depthBufferFormat);
daniel@transgaming.comb9bb2792012-11-28 19:36:49 +0000263}
264
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000265void Renderer11::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState)
266{
267 // TODO
268 UNIMPLEMENTED();
269}
270
271void Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *texture)
272{
273 // TODO
274 UNIMPLEMENTED();
275}
276
daniel@transgaming.com237bc7e2012-11-28 21:01:06 +0000277void Renderer11::setRasterizerState(const gl::RasterizerState &rasterState)
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000278{
daniel@transgaming.com237bc7e2012-11-28 21:01:06 +0000279 if (mForceSetRasterState || memcmp(&rasterState, &mCurRasterState, sizeof(gl::RasterizerState)) != 0)
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000280 {
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000281 ID3D11RasterizerState *dxRasterState = mStateCache.getRasterizerState(rasterState, mScissorEnabled,
282 mCurDepthSize);
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000283 if (!dxRasterState)
284 {
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000285 ERR("NULL blend state returned by RenderStateCache::getRasterizerState, setting the default"
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000286 "rasterizer state.");
287 }
288
289 mDeviceContext->RSSetState(dxRasterState);
290
291 if (dxRasterState)
292 {
293 dxRasterState->Release();
294 }
295 mCurRasterState = rasterState;
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000296 }
297
298 mForceSetRasterState = false;
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000299}
300
301void Renderer11::setBlendState(const gl::BlendState &blendState, const gl::Color &blendColor,
302 unsigned int sampleMask)
303{
daniel@transgaming.comf8ba1092012-11-28 19:37:53 +0000304 if (mForceSetBlendState ||
305 memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0 ||
306 memcmp(&blendColor, &mCurBlendColor, sizeof(gl::Color)) != 0 ||
307 sampleMask != mCurSampleMask)
308 {
309 ID3D11BlendState *dxBlendState = mStateCache.getBlendState(blendState);
310 if (!dxBlendState)
311 {
312 ERR("NULL blend state returned by RenderStateCache::getBlendState, setting the default "
313 "blend state.");
314 }
315
316 const float blendColors[] = { blendColor.red, blendColor.green, blendColor.blue, blendColor.alpha };
317 mDeviceContext->OMSetBlendState(dxBlendState, blendColors, sampleMask);
318
319 if (dxBlendState)
320 {
321 dxBlendState->Release();
322 }
323 mCurBlendState = blendState;
324 mCurBlendColor = blendColor;
325 mCurSampleMask = sampleMask;
326 }
327
328 mForceSetBlendState = false;
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000329}
330
daniel@transgaming.com08c331d2012-11-28 19:38:39 +0000331void Renderer11::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
daniel@transgaming.com3a0ef482012-11-28 21:01:20 +0000332 int stencilBackRef, bool frontFaceCCW)
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000333{
daniel@transgaming.com5503fd02012-11-28 19:38:57 +0000334 if (mForceSetDepthStencilState ||
335 memcmp(&depthStencilState, &mCurDepthStencilState, sizeof(gl::DepthStencilState)) != 0 ||
336 stencilRef != mCurStencilRef || stencilBackRef != mCurStencilBackRef)
337 {
338 if (depthStencilState.stencilWritemask != depthStencilState.stencilBackWritemask ||
339 stencilRef != stencilBackRef ||
340 depthStencilState.stencilMask != depthStencilState.stencilBackMask)
341 {
342 ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are "
343 "invalid under WebGL.");
344 return error(GL_INVALID_OPERATION);
345 }
346
347 ID3D11DepthStencilState *dxDepthStencilState = mStateCache.getDepthStencilState(depthStencilState);
348 if (!dxDepthStencilState)
349 {
350 ERR("NULL depth stencil state returned by RenderStateCache::getDepthStencilState, "
351 "setting the default depth stencil state.");
352 }
353
354 mDeviceContext->OMSetDepthStencilState(dxDepthStencilState, static_cast<UINT>(stencilRef));
355
356 if (dxDepthStencilState)
357 {
358 dxDepthStencilState->Release();
359 }
360 mCurDepthStencilState = depthStencilState;
361 mCurStencilRef = stencilRef;
362 mCurStencilBackRef = stencilBackRef;
363 }
364
365 mForceSetDepthStencilState = false;
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000366}
367
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000368void Renderer11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled)
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000369{
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000370 if (mForceSetScissor || memcmp(&scissor, &mCurScissor, sizeof(gl::Rectangle)) != 0 ||
371 enabled != mScissorEnabled)
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000372 {
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000373 if (enabled)
374 {
375 D3D11_RECT rect;
376 rect.left = gl::clamp(scissor.x, 0, static_cast<int>(mRenderTargetDesc.width));
377 rect.top = gl::clamp(scissor.y, 0, static_cast<int>(mRenderTargetDesc.height));
378 rect.right = gl::clamp(scissor.x + scissor.width, 0, static_cast<int>(mRenderTargetDesc.width));
379 rect.bottom = gl::clamp(scissor.y + scissor.height, 0, static_cast<int>(mRenderTargetDesc.height));
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000380
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000381 mDeviceContext->RSSetScissorRects(1, &rect);
382 }
383
384 if (enabled != mScissorEnabled)
385 {
386 mForceSetRasterState = true;
387 }
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000388
389 mCurScissor = scissor;
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000390 mScissorEnabled = enabled;
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000391 }
392
393 mForceSetScissor = false;
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000394}
395
daniel@transgaming.com12985182012-12-20 20:56:31 +0000396bool Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
397 bool ignoreViewport, gl::ProgramBinary *currentProgram, bool forceSetUniforms)
daniel@transgaming.com83e80ee2012-11-28 19:40:53 +0000398{
daniel@transgaming.com4c4ce232012-11-28 21:01:40 +0000399 gl::Rectangle actualViewport = viewport;
400 float actualZNear = gl::clamp01(zNear);
401 float actualZFar = gl::clamp01(zFar);
402 if (ignoreViewport)
403 {
404 actualViewport.x = 0;
405 actualViewport.y = 0;
406 actualViewport.width = mRenderTargetDesc.width;
407 actualViewport.height = mRenderTargetDesc.height;
408 actualZNear = 0.0f;
409 actualZFar = 1.0f;
410 }
daniel@transgaming.com53670042012-11-28 20:55:51 +0000411
412 D3D11_VIEWPORT dxViewport;
daniel@transgaming.com4c4ce232012-11-28 21:01:40 +0000413 dxViewport.TopLeftX = gl::clamp(actualViewport.x, 0, static_cast<int>(mRenderTargetDesc.width));
414 dxViewport.TopLeftY = gl::clamp(actualViewport.y, 0, static_cast<int>(mRenderTargetDesc.height));
415 dxViewport.Width = gl::clamp(actualViewport.width, 0, static_cast<int>(mRenderTargetDesc.width) - static_cast<int>(dxViewport.TopLeftX));
416 dxViewport.Height = gl::clamp(actualViewport.height, 0, static_cast<int>(mRenderTargetDesc.height) - static_cast<int>(dxViewport.TopLeftY));
417 dxViewport.MinDepth = actualZNear;
418 dxViewport.MaxDepth = actualZFar;
daniel@transgaming.com53670042012-11-28 20:55:51 +0000419
420 if (dxViewport.Width <= 0 || dxViewport.Height <= 0)
421 {
422 return false; // Nothing to render
423 }
424
daniel@transgaming.com4c4ce232012-11-28 21:01:40 +0000425 bool viewportChanged = mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 ||
426 actualZNear != mCurNear || actualZFar != mCurFar;
427
daniel@transgaming.com53670042012-11-28 20:55:51 +0000428 if (viewportChanged)
429 {
430 mDeviceContext->RSSetViewports(1, &dxViewport);
431
daniel@transgaming.com4c4ce232012-11-28 21:01:40 +0000432 mCurViewport = actualViewport;
433 mCurNear = actualZNear;
434 mCurFar = actualZFar;
daniel@transgaming.com53670042012-11-28 20:55:51 +0000435 }
436
437 if (currentProgram && (viewportChanged || forceSetUniforms))
438 {
daniel@transgaming.com88853c52012-12-20 20:56:40 +0000439 currentProgram->applyDxHalfPixelSize(0.0f, 0.0f);
daniel@transgaming.com53670042012-11-28 20:55:51 +0000440
441 // These values are used for computing gl_FragCoord in Program::linkVaryings().
daniel@transgaming.com88853c52012-12-20 20:56:40 +0000442 currentProgram->applyDxCoord(actualViewport.width * 0.5f,
443 actualViewport.height * 0.5f,
444 actualViewport.x + (actualViewport.width * 0.5f),
445 actualViewport.y + (actualViewport.height * 0.5f));
daniel@transgaming.com53670042012-11-28 20:55:51 +0000446
daniel@transgaming.com12985182012-12-20 20:56:31 +0000447 GLfloat ccw = !gl::IsTriangleMode(drawMode) ? 0.0f : (frontFace == GL_CCW ? 1.0f : -1.0f);
daniel@transgaming.com88853c52012-12-20 20:56:40 +0000448 currentProgram->applyDxDepthFront((actualZFar - actualZNear) * 0.5f, (actualZNear + actualZFar) * 0.5f, ccw);
daniel@transgaming.com53670042012-11-28 20:55:51 +0000449
daniel@transgaming.com88853c52012-12-20 20:56:40 +0000450 currentProgram->applyDxDepthRange(actualZNear, actualZFar, actualZFar - actualZNear);
daniel@transgaming.com53670042012-11-28 20:55:51 +0000451 }
452
453 mForceSetViewport = false;
daniel@transgaming.com83e80ee2012-11-28 19:40:53 +0000454 return true;
455}
456
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000457bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count)
458{
daniel@transgaming.comc52be632012-11-28 21:04:28 +0000459 D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000460
daniel@transgaming.com0b03b062012-11-28 21:03:49 +0000461 switch (mode)
462 {
daniel@transgaming.comc52be632012-11-28 21:04:28 +0000463 case GL_POINTS: primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; break;
464 case GL_LINES: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINELIST; break;
daniel@transgaming.com0b03b062012-11-28 21:03:49 +0000465 case GL_LINE_LOOP: UNIMPLEMENTED(); /* TODO */ break;
daniel@transgaming.comc52be632012-11-28 21:04:28 +0000466 case GL_LINE_STRIP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; break;
467 case GL_TRIANGLES: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; break;
468 case GL_TRIANGLE_STRIP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; break;
daniel@transgaming.com0b03b062012-11-28 21:03:49 +0000469 case GL_TRIANGLE_FAN: UNIMPLEMENTED(); /* TODO */ break;
470 default:
471 return error(GL_INVALID_ENUM, false);
472 }
473
daniel@transgaming.comc52be632012-11-28 21:04:28 +0000474 mDeviceContext->IASetPrimitiveTopology(primitiveTopology);
daniel@transgaming.com0b03b062012-11-28 21:03:49 +0000475
476 return count > 0;
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000477}
478
479bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer)
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000480{
daniel@transgaming.com80fc3322012-11-28 21:02:13 +0000481 // Get the color render buffer and serial
482 gl::Renderbuffer *renderbufferObject = NULL;
483 unsigned int renderTargetSerial = 0;
484 if (framebuffer->getColorbufferType() != GL_NONE)
485 {
486 renderbufferObject = framebuffer->getColorbuffer();
daniel@transgaming.comdcf1e672012-11-28 19:38:19 +0000487
daniel@transgaming.com80fc3322012-11-28 21:02:13 +0000488 if (!renderbufferObject)
489 {
490 ERR("render target pointer unexpectedly null.");
daniel@transgaming.come9c71b42012-11-28 21:02:23 +0000491 return false;
daniel@transgaming.com80fc3322012-11-28 21:02:13 +0000492 }
493
494 renderTargetSerial = renderbufferObject->getSerial();
495 }
496
497 // Get the depth stencil render buffer and serials
498 gl::Renderbuffer *depthStencil = NULL;
499 unsigned int depthbufferSerial = 0;
500 unsigned int stencilbufferSerial = 0;
501 if (framebuffer->getDepthbufferType() != GL_NONE)
502 {
503 depthStencil = framebuffer->getDepthbuffer();
504 if (!depthStencil)
505 {
506 ERR("Depth stencil pointer unexpectedly null.");
507 return false;
508 }
509
510 depthbufferSerial = depthStencil->getSerial();
511 }
512 else if (framebuffer->getStencilbufferType() != GL_NONE)
513 {
514 depthStencil = framebuffer->getStencilbuffer();
515 if (!depthStencil)
516 {
517 ERR("Depth stencil pointer unexpectedly null.");
518 return false;
519 }
520
521 stencilbufferSerial = depthStencil->getSerial();
522 }
523
524 // Extract the render target dimensions and view
525 unsigned int renderTargetWidth = 0;
526 unsigned int renderTargetHeight = 0;
527 GLenum renderTargetFormat = 0;
528 ID3D11RenderTargetView* framebufferRTV = NULL;
529 if (renderbufferObject)
530 {
531 RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(renderbufferObject->getRenderTarget());
532 if (!renderTarget)
533 {
534 ERR("render target pointer unexpectedly null.");
535 return false;
536 }
537
538 framebufferRTV = renderTarget->getRenderTargetView();
539 if (!framebufferRTV)
540 {
541 ERR("render target view pointer unexpectedly null.");
542 return false;
543 }
544
545 renderTargetWidth = renderbufferObject->getWidth();
546 renderTargetHeight = renderbufferObject->getHeight();
547 renderTargetFormat = renderbufferObject->getActualFormat();
548 }
549
550 // Extract the depth stencil sizes and view
551 unsigned int depthSize = 0;
552 unsigned int stencilSize = 0;
553 ID3D11DepthStencilView* framebufferDSV = NULL;
554 if (depthStencil)
555 {
556 RenderTarget11 *depthStencilRenderTarget = RenderTarget11::makeRenderTarget11(depthStencil->getDepthStencil());
557 if (!depthStencilRenderTarget)
558 {
559 ERR("render target pointer unexpectedly null.");
560 if (framebufferRTV)
561 {
562 framebufferRTV->Release();
563 }
564 return false;
565 }
566
567 framebufferDSV = depthStencilRenderTarget->getDepthStencilView();
568 if (!framebufferDSV)
569 {
570 ERR("depth stencil view pointer unexpectedly null.");
571 if (framebufferRTV)
572 {
573 framebufferRTV->Release();
574 }
575 return false;
576 }
577
578 // If there is no render buffer, the width, height and format values come from
579 // the depth stencil
580 if (!renderbufferObject)
581 {
582 renderTargetWidth = depthStencil->getWidth();
583 renderTargetHeight = depthStencil->getHeight();
584 renderTargetFormat = depthStencil->getActualFormat();
585 }
586
587 depthSize = depthStencil->getDepthSize();
588 stencilSize = depthStencil->getStencilSize();
589 }
590
591 // Apply the render target and depth stencil
592 if (!mRenderTargetDescInitialized || !mDepthStencilInitialized ||
593 renderTargetSerial != mAppliedRenderTargetSerial ||
594 depthbufferSerial != mAppliedDepthbufferSerial ||
595 stencilbufferSerial != mAppliedStencilbufferSerial)
596 {
597 mDeviceContext->OMSetRenderTargets(1, &framebufferRTV, framebufferDSV);
598
599 mRenderTargetDesc.width = renderTargetWidth;
600 mRenderTargetDesc.height = renderTargetHeight;
601 mRenderTargetDesc.format = renderTargetFormat;
602 mForceSetViewport = true; // TODO: It may not be required to clamp the viewport in D3D11
603 mForceSetScissor = true; // TODO: It may not be required to clamp the scissor in D3D11
604
605 if (!mDepthStencilInitialized || depthSize != mCurDepthSize)
606 {
607 mCurDepthSize = depthSize;
608 mForceSetRasterState = true;
609 }
610
611 mCurStencilSize = stencilSize;
612
613 mAppliedRenderTargetSerial = renderTargetSerial;
614 mAppliedDepthbufferSerial = depthbufferSerial;
615 mAppliedStencilbufferSerial = stencilbufferSerial;
616 mRenderTargetDescInitialized = true;
617 mDepthStencilInitialized = true;
618 }
619
620 if (framebufferRTV)
621 {
622 framebufferRTV->Release();
623 }
624 if (framebufferDSV)
625 {
626 framebufferDSV->Release();
627 }
daniel@transgaming.comae39ee22012-11-28 19:42:02 +0000628
629 return true;
daniel@transgaming.com493d4f82012-11-28 19:35:45 +0000630}
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000631
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000632GLenum Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances)
daniel@transgaming.comdef9f0f2012-11-28 20:53:20 +0000633{
daniel@transgaming.comc5431eb2012-12-20 21:10:15 +0000634 TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS];
635 GLenum err = mVertexDataManager->prepareVertexData(vertexAttributes, programBinary, first, count, attributes, instances);
636 if (err != GL_NO_ERROR)
daniel@transgaming.comda495a12012-11-28 21:03:56 +0000637 {
daniel@transgaming.comc5431eb2012-12-20 21:10:15 +0000638 return err;
639 }
daniel@transgaming.comda495a12012-11-28 21:03:56 +0000640
daniel@transgaming.comc5431eb2012-12-20 21:10:15 +0000641 return mInputLayoutCache.applyVertexBuffers(attributes, programBinary);
daniel@transgaming.comdef9f0f2012-11-28 20:53:20 +0000642}
643
daniel@transgaming.com31240482012-11-28 21:06:41 +0000644GLenum Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000645{
daniel@transgaming.comc5431eb2012-12-20 21:10:15 +0000646 GLenum err = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo);
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000647
daniel@transgaming.comc5431eb2012-12-20 21:10:15 +0000648 if (err == GL_NO_ERROR)
649 {
650 if (indexInfo->serial != mAppliedIBSerial)
651 {
652 IndexBuffer11* indexBuffer = IndexBuffer11::makeIndexBuffer11(indexInfo->indexBuffer);
653
654 mDeviceContext->IASetIndexBuffer(indexBuffer->getBuffer(), indexBuffer->getIndexFormat(), indexInfo->startIndex);
655 mAppliedIBSerial = indexInfo->serial;
656 }
657 }
658
659 return err;
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000660}
661
662void Renderer11::drawArrays(GLenum mode, GLsizei count, GLsizei instances)
663{
daniel@transgaming.comd4cf2512012-11-28 21:05:41 +0000664 mDeviceContext->Draw(count, 0);
daniel@transgaming.com91207b72012-11-28 20:56:43 +0000665}
666
daniel@transgaming.com31240482012-11-28 21:06:41 +0000667void 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 +0000668{
669 // TODO
670 UNIMPLEMENTED();
671}
672
daniel@transgaming.com5fbf1772012-11-28 20:54:43 +0000673void Renderer11::applyShaders(gl::ProgramBinary *programBinary)
674{
daniel@transgaming.come4991412012-12-20 20:55:34 +0000675 unsigned int programBinarySerial = programBinary->getSerial();
676 if (programBinarySerial != mAppliedProgramBinarySerial)
677 {
678 ShaderExecutable *vertexExe = programBinary->getVertexExecutable();
679 ShaderExecutable *pixelExe = programBinary->getPixelExecutable();
daniel@transgaming.comd4b2db22012-11-28 21:05:15 +0000680
daniel@transgaming.come4991412012-12-20 20:55:34 +0000681 ID3D11VertexShader *vertexShader = NULL;
682 if (vertexExe) vertexShader = ShaderExecutable11::makeShaderExecutable11(vertexExe)->getVertexShader();
daniel@transgaming.comd4b2db22012-11-28 21:05:15 +0000683
daniel@transgaming.come4991412012-12-20 20:55:34 +0000684 ID3D11PixelShader *pixelShader = NULL;
685 if (pixelExe) pixelShader = ShaderExecutable11::makeShaderExecutable11(pixelExe)->getPixelShader();
daniel@transgaming.comd4b2db22012-11-28 21:05:15 +0000686
daniel@transgaming.come4991412012-12-20 20:55:34 +0000687 mDeviceContext->PSSetShader(pixelShader, NULL, 0);
688 mDeviceContext->VSSetShader(vertexShader, NULL, 0);
689 programBinary->dirtyAllUniforms();
690
691 mAppliedProgramBinarySerial = programBinarySerial;
692 }
daniel@transgaming.com5fbf1772012-11-28 20:54:43 +0000693}
694
daniel@transgaming.comab1c1462012-12-20 21:08:30 +0000695void Renderer11::applyUniforms(const gl::UniformArray *uniformArray)
696{
697 // TODO
698 if (uniformArray->size() != 0)
699 {
700 UNIMPLEMENTED();
701 }
702}
703
daniel@transgaming.com084a2572012-11-28 20:55:17 +0000704void Renderer11::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer)
daniel@transgaming.comd084c622012-11-28 19:36:05 +0000705{
daniel@transgaming.com54e67542012-11-28 21:02:31 +0000706 if (clearParams.mask & GL_COLOR_BUFFER_BIT)
707 {
708 gl::Renderbuffer *renderbufferObject = frameBuffer->getColorbuffer();
709 if (renderbufferObject)
710 {
711 RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(renderbufferObject->getRenderTarget());
712 if (!renderTarget)
713 {
714 ERR("render target pointer unexpectedly null.");
715 return;
716 }
717
718 ID3D11RenderTargetView *framebufferRTV = renderTarget->getRenderTargetView();
719 if (!framebufferRTV)
720 {
721 ERR("render target view pointer unexpectedly null.");
722 return;
723 }
724
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000725 if (mScissorEnabled && (mCurScissor.x > 0 || mCurScissor.y > 0 ||
726 mCurScissor.x + mCurScissor.width < renderTarget->getWidth() ||
727 mCurScissor.y + mCurScissor.height < renderTarget->getHeight()))
daniel@transgaming.com54e67542012-11-28 21:02:31 +0000728 {
729 // TODO: clearing of subregion of render target
730 UNIMPLEMENTED();
731 }
732
733 bool alphaUnmasked = (gl::GetAlphaSize(mRenderTargetDesc.format) == 0) || clearParams.colorMaskAlpha;
734 const bool needMaskedColorClear = (clearParams.mask & GL_COLOR_BUFFER_BIT) &&
735 !(clearParams.colorMaskRed && clearParams.colorMaskGreen &&
736 clearParams.colorMaskBlue && alphaUnmasked);
737
738 if (needMaskedColorClear)
739 {
740 // TODO: masked color clearing
741 UNIMPLEMENTED();
742 }
743 else
744 {
745 const float clearValues[4] = { clearParams.colorClearValue.red,
746 clearParams.colorClearValue.green,
747 clearParams.colorClearValue.blue,
748 clearParams.colorClearValue.alpha };
749 mDeviceContext->ClearRenderTargetView(framebufferRTV, clearValues);
750 }
751
752 framebufferRTV->Release();
753 }
754 }
755 if (clearParams.mask & GL_DEPTH_BUFFER_BIT || clearParams.mask & GL_STENCIL_BUFFER_BIT)
756 {
757 gl::Renderbuffer *renderbufferObject = frameBuffer->getDepthOrStencilbuffer();
758 if (renderbufferObject)
759 {
760 RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(renderbufferObject->getRenderTarget());
761 if (!renderTarget)
762 {
763 ERR("render target pointer unexpectedly null.");
764 return;
765 }
766
767 ID3D11DepthStencilView *framebufferDSV = renderTarget->getDepthStencilView();
768 if (!framebufferDSV)
769 {
770 ERR("depth stencil view pointer unexpectedly null.");
771 return;
772 }
773
daniel@transgaming.comd55e8c12012-11-28 21:07:02 +0000774 if (mScissorEnabled && (mCurScissor.x > 0 || mCurScissor.y > 0 ||
775 mCurScissor.x + mCurScissor.width < renderTarget->getWidth() ||
776 mCurScissor.y + mCurScissor.height < renderTarget->getHeight()))
daniel@transgaming.com54e67542012-11-28 21:02:31 +0000777 {
778 // TODO: clearing of subregion of depth stencil view
779 UNIMPLEMENTED();
780 }
781
782 unsigned int stencilUnmasked = 0x0;
783 if ((clearParams.mask & GL_STENCIL_BUFFER_BIT) && frameBuffer->hasStencil())
784 {
785 unsigned int stencilSize = gl::GetStencilSize(frameBuffer->getStencilbuffer()->getActualFormat());
786 stencilUnmasked = (0x1 << stencilSize) - 1;
787 }
788
789 const bool needMaskedStencilClear = (clearParams.mask & GL_STENCIL_BUFFER_BIT) &&
790 (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked;
791
792 if (needMaskedStencilClear)
793 {
794 // TODO: masked clearing of depth stencil
795 UNIMPLEMENTED();
796 }
797 else
798 {
799 UINT clearFlags = 0;
800 if (clearParams.mask & GL_DEPTH_BUFFER_BIT)
801 {
802 clearFlags |= D3D11_CLEAR_DEPTH;
803 }
804 if (clearParams.mask & GL_STENCIL_BUFFER_BIT)
805 {
806 clearFlags |= D3D11_CLEAR_STENCIL;
807 }
808
809 float depthClear = clearParams.depthClearValue;
810 UINT8 stencilClear = clearParams.stencilClearValue & 0x000000FF;
811
812 mDeviceContext->ClearDepthStencilView(framebufferDSV, clearFlags, depthClear, stencilClear);
813 }
814
815 framebufferDSV->Release();
816 }
817 }
daniel@transgaming.comd084c622012-11-28 19:36:05 +0000818}
819
daniel@transgaming.comc43a6052012-11-28 19:41:51 +0000820void Renderer11::markAllStateDirty()
821{
daniel@transgaming.com9a067372012-12-20 20:55:24 +0000822 mAppliedRenderTargetSerial = 0;
823 mAppliedDepthbufferSerial = 0;
824 mAppliedStencilbufferSerial = 0;
daniel@transgaming.com7b6b83e2012-11-28 21:00:30 +0000825 mDepthStencilInitialized = false;
826 mRenderTargetDescInitialized = false;
827
daniel@transgaming.comc43a6052012-11-28 19:41:51 +0000828 mForceSetBlendState = true;
829 mForceSetRasterState = true;
830 mForceSetDepthStencilState = true;
831 mForceSetScissor = true;
daniel@transgaming.com53670042012-11-28 20:55:51 +0000832 mForceSetViewport = true;
daniel@transgaming.come4991412012-12-20 20:55:34 +0000833
daniel@transgaming.comc5431eb2012-12-20 21:10:15 +0000834 mAppliedIBSerial = 0;
daniel@transgaming.come4991412012-12-20 20:55:34 +0000835 mAppliedProgramBinarySerial = 0;
daniel@transgaming.comc43a6052012-11-28 19:41:51 +0000836}
837
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000838void Renderer11::releaseDeviceResources()
839{
daniel@transgaming.comf8ba1092012-11-28 19:37:53 +0000840 mStateCache.clear();
daniel@transgaming.comc5431eb2012-12-20 21:10:15 +0000841 mInputLayoutCache.clear();
842
843 delete mVertexDataManager;
844 mVertexDataManager = NULL;
845
846 delete mIndexDataManager;
847 mIndexDataManager = NULL;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000848}
849
850void Renderer11::markDeviceLost()
851{
852 mDeviceLost = true;
853}
854
855bool Renderer11::isDeviceLost()
856{
857 return mDeviceLost;
858}
859
860// set notify to true to broadcast a message to all contexts of the device loss
861bool Renderer11::testDeviceLost(bool notify)
862{
863 bool isLost = false;
864
865 // TODO
daniel@transgaming.comb9bb2792012-11-28 19:36:49 +0000866 //UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000867
868 if (isLost)
869 {
870 // ensure we note the device loss --
871 // we'll probably get this done again by markDeviceLost
872 // but best to remember it!
873 // Note that we don't want to clear the device loss status here
874 // -- this needs to be done by resetDevice
875 mDeviceLost = true;
876 if (notify)
877 {
878 mDisplay->notifyDeviceLost();
879 }
880 }
881
882 return isLost;
883}
884
885bool Renderer11::testDeviceResettable()
886{
887 HRESULT status = D3D_OK;
888
889 // TODO
890 UNIMPLEMENTED();
891
892 switch (status)
893 {
894 case D3DERR_DEVICENOTRESET:
895 case D3DERR_DEVICEHUNG:
896 return true;
897 default:
898 return false;
899 }
900}
901
902bool Renderer11::resetDevice()
903{
904 releaseDeviceResources();
905
906 // TODO
907 UNIMPLEMENTED();
908
909 // reset device defaults
910 initializeDevice();
911 mDeviceLost = false;
912
913 return true;
914}
915
916DWORD Renderer11::getAdapterVendor() const
917{
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000918 return mAdapterDescription.VendorId;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000919}
920
921const char *Renderer11::getAdapterDescription() const
922{
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000923 return mDescription;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000924}
925
926GUID Renderer11::getAdapterIdentifier() const
927{
928 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000929 // UNIMPLEMENTED();
930 GUID foo = {0};
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000931 return foo;
932}
933
934bool Renderer11::getDXT1TextureSupport()
935{
936 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000937 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000938 return false;
939}
940
941bool Renderer11::getDXT3TextureSupport()
942{
943 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000944 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000945 return false;
946}
947
948bool Renderer11::getDXT5TextureSupport()
949{
950 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000951 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000952 return false;
953}
954
955bool Renderer11::getDepthTextureSupport() const
956{
957 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000958 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000959 return false;
960}
961
962bool Renderer11::getFloat32TextureSupport(bool *filtering, bool *renderable)
963{
964 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000965 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000966
967 *filtering = false;
968 *renderable = false;
969 return false;
970}
971
972bool Renderer11::getFloat16TextureSupport(bool *filtering, bool *renderable)
973{
974 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000975 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000976
977 *filtering = false;
978 *renderable = false;
979 return false;
980}
981
982bool Renderer11::getLuminanceTextureSupport()
983{
984 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000985 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000986 return false;
987}
988
989bool Renderer11::getLuminanceAlphaTextureSupport()
990{
991 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000992 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +0000993 return false;
994}
995
996bool Renderer11::getTextureFilterAnisotropySupport() const
997{
998 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +0000999 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001000 return false;
1001}
1002
1003float Renderer11::getTextureMaxAnisotropy() const
1004{
1005 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001006 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001007 return 1.0f;
1008}
1009
1010bool Renderer11::getEventQuerySupport()
1011{
1012 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001013 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001014 return false;
1015}
1016
1017bool Renderer11::getVertexTextureSupport() const
1018{
1019 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001020 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001021 return false;
1022}
1023
1024bool Renderer11::getNonPower2TextureSupport() const
1025{
1026 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001027 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001028 return false;
1029}
1030
1031bool Renderer11::getOcclusionQuerySupport() const
1032{
1033 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001034 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001035 return false;
1036}
1037
1038bool Renderer11::getInstancingSupport() const
1039{
1040 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001041 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001042 return false;
1043}
1044
1045bool Renderer11::getShareHandleSupport() const
1046{
1047 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001048 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001049
1050 // PIX doesn't seem to support using share handles, so disable them.
1051 return false && !gl::perfActive();
1052}
1053
daniel@transgaming.com9549bea2012-11-28 20:57:23 +00001054int Renderer11::getMajorShaderModel() const
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001055{
daniel@transgaming.com9549bea2012-11-28 20:57:23 +00001056 switch (mFeatureLevel)
1057 {
1058 case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MAJOR_VERSION; // 5
1059 case D3D_FEATURE_LEVEL_10_1:
1060 case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MAJOR_VERSION; // 4
1061 default: UNREACHABLE(); return 0;
1062 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001063}
1064
1065float Renderer11::getMaxPointSize() const
1066{
1067 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001068 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001069 return 1.0f;
1070}
1071
1072int Renderer11::getMaxTextureWidth() const
1073{
daniel@transgaming.com25072f62012-11-28 19:31:32 +00001074 switch (mFeatureLevel)
1075 {
1076 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
1077 case D3D_FEATURE_LEVEL_10_1:
1078 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
1079 default: UNREACHABLE(); return 0;
1080 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001081}
1082
1083int Renderer11::getMaxTextureHeight() const
1084{
daniel@transgaming.com25072f62012-11-28 19:31:32 +00001085 switch (mFeatureLevel)
1086 {
1087 case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
1088 case D3D_FEATURE_LEVEL_10_1:
1089 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
1090 default: UNREACHABLE(); return 0;
1091 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001092}
1093
1094bool Renderer11::get32BitIndexSupport() const
1095{
daniel@transgaming.com25072f62012-11-28 19:31:32 +00001096 switch (mFeatureLevel)
1097 {
1098 case D3D_FEATURE_LEVEL_11_0:
1099 case D3D_FEATURE_LEVEL_10_1:
1100 case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP >= 32; // true
1101 default: UNREACHABLE(); return false;
1102 }
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001103}
1104
1105int Renderer11::getMinSwapInterval() const
1106{
daniel@transgaming.com8c7b1a92012-11-28 19:34:06 +00001107 return 0;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001108}
1109
1110int Renderer11::getMaxSwapInterval() const
1111{
daniel@transgaming.com8c7b1a92012-11-28 19:34:06 +00001112 return 4;
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001113}
1114
1115int Renderer11::getMaxSupportedSamples() const
1116{
1117 // TODO
daniel@transgaming.com1f811f52012-11-28 20:57:39 +00001118 // UNIMPLEMENTED();
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001119 return 1;
1120}
1121
daniel@transgaming.com87705f82012-12-20 21:10:45 +00001122bool Renderer11::copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source)
daniel@transgaming.comad6aee72012-11-28 19:33:42 +00001123{
1124 // TODO
1125 UNIMPLEMENTED();
1126 return false;
1127}
1128
daniel@transgaming.com87705f82012-12-20 21:10:45 +00001129bool Renderer11::copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source)
daniel@transgaming.comad6aee72012-11-28 19:33:42 +00001130{
1131 // TODO
1132 UNIMPLEMENTED();
1133 return false;
1134}
1135
daniel@transgaming.com38380882012-11-28 19:36:39 +00001136bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat,
daniel@transgaming.com87705f82012-12-20 21:10:45 +00001137 GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level)
daniel@transgaming.com38380882012-11-28 19:36:39 +00001138{
1139 // TODO
1140 UNIMPLEMENTED();
1141 return false;
1142}
1143
1144bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat,
daniel@transgaming.com87705f82012-12-20 21:10:45 +00001145 GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level)
daniel@transgaming.com38380882012-11-28 19:36:39 +00001146{
1147 // TODO
1148 UNIMPLEMENTED();
1149 return false;
1150}
1151
daniel@transgaming.comf2423652012-11-28 20:53:50 +00001152RenderTarget *Renderer11::createRenderTarget(SwapChain *swapChain, bool depth)
1153{
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +00001154 SwapChain11 *swapChain11 = SwapChain11::makeSwapChain11(swapChain);
1155 RenderTarget11 *renderTarget = NULL;
1156 if (depth)
1157 {
1158 renderTarget = new RenderTarget11(this, swapChain11->getDepthStencil(), swapChain11->getWidth(), swapChain11->getHeight());
1159 }
1160 else
1161 {
1162 renderTarget = new RenderTarget11(this, swapChain11->getRenderTarget(), swapChain11->getWidth(), swapChain11->getHeight());
1163 }
1164 return renderTarget;
daniel@transgaming.comf2423652012-11-28 20:53:50 +00001165}
1166
1167RenderTarget *Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth)
1168{
1169 // TODO
1170 UNIMPLEMENTED();
1171 return NULL;
1172}
1173
daniel@transgaming.com7b18d0c2012-11-28 21:04:10 +00001174ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length, GLenum type, void *data)
daniel@transgaming.com55318902012-11-28 20:58:58 +00001175{
daniel@transgaming.coma2f9fbe2012-11-28 21:03:40 +00001176 ShaderExecutable11 *executable = NULL;
1177
1178 switch (type)
1179 {
1180 case GL_VERTEX_SHADER:
1181 {
1182 ID3D11VertexShader *vshader = NULL;
1183 HRESULT result = mDevice->CreateVertexShader(function, length, NULL, &vshader);
1184 ASSERT(SUCCEEDED(result));
1185
1186 if (vshader)
1187 {
daniel@transgaming.com7b18d0c2012-11-28 21:04:10 +00001188 executable = new ShaderExecutable11(function, length, vshader);
daniel@transgaming.coma2f9fbe2012-11-28 21:03:40 +00001189 }
1190 }
1191 break;
1192 case GL_FRAGMENT_SHADER:
1193 {
1194 ID3D11PixelShader *pshader = NULL;
1195 HRESULT result = mDevice->CreatePixelShader(function, length, NULL, &pshader);
1196 ASSERT(SUCCEEDED(result));
1197
1198 if (pshader)
1199 {
daniel@transgaming.com7b18d0c2012-11-28 21:04:10 +00001200 executable = new ShaderExecutable11(function, length, pshader);
daniel@transgaming.coma2f9fbe2012-11-28 21:03:40 +00001201 }
1202 }
1203 break;
1204 default:
1205 UNREACHABLE();
1206 break;
1207 }
1208
1209 return executable;
daniel@transgaming.com55318902012-11-28 20:58:58 +00001210}
1211
daniel@transgaming.coma9c71422012-11-28 20:58:45 +00001212ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, GLenum type)
1213{
daniel@transgaming.com071ee6a2012-11-28 21:03:21 +00001214 const char *profile = NULL;
1215
1216 switch (type)
1217 {
1218 case GL_VERTEX_SHADER:
1219 profile = "vs_4_0";
1220 break;
1221 case GL_FRAGMENT_SHADER:
1222 profile = "ps_4_0";
1223 break;
1224 default:
1225 UNREACHABLE();
1226 return NULL;
1227 }
1228
daniel@transgaming.com25e16af2012-11-28 21:05:57 +00001229 ID3DBlob *binary = compileToBinary(infoLog, shaderHLSL, profile, false);
daniel@transgaming.com071ee6a2012-11-28 21:03:21 +00001230 if (!binary)
1231 return NULL;
1232
1233 ShaderExecutable *executable = loadExecutable((DWORD *)binary->GetBufferPointer(), binary->GetBufferSize(), type, NULL);
1234 binary->Release();
1235
1236 return executable;
1237}
1238
daniel@transgaming.com3f255b42012-12-20 21:07:35 +00001239VertexBuffer *Renderer11::createVertexBuffer()
1240{
daniel@transgaming.com2c4d0702012-12-20 21:08:51 +00001241 return new VertexBuffer11(this);
daniel@transgaming.com3f255b42012-12-20 21:07:35 +00001242}
1243
daniel@transgaming.com0b6d7742012-12-20 21:09:47 +00001244IndexBuffer *Renderer11::createIndexBuffer()
1245{
daniel@transgaming.com11c2af52012-12-20 21:10:01 +00001246 return new IndexBuffer11(this);
daniel@transgaming.com0b6d7742012-12-20 21:09:47 +00001247}
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.com413d2712012-12-20 21:11:04 +00001277TextureStorage *Renderer11::createTextureStorage2D(SwapChain *swapChain)
1278{
1279 // TODO
1280 UNIMPLEMENTED();
1281 return NULL;
1282}
1283
1284TextureStorage *Renderer11::createTextureStorage2D(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height)
1285{
1286 // TODO
1287 UNIMPLEMENTED();
1288 return NULL;
1289}
1290
1291TextureStorage *Renderer11::createTextureStorageCube(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size)
1292{
1293 // TODO
1294 UNIMPLEMENTED();
1295 return NULL;
1296}
1297
daniel@transgaming.com1d6aff22012-11-28 19:30:42 +00001298}